最近、AIエージェントについてまとまった時間を割いて勉強した。書籍『実践 AIエージェント開発』を読み、Developers Summitの登壇資料に目を通し、自分のZettelkastenに溜まっていた素材も棚卸しした。ひとしきりインプットを終えて気づいたのは、自分が「エージェント」という言葉を、思っていたよりも雑に使っていたという事実だ。
Claude CodeやCodexを毎日触っているので、感覚的にはわかっているつもりだった。ただ、いざ設計の話になると、モデル・ツール・メモリ・ループをどの順番で決めるべきか、自分の中に整理された軸がなかった。今回はその棚卸しの結果を、自分の言葉でまとめておく。
エージェントは「オーケストレーション」を起点に考える
エージェントシステムの基本形は、ユーザーの入力をオーケストレーションが受け取り、モデル・ツール・メモリ・ナレッジベースへ処理を振り分ける構成だ。複数のエージェントを連携させる方法は、大きく2つに整理できる。処理を別のエージェントへ委譲するRoutingパターンと、エージェントをツールとして呼び出すSupervisorパターンだ。
固定ロジックのワークフローと自律的なエージェントは、対立するものではない。両者を組み合わせた「Agentic Workflow」によって、柔軟性と予測可能性を両立できる。ここが最初の気づきだった。「エージェントらしさ」を自律性の高さだけで測っていたが、実際には決定論的なワークフローをどれだけ賢く組み込めるかの勝負でもある。
現場のLLM活用も、対話で推論を制御する協働型と、SkillsやテンプレートでAIに任せる委託型の2流派に収斂する。どちらが優れているという話ではなく、チームの経験量と現場特性で使い分けるものだと理解した。
普段使っているClaude Codeも、この2パターンを併用している。コード検索を任せるExploreのような探索特化のsubagentと、専門知識に特化したsubagentを、状況に応じて呼び分けている。呼び出す側が全体を統括し、個々の作業は専用のsubagentに投げる。これはSupervisorパターンそのものだ。
ツールの粒度と段階的開示は同じ問題を解いている
ツールを外部システムに繋ぐ汎用プロトコルとしてMCP(Model Context Protocol)がある。従来のAPI呼び出しと違い、動的なコンテキストを推論プロセスへ直接注入できる点が強みだ。
ここで悩ましいのがツールの粒度だった。プリミティブな操作を1つずつツール化する「シンプルなツール群」は柔軟性が高い一方、コンテキストを圧迫しやすい。ユースケース単位でまとめた「複雑な単一ツール」は挙動が一貫する一方、設計工数がかかる。
この構図は、Agent Skillsの設計原則とそっくりだと気づいた。Skillsの価値は新しい能力の追加ではなく、必要なときに必要な知識だけを読み込ませる段階的開示とルーティングにある。ツールの粒度設計もSkillsの設計も、突き詰めると「コンテキストという有限のリソースをどう配分するか」という同じ問題を解いている。
手元の環境でも、この違いは実感しやすい。Figma MCPは画面情報の取得やスクリーンショットなど、操作を細かく分けた「シンプルなツール群」型で、目的に応じて複数のツールを組み合わせる必要がある。一方でObsidian CLIは、ノート作成や検索といったユースケース単位でまとまった「複雑な単一ツール」型に近い。同じMCPというプロトコルの上でも、設計思想の違うツールが混在している。
学習はまずノンパラメトリックから試す
エージェントが経験から学習する手段は、モデルのパラメーターを変えるパラメトリック学習と、プロンプトやメモリ、検索コンテキストの調整で性能を改善するノンパラメトリック学習に分かれる。
ファインチューニングだけが「賢くする」手段だと思い込んでいたが、モデルのパラメーターに手を入れずに記憶や検索の仕組みだけで性能を改善できる、という整理は素直に驚いた。コストと運用の柔軟性を考えれば、まずノンパラメトリックな改善で伸ばせるところまで伸ばし、それでも足りない部分だけファインチューニングを検討する順番が現実的だ。ノンパラメトリック学習はメモリの設計と切り離せないので、学習の話は自然と記憶の話にもつながっていく。
この整理を読んで、一番腑に落ちたのは自分が使っているClaude Codeのメモリ機能だった。ユーザーの好みや過去のフィードバックをMarkdownファイルに書き出し、次回以降の会話で読み込む。モデルのパラメーターは何も変えていないのに、振る舞いだけが会話を重ねるごとに変わっていく。
品質責任はハーネスへ、その先にあるループエンジニアリング
一連のインプットの中で、いちばん自分の実感と結びついたのがこのテーマだった。
モデルの性能そのものより、ツール呼び出しや検証の仕組みといった「モデルの外側」の作り込みが成果を左右する。これがハーネスの考え方だ。lintや型検査、テストでAI出力を縛るだけでなく、着手前の質問やプレモーテムのように、人間の理解を強制する用途にも広がっている。
ループエンジニアリングは、この考え方を「継続的に回る系」へ拡張したものだと捉えている。生成は確率的なままでよく、コードを書いたAI自身に自己評価させるのではなく、作る役と採点する役を別のエージェントに分離し、品質責任をテスト実行やカバレッジ計測のような決定論的な評価系へ寄せる。これでループを何周させても、結果の揺れが収まっていく。
ただし代償もある。
- 検証負債 — 誰も見ていない出力が積み上がる
- 理解負債 — 自分が書いていないコードへの理解が追いつかなくなる
- 認知的降伏 — ループが安定して動くほど、出力に意見を持たなくなる
- トークン暴走 — コストが見積もりを超えやすい
どれも動いている最中は音を立てず、気づいた頃には手遅れになっているのが厄介なところだ。
ループエンジニアリングについては書きたいことが多いので、この記事では概要にとどめ、前に書いた記事やOrange Bookの要約で触れた内容を別記事でまとめて深掘りする予定にしている。
事例:自分のVaultをエージェントシステムとして組み直した
抽象的な整理だけでは実感が湧かないので、自分が運用しているObsidianのZettelkastenで、実際に何を変えたかを書いておく。
以前は「素材を集めて、AIに聞けば答えてくれる」くらいの雑な運用だった。今回の勉強を踏まえて、役割ごとに3つのSkillへ分割し直した。
- kb-compile(編纂役) — InboxやFleeting Notesという「raw」な素材を読み、繰り返し登場する概念をPermanent Notesという「wiki」に書き出す。生成する役
- kb-report(図書館係) — 問いを受け取り、wikiだけを読んで回答をレポートとして書く。rawには直接触れない
- kb-lint(健康診断役) — wiki全体を週次でスキャンし、矛盾や重複、数値の不整合を洗い出す。生成した本人ではなく別の役として検証する
これは、記事の前半で書いたRoutingパターンや委託型の話そのものだ。1つの万能Skillに全部やらせず、生成・参照・検証という役割ごとに委託先を分けている。
境界の引き方も意識して決めた。rawは読み取り専用にし、Claudeが勝手に削除やリネームをできないようにしている。レポートはwikiだけを引用し、rawを直接引用しない。これは人間が「何を作るべきか」を決め、AIに「正しく動くか」の検証を任せるという分業ラインを、フォルダ構造として固定した例だ。
kb-lintは、ハーネスとループエンジニアリングの節で書いた「作る役と採点する役の分離」の実装でもある。kb-compileが生成した内容を、kb-compile自身には評価させない。別のSkillであるkb-lintに棚卸しさせる。週次で回すこの仕組みには、最小構成のループに必要な4点がすでに揃っている。オートメーション(週次トリガー)、Skill(役割ごとの前提知識)、ステートファイル(issues.md)、ゲート(矛盾チェック)だ。
人間に残るのは、判断と検証と境界設計
実装のコモディティ化が進むほど、「何を作るべきか」を見極める力と、「作られたものが正しく動くか」を検証する力の価値が上がる。仕様が閉じた領域はAIが担い、正解のない可変な領域は人間の担当として残る、という分業が進んでいく。
作るコストが下がっても、検証・運用・保守にかかる維持コストは自然には下がらない。生成コストが下がるほど、工程間の受け渡しが相対的なボトルネックとして目立つようになる。ボトルネックは消えずに移動し続けるので、移った先に合わせてプロセスや組織、アーキテクチャを組み替え続ける姿勢が必要だ、という指摘には素直にうなずいた。
この記事の執筆も同じだ。textlintで表記の誤りは機械的に検出できるし、事例の叩き台もAIが出せる。ただし、どの事例が読者に刺さるか、どこまで書けば十分かという最終判断は、結局自分がしている。検証は任せられても、境界線を引く判断は残る。
まとめ
一気に勉強してみて、自分の中で一番変わったのは「エージェントを賢くする」という発想の解像度だった。モデルを強くする、プロンプトを工夫するという単一の手段ではない。オーケストレーション・ツールの粒度・学習方法・ハーネス・ループという複数の層に分け、層ごとに別の設計判断をする話だとわかった。
面白かったのは、この整理が本の中だけで終わらなかったことだ。
- Claude Codeのsubagentの使い分け
- 普段触っているMCPツール群の粒度差
- メモリ機能
- 自分のVaultのkb-compile・kb-report・kb-lint
振り返れば、どれも同じ原則の実装だった。知らないうちに、自分はすでにこの設計原則の上で動いていたことになる。
とくにループエンジニアリングは、ハーネスのさらに上に位置する層として、今の自分の日常的な使い方に一番近い。次はこのテーマだけを掘り下げた記事を書くつもりだ。