176 Views
March 11, 26
スライド概要
「AI活用」は、単なるチャットボットへの質問やコード生成だけで終わらせてはいけない――。
DeNAのゲーム事業でこれを乗り越えた「AIが開発環境に溶け込む世界」を目指すために選択・構築したエコシステムの全貌を解説します。
このようなエコシステムを構築するために、我々はMicrosoft.Extensions.AIを中核に据え、UnityとAIを接続する「Rinchan.Client」、AIを含む外部からの実機操作を可能にするRPCシステム「Leap」、社内知識を統合する「Rinchan」を開発しました。 ログ解析から仕様確認、コード修正、そしてUnityでのコンパイルと実機テストまで——。AIが開発者の「手」となり「脳」となって自律的に動くワークフローを実現するための実装論をご紹介します 。
DeNA が社会の技術向上に貢献するため、業務で得た知見を積極的に外部に発信する、DeNA 公式のアカウントです。DeNA エンジニアの登壇資料をお届けします。
LLMを"あたりまえ"に! 開発環境のエコシステム 大竹 悠人 1
自己紹介 大竹 悠人 エンジニア / 株式会社ディー・エヌ・エー モバイルゲームの開発効率を高めるための 様々な仕組み作りに、 継続的に取り組んでいます。 2
目次 ● 意義と5つの壁 ● 標準化と実装: Microsoft.Extensions.AIと Rinchan.Client ● 実行手段を与える: Leap ● 知識を与える: Rinchan ● まとめ 3
意義と5つの壁 4
“あたりまえ”とは何か ● ● 「AI活用」が「チャットボットに質問すること」や、 「コーディングエージェントにコードを書かせること」になっていないか? ○ チャットボットやコーディングエージェントは幅広い課題解決の役に立つが、 ○ 手でコンテキストを伝えるのも手間だし、限界がある。 ○ そもそも、ゲーム開発で行われる作業は、質問やコーディングだけではない 「AIを使うぞ」と身構える必要がある時点で、特別扱いしている 5
“あたりまえ”とは何か ● ● ゲーム開発は多数のツールを利用・作成し、開発フローを構築している ○ レベルエディタ/コリジョン設定/アニメーション設定など... 「開発者が”あたりまえ”に行う開発の中に、AIが馴染んだ世界」を目指す ○ AIが様々なUnity Editor拡張や社内ツールの中に組み込まれ、 多様な領域で効率化の手段として機能する状態にする ○ コーディングエージェントを筆頭とした汎用AIエージェントも 非常に強力な存在で、多様な作業を自動化できる可能性がある。 ゲーム開発で必要な作業を、AIエージェントからも行えるようにする 6
汎用ツールが越えられない「現場の壁」 ● ● 全社AI基盤やコーディングエージェントの普及により、 高性能なモデルへのアクセスは民主化され、AI活用することは”あたりまえ”になった ○ しかし、ゲーム開発などのコンテキストの極めて深い作業を行わせると、 彼らは単なる「優秀な外野」になってしまう 現場との間の2つの大きな「ラストワンマイル」の断絶を埋める必要がある 7
外野を阻む2つの断絶(ラストワンマイル) ● ● コンテキストの断絶(見えない) ○ 静的な暗黙知: ■ プロジェクト特有のアセット規則/ディレクトリ構成/独自ライブラリなど ○ 動的な状態: ■ 「今、Unity Editorで何が起きているか」(エラーログなど)が見えていない アクションの断絶(手出しできない) ○ 部品になれない (AI as a Component): ■ Unity内のツールにAIを組み込むにも、 実装やスキーマ定義のコストが課題に対して重い ○ 手足がない (AI as an Agent): ■ AIからUnity特有のライフサイクル管理や、UnityEditorに実装された プロジェクト特有の操作ができず、自律的な作業ができない ○ ツールの分断が解消されず、連続したフローとして統合できない 8
「享受」から「当事者」へ ● ● 誰かが完璧な汎用ツールを提供してくれるのを、ただ「享受」しているだけでは、 この現場特有の「2つの断絶」は埋まらない ○ モデルの性能の問題ではなく、それを囲む環境(エコシステム)の問題になる 対象業務を最も深く理解する現場の我々自身が、当事者として埋める必要がある ○ 現場でAIを組み込もうとすると、本質的な機能開発以前に技術的な壁が多くある ○ “自分たちがやるしかない”が、”それをやるのは大変”というジレンマ ○ 小さな課題解決に大きな工数がかかると、割に合わない 現場のエンジニアが、AIを「息をするように」低コストで、 自らの手足として活用できる環境が必要になる 9
課題の分解 - 現場主導を阻む「5つの壁」 ● 現場のエンジニアが「あたりまえ」を実現しようとした時、立ちはだかる壁 ○ 標準化の壁: モデルごとに異なるAPI/SDKを覚える学習コスト ○ 環境の壁: 認証や通信をセキュアに保つ実装コスト ○ 実装の壁: Unityで動く標準準拠のクライアントの不在 ○ 実行の壁: AIから、手元のUnity(ローカル)を操作する手段の欠如 ○ 知識の壁: 汎用LLMは社内ライブラリやプロジェクト固有の仕様を知らない 10
壁を乗り越えるためのエコシステム ● これらの壁を乗り越えるため、OSS/クラウドサービス/内製プロダクトを 組み合わせてエコシステムを構築 ○ [標準化] Microsoft.Extensions.AI: すべての中心となる標準インターフェース ○ [環 境] Cloud IAP + OAuth: セキュアかつ手軽な認証 ○ [実 装] Rinchan.Client: Unity上で動作するMicrosoft.Extensions.AI準拠の実装 ○ [実 行] Leap: ツール実行をUnityへ届けるデリバリーシステム ○ [知 識] Rinchan: 社内ナレッジへのアクセスハブ 11
標準化と実装: Microsoft.Extensions.AIと Rinchan.Client 12
課題 - UnityとモダンAIエコシステムの「断絶」 ● ● 現場の使命は「機能開発」であり、「AI基盤の開発」ではない ○ LLMを使おうとするたび、HTTP通信、JSON Schema、Function Callingループ、 エラーハンドリングを各プロジェクトで実装するのは非効率 ○ 「このエディタ拡張にちょっとAI入れたい」と思っても準備が大変で割に合わない ■ 結果、Unity Editorの中にAIが浸透していかず、AI as a Componentを阻む Unity Editor内で実用的に、簡単にAIを利用できるライブラリが必要 13
[標準化] - Microsoft.Extensions.AI の採用 ● ● ● ● Microsoft.Extensions.AI とは?: ○ Microsoftが策定した、LLM利用のための強力な抽象化レイヤ 統合されたインターフェース: ○ Gemini, OpenAI, Local LLM... モデルごとのAPI差異を吸収する抽象化レイヤ 基盤となる共通ロジック: ○ C#のメソッド定義からLLM用のJSON Schemaを自動生成 ○ 「LLMが関数実行を要求 →プログラム側が実行 → 結果をLLMに送信」 という面倒なループ処理を透過的に行える 開発者は「LLMの制御ロジック」を書く必要がない。 「どんな機能を作りたいか」(プロンプトと関数定義)だけに集中できる。 14
Function Callingの抽象化 - AIFunctionとFunctionInvokingChatClient
●
●
// 戻り値の型定義
AI用スキーマの自動生成
public class WeaponData
○ C#の属性によるアノテーションや型の {
[Description("武器の名称 (例: エクスカリバー )")]
情報から、Function
public string Name { get; set; }
[Description("武器の基礎攻撃力 ")]
Calling/Structured ResponseでAIが必
public int AttackPower { get; set; }
要とする
}
// ツール本体
JSONスキーマが動的に生成される
public class GameDatabase
実装と仕様の統一
{//..中略..
[Description("武器カタログからスペックを検索します ")]
○ C#コードとAI用のスキーマが
public WeaponData GetWeaponStats(
別々に存在するのではなく、
[Description("検索したい武器の名前 ")] string name)
{
C#コード自体がスキーマを兼ねる為、
// 実際のDB検索処理 (AIは関知しない )
乖離が発生しない
return _db.Weapon.Find(name);
}
}
15
Function Callingの抽象化 - AIFunctionとFunctionInvokingChatClient
// 1. ツール生成
●
●
●
AIFunctionFactoryに関数のデリゲートを // 定義済みのメソッドを渡すだけで、 AI用ツールオブジェクト化される
渡す事で、入出力のスキーマ情報を持ち、 var database = new GameDatabase();
var tool = AIFunctionFactory.Create(database.GetWeaponStats);
JSONを入力として関数を実行できる、
// 2. FunctionInvokingChatCl
// .UseFunctionInvocation() を挟むだけで、
AIFunctionを生成
// 自律的なループ処理が有効化される
FunctionInvokingChatClientによる、
IChatClient client = new ChatClientBuilder(innerClient)
.UseFunctionInvocation()
AIFunctionを利用した「AIの要求検知」→
.Build();
「引数パース&実行」→「結果の送信」
// 3. 完了
// User: "エクスカリバーの強さは? "
というループの自動実行
// -> 自動処理 : AI要求検知 -> C#実行 -> 結果フィードバック
ChatClientBuilderで
// -> AI回答: "攻撃力は 999です"
await client.GetResponseAsync(
UseFunctionInvocation
[new ChatMessage(
を呼び出す形でIChatClientを生成し、
ChatRole.User, "エクスカリバーの強さは? "
)],
ChatOptionsのToolsにAIFunctionを渡す
new ChatOptions() { Tools = [tool] }
);
16
Function Callingの抽象化 - AIFunctionとFunctionInvokingChatClient
// 1. 型定義が「出力フォーマットの指示」になる
●
●
●
ネイティブなスキーマ強制
○ 単なるプロンプト指示ではなく、
LLMの Structured Output 機能に対して
スキーマ定義を適用し、
構造を強制できる
パース可能性の保証
○ 高確率でパース可能なJSONを返却する
型安全なラッピング
○ Resultプロパティからパース後のC#
オブジェクトを型付きで直接取り出せる
public class NpcProfile
{
[Description("ファンタジー風の名前 ")]
public string Name { get; set; }
[Description("プレイヤーへの挨拶セリフ (3パターン)")]
public List<string> Greetings { get; set; }
}
// 2. 実行 (GetResponseAsync<T>)
// 裏側で Structured Output (JSON出力) が機能する
ChatResponse<NpcProfile> response =
await client.GetResponseAsync<NpcProfile>(
"村の入り口にいる怪しい商人を生成して .",
useJsonSchemaResponseFormat: true
);
// 3. 結果の利用
// .Result プロパティにデシリアライズ済みの実体が入っている
NpcProfile npc = response.Result;
// 出力例: "ザルバ: ヒッヒッヒ、良い品あるよ ..."
Console.WriteLine($"{npc.Name}: {npc.Greetings[0]}");
17
[環境] - 認証の壁を突破する ● 権限の「隠蔽」と、プロジェクト単位の「制御」。2つの課題を解決する。 18
[環境] - 認証の壁を突破する - 権限の隠蔽 ● ● なぜ権限の隠蔽が必要か ○ Vertex AIの利用にはroles/aiplatform.user という比較的広い権限のロールが必要 ○ これを個人のGoogleアカウントに付与するのは過剰権限であり、 Service Accountキーの直接的な配布は漏洩リスクが高い 中継サーバの設置による、権限借用的な解決 ○ 強い権限はCloud Run上の「中継サーバ」だけが持つ ユーザーは「中継サーバへのアクセス権」だけを持てばよい 19
[環境] - 認証の壁を突破する - プロジェクト単位のアクセス制御 ● ● なぜプロジェクト単位のアクセス制御が必要か ○ AIが「知識(社外秘)」と「操作(実機)」を扱う以上、社内一律の許可では危 険。 ○ 「プロジェクトAのメンバーだけが使える」という厳密な制御が不可欠。 Cloud IAP + Google Group管理による解決 ○ IAP for Cloud Run: ■ iap_enabled を有効にするだけで、Webアプリの前段にGoogleアカウントに よる OAuth2認証を簡単・安全に導入可能 ○ Google Groupと連携することで、IAM同様のアクセス制御を追加実装なしで実現 20
[実装] - AI活用の為のクライアントSDK "Rinchan.Client" ● ● インフラ構成や認証を隠蔽し、Microsoft.Extensions.AIから接続可能にする 実装の動機 ○ 構造的必然性: ■ 前述の中継サーバ及び認証を経由するためには、独自の実装が必要不可欠 ○ 環境制約: ■ Vertex AIをWebGLビルドでも使える、Unityに特化した実装は存在しない 21
[実装] - AI活用の為のクライアントSDK "Rinchan.Client" ● ● Rinchan.Client - Unityに最適化されたMicrosoft.Extensions.AI実装 ○ 公式のVertex AI SDKも未対応の中、Microsoft.Extensions.AIのIChatClient を実 装 ■ ごく最近になって、Vertex AI SDKもbeta版で対応を開始 ○ 依存ライブラリを極力減らし、 UnityWebRequest ベースで実装することで、 モバイルからWebGLまで、あらゆる環境で動作 低い導入障壁で、Unity上でMicrosoft.Extensions.AI対応を実現 ○ エンジニアはLLMを、標準的なMicrosoft.Extensions.AIの作法で、簡単に利用で きる 22
AI as Componentの実現 ● ● Microsoft.Extensions.AIとRinchan.Clientによる、AI活用におけるUnity標準への準拠 ○ 複雑な認証やインフラ構成を隠蔽し、Unity上のあらゆる環境で、 コードと仕様の一致した、Microsoft.Extensions.AIの標準作法でAIを利用可能に した ○ これによって、Unity Editor内にAIの推論を「サクッと組み込める」状態が整い、 「AI as Component」が実現した 「AI as Agent」への重要な仕込み ○ Microsoft.Extensions.AIで定義したAIFunctionは、単なる関数ではなく、 エージェントにとっての能力として資産化される 23
実行手段を与える: Leap 24
次のステップ: AI as Agent ● ● 世の中にはすでにGemini CLIなどの「自律的なエージェント」が存在するが、 それらはUnityに直接干渉する術を持っておらずAIFunctionという資産を活用できない 外部の強力なAIエージェントに、Unityを自在に操る手段を与えられれば、 開発フローの中でより広範に、有効に機能するようにする 25
AI as Agent実現のための課題 ● ● ● UnityはサーバでもCLIアプリケーションでもない ○ Unity EditorはGUIアプリケーションであり、 ○ モバイル端末上では、ネットワーク的にAI(が動作しているPC)から 操作対象のノードを識別するのは、非常に煩雑 Unityはスクリプト変更や再生の度に実行環境をリセット(ドメインリロード)する ○ この瞬間、通常のソケット通信は切断され、AIの操作フローは中断してしまう Editorのみなら現実的に可能であり、事例も多くあるが... ○ モバイル端末上を含む、ゲームの開発ビルドの操作は不可能 ○ 独自のツールの追加が煩雑になる、拡張性に乏しくなる ○ 再コンパイルやプレビュー再生などで動作が不安定になることも 26
外からAIFunctionを実行するためのシステム: Leap ● ● ● Unity外のAIから、Unity内で定義された AIFunction を実行させるためのシステム ○ “生成したAIFunctionを登録すると、外部から呼び出し可能になる” 社内のデバッグメニューライブラリとの連携もあり、定義された機能をそのまま AIFunction化して、AIが操作できる関数として取り込み可能 ○ これにより、既存の資産を活かしつつ、「自然言語操作」という新たなインター フェースを追加できるという側面も 対象となるユーザは内部のゲーム開発者であり、製品ビルドからは完全に除外される 27
アーキテクチャ - Firestoreを中心とした非同期ポーリング ● ● ● 構成要素 : ○ User Env (Caller): Web UI または Leap.Cli (MCP)。指示の発生源 ○ Caller Server: ユーザー/AIからの要求を受け、FirestoreにInvocation(実行命令) を発行 ○ Firestore: 状態管理とメッセージングの中核ハブ ○ Callee Server: デバイス認証と接続を管理するゲートウェイ ○ Callee (Unity): 呼び出される関数が存在する、実行環境 仕組み: ○ Caller (Web/AI): サーバー(Firestore)に「Invocation(実行命令書)」を置く ○ Callee (Unity): サーバーにポーリングし、自分宛ての命令を取りに行く サーバーが分離され、Firestoreを介して非同期に連携することで、 内と外のネットワーク的な分断を安全に解決している 28
Leapのシステム構成 ● ● ● サーバは全てCloud Run上に構築 ○ 呼び出し側はCloud IAPで Googleアカウントによってユーザを認証 貸与デバイスでの利用の可能性も高い デバイス上でのGoogleアカウント 認証は煩雑な為、独自に匿名認証で識別 ○ Cloud IAP + サービスアカウント認証に よるセキュリティ担保も同時に実施 認証した呼び出す側のユーザーと、 呼び出される側のデバイスのペアリングが必要 ○ VODサービスのようなPINコードによる ペアリング方式を採用し、 利便性と安全性を両立 29
Leapのシーケンス 30
非同期ポーリングによる監視を行う理由 ● Unity開発における「切断」の常態化 ○ Unityはスクリプトの変更(コンパイル)やPlayModeへの遷移のたびに ドメイン リロード(Domain Reload) が発生する ○ この瞬間、メモリ上の全ステートは破棄され、一般的なソケット通信 (WebSocketサーバー等)による接続は切断されてしまう ○ 従来の双方向通信では、「コンパイルして、終わったらテストする」という連続的 な命令を安定して処理することが困難だった 31
非同期ポーリングによる監視を行う理由 ● ● ステートレスなポーリング構造による「待ち」の実現 ○ 状態の外部化: 実行命令(Invocation)の状態は常にFirestoreで管理され、 Unityは単なるワーカーとしてふるまう ○ 再接続のシームレス化: Unity側でドメインリロードが発生しても、 復帰後に即座にポーリングを再開するため、切断中の自分宛ての命令や、 中断していたタスクの結果報告を継続できる。 エージェント側の視点: ○ AIエージェントはFirestoreを見ているため、Unityが再起動中であっても 処理中として認識し、完了まで正しく待ち続けることができる 32
ポーリング構造によるコンパイル完了待機の実現 ● ● RefreshAndWait (コンパイル&完了待機): ○ AIが「コード修正」→「RefreshAndWait」命令を発行 ○ Unityが命令を受理し、コンパイル開始 & コンパイル中フラグをONで永続化 (ここで命令を完了状態にしないまま、Unity側の実行環境がリセットされる) ○ コンパイル完了後、ドメインリロードが走り、Leapが自動復帰 ○ コンパイル中フラグがONなら該当命令を完了状態に更新し、AIに制御を戻す この仕組みにより、「修正 → コンパイル → プレイモード開始 → テスト実行」 とい う、Unityのライフサイクルを何度も跨ぐ複雑な操作を、AIが自律的に実行可能になっ た 33
FunctionPath - 関数を整理するファイルシステム的識別子 ● ● ● 階層を持つパスで関数を一意に識別 ○ 機能やドメイン単位で直感的に探索できる ○ 異なる機能間の関数名の衝突を防ぐ パス階層がそのまま後述するWeb UIにも マッピングされ、フォルダとして可視化される FunctionPathとAIFunctionをセットにして Registerすると、Leap経由で呼び出し可能になる /Debug/ Player/ SetLevel SetHP /Debug/ Enemy/ SetHP //プレイヤーのHPを設定するデバッグ関数を、 //ランタイム用のRegistryに登録 LeapRegistries.Runtime.Register( "/Debug/Player/SetHp", //AIFunctionを作成 AIFunctionFactory.Create(SetHpFunc) ); 34
Leap Web UI - AIとGUIのハイブリッド操作 ● ● ● Leap AI: ブラウザから接続中のデバイスに対して、直接指示を出せるAIエージェント。 ○ Gemini CLIなどのエージェントをセットアップしなくても、 ブラウザのみでAIからデバイスを操作できる 「リモートデバッグメニュー」機能: ○ Leap関数をディレクトリ階層(パス)ごとに一覧表示 ○ 引数の型情報(Schema)に基づいた入力フォームを自動生成 ○ AIからだけでなく、GUIで値を入力して関数を叩く、手動での使い方もサポート Deep Linkによる共有: ○ 「特定のプロンプト」や「特定の関数起動(引数付き)」をURLとして発行可能 ○ チームメンバーに一瞬で手順を共有 35
サーバは関数を知らない ● ● サーバとクライアントの疎結合化と、ステートレス化 ○ サーバは具体的な関数の定義については管理せず、Firestoreにも保存しない ○ 「今、どんな関数が使えるか」を知っているのは、接続している Unityだけ ○ サーバ側に関数一覧が必要な操作が要求されたときに、 サーバからUnity側に「今、どんな関数を使えるか」を問い合わせる メリット: パフォーマンスと柔軟性の両立 ○ アプリ起動毎のサーバへの同期作業が不要になり、関数の登録負荷を減らせる ○ 古いバージョンなら古い関数が、新しいバージョンなら新しい関数が、 サーバ側の変更なしに自動的に提示される 36
外部との接続 - Leap.CliによるMCPサーバーの実装
●
●
●
CLI版のCallerである、
dotnet tool install Leap.Cli
Leap.Cliを通してMCPに対応
○ Leap.CliがCallerサーバと通信し、
MCPサーバとして振る舞う
"mcpServers": {
"leap": {
認証用の設定が不要
"timeout": 300000,
○ ブラウザが開かれたらGoogleアカウントでログイン
"command": "Leap.Cli",
○ PINコードによって紐付け済みのデバイスを操作可能
"args": ["mcp"],
"env": {"LANG": "ja_JP.UTF-8"}
極めてシンプルに設定で、外部エージェントからは、
}
UnityがMCPサーバーであるかのように見える
}
37
スケーラビリティ - 膨大な数の関数をどう扱うか? ● ● ● ゲームには膨大な数のデバッグ関数があり、全てAIに見せるとコンテキスト長が足りな い 静的公開と動的探索のハイブリッド公開戦略による解決 ○ 静的公開: 直接MCP Toolとして公開 ■ シンプルにAIがToolとして認識できるが、コンテキストを常に消費する ○ 動的探索: 直接MCP Toolとしては公開せず、メタツールによって動的探索 ■ Leap.Cli は、個々の関数を隠し、代わりに 「関数検索ツール 」 と 「関数実行ツール」をMCPツールとして提供 ■ AIはls/grepでファイルを探すかのように、自律的に機能を探し出して実行 関数の登録時のIsMcpTool フラグによってどちらで公開するかを制御 ○ Unityのログ取得など、幅広い場面で、頻繁に利用する関数のみを静的公開 38
スケーラビリティ - 膨大な数の関数をどう扱うか? ● ● AIのコンテキストを汚さず、大規模プロジェクトの膨大な機能群へ 安全かつスケーラブルにアクセスできるようになった 登録可能な規模をスケールした事で、既存デバッグメニュー実装との連携が可能にな り、 AIが起こせるアクションを、少ない工数で飛躍的に増加させることができた 39
LeapによるAI as Agentの実現 ● ● ● 「実行の断絶」を埋める非同期アーキテクチャ ○ Unity特有のドメインリロードをステートレスなポーリング形式で克服 ○ 「修正 → コンパイル → 再生」という、 実行環境を跨ぐ連続的なタスクをAIが自律的に完遂できる Microsoft.Extensions.AIで資産化した関数の外部デリバリー ○ MEAで資産化した「部品」を、MCPを通じて外部のGemini CLI等へ開放 ○ AIエージェントは、Unityを「数千のツールを持った巨大なサーバー」として 自在に操作可能になる LeapはMicrosoft.Exntensions.AIで定義された部品を動かす神経系となり、 AIエージェントがUnityを自在に操る「自律的なエージェント」への進化した 40
知識を与える: Rinchan 41
知識の壁 - ステアリングデータの限界 ● ● ● ● 「手足」だけでは動けない ○ LeapによってAIは操作手段を得たが、社内ライブラリやゲーム自体の仕様が どうなっているかという知識がなければ、正しく手足を動かせない 静的知識(文化)の欠如 ○ 汎用LLMは、プロジェクト固有の「暗黙知」を学習していない 活用の摩擦 ○ 毎回プロンプトで前提条件を説明するコストが、AI活用の大きな障壁となる AGENTS.md, GEMINI.md等のステアリングデータの整備は対策として有効だが、問題も 42
知識の壁 - ステアリングデータの限界 ● ● ● Single Source of Trushの欠如と、メンテナンス性の破綻 ○ 仕様書はConfluenceなどのサービスで管理されており、情報の二重管理を生む ○ 知識が積みあがった状態から、仕様書の管理を移し替えるのは非常に困難 ○ ConfluenceなどへのRAGにも限界があり、業務に必要な精度はなかなか出ない スケーラビリティの限界 ○ 仕様書は膨大な量があり、すべてのデータを乗せるにはコンテキスト長が足らない ○ 常にすべての仕様書が関係があるわけではないため、無駄も多い ○ Agent Skills等を使う方法もあるが...? 統合されたナレッジハブを介して知識を取得できるようにすることに 43
解決策 - 社内ナレッジハブ “Rinchan” ● ● ゲーム事業部の仕様書や社内ライブラリ等の暗黙知を統合する、 Many-Shots In-Context LearningによるAIエージェント兼、社内ナレッジハブ Slack上から利用できる社内ライブラリ特化のチャットAIとして開発が始まり、 徐々に持つ知識の幅を広げ、ゲーム自体の知識も持つようになった ○ 【DeNA × AI Day】社内ライブラリ特化のチャットAIが起こす、開発現場での変革 44
Rinchanの知識の単位 - セグメントと段階的開示 ● ● セグメント: ○ ドキュメントをドメイン単位(機能A/ライブラリB..)でグルーピングして管理 ○ 設定ファイルで、セグメントに所属するファイルパスのパターンを列挙して定義 ○ ドキュメントの実体はCloud Storageで管理 ○ セグメントがLLMに読み込まれるとき、所属する全ファイルの内容が読み込まれる セグメントの段階的開示による読み込み: ○ Agent Skillsにも通じる考え方で、トークンの節約と高い回答精度を両立 ○ セグメント毎にセグメント全体の概要,構成,用途等を記したサマリをAIで事前生成 ○ サマリをさらに短く要約した200字程度のショートサマリもAIで事前生成 ○ ショートサマリ > サマリ > 全文の順で段階的にセグメント内の情報を取得 45
社内ナレッジの動的な取得 ● セグメント化していない社内ナレッジを動的に取得する機能を数多くサポート ○ Confluenceの特定のIDのページを取得したり、特定の条件で検索 ■ Markdown化と添付データの取得もサポート ● Atlassian 公式のRemote MCP Serverでは添付データが取得できない ● また、ユーザーがアクセスできるスペースの制約が難しい (プロジェクト単位で制約できない) ○ 任意の事前許可済みチャンネルのSlack会話データの取得 ○ 内製マスタデータ管理ツール”Oyakata”上のマスタデータをSQLを用いて検索 ○ 任意の社内APIサーバに対するブリッジ(OpenAPI Specificationで定義) 46
外部AIエージェントに対してRinchanの知識を供給する
●
●
CLI版のクライアントである
dotnet tool install Rinchan.Cli
Rinchan.Cliを通してMCPに対応
○ Rinchan.CliがRinchanサーバと通信し、
MCPサーバとして振る舞う
"mcpServers": {
"rinchan": {
Leap同様に、細かな認証設定は不要
"timeout": 300000,
○ MCPサーバ起動時にブラウザが起動し、
"command": "Rinchan.Cli",
OAuthによるGoogleアカウント認証を行う
"args": [
"mcp_server", "--baseUrl"
○ プロジェクトの所属メンバーのみアクセス可能
"プロジェクト毎の CloudRunサービスの URL"
]
}
}
47
Rinchan.CliによるMCPが提供するツール ● ● ● 基本機能であるセグメント関連のツール ○ 特定のセグメントのサマリ、ショートサマリ、全データの取得 特定の質問文を投げて、ナレッジに基づく回答をサーバ側で生成して受け取るツール セグメント関連以外のナレッジ取得用ツール ○ Confluence / Slack / Oyakata(マスタデータ)... 48
プロジェクトのリソースへのアクセス制限の考え方 ● ● Atlassian Rovo Remote MCP ServerではAtlassian Cloudのアカウントで OAuthによるユーザ認証を行い、そのユーザの権限で行える操作が可能になる ○ 一見安全に見えるが、社内では複数のプロジェクトにかかわるメンバーも多いた め、 ユーザが見えるプロジェクトの情報や、限られたメンバーしか見れない情報が、 異なるプロジェクトに気付かずに混入してしまう危険性がある “プロジェクト外秘”なアクセス制限を行う必要がある 49
プロジェクトのリソースへのアクセス制限の考え方 ● “AIエージェントに見せてよいものを固定”して、”プロジェクトメンバーにのみ見せる” ○ AIエージェント専用のアカウントを用意した上で、 “AIエージェントに見せてもよいもの”にだけ閲覧権限をつけておき、 このアカウントをRinchanからのアクセスに固定的に利用 ○ Rinchan自体を利用する権限をIAPによりプロジェクトメンバーのみに厳格に制限 50
知識の資産化 - 「暗黙知」をAIのスキルとして定義する ● ● Rinchan.ClientはMicrosoft.Extensions.AIのUnity用実装だけではなく、 Rinchan.Cliで利用できる各種ツールを直接Unityから呼び出すSDKでもある ○ Rinchan.CliはRinchan.ClientをMCPやCLI経由で AIエージェントから呼び出す為のフロントエンドという立ち位置 Rinchan.Client内のツールはAIFunctionとして直接エクスポート可能 ○ 社内知識へのアクセス機能自体がツール化され、 AIを活用したUnity Editor拡張などからも自由に呼び出せるようになる Rinchanにより、AIはプロジェクトの文脈を理解する能力を手に入れ、 その知識取得機能も一つの「部品」として扱えるようになった 51
まとめ 52
5つの壁の解決策 ● ● ● ● ● 標準化 ○ Microsoft.Extensions.AI: すべての中心となる標準インターフェース 環境 ○ Cloud IAP + OAuth: セキュアかつ手軽な接続アーキテクチャ 実装 ○ Rinchan.Client: Unity上で動作するMicrosoft.Extensions.AI準拠の実装 実行 ○ Leap: ツール実行をUnityへ届けるデリバリーシステム 知識 ○ Rinchan: 社内ナレッジへのアクセスハブ 53
ラストワンマイルの解決 - 知識と操作の相互乗り入れ ● ● ● 「知識(Rinchan)」と「実行手段(Leap)」を統合 「エラーログを取得し(Leap)、社内Wikiで関連情報を確認し(Rinchan)、 修正とテストを行う(Leap)」という、文脈と操作が統合したループが実現可能に Unity内に書いた一つのC#メソッドがナレッジと連携して動かせるように 54
さいごに ● AIは魔法ではない。正しいエンジニアリングでAIを取り巻くアーキテクチャを設計し、 「あたりまえの道具」にしていく必要がある。 55
56