この回のゴール
- 第 5 章の RAG を ツール として第 6 章のエージェントに組み込む
- 複数種類のツール を連携させた本格タスクを解かせる
- 本番運用に近い「有能なアシスタント」を体験する
- ここまでの全知識が 1 つの動くシステム として統合されたことを実感する
1. 設計する「本格エージェント」
用意するツール
| ツール | 役割 | 実装 |
|---|---|---|
search_handbook(query) |
社内文書を検索 | 第 5 章の RAG をそのまま |
calculator(expression) |
数値計算 | Python eval(安全化) |
get_current_time() |
現在時刻 | datetime.now() |
get_exchange_rate(...) |
為替レート | 擬似データ |
キモは search_handbook。第 5 章の RAG パイプラインを 1 つの関数 にして、エージェントのツールとして登録します。
解けるようになるタスクの例
「勤続 7 年目で有給を全部使った場合の、有給の経済価値 を概算して。月給は 45 万円として。」
このタスクには:
- search_handbook("勤続 7 年 有給") で日数を調べる → 25 日
- calculator("450000 / 20") で日給を計算 → 22,500 円
- calculator("22500 * 25") で合計 → 562,500 円
- 自然言語で回答
→ 4 ステップ必要。単体のツールや RAG では不可能。
2. RAG をツール化する設計
class RAGSearchTool:
def __init__(self, chunks, embed_model, faiss_index):
self.chunks = chunks
self.model = embed_model
self.index = faiss_index
def __call__(self, query: str, top_k: int = 3) -> str:
q_vec = self.model.encode([query], normalize_embeddings=True)
D, I = self.index.search(q_vec, top_k)
results = []
for rank, idx in enumerate(I[0]):
results.append(f"[{rank+1}] {self.chunks[idx]}")
return "\n\n".join(results)
エージェント側のツール定義:
{
"name": "search_handbook",
"description": (
"ネオテック社の社員ハンドブックを検索する。"
"制度・規定・福利厚生に関する質問があれば必ずこのツールを使う。"
),
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "検索クエリ"}
},
"required": ["query"],
}
}
3. プロンプトエンジニアリングのポイント
役割と方針
あなたはネオテック社の社員向けアシスタントです。
ルール:
- 事実情報は必ず search_handbook で取得してから回答
- 計算は必ず calculator を使う(自分では計算しない)
- 社内規定にない情報を推測で埋めない
- 根拠となった文書を引用する
効率化の指示
- 同じ検索を繰り返さない
- 既に取得した情報は再利用する
- 不明点は正直に「情報なし」と答える
これがないと前章の「暴走」が起きます。
4. 出典(Citation)の扱い
エージェントに「引用元を明示せよ」と指示すると、RAG 結果の [1] [2] などを引用してくれます:
あなたの質問「...」に対する回答:
勤続 5 年以上の社員の有給は年間 25 日です [1]。
月給 45 万円の場合、日給は 22,500 円になるので [2]、
有給 25 日の経済価値は約 562,500 円となります [2]。
---
[1] 第 3 章 休日および休暇 — 年次有給休暇は...
[2] 計算: 450000 / 20 = 22500, 22500 × 25 = 562500
RAG と calculator の出力を 同じように引用 できるのがポイント。
5. 思考トレースを UI で見せる
対話型 UI では:
- 最終回答を目立たせる
- 思考とツール呼び出しを折りたたみ で見られる
- 引用元を展開可能 に
6. さらなる発展(参考)
サブエージェント
複雑タスクを 別のエージェント に委譲する(Anthropic の Claude Code もこれを使用):
メインエージェント
├─ search_subagent (RAG 特化)
├─ calc_subagent (計算特化)
└─ write_subagent (文書作成特化)
メモリ
セッションを跨いで覚える:
- 会話履歴の要約
- ユーザー情報の保持
- memory_tool による永続化
プランニング
「最初に TODO リストを作らせる」パターン:
Step 1: 有給日数を検索
Step 2: 月給を確認
Step 3: 日給を計算
Step 4: 合計を計算
Step 5: 回答
Claude に先にプランを作らせてから実行する → 計画性が上がる。
まとめ
- RAG を「1 つのツール」として登録すれば、エージェントから自然に呼べる
- 4 ツール (RAG + calc + time + rate) を組み合わせた本格エージェントで多段タスクを解ける
- system プロンプトで「役割・効率化指示・引用」を強制
- 発展形: サブエージェント / メモリ / プランニング
この回の限界(次への動機)
賢いエージェントは作れた。でも 何が得意で何が苦手か を見極めないと過剰設計・誤用に陥る。 👉 次回「できること・できないこと」で、限界とアンチパターンを直視します。
参考文献
- Anthropic: Building Effective Agents
- Anthropic Cookbook: Customer Support Agent