検索/AIエージェントが調べられる、ローカルのコードグラフツールを作る

AIエージェントが調べられる、ローカルのコードグラフツールを作る

コードを解析してAIエージェント向けのグラフにまとめるツールを作る時に使う。構文木からのシンボルと関係の取り出し、複数のクライアントへの入れ方ときれいな外し方、エージェントが使いやすい検索の答え、実際のリポジトリとOSでのテスト、リリースの進め方を決める。

このAIルールを使うには
## AIの要約ではなく構文木から、ローカルでコードグラフを作る プロジェクトの解析はローカルかつ決定論的に保つ。言語モデルによる要約ではなく構文木からシンボル、関係、ファイルを導き、プロジェクト単位の状態をローカルのインデックス付きデータベースへ保存し、得られたナレッジグラフをライブラリ、コマンドラインインターフェース、またはエージェント用プロトコルを通じて提供する。 システムを階層化されたパイプラインとして構成する。 - 抽出はソースを解析して標準シンボルを生成する。 - 解決はインポート、名前、フレームワーク、その他の関係を接続する。 - グラフクエリは呼び出し元、呼び出し先、経路、影響に答える。 - コンテキスト整形は利用側のために簡潔なMarkdownまたはJSONを用意する。 負荷の高い解析をメインスレッドで実行しない。各層を単一の公開エントリポイントへ通し、そのエントリポイントだけをサポート対象のライブラリ窓口とする。一つの実行ファイルが意図的にインストーラ、インデクサ、プロトコルサーバーを兼ねる場合は、同じ成果物を通じてすべての役割をテストする。 エージェント向けツール案内の正本を一つに保ち、できればプロトコルの初期化応答を正本にする。同じ指示を各クライアントのリポジトリファイルへ複製しない。複製は次第に食い違い、アップグレードやアンインストールを不完全にする。 ## ランタイムを固定し、コード以外のファイルもビルドに入れる リポジトリに文書化されたビルド、開発、クリーンアップ、テスト、評価、ローカルCLIの各コマンドを確認して使用する。固定されたランタイム範囲を守り、範囲外では明確に失敗させる。新しいメジャーバージョンに自動で互換性があるとは限らず、ソースからの実行にはバンドル配布物より厳しい最低バージョンが必要な場合がある。 ランタイムアセットをビルド契約の一部として扱う。データベーススキーマ、パーサー文法、WebAssemblyモジュール、その他のコード以外のファイルを配布物へコピーする。新しいアセットを追加したら必ずコピー工程も更新しなければ、配布物には含まれない。 対象を絞ったテストファイルまたは名前パターンから検証を始め、その後に直接影響を受けるテストスイートを実行する。通常の単体テストではなくフィクスチャを構築したり動作を採点したりする評価スイートは分離しておく。 ストレージの意味が重要な箇所では実際のストレージ動作を使う。隔離した一時ディレクトリを作成して各テスト後に片付け、モックで覆い隠さず実際のデータベースモードを検証する。 ## ノードとエッジの種類をそろえ、公開APIを小さく保つ 標準のノード種別とエッジ種別を単一のスキーマで定義する。抽出器と解決器はその文字列を正確に生成しなければならない。クエリ、走査、シリアライズ済みデータを気付かないまま分断する類似種別を導入しない。 公開APIを狭く保つ。サポート対象の型は公開エントリポイントから再エクスポートし、コマンドラインおよびプロトコルのアダプタには、中核サービスを迂回せず同じサービスを利用させる。 ストレージに関する主張を明確で検証可能にする。先行書き込みログと全文検索を備えたサポート対象のデータベースバックエンドが一つだけなら、稼働中のそのバックエンドを報告し、互換アダプタを薄く保ち、未実装のネイティブまたはWebAssemblyフォールバックがあるように示さない。 言語、フレームワーク、クエリ、スキーマフィールドを追加する時は、担当する抽出器または解決器、公開契約、シリアライズ、テスト、ユーザー向け案内をまとめて更新する。 ## 複数のAIクライアントへ設定を壊さず入れ、きれいに戻せるようにする サポートする各クライアントを、それぞれ固有の設定場所、形式、プロトコル引数を持つターゲットとして設計する。インストーラ全体に条件分岐を散らさず、一つのターゲット実装と一つのレジストリエントリを通じて新しいクライアントを追加する。 設定は局所的に編集する。無関係なTOMLのテーブルと配列を保ち、コメント付きJSONの書式とコメントを維持し、サポート対象の既存ファイル形式を優先し、新規インストールの場合だけ文書化された既定形式を作成する。 インストールは冪等、再インストールは部分的な状態を自己修復可能、アンインストールはインストーラが所有する変更だけを元に戻せる状態にする。安定したマーカーを使って古い指示ブロックを取り除くが、現在のエージェント向け案内は別の複製を書かず、ランタイム側の単一の正本に保つ。 関連設定の維持、バイト単位で同一の再実行、可逆なアンインストール、部分状態からの復旧について、パラメータ化した契約テストですべてのターゲットを網羅する。クライアントが誤ったディレクトリからプロトコルのサブプロセスを起動する場合に明示的なプロジェクトパスを注入するなど、クライアント固有の作業ディレクトリ対策を維持する。 ## エージェントが今使っている検索ツールを強くする 検索機能を構築する前に、エージェントがすでに呼び出すツールを、エージェントがすでに渡している入力のまま強化できるかを確認する。エージェントが新しいツールを学ぶこと、別のクエリ形式を採用すること、目立ちにくい例や初期化時の説明に気付くことを前提にしない。 正確な回答には正確な入力を使う。主要な探索ツールは、修飾名を含む簡潔なシンボル名の集合を受け取り、その間のフローを接続する。補助的なノードツールはソース全文に呼び出し元と呼び出し先のコンテキストを添えて返し、名前が曖昧な場合は考えられるすべてのオーバーロードを一つの応答で返す。 終点を区別できない曖昧な自然言語ツールへ、正確なフロー回答を組み込まない。静的抽出や証拠に基づく動的関係を含め、エージェントがすでに選ぶツールの内部で網羅範囲を改善する。 実時間とツール呼び出し回数に加え、トークン使用量も最適化する。節約は、蓄積するコンテキストを小さくしながら往復回数を減らすことで生じるため、最終応答だけではなく全ターンの合計使用量を測定する。 ## エージェントがファイルを直接読みに戻らない答えを返す 想定内の状態は成功形式で返す。未インデックスのプロジェクト、存在しないシンボル、インデックス外のファイルには、エラーフラグを付けず実行可能な案内を返す。真のエラーはセキュリティ上の拒否と実際の故障に限り、再試行が適切な場合だけ回数を限定した再試行指示を添える。 現在のルートが未インデックスでもツール群を公開する。インデックス済みプロジェクトの選び方は説明するが、インデックス作成はユーザーの判断に委ねる。起動時にツールを隠すと、モノレポやインデックス作成前に開始したセッションを壊す可能性がある。 探索の呼び出し予算と出力予算の両方を、リポジトリの規模に応じて単調に増やす。 - 500ファイル未満:1回、約18,000文字、ファイル当たり3,800文字。 - 500〜4,999ファイル:2回、約28,000文字、ファイル当たり6,500文字。 - 5,000〜14,999ファイル:3回、約35,000文字、ファイル当たり7,000文字。 - 15,000〜24,999ファイル:4回、約38,000文字、ファイル当たり7,000文字。 - 25,000ファイル以上:最大5回、約38,000文字、ファイル当たり7,000文字。 規模が大きい区分のファイル当たり予算を、小さい区分より少なくしてはならない。エージェントに生ファイルの読み取りへ戻るよう案内してはならない。別のグラフ呼び出しへ導き、返されたソースはすでに読んだものとして扱うよう明記する。 ## コールバックやイベントの流れを、最初から最後までつなぐ 静的解析ではコールバック、オブザーバー、イベントエミッター、リアクティブな描画、ディスクリプタ、その他の間接ディスパッチを捉えられない。十分な証拠に基づいて標準フローを接続できる場合にだけ、範囲を絞った合成器またはフレームワーク解決器を追加する。 合成されたすべてのエッジをヒューリスティックとして記録し、どの仕組みが生成したかを残し、登録地点または接続地点を含める。解析済みの事実と推論した関係を利用側が区別できるよう、その由来をフローとともに示す。 一つの間接的な区間を示しても次の境界が切れたままなら、部分的な網羅は網羅なしより悪い。開始アクションから目に見える結果までフローを接続し、エージェントを再計測し、手作業での再構築が残る中途半端な経路を出荷しない。 安全に推論できないランタイム境界では、誤ったエッジより沈黙を選ぶ。再インデックスでノード数が膨張しないことを検証し、解決器の範囲を広げる前に合成エッジの精度を抜き取り確認する。 ## 実際のリポジトリとWindows・Linuxで、エージェントの動きを確かめる 各言語とフレームワークについて、小規模、中規模、大規模の実在リポジトリを、少なくとも3種類の異なるフロー質問でテストする。難しいディスパッチ境界を避けた孤立シンボルではなく、各フレームワークの標準的な端から端までのフローを選ぶ。 ビルド済み成果物に対して決定論的なプローブを実行する。探索が予算内で想定した終点同士を接続すること、再インデックスをまたいでもノード数が安定していること、ヒューリスティックなエッジが正確な由来を持つことを確認する。 同じ意図的な下限モデルと推論強度を使い、各群で少なくとも2回ずつエージェントA/Bテストを実行する。所要時間、ツール呼び出し総数、生ファイル読み取り、テキスト検索を記録し、都合のよい単独実行ではなく幅で報告する。起動遅延でツールが見えなくなる場合は、常駐プロトコルプロセスを事前に起動し、初期化時のスナップショットではなく実際の呼び出しで接続を判断する。 リポジトリの探索予算内で生ファイルの読み取りと検索をほぼゼロにし、対照より速く完了し、対照リポジトリで回帰がないことを合格条件にする。 プラットフォーム固有の動作は実際のプラットフォームで検証する。Windows専用と非Windows用のアサーションを明示的に分ける。Linuxでは、使い捨てコンテナ内にプラットフォーム固有の依存関係を新しく導入してビルドし、終了した子プロセスを回収できるようinitプロセスを使う。Windowsでは、実在する仮想マシンのローカルファイルシステムと新しく導入した依存関係を使い、疑わしい失敗を既定ブランチと比較してから原因を判断する。 ## リリースノートを書き、公開は自動のリリースワークフローに任せる 今後の変更はUnreleasedセクションに記載する。リリースワークフローがUnreleasedの内容を自動的に昇格させる場合、次のバージョン区画を先に作らない。 リリースノートをユーザーに役立つ内容にする。 - 該当する場合だけ、ユーザー向けの新機能、修正、セキュリティ、破壊的変更の見出しに内容をまとめる。 - 各箇条書きは、機能または解決した症状を説明する平易な一文にする。 - 内部パス、実装シンボル、ベンチマークの詳細、空の節は含めない。 - 有用な課題参照、サポート対象のプラットフォーム名、ユーザーが実際に入力するコマンドは残す。 自動リリースワークフローに、ロックファイルのバージョン同期、変更履歴の昇格、プラットフォーム別バンドルのビルド、チェックサム生成、リリース公開、パッケージ公開を任せる。明示的な依頼なしにバージョンを上げず、それらをワークフローが担当する場合はパッケージの手動公開、リリースコミットのプッシュ、タグ作成を行わない。 課題、レビューコメント、外部報告に対応する前に日付を基準にし、公開済み、マージ済みだが未公開、現在のブランチという各状態を比較する。進行中の修正を、報告者が以前に確認できた状態へ帰属させない。 プロダクト要件はコードグラフから推測した事実ではなく、ユーザーが決める事項として扱う。すべてのドキュメント画像URLにバージョンを付け、アセットが変わるたびにクエリタグを増やし、キャッシュが古い内容を返し続けないようにする。