我构建过很多人工智能演示程序,它们在笔记本上看起来很棒,但在实际生产环境中却都崩溃了。通常的罪魁祸首是什么?就是把逻辑推理模型(LLM)当作搜索引擎来对待,输入一个问题,输出一个答案,而不是把它当作真正的推理引擎来使用——它可以集成到实际的工作流程中。

本教程旨在指导您如何正确地构建人工智能代理。我们将从零开始,使用 Anthropic 的 Claude API 构建一个功能齐全的人工智能代理,而不是仅仅使用框架的封装层。我们将深入讲解实际的机制:ReAct 循环、自定义工具的使用以及可实际部署的结构。教程结束时,您将拥有可运行的代码,并建立一个清晰的思维模型,这将使​​您能够理解之后的所有人工智能代理教程。

让我们开始吧。

我们实际在建造什么

我们正在开发的代理将具备以下功能:

  • 接受用户查询
  • 决定它需要哪些工具来回答这个问题
  • 调用这些工具,观察结果
  • 仔细分析结果,然后决定是调用更多工具还是给出最终答案。

这种模式称为 ReAct(推理 + 行动)。它是大多数生产级智能体的核心,并且与 Claude 的工具使用 API 的工作方式完美契合,方便团队使用Claude 构建用于实际自动化的 AI 智能体。

先决条件

bash
pip install anthropic python-dotenv

您需要从 console.anthropic.com 获取 Claude API 密钥。请妥善保管:

bash
.env
ANTHROPIC_API_KEY=your_key_here

步骤 1:Claude API 基本设置

在创建代理之前,让我们确认你可以和克劳德对话。

<span style="color:#f8f8f2"><span style="color:#f8f8f2"><code><span style="color:#f8f8f2">python</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">os</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">anthropic</span>
<span style="color:#f9690e">from</span> <span style="color:#f8f8f2">dotenv</span> <span style="color:#f9690e">import</span> <span style="color:#f8f8f2">load_dotenv</span>

<span style="color:#7ed07e">load_dotenv</span><span style="color:#f8f8f2">()</span>

<span style="color:#f8f8f2">client</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">anthropic</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">Anthropic</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">api_key</span><span style="color:#f9690e">=</span><span style="color:#f8f8f2">os</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">getenv</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">ANTHROPIC_API_KEY</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">))</span>

<span style="color:#f39c12">def</span> <span style="color:#7ed07e">ask_claude</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">prompt</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">)</span> <span style="color:#f9690e">-></span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">:</span>
    <span style="color:#f8f8f2">message</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">client</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">messages</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">create</span><span style="color:#f8f8f2">(</span>
        <span style="color:#f8f8f2">model</span><span style="color:#f9690e">=</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">claude-sonnet-4-5</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
        <span style="color:#f8f8f2">max_tokens</span><span style="color:#f9690e">=</span><span style="color:#dda0dd">1024</span><span style="color:#f8f8f2">,</span>
        <span style="color:#f8f8f2">messages</span><span style="color:#f9690e">=</span><span style="color:#f8f8f2">[</span>
            <span style="color:#f8f8f2">{</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">role</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">user</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">prompt</span><span style="color:#f8f8f2">}</span>
        <span style="color:#f8f8f2">]</span>
    <span style="color:#f8f8f2">)</span>
    <span style="color:#f39c12">return</span> <span style="color:#f8f8f2">message</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">content</span><span style="color:#f8f8f2">[</span><span style="color:#dda0dd">0</span><span style="color:#f8f8f2">].</span><span style="color:#f8f8f2">text</span>

<span style="color:#808080"># Quick test
</span><span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#7ed07e">ask_claude</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">What is 2 + 2? Answer in one word.</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">))</span>
</code></span></span>

这是基础。如果运行顺利,就可以在此基础上继续开发了。如需更深入地了解模型选择和 API 参数,建议您在继续学习之前先阅读 Dextra Labs 提供的Claude API 使用教程。

步骤二:定义你的工具

工具是智能体的双手。没有它们,Claude 只能推理,而无法行动。我们将定义智能体可以使用的三种工具:计算器、网络搜索模拟器和文件写入器。
在 Claude 的 API 中,工具以 JSON 模式的形式定义。Claude 读取这些模式,并决定何时以及如何调用它们。

