デジタル庁の「源内」をローカルで動かした

きっかけ

源内の存在は以前から知っていて興味を持っていた。先日のAWS Summitでもセッションが話題になっていて、行政向けのAI基盤がOSSで出ているのは面白いと思っていた。何か源内でしてみたいなと思っていた。

そんな時に、こんな通知を見かけた。

クラウド依存を全部OSSに置き換えたフォークがあると知って、試してみた。

何をやったか

デジタル庁がMITライセンスで公開しているガバメントAI「源内(GENAI)」。チャット、RAG、翻訳、文字起こし、チーム管理まで一通り揃っている。ただし構成がAWSべったり(Cognito、Bedrock、DynamoDB、Lambda等)で、そのままでは庁内の閉域網では動かない。

有志が作った Open GENAI は、そのクラウド依存を全部OSSに置き換えたフォーク。MacBook Pro 1台でDocker起動して、行政業務を想定した4つのデモを試した。

免責: Open GENAIはデジタル庁の非公式フォーク。同庁とは無関係。

置き換えの中身

機能

源内オリジナル(AWS)

Open GENAI(ローカル)

認証

Amazon Cognito

Keycloak(SAML)

LLM推論

Amazon Bedrock

Ollama(OpenAI互換API)

チャット履歴

DynamoDB

SQLite

RAG

OpenSearch + Bedrock

Qdrant + mxbai-embed-large

文字起こし

Amazon Transcribe

faster-whisper

画像生成

Bedrock

Stable Diffusion(A1111互換)

構成はシンプルで、ブラウザ → 源内Web(Vite:5173) → backend(FastAPI:8000) → Ollama(11434)。履歴とベクトルDBはSQLiteとQdrant。

セットアップ

READMEの手順だけでは動かなかった。実際に踏んだ問題と対処を書いておく。

基本の流れ:

ollama pull qwen2.5:7b
ollama pull mxbai-embed-large
git clone https://github.com/nananaman/open-genai.git
cd open-genai
cp .env.example .env
docker compose up --build

これだけでは足りない。以下を手動で直す必要があった。

.envの修正:

RAG_MODEL=gpt-oss:20bRAG_MODEL=qwen2.5:7b に変える。デフォルトの gpt-oss:20b はOllamaにpullしていないと502が返る。

フロントのモデル一覧:

genai-web/packages/web/.envVITE_APP_MODEL_IDS にデフォルトで gpt-oss:20bgemma3:27b しか入っていない。自分がpullした qwen2.5:7b を足してrebuild。

埋め込みモデル:

RAGを使うには mxbai-embed-large が必要。これを入れずにドキュメントを登録すると、ベクトルが空のまま保存されて検索が効かない。後からpullした場合は知識ベースを全消去して再登録する。

ブラウザのキャッシュ:

モデル選択がlocalStorageに保存されるので、モデル一覧を変えてもブラウザが前回の選択を覚えていてエラーになる。DevToolsで localStorage.removeItem('modelId_v20260218') するか、ドロップダウンで手動選択し直す。

初回起動からチャットが動くまで15分くらい。Keycloakの起動が遅いので焦らず待つ。

デモ1: 行政文書のドラフト作成

チャットにシステムプロンプトを設定して公文書の下書きを作らせた。

システムプロンプトに「桜川市の政策秘書」「議会答弁書の下書き」「事実と方針を区別」等のルールを入れて、議員質問への答弁を生成。

出力の一部:

本市においては、先般から庁内AIチャットの試験導入を行い、
6月中旬より本格的に運用を開始いたしました。
これにより、総務課及び住民課で35名の職員が利用しており、
現在では月間約420回の活用実績があるところです。

このAIチャットプラットフォームは、完全なローカル環境であるため、
データは本市へ残され、庁外に一切出ることはございません。

qwen2.5:7bで答弁書の型をそれなりに守れている。ただし途中で「時間izzas」のような文字化けが出たり、語尾が揺れたりする。下書きとして使って職員が直す前提ならアリ。GPT-4oと比べたら当然落ちるが、「クラウドに出せない環境での第一歩」としては成立している。

システムプロンプトを変えれば通知文や住民向けお知らせにも切り替えられる。「やさしい日本語で」と指示すれば平易な表現に書き換えもできた。

デモ2: 庁内文書のRAG検索

AIアプリの「ローカルRAG」に、架空の桜川市の文書を3件登録して質問した。

  • 桜川市個人情報保護条例

  • 桜川市AI利活用ガイドライン

  • 桜川市子育て支援給付金交付要綱

うまくいった質問:

「AIシステムで個人情報を扱う場合、どのような安全管理措置が必要ですか?条例とガイドラインの両方から教えてください。」

→ ガイドライン(アクセス制御、ログ管理、定期監査、インシデント対応)と条例(個人情報ファイルの管理)を横断して回答。出典番号付き。類似度0.808〜0.756。

「個人情報の開示請求をした場合、何日以内に回答がもらえますか?」

→ 「15日以内。ただし事務処理上の困難その他正当な理由があるときは30日以内に延長可」。出典: 条例、類似度0.799。正確。

うまくいかなかった質問:

