JA EN
体系エージェント
·★ 会員·論文·12分で読めます

【実装】エージェントループを自作する — ツール呼び出しの最小形

「AIエージェント」の中心はwhile文ひとつです。JSON関数呼び出しの形、ReActが残した設計、そして事故のほとんどが集まる停止条件までを、フレームワークを使わない40行のコードとして1から組み上げます。

対象textタスクagent

ReAct: Synergizing Reasoning and Acting in Language Models

一次資料 — この記事の根拠

論文の発表 2022-10-06この解説の公開 2026-08-273年11か月後

ReAct: Synergizing Reasoning and Acting in Language ModelsShunyu Yao, Jeffrey Zhao, Dian Yu ほか · 2022-10-06 · v3arXiv:2210.03629論文ページ·PDF
原文の要旨(Abstract)を読む

While large language models (LLMs) have demonstrated impressive capabilities across tasks in language understanding and interactive decision making, their abilities for reasoning (e.g. chain-of-thought prompting) and acting (e.g. action plan generation) have primarily been studied as separate topics. In this paper, we explore the use of LLMs to generate both reasoning traces and task-specific actions in an interleaved manner, allowing for greater synergy between the two: reasoning traces help the model induce, track, and update action plans as well as handle exceptions, while actions allow it to interface with external sources, such as knowledge bases or environments, to gather additional information. We apply our approach, named ReAct, to a diverse set of language and decision making tasks and demonstrate its effectiveness over state-of-the-art baselines, as well as improved human interpretability and trustworthiness over methods without reasoning or acting components. Concretely, on question answering (HotpotQA) and fact verification (Fever), ReAct overcomes issues of hallucination and error propagation prevalent in chain-of-thought reasoning by interacting with a simple Wikipedia API, and generates human-like task-solving trajectories that are more interpretable than baselines without reasoning traces. On two interactive decision making benchmarks (ALFWorld and WebShop), ReAct outperforms imitation and reinforcement learning methods by an absolute success rate of 34% and 10% respectively, while being prompted with only one or two in-context examples. Project site with code: https://react-lm.github.io


電話越しの助手

とても物知りだが、目の前にいない助手に電話で仕事を頼む場面を想像してください。助手には手も足もなく、あなたの声しか届きません。だから助手は「そのフォルダに何が入っているか読み上げてください」と頼み、あなたが読み上げ、それを聞いた助手が次の指示を出します。この往復を何度か繰り返して、ようやく仕事が片づく。

いま「AIエージェント」と呼ばれているものの正体は、これです。言語モデルは文字列を受け取って文字列を返す関数でしかなく、ファイルを開くこともメールを送ることもできません。手を動かすのは常に外側のプログラムです。エージェントフレームワークの中心的な価値は、この電話の往復を自動化する十数行のループにすぎません。

この記事ではそのループをフレームワークなしで組みます。ゴールは動くコードを手に入れることではなく、どの行を消すと何が壊れるかを説明できるようになることです。

正体は while 文

先に結論を出します。エージェントの中核はこれだけです。

messages = [{"role": "user", "content": task}]
while True:
    reply = model(messages, tools=TOOLS)     # 1. 考えさせる
    messages.append(assistant_turn(reply))   # 2. 発言を履歴に積む
    calls = tool_calls_in(reply)
    if not calls:                            # 3. 道具を使わなかった = 終わり
        return text_of(reply)
    results = [run(c) for c in calls]        # 4. こちらが手を動かす
    messages.append(user_turn(results))      # 5. 結果を履歴に積む

「エージェント」という言葉の魔法は、ここで一度解けておいたほうがいい。モデルは意志を持って動き続けているのではありません。毎回まっさらな状態で会話履歴を頭から読み直し、次の1手だけを出力して終わっています。 連続性を持つのは messages 配列のほうで、モデル側に前回の記憶は残りません。

この非対称性が、あとの設計判断のほとんどを決めます。履歴が唯一の記憶だから、書かなかったことはモデルにとって存在せず、ステップを重ねるほど毎回の入力が膨らみ、失敗の原因も書いてやらないと同じ失敗を繰り返します。

部品は4つだけです。道具の一覧表モデル呼び出しディスパッチャ(道具の名前を実際の関数に結びつける対応表)、そして停止条件

道具をどう説明するか

モデルに道具を渡すというのは、実質的には関数のシグネチャをJSONで書いて渡すことです。

{
  "name": "read_file",
  "description": "リポジトリ内のテキストファイルを1つ読む。パスはリポジトリルートからの相対。バイナリには使えない。存在を確認したいだけなら list_dir を使うこと。",
  "input_schema": {
    "type": "object",
    "properties": {
      "path": { "type": "string", "description": "例: src/main.py" }
    },
    "required": ["path"]
  }
}

ここで初学者がほぼ必ず一度はやる失敗があります。description を人間向けに書いてしまうことです。この文章の読者は同僚ではなくモデルです。気の利いた要約より、「使ってはいけない場面」「引数の書式の実例」「失敗したときに何が返るか」を書いたほうが効きます。説明文を1行足しただけで挙動が変わることは珍しくありません。

なお、返ってくるJSONが構文として壊れないことは、制約デコーディング(文法的に許されないトークンを出力前に潰す仕組み)でかなり保証できます。ただし構文が正しいことと引数の中身が正しいことは別で、実在しないパスを型どおりの文字列で渡してくることは平気で起きます。この境界は構造化出力と制約デコーディングで扱っています。

ループを回すときの温度(サンプリングのばらつきを決めるパラメータ)は、通常の文章生成より低めに置きます。道具の名前の綴りが揺れれば存在しない関数を呼びますし、同じ状況で毎回違う判断をされるとデバッグが成立しないからです。

FIG 1温度を下げると確率が一点に集中し、上げると平らになる。エージェントでは道具の選択がこの分布そのもの — 高温では「2番目に良い道具」が選ばれる確率が無視できなくなる

ただし温度を0にすれば安全、という話でもありません。履歴が同じなら出力も同じになるので、一度失敗ループに入ると自力で抜けられなくなります。低め(おおむね0〜0.3)に置いたうえで、抜け出せない状況は停止条件のほうで扱う、というのが実装上の分担です。

擬似コードを実際のAPIの形に落とします。以下はClaudeのMessages APIの形ですが、名前が違うだけで他社のfunction callingでも構造は同じです。

この先にあるもの

§

ここから先は会員限定です

解説記事371本・教科書26章・学生モード48単元・論文精読6本が、月額¥490ですべて読み放題になります。新しい解説は毎日3本ずつ増えます。いつでも解約でき、解約後も期間の終わりまで読めます。

会員の方はログインすると続きが表示されます

参考文献

  1. Shunyu Yao, Jeffrey Zhao, Dian Yu, Nan Du et al.. (2022-10-06) ReAct: Synergizing Reasoning and Acting in Language Models. arXiv:2210.03629論文ページ·PDF

本記事は上記論文の本文にもとづいて執筆しています。数値・主張は原典を優先してください。

コメント

コメントにはログインが必要です