<span style="color:#f8f8f2"><span style="color:#f8f8f2"><code><span style="color:#f8f8f2">python</span>
<span style="color:#f8f8f2">tools</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">[</span>
    <span style="color:#f8f8f2">{</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">name</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">calculator</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">description</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">Performs basic arithmetic. Use this for any math operations.</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">input_schema</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">type</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">object</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">properties</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">expression</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{</span>
                    <span style="color:#f2ca27">"</span><span style="color:#f2ca27">type</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">string</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
                    <span style="color:#f2ca27">"</span><span style="color:#f2ca27">description</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">Math expression to evaluate, e.g. </span><span style="color:#f2ca27">'</span><span style="color:#f2ca27">15 * 24 + 100</span><span style="color:#f2ca27">'"</span>
                <span style="color:#f8f8f2">}</span>
            <span style="color:#f8f8f2">},</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">required</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">[</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">expression</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">]</span>
        <span style="color:#f8f8f2">}</span>
    <span style="color:#f8f8f2">},</span>
    <span style="color:#f8f8f2">{</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">name</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">web_search</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">description</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">Searches the web for current information on a topic.</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">input_schema</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">type</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">object</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">properties</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">query</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{</span>
                    <span style="color:#f2ca27">"</span><span style="color:#f2ca27">type</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">string</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
                    <span style="color:#f2ca27">"</span><span style="color:#f2ca27">description</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">The search query</span><span style="color:#f2ca27">"</span>
                <span style="color:#f8f8f2">}</span>
            <span style="color:#f8f8f2">},</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">required</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">[</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">query</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">]</span>
        <span style="color:#f8f8f2">}</span>
    <span style="color:#f8f8f2">},</span>
    <span style="color:#f8f8f2">{</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">name</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">save_to_file</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">description</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">Saves text content to a local file.</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">input_schema</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">type</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">object</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">properties</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">filename</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">type</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">string</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">},</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">type</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">string</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">}</span>
            <span style="color:#f8f8f2">},</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">required</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">[</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">filename</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">]</span>
        <span style="color:#f8f8f2">}</span>
    <span style="color:#f8f8f2">}</span>
<span style="color:#f8f8f2">]</span>

</code></span></span>

现在让我们编写当 Claude 调用这些工具时实际执行的 Python 函数:

<span style="color:#f8f8f2"><span style="color:#f8f8f2"><code><span style="color:#f8f8f2">python</span>
<span style="color:#f9690e">import</span> <span style="color:#f8f8f2">math</span>

<span style="color:#f39c12">def</span> <span style="color:#7ed07e">calculator</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">expression</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">)</span> <span style="color:#f9690e">-></span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">:</span>
    <span style="color:#f39c12">try</span><span style="color:#f8f8f2">:</span>
        <span style="color:#808080"># Safe eval for math expressions
</span>        <span style="color:#f8f8f2">allowed</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">{</span><span style="color:#f8f8f2">k</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">v</span> <span style="color:#f39c12">for</span> <span style="color:#f8f8f2">k</span><span style="color:#f8f8f2">,</span> <span style="color:#f8f8f2">v</span> <span style="color:#f9690e">in</span> <span style="color:#f8f8f2">math</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">__dict__</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">items</span><span style="color:#f8f8f2">()</span> 
                   <span style="color:#f39c12">if</span> <span style="color:#f9690e">not</span> <span style="color:#f8f8f2">k</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">startswith</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">__</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)}</span>
        <span style="color:#f8f8f2">result</span> <span style="color:#f9690e">=</span> <span style="color:#7ed07e">eval</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">expression</span><span style="color:#f8f8f2">,</span> <span style="color:#f8f8f2">{</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">__builtins__</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">{}},</span> <span style="color:#f8f8f2">allowed</span><span style="color:#f8f8f2">)</span>
        <span style="color:#f39c12">return</span> <span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">Result: </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">result</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span>
    <span style="color:#f39c12">except</span> <span style="color:#f8f8f2">Exception</span> <span style="color:#f39c12">as</span> <span style="color:#f8f8f2">e</span><span style="color:#f8f8f2">:</span>
        <span style="color:#f39c12">return</span> <span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">Error: </span><span style="color:#f2ca27">{</span><span style="color:#7ed07e">str</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">e</span><span style="color:#f8f8f2">)</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span>