「子育て支援給付金の申請期限はいつまでですか?」

→ 参照件数4(デフォルト)だと「情報が見つかりません」。10に上げてようやく類似度0.762でヒット。mxbai-embed-largeの埋め込みで「期限」と「期間」の意味距離が遠いらしく、申請期間を定めた条文が上位に来ない。

ここが正直な限界。埋め込みモデルの語彙特性に左右されるので、聞き方を工夫するか、参照件数を多めに取る運用が要る。ただ「出典がない場合は推測しない」という振る舞いは、行政文書の検索としてはむしろ健全だと思った。

デモ3: 多言語翻訳

住民向け案内文を「やさしい日本語」に変換した。

やさしい日本語は、1995年の阪神・淡路大震災で外国人住民に災害情報が届かなかった教訓から広まった書き方。自治体の窓口ではすでに使われている。1文を短く、難しい言葉を避け、具体的に書く。

入力:

令和8年度において、子育て世帯の経済的負担を軽減するため、
18歳未満の児童を養育する世帯に対し、
児童1人あたり3万円の給付金を支給いたします。
申請期間は令和8年7月1日から同年9月30日までとなっております。

出力:

18歳未満の子供がいる家族へ、一人3万円を支給します。
7月1日から9月30日まで申請します。
インターネットや市役所窓口でできます。
期日までに申請してください。

文が短くなり、「経済的負担を軽減するため」のような理由書きが消え、やるべきことだけ残っている。窓口で外国人住民に渡す案内としてそのまま使える水準だった。

英語や中国語への翻訳もそのまま動く。転入届、ごみの出し方など定型文書の多言語化に向いている。

デモ4: 議事録の文字起こし

AIアプリの「ローカル文字起こし(Whisper)」に、架空の会議を読み上げた1分の音声を投げた。faster-whisperがCPUで動く。

出力(一部):

[00:32 - 00:37] 6月から2ヶ月間総務課と住民課で 試験運用を行いました
[00:37 - 00:39] 利用者は合計35名
[00:39 - 00:43] 月間の利用回数は約420回でした
[00:50 - 00:56] 問合わせ対応のF1級政策が25%でした
[00:56 - 01:03] 職員アンケートでは89% 業務効率が2役だったと回答しています

「FAQ作成が25%」→「F1級政策が25%」、「役立った」→「2役だった」。認識誤りはある。ただ1分の音声を数秒でテキスト化できるのは事実で、この結果をそのままチャットに貼って「要点3つにまとめて」と頼むと:

  • 議題: 庁内AIチャットの試験運用結果と今後の展開方針

  • 試験結果: 35名利用、月420回、89%が効率向上を評価

  • 好評だった機能: 通知文ドラフト作成と多言語対応

文字起こし→要約の2段階がローカルで完結する。審議会の録音をクラウドに上げたくない自治体には使える流れだと思う。

ネットワークの話

「完全ローカル」と書いたが、1つ落とし穴がある。

Wi-Fiを完全にオフにした状態で試したら、ブラウザが「インターネットに接続されていません」と出て localhost に繋がらなかった。バックエンドは生きている:

$ curl http://localhost:11434/v1/models   # OK
$ curl http://localhost:8000/health       # OK
$ curl http://localhost:8088/realms/open-genai  # OK

ブラウザの仕様で、ネットワークインターフェースがdownするとlocalhostへのリクエスト自体を止める。源内やDockerの問題ではない。

要するに「外部インターネットへの通信は不要だが、ネットワークインターフェースはupしている必要がある」。LGWAN環境(閉域網に接続されているがインターネットには出ない)なら問題ない。実際の庁内ネットワークとは合致する。

行政で使うとしたら

自分が自治体の情報システム課にいたとして、これをどう使うか考えた。

使えそうな場面:

  • 住民の個人情報を含む文書の処理。データが庁外に出ない

  • 部署ごとに知識ベースを分離したRAG。福祉課は福祉、税務課は税務だけ検索できる

  • 窓口での多言語対応。翻訳結果を印刷して渡す

  • 審議会の録音をその場で文字起こし

PoCとしての利点は「予算がかからない」こと。クラウド利用料ゼロで、情報システム課の担当者が自分の判断で検証を始められる。

使えない場面:

  • 回答品質を求める場面。qwen2.5:7bはGPT-4oやClaude Sonnetとは差がある。文字化け、幻覚、文体の崩れが出る

  • 即応性が求められる場面。Apple SiliconのGPU(Metal)でも回答に数秒〜十数秒かかる

  • 本番運用。認証がHTTP+既定パスワードの開発設定なので、そのまま庁内展開するなら鍵とTLSの見直しが必要

まとめ

源内のUI・機能セットを丸ごとローカルで動かせるのは、検証用としては十分に価値がある。「クラウドに出せないからAIは使えない」という状態から一歩進める。

品質はモデル次第で、7Bパラメータのローカルモデルにクラウドの大規模モデルと同じ品質を求めるのは無理がある。「下書きを作って職員が直す」「検索で根拠を出して職員が判断する」という使い方なら成立する。まずは机の上で動かしてみるところから。