IssueやMerge Request/Pull Requestの処理を行う際、対象プロジェクト(リポジトリ)のファイル一覧を初期コンテキストに含めることで、エージェントがプロジェクト構造を把握しやすくし、より適切な処理を実現します。
現状、エージェントはタスクの内容(Issue/MR/PRの本文やコメント)のみを初期コンテキストとして受け取っています。プロジェクトの構造を知るためには、エージェントが自らファイル一覧を取得するツール呼び出しを行う必要があり、以下の問題があります:
- 処理ステップの増加: ファイル構造把握のために追加のツール呼び出しが必要
- トークン消費の増加: ファイル一覧取得のためのリクエスト・レスポンスでトークンを消費
- 判断の遅延: プロジェクト構造を把握してから適切な処理を開始するまでに時間がかかる
- 処理効率の向上: 初期段階でプロジェクト構造を把握できるため、適切な処理をすぐに開始可能
- コンテキスト品質の向上: プロジェクトの全体像を持った状態で判断可能
- ツール呼び出しの削減: ファイル一覧取得のためのMCPツール呼び出しが不要
- タスク処理開始時に、対象プロジェクトのファイル一覧を自動取得する
- 取得したファイル一覧をシステムプロンプト末尾に含める
- ファイル一覧の取得深度(ディレクトリ階層)を設定可能にする
- ファイル一覧取得に失敗した場合でもタスク処理を継続可能にする
- パフォーマンス: ファイル一覧取得はタスク処理開始時のオーバーヘッドを最小限に抑える
- 堅牢性: API制限やネットワークエラーでもタスク処理に影響を与えない
ファイル一覧の取得は、TaskHandler.handle()メソッドの処理開始時、システムプロンプト送信前に実行します。
flowchart TD
A[TaskHandler.handle開始] --> B{file_list_context有効?}
B -->|No| C[通常処理へ]
B -->|Yes| D[リポジトリ情報取得]
D --> E[MCPクライアントでファイル一覧取得]
E --> F{取得成功?}
F -->|Yes| G[階層制限適用]
F -->|No| H[ログ出力]
H --> C
G --> I[フラットリスト形式に変換]
I --> J[システムプロンプト末尾に追加]
J --> C
タスクオブジェクトから以下の情報を取得します:
- owner: リポジトリオーナー(組織名またはユーザー名)
- repo: リポジトリ名
- project_id: GitLabの場合のプロジェクトID
GitHub MCPサーバーまたはGitLab MCPサーバーのファイル一覧取得機能を使用します。
GitHub MCPサーバーの場合:
get_file_contentsツールを使用(本ツールはファイルまたはディレクトリの内容を取得可能)- ルートディレクトリ(path=""または"/")を指定してディレクトリ一覧を取得
- ディレクトリが返された場合は、設定に応じて再帰的にサブディレクトリを取得
- 再帰取得時は階層制限(max_depth)を適用
GitLab MCPサーバーの場合:
get_repository_treeツールを使用(リポジトリツリーの取得専用ツール)- プロジェクトID、パス(ルート)、参照(デフォルトブランチ)を指定
- 設定に応じて再帰的にサブディレクトリを取得
設定で指定された最大深度(max_depth)までのファイル・ディレクトリのみを含めます。max_depthが-1の場合は無制限とします。
ファイル一覧はシステムプロンプト末尾に追加します。他のプロジェクト固有情報(プロジェクトエージェントルール等)と共にシステムプロンプトに含めます。
フラットリスト形式で出力します。
- プロジェクトルートからの相対パスを1行1ファイルで表示
- ディレクトリパスを含めたフルパス形式(例:
foo/bar/sample1.py) - アルファベット順でソート
- ディレクトリエントリ自体は含めず、ファイルのみを列挙
ファイル一覧の前後に識別用のヘッダーとフッターを付与します。
ヘッダー内容:
- セクション開始の識別子
- プロジェクト情報(オーナー/リポジトリ名)
フッター内容:
- セクション終了の識別子
- ファイル数の統計情報
sequenceDiagram
participant TH as TaskHandler
participant FLC as FileListContextLoader
participant MCP as MCPToolClient
participant MS as MessageStore
TH->>TH: タスク処理開始
TH->>FLC: load_file_list(task, mcp_clients)
FLC->>FLC: リポジトリ情報取得
alt GitHubの場合
FLC->>MCP: get_file_contents(owner, repo, path="")
else GitLabの場合
FLC->>MCP: get_repository_tree(project_id, path="", ref)
end
MCP-->>FLC: ファイル一覧(JSON)
FLC->>FLC: 階層制限適用
FLC->>FLC: フラットリスト形式に変換
FLC-->>TH: 整形済みファイル一覧
TH->>MS: add_message(system, prompt + file_list)
TH->>TH: 通常タスク処理続行
| ファイルパス | 説明 |
|---|---|
| handlers/file_list_context_loader.py | ファイル一覧取得・整形を担当するモジュール |
| handlers/task_handler.py | 既存ファイル。FileListContextLoaderの呼び出しを追加 |
| handlers/planning_coordinator.py | 既存ファイル。FileListContextLoaderの呼び出しを追加 |
handlers/file_list_context_loader.py
FileListContextLoaderクラスを新規作成します。
__init__メソッド
引数:
- config: dict型。設定情報を含む辞書
- mcp_clients: dict型。MCPツールクライアントの辞書(キー: "github"または"gitlab")
処理内容:
- 設定からfile_list_contextセクションを読み込み、インスタンス変数に保持
- enabled、max_depthの値を取得
- MCPクライアントの辞書を保持
load_file_listメソッド
引数:
- task: Task型。タスクオブジェクト
戻り値:
- str型。整形済みファイル一覧文字列。取得失敗時は空文字列
処理内容:
- 設定でenabledがFalseの場合は空文字列を返す
- タスクからプラットフォーム(GitHub/GitLab)を判定
- _fetch_file_list_from_githubまたは_fetch_file_list_from_gitlabメソッドを呼び出してファイル一覧を取得
- 取得に失敗した場合はログ出力して空文字列を返す
- _apply_depth_limitメソッドを呼び出して階層制限を適用
- _format_file_listメソッドを呼び出してフラットリスト形式に整形
- ヘッダーとフッターを付与して返す
_fetch_file_list_from_githubメソッド
引数:
- owner: str型。リポジトリオーナー
- repo: str型。リポジトリ名
戻り値:
- list[str]型。ファイルパスのリスト
処理内容:
- GitHub MCPクライアントの
get_file_contentsツールを使用 - ルートディレクトリから再帰的にファイル一覧を取得
- 各ファイルのフルパス(ディレクトリパスを含む)をリストに追加
- API呼び出しに失敗した場合はエラー内容をログ出力して空リストを返す
_fetch_file_list_from_gitlabメソッド
引数:
- project_id: str型。GitLabプロジェクトID
戻り値:
- list[str]型。ファイルパスのリスト
処理内容:
- GitLab MCPクライアントの
get_repository_treeツールを使用 - プロジェクトのファイルツリーを取得
- 各ファイルのフルパス(ディレクトリパスを含む)をリストに追加
- API呼び出しに失敗した場合はエラー内容をログ出力して空リストを返す
_apply_depth_limitメソッド
引数:
- file_list: list[str]型。ファイルパスのリスト
- max_depth: int型。最大深度。-1の場合は無制限
戻り値:
- list[str]型。深度制限適用後のファイルパスのリスト
処理内容:
- max_depthが-1の場合はそのまま返す
- 各ファイルパスのディレクトリ深度を計算(スラッシュの数をカウント)
- max_depthを超えるファイルは除外
- フィルタリング後のリストを返す
_format_file_listメソッド
引数:
- file_list: list[str]型。ファイルパスのリスト
- owner: str型。リポジトリオーナー
- repo: str型。リポジトリ名
戻り値:
- str型。整形済みファイル一覧文字列
処理内容:
- ファイルリストをアルファベット順にソート
- ヘッダー行を生成(プロジェクト情報を含む)
- 各ファイルパス(ディレクトリパスを含むフルパス形式)を1行ずつ追加
- フッター行を生成(ファイル数を含む)
- 全体を改行で連結して返す
handlers/task_handler.py
コンストラクタの修正
処理内容の追加:
- FileListContextLoaderのインスタンスを生成し、インスタンス変数として保持
- MCPクライアントの辞書を渡す
handleメソッドの修正
処理内容の追加:
- メソッド冒頭で保持しているFileListContextLoaderインスタンスのload_file_listメソッドを呼び出してファイル一覧を取得
- 取得したファイル一覧をシステムプロンプトの末尾に追加
- システムプロンプト送信処理へ継続
handlers/planning_coordinator.py
コンストラクタの修正
処理内容の追加:
- FileListContextLoaderのインスタンスを生成し、インスタンス変数として保持
- MCPクライアントの辞書を渡す
_load_planning_system_promptメソッドの修正
処理内容の追加:
- プロジェクト固有のエージェントルールを追加した後に、FileListContextLoaderインスタンスのload_file_listメソッドを呼び出してファイル一覧を取得
- 取得したファイル一覧をシステムプロンプトの末尾に追加
- システムプロンプト送信処理へ継続
file_list_contextセクションで以下を設定します:
- enabled: ファイル一覧コンテキスト機能の有効/無効(デフォルト: true)
- max_depth: 取得する最大階層深度(デフォルト: -1、無制限)
ファイル一覧の取得に失敗した場合:
- エラー内容をログに記録
- ファイル一覧なしでタスク処理を継続
- エージェントには取得失敗を通知しない(通常通り処理を開始)
- 原因: GitHub/GitLab APIのレート制限に到達
- 対応: ログ出力後、ファイル一覧なしで継続
- 原因: トークンの期限切れや権限不足
- 対応: ログ出力後、ファイル一覧なしで継続
- 原因: 大規模リポジトリでの取得に時間がかかる
- 対応: タイムアウト後、ファイル一覧なしで継続
- 原因: リポジトリが削除された、またはプライベート化された
- 対応: ログ出力後、ファイル一覧なしで継続
文書バージョン: 2.0
最終更新日: 2024-11-28
ステータス: 設計中