<span style="color:#f39c12">def</span> <span style="color:#7ed07e">web_search</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">query</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">)</span> <span style="color:#f9690e">-></span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">:</span>
    <span style="color:#808080"># In production, wire this to SerpAPI, Tavily, or Brave Search
</span>    <span style="color:#808080"># Simulated response for tutorial purposes
</span>    <span style="color:#7ed07e">return </span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">Search results for </span><span style="color:#f2ca27">'</span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">query</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">'</span><span style="color:#f2ca27">: </span><span style="color:#f2ca27">"</span>
            <span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">[Simulated] Top result: Relevant information about </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">query</span><span style="color:#f2ca27">}</span> <span style="color:#f2ca27">"</span>
            <span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">from authoritative sources. Published 2025.</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>

<span style="color:#f39c12">def</span> <span style="color:#7ed07e">save_to_file</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">filename</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">,</span> <span style="color:#f8f8f2">content</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">)</span> <span style="color:#f9690e">-></span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">:</span>
    <span style="color:#f39c12">try</span><span style="color:#f8f8f2">:</span>
        <span style="color:#f39c12">with</span> <span style="color:#7ed07e">open</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">filename</span><span style="color:#f8f8f2">,</span> <span style="color:#f2ca27">'</span><span style="color:#f2ca27">w</span><span style="color:#f2ca27">'</span><span style="color:#f8f8f2">)</span> <span style="color:#f39c12">as</span> <span style="color:#f8f8f2">f</span><span style="color:#f8f8f2">:</span>
            <span style="color:#f8f8f2">f</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">write</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">content</span><span style="color:#f8f8f2">)</span>
        <span style="color:#f39c12">return</span> <span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">Successfully saved to </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">filename</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span>
    <span style="color:#f39c12">except</span> <span style="color:#f8f8f2">Exception</span> <span style="color:#f39c12">as</span> <span style="color:#f8f8f2">e</span><span style="color:#f8f8f2">:</span>
        <span style="color:#f39c12">return</span> <span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">Error saving file: </span><span style="color:#f2ca27">{</span><span style="color:#7ed07e">str</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">e</span><span style="color:#f8f8f2">)</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span>

<span style="color:#f8f8f2">Tool</span> <span style="color:#f8f8f2">dispatcher</span>
<span style="color:#f39c12">def</span> <span style="color:#7ed07e">execute_tool</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">tool_name</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">,</span> <span style="color:#f8f8f2">tool_input</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">dict</span><span style="color:#f8f8f2">)</span> <span style="color:#f9690e">-></span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">:</span>
    <span style="color:#f39c12">if</span> <span style="color:#f8f8f2">tool_name</span> <span style="color:#f9690e">==</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">calculator</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span>
        <span style="color:#f39c12">return</span> <span style="color:#7ed07e">calculator</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">tool_input</span><span style="color:#f8f8f2">[</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">expression</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">])</span>
    <span style="color:#f39c12">elif</span> <span style="color:#f8f8f2">tool_name</span> <span style="color:#f9690e">==</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">web_search</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span>
        <span style="color:#f39c12">return</span> <span style="color:#7ed07e">web_search</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">tool_input</span><span style="color:#f8f8f2">[</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">query</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">])</span>
    <span style="color:#f39c12">elif</span> <span style="color:#f8f8f2">tool_name</span> <span style="color:#f9690e">==</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">save_to_file</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span>
        <span style="color:#f39c12">return</span> <span style="color:#7ed07e">save_to_file</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">tool_input</span><span style="color:#f8f8f2">[</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">filename</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">],</span> <span style="color:#f8f8f2">tool_input</span><span style="color:#f8f8f2">[</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">])</span>
    <span style="color:#f39c12">else</span><span style="color:#f8f8f2">:</span>
        <span style="color:#f39c12">return</span> <span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">Unknown tool: </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">tool_name</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span>
</code></span></span>

这里的调度器设计得比较简单。在生产环境中,你会想要使用注册表模式,但对于学习而言,明确性比巧妙的设计更好。

步骤 3:构建 React Agent 循环

这是本教程的核心内容。ReAct 循环的工作原理如下:

  1. 将用户查询和可用工具发送给 Claude
  2. Claude 要么返回最终答案,要么返回工具调用请求。
  3. 如果调用工具 → 执行该工具,则将结果发送回 Claude。
  4. 重复此过程,直到克劳德给出最终答案。
<span style="color:#f8f8f2"><span style="color:#f8f8f2"><code><span style="color:#f8f8f2">python</span>
<span style="color:#f39c12">def</span> <span style="color:#7ed07e">run_agent</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">user_query</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">,</span> <span style="color:#f8f8f2">max_iterations</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">int</span> <span style="color:#f9690e">=</span> <span style="color:#dda0dd">10</span><span style="color:#f8f8f2">)</span> <span style="color:#f9690e">-></span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">:</span>
    <span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#dda0dd">\n</span><span style="color:#f2ca27">{</span><span style="color:#f2ca27">'</span><span style="color:#f2ca27">=</span><span style="color:#f2ca27">'</span><span style="color:#f9690e">*</span><span style="color:#dda0dd">50</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>
    <span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">User: </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">user_query</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>
    <span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">{</span><span style="color:#f2ca27">'</span><span style="color:#f2ca27">=</span><span style="color:#f2ca27">'</span><span style="color:#f9690e">*</span><span style="color:#dda0dd">50</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>

    <span style="color:#f8f8f2">messages</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">[</span>
        <span style="color:#f8f8f2">{</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">role</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">user</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">user_query</span><span style="color:#f8f8f2">}</span>
    <span style="color:#f8f8f2">]</span>

    <span style="color:#f8f8f2">system_prompt</span> <span style="color:#f9690e">=</span> <span style="color:#f2ca27">"""</span><span style="color:#f2ca27">You are a helpful AI agent with access to tools.
    Think step by step. Use tools when you need real data or calculations.
    When you have enough information, provide a clear final answer.</span><span style="color:#f2ca27">"""</span>

    <span style="color:#f39c12">for</span> <span style="color:#f8f8f2">iteration</span> <span style="color:#f9690e">in</span> <span style="color:#7ed07e">range</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">max_iterations</span><span style="color:#f8f8f2">):</span>
        <span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#dda0dd">\n</span><span style="color:#f2ca27">[Iteration </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">iteration</span> <span style="color:#f9690e">+</span> <span style="color:#dda0dd">1</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">]</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>

        <span style="color:#808080"># Call Claude with tools
</span>        <span style="color:#f8f8f2">response</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">client</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">messages</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">create</span><span style="color:#f8f8f2">(</span>
            <span style="color:#f8f8f2">model</span><span style="color:#f9690e">=</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">claude-sonnet-4-5</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f8f8f2">max_tokens</span><span style="color:#f9690e">=</span><span style="color:#dda0dd">4096</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f8f8f2">system</span><span style="color:#f9690e">=</span><span style="color:#f8f8f2">system_prompt</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f8f8f2">tools</span><span style="color:#f9690e">=</span><span style="color:#f8f8f2">tools</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f8f8f2">messages</span><span style="color:#f9690e">=</span><span style="color:#f8f8f2">messages</span>
        <span style="color:#f8f8f2">)</span>

        <span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">Stop reason: </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">response</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">stop_reason</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>

        <span style="color:#808080"># If Claude is done reasoning, return the final answer
</span>        <span style="color:#f39c12">if</span> <span style="color:#f8f8f2">response</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">stop_reason</span> <span style="color:#f9690e">==</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">end_turn</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span>
            <span style="color:#f8f8f2">final_answer</span> <span style="color:#f9690e">=</span> <span style="color:#f2ca27">""</span>
            <span style="color:#f39c12">for</span> <span style="color:#f8f8f2">block</span> <span style="color:#f9690e">in</span> <span style="color:#f8f8f2">response</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">content</span><span style="color:#f8f8f2">:</span>
                <span style="color:#f39c12">if</span> <span style="color:#7ed07e">hasattr</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">,</span> <span style="color:#f2ca27">'</span><span style="color:#f2ca27">text</span><span style="color:#f2ca27">'</span><span style="color:#f8f8f2">):</span>
                    <span style="color:#f8f8f2">final_answer</span> <span style="color:#f9690e">+=</span> <span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">text</span>
            <span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#dda0dd">\n</span><span style="color:#f2ca27">Final Answer: </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">final_answer</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>
            <span style="color:#f39c12">return</span> <span style="color:#f8f8f2">final_answer</span>

        <span style="color:#808080"># If Claude wants to use tools
</span>        <span style="color:#f39c12">if</span> <span style="color:#f8f8f2">response</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">stop_reason</span> <span style="color:#f9690e">==</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">tool_use</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span>
            <span style="color:#808080"># Add Claude's response to message history
</span>            <span style="color:#f8f8f2">messages</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">append</span><span style="color:#f8f8f2">({</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">role</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">assistant</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">response</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">content</span>
            <span style="color:#f8f8f2">})</span>

            <span style="color:#808080"># Process each tool call
</span>            <span style="color:#f8f8f2">tool_results</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">[]</span>
            <span style="color:#f39c12">for</span> <span style="color:#f8f8f2">block</span> <span style="color:#f9690e">in</span> <span style="color:#f8f8f2">response</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">content</span><span style="color:#f8f8f2">:</span>
                <span style="color:#f39c12">if</span> <span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">type</span> <span style="color:#f9690e">==</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">tool_use</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span>
                    <span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">  Tool: </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">name</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>
                    <span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">  Input: </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">input</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>

                    <span style="color:#808080"># Execute the tool
</span>                    <span style="color:#f8f8f2">result</span> <span style="color:#f9690e">=</span> <span style="color:#7ed07e">execute_tool</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">name</span><span style="color:#f8f8f2">,</span> <span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">input</span><span style="color:#f8f8f2">)</span>
                    <span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">f</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">  Result: </span><span style="color:#f2ca27">{</span><span style="color:#f8f8f2">result</span><span style="color:#f2ca27">}</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>

                    <span style="color:#f8f8f2">tool_results</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">append</span><span style="color:#f8f8f2">({</span>
                        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">type</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">tool_result</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
                        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">tool_use_id</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">id</span><span style="color:#f8f8f2">,</span>
                        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">result</span>
                    <span style="color:#f8f8f2">})</span>

            <span style="color:#808080"># Send tool results back to Claude
</span>            <span style="color:#f8f8f2">messages</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">append</span><span style="color:#f8f8f2">({</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">role</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">user</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">tool_results</span>
            <span style="color:#f8f8f2">})</span>

    <span style="color:#f39c12">return</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">Max iterations reached without a final answer.</span><span style="color:#f2ca27">"</span>
</code></span></span>

这里的关键在于消息历史记录。每次工具调用及其结果都会被添加到记录中messages,因此 Claude 始终能够完整地了解它已经尝试过的操作。这正是有状态代理与无状态聊天机器人的区别所在。

第四步:运行它

<span style="color:#f8f8f2"><span style="color:#f8f8f2"><code><span style="color:#f8f8f2">python</span>
<span style="color:#f39c12">if</span> <span style="color:#f8f8f2">__name__</span> <span style="color:#f9690e">==</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">__main__</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span>
    <span style="color:#808080"># Test 1: Math + file output
</span>    <span style="color:#f8f8f2">result</span> <span style="color:#f9690e">=</span> <span style="color:#7ed07e">run_agent</span><span style="color:#f8f8f2">(</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">Calculate compound interest on $10,000 at 7% for 10 years, </span><span style="color:#f2ca27">"</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">then save the result to </span><span style="color:#f2ca27">'</span><span style="color:#f2ca27">investment.txt</span><span style="color:#f2ca27">'"</span>
    <span style="color:#f8f8f2">)</span>

    <span style="color:#808080"># Test 2: Research + synthesis
</span>    <span style="color:#f8f8f2">result</span> <span style="color:#f9690e">=</span> <span style="color:#7ed07e">run_agent</span><span style="color:#f8f8f2">(</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">Search for information about RAG architecture </span><span style="color:#f2ca27">"</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">and summarize the key components.</span><span style="color:#f2ca27">"</span>
    <span style="color:#f8f8f2">)</span>

    <span style="color:#f8f8f2">Test</span> <span style="color:#dda0dd">3</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">Multi</span><span style="color:#f9690e">-</span><span style="color:#f8f8f2">step</span> <span style="color:#f8f8f2">reasoning</span>
    <span style="color:#f8f8f2">result</span> <span style="color:#f9690e">=</span> <span style="color:#7ed07e">run_agent</span><span style="color:#f8f8f2">(</span>
        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">What is the square root of 144 multiplied by the number of days in a leap year?</span><span style="color:#f2ca27">"</span>
    <span style="color:#f8f8f2">)</span>
</code></span></span>

运行此命令,并在终端中观察代理程序如何执行每一步操作。迭代日志会详细显示 Claude 如何决定调用哪个工具以及何时停止。

第五步:添加内存(生产环境升级)

上述代理是无状态的,每次run_agent通话都会重新开始。但实际应用需要会话记忆功能。以下是一个最小实现示例:

<span style="color:#f8f8f2"><span style="color:#f8f8f2"><code><span style="color:#f8f8f2">python</span>
<span style="color:#f39c12">class</span> <span style="color:#7ed07e">AgentWithMemory</span><span style="color:#f8f8f2">:</span>
    <span style="color:#f39c12">def</span> <span style="color:#7ed07e">__init__</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">):</span>
        <span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">conversation_history</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">[]</span>
        <span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">client</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">anthropic</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">Anthropic</span><span style="color:#f8f8f2">(</span>
            <span style="color:#f8f8f2">api_key</span><span style="color:#f9690e">=</span><span style="color:#f8f8f2">os</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">getenv</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">ANTHROPIC_API_KEY</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">)</span>
        <span style="color:#f8f8f2">)</span>

    <span style="color:#f39c12">def</span> <span style="color:#7ed07e">chat</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">,</span> <span style="color:#f8f8f2">user_message</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">)</span> <span style="color:#f9690e">-></span> <span style="color:#f8f8f2">str</span><span style="color:#f8f8f2">:</span>
        <span style="color:#808080"># Add user message to history
</span>        <span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">conversation_history</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">append</span><span style="color:#f8f8f2">({</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">role</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">user</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">user_message</span>
        <span style="color:#f8f8f2">})</span>

        <span style="color:#f8f8f2">response</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">client</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">messages</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">create</span><span style="color:#f8f8f2">(</span>
            <span style="color:#f8f8f2">model</span><span style="color:#f9690e">=</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">claude-sonnet-4-5</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f8f8f2">max_tokens</span><span style="color:#f9690e">=</span><span style="color:#dda0dd">4096</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f8f8f2">system</span><span style="color:#f9690e">=</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">You are a helpful assistant with memory of our conversation.</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f8f8f2">tools</span><span style="color:#f9690e">=</span><span style="color:#f8f8f2">tools</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f8f8f2">messages</span><span style="color:#f9690e">=</span><span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">conversation_history</span>
        <span style="color:#f8f8f2">)</span>

        <span style="color:#808080"># Handle tool use within persistent history
</span>        <span style="color:#f39c12">if</span> <span style="color:#f8f8f2">response</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">stop_reason</span> <span style="color:#f9690e">==</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">tool_use</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span>
            <span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">conversation_history</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">append</span><span style="color:#f8f8f2">({</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">role</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">assistant</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">response</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">content</span>
            <span style="color:#f8f8f2">})</span>
            <span style="color:#f8f8f2">tool_results</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">[]</span>
            <span style="color:#f39c12">for</span> <span style="color:#f8f8f2">block</span> <span style="color:#f9690e">in</span> <span style="color:#f8f8f2">response</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">content</span><span style="color:#f8f8f2">:</span>
                <span style="color:#f39c12">if</span> <span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">type</span> <span style="color:#f9690e">==</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">tool_use</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span>
                    <span style="color:#f8f8f2">result</span> <span style="color:#f9690e">=</span> <span style="color:#7ed07e">execute_tool</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">name</span><span style="color:#f8f8f2">,</span> <span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">input</span><span style="color:#f8f8f2">)</span>
                    <span style="color:#f8f8f2">tool_results</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">append</span><span style="color:#f8f8f2">({</span>
                        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">type</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">tool_result</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
                        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">tool_use_id</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">block</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">id</span><span style="color:#f8f8f2">,</span>
                        <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">result</span>
                    <span style="color:#f8f8f2">})</span>
            <span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">conversation_history</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">append</span><span style="color:#f8f8f2">({</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">role</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">user</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
                <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">tool_results</span>
            <span style="color:#f8f8f2">})</span>
            <span style="color:#808080"># Recursive call to get final answer
</span>            <span style="color:#f39c12">return</span> <span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">chat</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">""</span><span style="color:#f8f8f2">)</span>

        <span style="color:#f8f8f2">assistant_message</span> <span style="color:#f9690e">=</span> <span style="color:#f8f8f2">response</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">content</span><span style="color:#f8f8f2">[</span><span style="color:#dda0dd">0</span><span style="color:#f8f8f2">].</span><span style="color:#f8f8f2">text</span>
        <span style="color:#f8f8f2">self</span><span style="color:#f8f8f2">.</span><span style="color:#f8f8f2">conversation_history</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">append</span><span style="color:#f8f8f2">({</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">role</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f2ca27">"</span><span style="color:#f2ca27">assistant</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">,</span>
            <span style="color:#f2ca27">"</span><span style="color:#f2ca27">content</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">:</span> <span style="color:#f8f8f2">assistant_message</span>
        <span style="color:#f8f8f2">})</span>
        <span style="color:#f39c12">return</span> <span style="color:#f8f8f2">assistant_message</span>

<span style="color:#808080">## **Usage**
</span><span style="color:#f8f8f2">agent</span> <span style="color:#f9690e">=</span> <span style="color:#7ed07e">AgentWithMemory</span><span style="color:#f8f8f2">()</span>
<span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">agent</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">chat</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">My budget is $50,000. Calculate 7% annual return over 5 years.</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">))</span>
<span style="color:#7ed07e">print</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">agent</span><span style="color:#f8f8f2">.</span><span style="color:#7ed07e">chat</span><span style="color:#f8f8f2">(</span><span style="color:#f2ca27">"</span><span style="color:#f2ca27">Now do the same calculation but for 10 years.</span><span style="color:#f2ca27">"</span><span style="color:#f8f8f2">))</span>

<span style="color:#f9690e">**</span><span style="color:#f8f8f2">Claude</span> <span style="color:#f8f8f2">remembers</span> <span style="color:#f8f8f2">the</span> $<span style="color:#dda0dd">50</span><span style="color:#f8f8f2">,</span><span style="color:#dda0dd">000</span> <span style="color:#f9690e">and</span> <span style="color:#dda0dd">7</span><span style="color:#f9690e">%</span> <span style="color:#f39c12">from</span> <span style="color:#f8f8f2">the</span> <span style="color:#f8f8f2">first</span> <span style="color:#f8f8f2">message</span><span style="color:#f9690e">**</span>

</code></span></span>

这里大部分繁重的工作都由列表conversation_history完成。在生产环境中,你需要将列表持久化到 Redis 或数据库中,以便在会话之间保持数据一致。

接下来要建造什么?

一旦运行起来,接下来的步骤自然是:
流式响应——用于client.messages.stream()Web 应用中的实时输出;
错误处理和重试——将工具调用封装在带有指数退避的 try/except 语句中;
异步执行——并行调用工具,asyncio显著降低多工具查询的延迟;
结构化输出——使用 Pydantic 模型来强制执行工具的输入/输出模式。

关于完整的架构模式和生产部署策略,[ Dextra Labs发布了一份关于 Claude AI 代理架构和部署的深度指南],涵盖了容器化、监控和扩展模式等内容,远超单个教程所能涵盖的范围。
 

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