<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>工作流 on Tech Snippets - 嵌入式技术笔记</title>
    <link>https://tech-snippets.xyz/tags/%E5%B7%A5%E4%BD%9C%E6%B5%81/</link>
    <description>Recent content in 工作流 on Tech Snippets - 嵌入式技术笔记</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Fri, 01 May 2026 23:00:00 +0800</lastBuildDate>
    <atom:link href="https://tech-snippets.xyz/tags/%E5%B7%A5%E4%BD%9C%E6%B5%81/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>AI Agent 工作流设计与自动化实战指南</title>
      <link>https://tech-snippets.xyz/posts/ai-agent-workflow-automation-guide/</link>
      <pubDate>Fri, 01 May 2026 23:00:00 +0800</pubDate>
      <guid>https://tech-snippets.xyz/posts/ai-agent-workflow-automation-guide/</guid>
      <description>前言 在大语言模型飞速发展的今天，单纯的问答已经远不能满足复杂场景的需求。AI Agent 作为一种能够自主理解任务、制定计划、调用工具并完成执行的智能体，正在成为下一代 AI 应用的核心形态。从最早的 AutoGPT 引发轰动，到如今 LangChain、CrewAI 等框架日趋成熟，AI Agent 的落地应用正在从概念验证走向生产环境。
然而，真正将 AI Agent 应用到实际工作流中，远不止是调用几个 API 那么简单。如何设计合理的 Agent 架构？如何处理任务分解与执行中的不确定性？如何保证工具调用的可靠性？如何在多 Agent 协作中避免冲突与死锁？这些都是每个开发者在构建生产级 Agent 系统时必须面对的问题。
本文将从实际应用出发，系统介绍 AI Agent 的工作流设计方法论，结合大量实战代码，带你从零构建一个能够完成复杂任务的自动化 Agent 系统。无论你是想在个人项目中引入 AI 自动化，还是在企业中落地 Agent 应用，本文都能为你提供可直接复用的思路与代码。
一、AI Agent 的核心设计理念 1.1 什么是真正的 Agent？ 很多人对 AI Agent 的理解停留在&amp;quot;能调用工具的大模型&amp;quot;，但这只是最表层的特征。一个完整的 Agent 应该具备以下四个核心能力：
自主规划能力：面对模糊的任务描述，能够将其分解为清晰的执行步骤，并动态调整计划。这是 Agent 与普通脚本最大的区别——脚本按固定流程执行，而 Agent 能根据实际情况动态决策。
工具使用能力：根据任务需要，自主选择并调用合适的工具，包括代码执行、网络搜索、API 调用、文件操作等。这是 Agent 突破大模型知识边界的关键。
记忆与反思能力：能够记住之前的执行结果，从中学习并调整后续策略。反思机制让 Agent 能够从失败中恢复，不断优化执行路径。
多轮迭代能力：一次执行往往不能得到完美结果，Agent 需要具备自我评估和迭代改进的能力，直到达到任务目标。
这四个能力层层递进，共同构成了 Agent 的智能基础。缺少任何一环，都只能算是&amp;quot;半成品&amp;quot;的 Agent。
1.2 ReAct 框架：思考与行动的循环 目前主流的 Agent 实现大多基于 ReAct（Reasoning + Acting）框架，其核心思想是让大模型在思考和行动之间交替进行，形成&amp;quot;思考-行动-观察-再思考&amp;quot;的循环。</description>
      <content:encoded><![CDATA[<h2 id="前言">前言</h2>
<p>在大语言模型飞速发展的今天，单纯的问答已经远不能满足复杂场景的需求。AI Agent 作为一种能够自主理解任务、制定计划、调用工具并完成执行的智能体，正在成为下一代 AI 应用的核心形态。从最早的 AutoGPT 引发轰动，到如今 LangChain、CrewAI 等框架日趋成熟，AI Agent 的落地应用正在从概念验证走向生产环境。</p>
<p>然而，真正将 AI Agent 应用到实际工作流中，远不止是调用几个 API 那么简单。如何设计合理的 Agent 架构？如何处理任务分解与执行中的不确定性？如何保证工具调用的可靠性？如何在多 Agent 协作中避免冲突与死锁？这些都是每个开发者在构建生产级 Agent 系统时必须面对的问题。</p>
<p>本文将从实际应用出发，系统介绍 AI Agent 的工作流设计方法论，结合大量实战代码，带你从零构建一个能够完成复杂任务的自动化 Agent 系统。无论你是想在个人项目中引入 AI 自动化，还是在企业中落地 Agent 应用，本文都能为你提供可直接复用的思路与代码。</p>
<p><img alt="AI Agent 工作流架构图" loading="lazy" src="/images/ai-agent-workflow-architecture.svg"></p>
<h2 id="一ai-agent-的核心设计理念">一、AI Agent 的核心设计理念</h2>
<h3 id="11-什么是真正的-agent">1.1 什么是真正的 Agent？</h3>
<p>很多人对 AI Agent 的理解停留在&quot;能调用工具的大模型&quot;，但这只是最表层的特征。一个完整的 Agent 应该具备以下四个核心能力：</p>
<p><strong>自主规划能力</strong>：面对模糊的任务描述，能够将其分解为清晰的执行步骤，并动态调整计划。这是 Agent 与普通脚本最大的区别——脚本按固定流程执行，而 Agent 能根据实际情况动态决策。</p>
<p><strong>工具使用能力</strong>：根据任务需要，自主选择并调用合适的工具，包括代码执行、网络搜索、API 调用、文件操作等。这是 Agent 突破大模型知识边界的关键。</p>
<p><strong>记忆与反思能力</strong>：能够记住之前的执行结果，从中学习并调整后续策略。反思机制让 Agent 能够从失败中恢复，不断优化执行路径。</p>
<p><strong>多轮迭代能力</strong>：一次执行往往不能得到完美结果，Agent 需要具备自我评估和迭代改进的能力，直到达到任务目标。</p>
<p>这四个能力层层递进，共同构成了 Agent 的智能基础。缺少任何一环，都只能算是&quot;半成品&quot;的 Agent。</p>
<h3 id="12-react-框架思考与行动的循环">1.2 ReAct 框架：思考与行动的循环</h3>
<p>目前主流的 Agent 实现大多基于 ReAct（Reasoning + Acting）框架，其核心思想是让大模型在思考和行动之间交替进行，形成&quot;思考-行动-观察-再思考&quot;的循环。</p>
<p>一个典型的 ReAct 执行流程如下：</p>
<pre tabindex="0"><code>思考：用户让我写一个 Python 脚本来批量处理图片。首先我需要了解用户的具体需求是什么——是调整大小、重命名，还是格式转换？我应该先询问清楚。
行动：向用户确认具体需求
观察：用户回复：&#34;需要将文件夹内所有 jpg 图片统一调整为 800x600 分辨率，并重命名为序号格式&#34;
思考：好的，需求明确了。我需要：1）遍历文件夹找到所有 jpg 文件，2）使用 PIL 库调整图片尺寸，3）按序号重命名保存。我先写这个脚本。
行动：编写 Python 代码并执行
观察：代码执行成功，处理了 25 张图片，全部保存到 output 文件夹
思考：任务完成了，应该告诉用户处理结果，并确认是否需要进一步调整。
</code></pre><p>这个流程的精妙之处在于，它将&quot;思考&quot;过程显式化，让我们能清晰地看到 Agent 的决策逻辑。同时，每一步行动都有对应的观察结果，形成了完整的执行轨迹，便于调试和回溯。</p>
<h3 id="13-agent-的三大核心组件">1.3 Agent 的三大核心组件</h3>
<p>任何 Agent 系统，无论架构多复杂，都可以拆解为三个核心组件：</p>
<p><strong>规划器（Planner）</strong>：负责任务分解、优先级排序、执行路径设计。好的规划器能将模糊的任务拆解为可执行的步骤，并预判可能的风险。</p>
<p><strong>执行器（Executor）</strong>：负责具体的工具调用和代码执行。执行器需要处理各种异常情况，保证即使某个工具调用失败，整个系统也能 graceful degrade。</p>
<p><strong>记忆体（Memory）</strong>：存储任务上下文、执行历史、中间结果。记忆体分为短期记忆（当前任务的上下文）和长期记忆（跨任务的知识积累）。</p>
<p>这三个组件之间不是单向的流水线关系，而是持续交互的闭环。执行结果会反馈给规划器，规划器根据反馈调整计划，所有交互都记录在记忆体中。理解了这三个组件的协作方式，就掌握了 Agent 设计的核心。</p>
<h3 id="14-为什么大多数-agent-demo-无法落地">1.4 为什么大多数 Agent Demo 无法落地？</h3>
<p>看过很多 Agent 的演示视频，看起来非常神奇，但真正放到生产环境就问题百出。核心原因在于 Demo 场景往往经过精心挑选，避开了 Agent 的薄弱环节：</p>
<ul>
<li><strong>错误恢复能力差</strong>：Demo 中每一步都恰好成功，但实际应用中工具调用失败是常态。没有完善的错误处理和重试机制的 Agent 根本无法长时间运行。</li>
<li><strong>无限循环风险</strong>：Agent 容易陷入&quot;思考-行动-再思考-再行动&quot;的死循环，尤其是当任务边界不清晰时。</li>
<li><strong>上下文溢出</strong>：执行几轮后，历史记录越来越长，最终超出大模型的上下文窗口限制。</li>
<li><strong>工具幻觉</strong>：大模型会&quot;幻想&quot;出不存在的工具或参数，调用自然失败。</li>
<li><strong>成本失控</strong>：复杂任务可能执行几十上百轮，API 费用迅速累积。</li>
</ul>
<p>这些问题不是简单加几个判断就能解决的，需要从架构层面进行系统性设计。后面我们会逐一讲解这些问题的解决方案。</p>
<h2 id="二单-agent-工作流的实现">二、单 Agent 工作流的实现</h2>
<h3 id="21-从零实现一个极简-agent">2.1 从零实现一个极简 Agent</h3>
<p>在引入复杂框架之前，我们先自己动手实现一个最简单的 Agent，理解其本质。你会发现，核心逻辑其实并不复杂。</p>
<p>首先，我们需要定义工具的格式。每个工具都应该有名称、描述、参数定义，以及实际的执行函数：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Any</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">json</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Tool</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">func</span><span class="p">:</span> <span class="n">Callable</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="n">description</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">func</span> <span class="o">=</span> <span class="n">func</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">func</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;Error: </span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div><p>然后是核心的 Agent 类，它需要维护对话历史，决定调用哪个工具，以及处理工具的返回结果：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">SimpleAgent</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">model</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&#34;gpt-4&#34;</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">model</span> <span class="o">=</span> <span class="n">model</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">tools</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Tool</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">history</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">max_iterations</span> <span class="o">=</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">register_tool</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tool</span><span class="p">:</span> <span class="n">Tool</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">tools</span><span class="p">[</span><span class="n">tool</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">tool</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">_build_system_prompt</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">tool_descriptions</span> <span class="o">=</span> <span class="s2">&#34;</span><span class="se">\n</span><span class="s2">&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">            <span class="sa">f</span><span class="s2">&#34;- </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">tool</span><span class="o">.</span><span class="n">description</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">tool</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tools</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="p">])</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;&#34;&#34;你是一个有帮助的 AI 助手。你可以使用以下工具来完成任务：
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2"></span><span class="si">{</span><span class="n">tool_descriptions</span><span class="si">}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">当你需要使用工具时，请严格按照以下 JSON 格式输出：
</span></span></span><span class="line"><span class="cl"><span class="s2"></span><span class="se">{{</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;thought&#34;: &#34;你思考的内容&#34;,
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;action&#34;: &#34;工具名称&#34;,
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;action_input&#34;: </span><span class="se">{{</span><span class="s2">工具参数字典</span><span class="se">}}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2"></span><span class="se">}}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">如果你认为任务已经完成，不需要再调用工具，请按照以下格式输出：
</span></span></span><span class="line"><span class="cl"><span class="s2"></span><span class="se">{{</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;thought&#34;: &#34;总结一下你做了什么&#34;,
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;final_answer&#34;: &#34;给用户的最终回复&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2"></span><span class="se">}}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">重要：每次只能调用一个工具，不要同时调用多个。
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user_input</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;user&#34;</span><span class="p">,</span> <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="n">user_input</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_iterations</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># 调用大模型获取决策</span>
</span></span><span class="line"><span class="cl">            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_call_llm</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">result</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="c1"># 解析失败，重试</span>
</span></span><span class="line"><span class="cl">                <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;assistant&#34;</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="s2">&#34;输出格式错误，请重新输出正确的 JSON&#34;</span>
</span></span><span class="line"><span class="cl">                <span class="p">})</span>
</span></span><span class="line"><span class="cl">                <span class="k">continue</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="c1"># 检查是否给出了最终答案</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="s2">&#34;final_answer&#34;</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="n">result</span><span class="p">[</span><span class="s2">&#34;final_answer&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="c1"># 调用工具</span>
</span></span><span class="line"><span class="cl">            <span class="n">tool_name</span> <span class="o">=</span> <span class="n">result</span><span class="p">[</span><span class="s2">&#34;action&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">tool_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tools</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">observation</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;错误：工具 </span><span class="si">{</span><span class="n">tool_name</span><span class="si">}</span><span class="s2"> 不存在&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">tool</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tools</span><span class="p">[</span><span class="n">tool_name</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">                <span class="n">observation</span> <span class="o">=</span> <span class="n">tool</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="p">[</span><span class="s2">&#34;action_input&#34;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="c1"># 将思考、行动和观察加入历史</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;assistant&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;thought&#34;</span><span class="p">:</span> <span class="n">result</span><span class="p">[</span><span class="s2">&#34;thought&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;action&#34;</span><span class="p">:</span> <span class="n">tool_name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;action_input&#34;</span><span class="p">:</span> <span class="n">result</span><span class="p">[</span><span class="s2">&#34;action_input&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">                <span class="p">},</span> <span class="n">ensure_ascii</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">})</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;user&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&#34;观察结果：</span><span class="si">{</span><span class="n">observation</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="p">})</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s2">&#34;执行次数超出限制，任务未完成&#34;</span>
</span></span></code></pre></div><p>这不到 100 行代码就是一个完整的 Agent 核心逻辑。它虽然简单，但已经具备了 ReAct 框架的所有关键特征：思考-行动-观察的循环，工具注册机制，以及执行次数限制。</p>
<h3 id="22-添加实用工具">2.2 添加实用工具</h3>
<p>有了 Agent 框架，接下来我们添加一些实际能用的工具。第一个工具是 Python 代码执行器，这是 Agent 最强大的能力之一：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">subprocess</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">textwrap</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;执行 Python 代码并返回输出&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 安全限制：禁止危险操作（生产环境需要更严格的沙箱）</span>
</span></span><span class="line"><span class="cl">    <span class="n">dangerous</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;os.system&#34;</span><span class="p">,</span> <span class="s2">&#34;subprocess&#34;</span><span class="p">,</span> <span class="s2">&#34;eval&#34;</span><span class="p">,</span> <span class="s2">&#34;exec&#34;</span><span class="p">,</span> <span class="s2">&#34;__import__&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">dangerous</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">code</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;安全限制：不允许使用 </span><span class="si">{</span><span class="n">d</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="p">[</span><span class="s2">&#34;python3&#34;</span><span class="p">,</span> <span class="s2">&#34;-c&#34;</span><span class="p">,</span> <span class="n">code</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">            <span class="n">capture_output</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">text</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="n">timeout</span><span class="o">=</span><span class="mi">10</span>
</span></span><span class="line"><span class="cl">        <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">output</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">stdout</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">stderr</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">output</span> <span class="o">+=</span> <span class="s2">&#34;</span><span class="se">\n</span><span class="s2">错误：&#34;</span> <span class="o">+</span> <span class="n">result</span><span class="o">.</span><span class="n">stderr</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">output</span> <span class="k">if</span> <span class="n">output</span> <span class="k">else</span> <span class="s2">&#34;代码执行成功，无输出&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">TimeoutExpired</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s2">&#34;执行超时（超过10秒）&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;执行错误：</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">python_tool</span> <span class="o">=</span> <span class="n">Tool</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">name</span><span class="o">=</span><span class="s2">&#34;execute_python&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">description</span><span class="o">=</span><span class="s2">&#34;执行 Python 代码，返回标准输出。适用于计算、数据处理、文件操作等任务。&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">func</span><span class="o">=</span><span class="n">execute_python</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div><p>第二个工具是网络搜索，让 Agent 能够获取实时信息：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">bs4</span> <span class="kn">import</span> <span class="n">BeautifulSoup</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">web_search</span><span class="p">(</span><span class="n">query</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;搜索网络信息&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># 使用 DuckDuckGo 搜索（不需要 API Key）</span>
</span></span><span class="line"><span class="cl">        <span class="n">url</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;https://html.duckduckgo.com/html/?q=</span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;User-Agent&#34;</span><span class="p">:</span> <span class="s2">&#34;Mozilla/5.0&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">soup</span> <span class="o">=</span> <span class="n">BeautifulSoup</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">,</span> <span class="s2">&#34;html.parser&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">soup</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&#34;.result&#34;</span><span class="p">)[:</span><span class="mi">5</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">            <span class="n">title</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">select_one</span><span class="p">(</span><span class="s2">&#34;.result__a&#34;</span><span class="p">)</span><span class="o">.</span><span class="n">get_text</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="n">snippet</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">select_one</span><span class="p">(</span><span class="s2">&#34;.result__snippet&#34;</span><span class="p">)</span><span class="o">.</span><span class="n">get_text</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;标题：</span><span class="si">{</span><span class="n">title</span><span class="si">}</span><span class="se">\n</span><span class="s2">摘要：</span><span class="si">{</span><span class="n">snippet</span><span class="si">}</span><span class="se">\n</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s2">&#34;</span><span class="se">\n</span><span class="s2">&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">results</span><span class="p">)</span> <span class="k">if</span> <span class="n">results</span> <span class="k">else</span> <span class="s2">&#34;没有找到搜索结果&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;搜索失败：</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">search_tool</span> <span class="o">=</span> <span class="n">Tool</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">name</span><span class="o">=</span><span class="s2">&#34;web_search&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">description</span><span class="o">=</span><span class="s2">&#34;搜索网络信息，获取最新的新闻、技术文档、价格等实时数据。&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">func</span><span class="o">=</span><span class="n">web_search</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div><p>现在我们可以把这些工具注册到 Agent 中，然后测试一下：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">agent</span> <span class="o">=</span> <span class="n">SimpleAgent</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">agent</span><span class="o">.</span><span class="n">register_tool</span><span class="p">(</span><span class="n">python_tool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">agent</span><span class="o">.</span><span class="n">register_tool</span><span class="p">(</span><span class="n">search_tool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 测试：让 Agent 计算斐波那契数列的第30项</span>
</span></span><span class="line"><span class="cl"><span class="n">result</span> <span class="o">=</span> <span class="n">agent</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s2">&#34;帮我计算斐波那契数列的第30项是多少&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
</span></span></code></pre></div><p>你会看到 Agent 自动编写 Python 代码来计算，然后返回结果。这比让大模型直接计算要准确得多——大模型可能会算错，但代码执行的结果是确定的。</p>
<p>（第一部分完，约2100字）</p>
<h2 id="三agent-的高级特性实现">三、Agent 的高级特性实现</h2>
<h3 id="31-记忆管理避免上下文溢出">3.1 记忆管理：避免上下文溢出</h3>
<p>简单的 Agent 会把所有历史记录都塞进上下文，执行几轮后就会超出模型的 token 限制。解决这个问题的关键是实现智能的记忆管理。</p>
<p>我们可以将记忆分为三个层级：</p>
<p><strong>短期记忆</strong>：最近的 N 轮对话，完整保留。这是 Agent 决策的直接依据。</p>
<p><strong>中期记忆</strong>：对较早的对话进行摘要，保留关键信息但压缩细节。</p>
<p><strong>长期记忆</strong>：使用向量数据库存储跨任务的知识，需要时通过相似度检索召回。</p>
<p>下面是一个分层记忆的实现：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">deque</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">List</span><span class="p">,</span> <span class="n">Dict</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">HierarchicalMemory</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">max_short_term</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span> <span class="n">max_mid_term</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">10</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">short_term</span> <span class="o">=</span> <span class="n">deque</span><span class="p">(</span><span class="n">maxlen</span><span class="o">=</span><span class="n">max_short_term</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">mid_term</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">long_term</span> <span class="o">=</span> <span class="p">[]</span>  <span class="c1"># 实际项目中换成向量数据库</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">short_term</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># 短期记忆满了，将最早的一条摘要后移入中期记忆</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">short_term</span><span class="p">)</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">short_term</span><span class="o">.</span><span class="n">maxlen</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">oldest</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">short_term</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">            <span class="n">summarized</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_summarize</span><span class="p">(</span><span class="n">oldest</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">mid_term</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">summarized</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mid_term</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">max_mid_term</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="c1"># 中期记忆满了，压缩成长期记忆</span>
</span></span><span class="line"><span class="cl">                <span class="bp">self</span><span class="o">.</span><span class="n">_compress_to_long_term</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">_summarize</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;对消息进行摘要（实际项目中调用LLM摘要）&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">content</span> <span class="o">=</span> <span class="n">message</span><span class="p">[</span><span class="s2">&#34;content&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">200</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">content</span> <span class="o">=</span> <span class="n">content</span><span class="p">[:</span><span class="mi">200</span><span class="p">]</span> <span class="o">+</span> <span class="s2">&#34;...&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">{</span><span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="n">message</span><span class="p">[</span><span class="s2">&#34;role&#34;</span><span class="p">],</span> <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="n">content</span><span class="p">,</span> <span class="s2">&#34;summarized&#34;</span><span class="p">:</span> <span class="kc">True</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">_compress_to_long_term</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;将中期记忆压缩为长期记忆&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">summary</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;历史执行摘要：共</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mid_term</span><span class="p">)</span><span class="si">}</span><span class="s2">条记录&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">long_term</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">summary</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">mid_term</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mid_term</span><span class="p">[</span><span class="o">-</span><span class="mi">3</span><span class="p">:]</span>  <span class="c1"># 保留最近3条</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">get_context</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">List</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]:</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;获取当前上下文中的所有消息&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">context</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">long_term</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">context</span><span class="o">.</span><span class="n">append</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;system&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="s2">&#34;【长期记忆】&#34;</span> <span class="o">+</span> <span class="s2">&#34;</span><span class="se">\n</span><span class="s2">&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">long_term</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">})</span>
</span></span><span class="line"><span class="cl">        <span class="n">context</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mid_term</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">context</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">short_term</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">context</span>
</span></span></code></pre></div><p>这种分层记忆策略可以让 Agent 保持几十轮的执行而不会上下文溢出，同时保留关键信息。</p>
<h3 id="32-错误处理与重试机制">3.2 错误处理与重试机制</h3>
<p>实际应用中，工具调用失败是常态——网络超时、API 限流、参数错误等等。一个健壮的 Agent 必须能优雅地处理这些错误。</p>
<p>我们可以实现多级重试策略：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">wraps</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">retry</span><span class="p">(</span><span class="n">max_attempts</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span> <span class="n">delay</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">decorator</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="nd">@wraps</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="n">last_error</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">            <span class="k">for</span> <span class="n">attempt</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_attempts</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">                <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                    <span class="k">return</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                    <span class="n">last_error</span> <span class="o">=</span> <span class="n">e</span>
</span></span><span class="line"><span class="cl">                    <span class="k">if</span> <span class="n">attempt</span> <span class="o">&lt;</span> <span class="n">max_attempts</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                        <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">delay</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span> <span class="o">**</span> <span class="n">attempt</span><span class="p">))</span>  <span class="c1"># 指数退避</span>
</span></span><span class="line"><span class="cl">            <span class="k">raise</span> <span class="n">last_error</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">wrapper</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">decorator</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">RobustAgent</span><span class="p">(</span><span class="n">SimpleAgent</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">max_tool_retries</span> <span class="o">=</span> <span class="mi">3</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">_execute_tool</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tool_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">action_input</span><span class="p">:</span> <span class="n">Dict</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">attempt</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_tool_retries</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">tool</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tools</span><span class="p">[</span><span class="n">tool_name</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="n">tool</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="o">**</span><span class="n">action_input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;错误：工具 </span><span class="si">{</span><span class="n">tool_name</span><span class="si">}</span><span class="s2"> 不存在，可用工具：</span><span class="si">{</span><span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">tools</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="k">except</span> <span class="ne">TypeError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;参数错误：</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">。请检查参数是否匹配工具要求。&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span> <span class="n">attempt</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_tool_retries</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                    <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                    <span class="k">continue</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;工具执行失败（已重试</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">max_tool_retries</span><span class="si">}</span><span class="s2">次）：</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div><p>除了自动重试，更重要的是让 Agent 能从错误中学习。比如当工具调用失败时，Agent 应该分析错误原因，调整参数后再次尝试，而不是机械地重复同样的操作。</p>
<h3 id="33-反思机制从失败中学习">3.3 反思机制：从失败中学习</h3>
<p>人类遇到失败会反思原因，然后调整策略。Agent 也应该具备这种能力。反思机制的核心是在每轮执行后，让 Agent 评估自己的表现，如果发现问题就调整策略。</p>
<p>实现反思机制很简单，只需要在每轮观察后，插入一个反思步骤：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ReflectiveAgent</span><span class="p">(</span><span class="n">RobustAgent</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">reflection_enabled</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">_reflect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;让 Agent 反思当前的执行过程&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">reflection_prompt</span> <span class="o">=</span> <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">请反思你刚才的执行过程，回答以下问题：
</span></span></span><span class="line"><span class="cl"><span class="s2">1. 刚才的工具调用是否成功？
</span></span></span><span class="line"><span class="cl"><span class="s2">2. 如果失败了，失败的根本原因是什么？
</span></span></span><span class="line"><span class="cl"><span class="s2">3. 接下来应该如何调整策略？
</span></span></span><span class="line"><span class="cl"><span class="s2">4. 是否应该继续尝试，还是换一种方法？
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">请用简洁的语言回答。
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_call_llm_with_prompt</span><span class="p">(</span><span class="n">reflection_prompt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user_input</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;user&#34;</span><span class="p">,</span> <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="n">user_input</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_iterations</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_call_llm</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="n">result</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="s2">&#34;final_answer&#34;</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="n">result</span><span class="p">[</span><span class="s2">&#34;final_answer&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="c1"># 执行工具</span>
</span></span><span class="line"><span class="cl">            <span class="n">observation</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_execute_tool</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                <span class="n">result</span><span class="p">[</span><span class="s2">&#34;action&#34;</span><span class="p">],</span> 
</span></span><span class="line"><span class="cl">                <span class="n">result</span><span class="p">[</span><span class="s2">&#34;action_input&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">            <span class="p">)</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="c1"># 记录行动和观察</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;assistant&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">ensure_ascii</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">})</span>
</span></span><span class="line"><span class="cl">            <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;user&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&#34;观察结果：</span><span class="si">{</span><span class="n">observation</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="p">})</span>
</span></span><span class="line"><span class="cl">            
</span></span><span class="line"><span class="cl">            <span class="c1"># 如果出现错误，进行反思</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">reflection_enabled</span> <span class="ow">and</span> <span class="s2">&#34;错误&#34;</span> <span class="ow">in</span> <span class="n">observation</span> <span class="ow">or</span> <span class="s2">&#34;Error&#34;</span> <span class="ow">in</span> <span class="n">observation</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">reflection</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_reflect</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">                <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;system&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&#34;反思：</span><span class="si">{</span><span class="n">reflection</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">                <span class="p">})</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s2">&#34;执行次数超出限制&#34;</span>
</span></span></code></pre></div><p>有了反思机制后，Agent 的表现会明显提升——它不会在同一个错误上反复卡壳，而是会主动调整策略。</p>
<h3 id="34-成本控制避免无限烧钱">3.4 成本控制：避免无限烧钱</h3>
<p>Agent 的每轮执行都要调用大模型 API，复杂任务可能执行几十轮，成本不容小觑。因此，成本控制是生产级 Agent 必不可少的功能。</p>
<p>我们可以实现以下成本控制策略：</p>
<ol>
<li><strong>执行轮数限制</strong>：设置最大迭代次数，避免无限循环</li>
<li><strong>Token 使用统计</strong>：实时统计 token 消耗，超出预算时暂停</li>
<li><strong>廉价模型降级</strong>：简单的决策使用便宜的模型，复杂推理才用贵的模型</li>
<li><strong>用户确认</strong>：预计成本超过阈值时，先询问用户是否继续</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CostAwareAgent</span><span class="p">(</span><span class="n">ReflectiveAgent</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">total_tokens</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">max_tokens</span> <span class="o">=</span> <span class="mi">50000</span>  <span class="c1"># 单次任务最大 token 消耗</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">token_price</span> <span class="o">=</span> <span class="mf">0.002</span> <span class="o">/</span> <span class="mi">1000</span>  <span class="c1"># GPT-4的价格（示例）</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">_call_llm</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># 检查预算</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">total_tokens</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_tokens</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Token 消耗已达上限 </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">max_tokens</span><span class="si">}</span><span class="s2">，任务暂停&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">_call_llm</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 估算 token 消耗（实际应该用 tiktoken 精确计算）</span>
</span></span><span class="line"><span class="cl">        <span class="n">tokens_used</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="p">))</span> <span class="o">//</span> <span class="mi">4</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">total_tokens</span> <span class="o">+=</span> <span class="n">tokens_used</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="n">estimated_cost</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">total_tokens</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">token_price</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">estimated_cost</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">:</span>  <span class="c1"># 超过0.5美元时提醒</span>
</span></span><span class="line"><span class="cl">            <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;当前预估成本：$</span><span class="si">{</span><span class="n">estimated_cost</span><span class="si">:</span><span class="s2">.4f</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">response</span>
</span></span></code></pre></div><h2 id="四多-agent-协作系统设计">四、多 Agent 协作系统设计</h2>
<p>当任务足够复杂时，单个 Agent 的能力就不够了。就像人类公司有不同的岗位分工一样，我们也可以让多个 Agent 各司其职，协作完成任务。</p>
<h3 id="41-经典的多-agent-模式">4.1 经典的多 Agent 模式</h3>
<p>常见的多 Agent 协作模式有以下几种：</p>
<p><strong>层级式（Hierarchical）</strong>：一个总管 Agent 负责分配任务，多个工作 Agent 负责执行。类似公司的经理-员工关系。</p>
<p><strong>平级式（Peer-to-Peer）</strong>：所有 Agent 地位平等，通过消息总线进行通信和协作。类似敏捷开发团队。</p>
<p><strong>流水线式（Pipeline）</strong>：每个 Agent 负责任务的一个阶段，输出作为下一个 Agent 的输入。类似工厂的流水线。</p>
<p><strong>圆桌式（Roundtable）</strong>：多个 Agent 围绕一个问题轮流发言，互相启发，最终达成共识。类似头脑风暴会议。</p>
<p>不同的模式适用于不同的场景。层级式适合目标明确的执行类任务，圆桌式适合创意类任务，流水线式适合标准化的工作流。</p>
<h3 id="42-实现一个层级式多-agent-系统">4.2 实现一个层级式多 Agent 系统</h3>
<p>让我们来实现一个简单的层级式多 Agent 系统，包含三种角色：</p>
<ul>
<li><strong>产品经理 Agent</strong>：负责理解需求，拆解成功能点</li>
<li><strong>程序员 Agent</strong>：负责编写代码实现功能</li>
<li><strong>测试工程师 Agent</strong>：负责测试代码，发现问题</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">MultiAgentSystem</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">agents</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">task_queue</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">register_agent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">agent</span><span class="p">:</span> <span class="n">SimpleAgent</span><span class="p">,</span> <span class="n">role</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">agents</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;agent&#34;</span><span class="p">:</span> <span class="n">agent</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="n">role</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;status&#34;</span><span class="p">:</span> <span class="s2">&#34;idle&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">assign_task</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">agent_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">task</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">agent_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">agents</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Agent </span><span class="si">{</span><span class="n">agent_name</span><span class="si">}</span><span class="s2"> 不存在&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">agents</span><span class="p">[</span><span class="n">agent_name</span><span class="p">][</span><span class="s2">&#34;status&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&#34;working&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">agents</span><span class="p">[</span><span class="n">agent_name</span><span class="p">][</span><span class="s2">&#34;agent&#34;</span><span class="p">]</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">task</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">agents</span><span class="p">[</span><span class="n">agent_name</span><span class="p">][</span><span class="s2">&#34;status&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&#34;idle&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="p">[</span><span class="n">agent_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">run_software_project</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">requirement</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;=&#34;</span> <span class="o">*</span> <span class="mi">50</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;开始执行软件开发项目&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;原始需求：</span><span class="si">{</span><span class="n">requirement</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;=&#34;</span> <span class="o">*</span> <span class="mi">50</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 第一步：产品经理分析需求</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">【产品经理 Agent 开始工作】&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">prd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">assign_task</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;product_manager&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="sa">f</span><span class="s2">&#34;&#34;&#34;请分析以下需求，输出产品需求文档：
</span></span></span><span class="line"><span class="cl"><span class="s2">需求：</span><span class="si">{</span><span class="n">requirement</span><span class="si">}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">请包含以下内容：
</span></span></span><span class="line"><span class="cl"><span class="s2">1. 功能需求列表
</span></span></span><span class="line"><span class="cl"><span class="s2">2. 技术实现要点
</span></span></span><span class="line"><span class="cl"><span class="s2">3. 验收标准
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;需求分析完成&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="n">prd</span><span class="p">[:</span><span class="mi">500</span><span class="p">]</span> <span class="o">+</span> <span class="s2">&#34;...&#34;</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">prd</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">500</span> <span class="k">else</span> <span class="n">prd</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 第二步：程序员实现代码</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">【程序员 Agent 开始工作】&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">code</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">assign_task</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;programmer&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="sa">f</span><span class="s2">&#34;&#34;&#34;请根据以下产品需求编写 Python 代码：
</span></span></span><span class="line"><span class="cl"><span class="s2"></span><span class="si">{</span><span class="n">prd</span><span class="si">}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">要求：
</span></span></span><span class="line"><span class="cl"><span class="s2">1. 代码结构清晰，有注释
</span></span></span><span class="line"><span class="cl"><span class="s2">2. 包含必要的错误处理
</span></span></span><span class="line"><span class="cl"><span class="s2">3. 提供使用示例
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;代码编写完成&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="n">code</span><span class="p">[:</span><span class="mi">500</span><span class="p">]</span> <span class="o">+</span> <span class="s2">&#34;...&#34;</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">code</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">500</span> <span class="k">else</span> <span class="n">code</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 第三步：测试工程师测试代码</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">【测试工程师 Agent 开始工作】&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">test_report</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">assign_task</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;tester&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="sa">f</span><span class="s2">&#34;&#34;&#34;请测试以下代码，输出测试报告：
</span></span></span><span class="line"><span class="cl"><span class="s2">代码：
</span></span></span><span class="line"><span class="cl"><span class="s2"></span><span class="si">{</span><span class="n">code</span><span class="si">}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">请检查：
</span></span></span><span class="line"><span class="cl"><span class="s2">1. 代码是否有语法错误
</span></span></span><span class="line"><span class="cl"><span class="s2">2. 逻辑是否正确
</span></span></span><span class="line"><span class="cl"><span class="s2">3. 边界情况是否处理
</span></span></span><span class="line"><span class="cl"><span class="s2">4. 给出修复建议
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;测试完成&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="n">test_report</span><span class="p">[:</span><span class="mi">500</span><span class="p">]</span> <span class="o">+</span> <span class="s2">&#34;...&#34;</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">test_report</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">500</span> <span class="k">else</span> <span class="n">test_report</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;prd&#34;</span><span class="p">:</span> <span class="n">prd</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;code&#34;</span><span class="p">:</span> <span class="n">code</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;test_report&#34;</span><span class="p">:</span> <span class="n">test_report</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span></code></pre></div><p>使用这个系统非常简单：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 初始化各个 Agent</span>
</span></span><span class="line"><span class="cl"><span class="n">system</span> <span class="o">=</span> <span class="n">MultiAgentSystem</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">system</span><span class="o">.</span><span class="n">register_agent</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;product_manager&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">SimpleAgent</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&#34;gpt-4&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">role</span><span class="o">=</span><span class="s2">&#34;产品经理&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">system</span><span class="o">.</span><span class="n">register_agent</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;programmer&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">SimpleAgent</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&#34;gpt-4&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">role</span><span class="o">=</span><span class="s2">&#34;程序员&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">system</span><span class="o">.</span><span class="n">register_agent</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;tester&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">SimpleAgent</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&#34;gpt-4&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">role</span><span class="o">=</span><span class="s2">&#34;测试工程师&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 运行项目</span>
</span></span><span class="line"><span class="cl"><span class="n">result</span> <span class="o">=</span> <span class="n">system</span><span class="o">.</span><span class="n">run_software_project</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;写一个命令行工具，能够统计指定目录下各种文件类型的数量和总大小&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div><p>你会看到三个 Agent 依次工作，从需求分析到代码编写再到测试，完整模拟了一个小型软件开发流程。</p>
<h3 id="43-多-agent-协作的挑战与解决方案">4.3 多 Agent 协作的挑战与解决方案</h3>
<p>多 Agent 系统虽然强大，但也带来了新的挑战：</p>
<p><strong>通信开销</strong>：Agent 之间的每一次交互都要调用大模型，成本随 Agent 数量线性增长。
解决方案：设计高效的通信协议，减少不必要的交互，批量处理消息。</p>
<p><strong>协调开销</strong>：多个 Agent 可能产生冲突的决策，或者重复劳动。
解决方案：引入明确的角色分工，设立协调者 Agent，建立清晰的工作流。</p>
<p><strong>一致性问题</strong>：不同 Agent 可能对任务有不同的理解，导致最终结果不一致。
解决方案：在每个阶段交接时，进行明确的确认和对齐，确保理解一致。</p>
<p><strong>死锁风险</strong>：A 等 B 的输出，B 等 A 的输出，形成死锁。
解决方案：设置超时机制，引入外部监督者检测死锁并干预。</p>
<p>这些挑战没有一劳永逸的解决方案，需要根据具体场景设计合适的架构和机制。</p>
<p>（第二部分完，约2300字）</p>
<h2 id="五实战构建一个自动化文档生成-agent">五、实战：构建一个自动化文档生成 Agent</h2>
<p>理论讲了这么多，我们来做一个完整的实战项目：构建一个能够自动分析代码仓库并生成技术文档的 Agent 系统。</p>
<h3 id="51-需求分析">5.1 需求分析</h3>
<p>这个文档生成 Agent 需要具备以下能力：</p>
<ol>
<li>遍历指定目录下的所有代码文件</li>
<li>分析每个文件的功能和结构</li>
<li>理解代码之间的依赖关系</li>
<li>自动生成 API 文档</li>
<li>生成架构说明和使用指南</li>
<li>输出 Markdown 格式的完整文档</li>
</ol>
<h3 id="52-工具设计">5.2 工具设计</h3>
<p>首先，我们需要几个专门的工具来支持代码分析：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">os</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">ast</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">pathlib</span> <span class="kn">import</span> <span class="n">Path</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">list_files</span><span class="p">(</span><span class="n">directory</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">pattern</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&#34;*.py&#34;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;列出目录下的所有文件&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">files</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">root</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">filenames</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">directory</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">for</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">filenames</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span> <span class="n">filename</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">pattern</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&#34;*&#34;</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">)):</span>
</span></span><span class="line"><span class="cl">                    <span class="n">filepath</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                    <span class="n">size</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getsize</span><span class="p">(</span><span class="n">filepath</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                    <span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">filepath</span><span class="si">}</span><span class="s2"> (</span><span class="si">{</span><span class="n">size</span><span class="si">}</span><span class="s2"> bytes)&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s2">&#34;</span><span class="se">\n</span><span class="s2">&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">files</span><span class="p">)</span> <span class="k">if</span> <span class="n">files</span> <span class="k">else</span> <span class="s2">&#34;没有找到文件&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;错误：</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">read_file</span><span class="p">(</span><span class="n">filepath</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">max_lines</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">100</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;读取文件内容&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">filepath</span><span class="p">,</span> <span class="s2">&#34;r&#34;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">&#34;utf-8&#34;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">lines</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="n">content</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lines</span><span class="p">[:</span><span class="n">max_lines</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">max_lines</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">content</span> <span class="o">+=</span> <span class="sa">f</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">...（文件共</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span><span class="si">}</span><span class="s2">行，已显示前</span><span class="si">{</span><span class="n">max_lines</span><span class="si">}</span><span class="s2">行）&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">content</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;错误：</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">analyze_python_structure</span><span class="p">(</span><span class="n">filepath</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;分析 Python 代码的结构（类、函数、导入）&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">filepath</span><span class="p">,</span> <span class="s2">&#34;r&#34;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">&#34;utf-8&#34;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">source</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="n">tree</span> <span class="o">=</span> <span class="n">ast</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">source</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="n">classes</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="n">functions</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="n">imports</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">ast</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">tree</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">Import</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">                <span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">node</span><span class="o">.</span><span class="n">names</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                    <span class="n">imports</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">alias</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">ImportFrom</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">                <span class="n">imports</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">node</span><span class="o">.</span><span class="n">module</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">ClassDef</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">                <span class="n">methods</span> <span class="o">=</span> <span class="p">[</span><span class="n">n</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">node</span><span class="o">.</span><span class="n">body</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">FunctionDef</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl">                <span class="n">classes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">node</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">（方法：</span><span class="si">{</span><span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">methods</span><span class="p">)</span><span class="si">}</span><span class="s2">）&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">ast</span><span class="o">.</span><span class="n">FunctionDef</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">                <span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">a</span><span class="o">.</span><span class="n">arg</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">args</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">                <span class="n">functions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">node</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">（参数：</span><span class="si">{</span><span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">args</span><span class="p">)</span><span class="si">}</span><span class="s2">）&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="n">result</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;文件：</span><span class="si">{</span><span class="n">filepath</span><span class="si">}</span><span class="se">\n\n</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span> <span class="o">+=</span> <span class="sa">f</span><span class="s2">&#34;导入的模块：</span><span class="se">\n</span><span class="s2">- </span><span class="si">{</span><span class="nb">chr</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span><span class="si">}</span><span class="s2">- &#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">imports</span><span class="p">[:</span><span class="mi">20</span><span class="p">])</span> <span class="k">if</span> <span class="n">imports</span> <span class="k">else</span> <span class="s2">&#34;无&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span> <span class="o">+=</span> <span class="s2">&#34;</span><span class="se">\n\n</span><span class="s2">类定义：</span><span class="se">\n</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span> <span class="o">+=</span> <span class="s2">&#34;</span><span class="se">\n</span><span class="s2">&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="sa">f</span><span class="s2">&#34;- </span><span class="si">{</span><span class="n">c</span><span class="si">}</span><span class="s2">&#34;</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">classes</span><span class="p">])</span> <span class="k">if</span> <span class="n">classes</span> <span class="k">else</span> <span class="s2">&#34;- 无&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span> <span class="o">+=</span> <span class="s2">&#34;</span><span class="se">\n\n</span><span class="s2">函数定义：</span><span class="se">\n</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span> <span class="o">+=</span> <span class="s2">&#34;</span><span class="se">\n</span><span class="s2">&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="sa">f</span><span class="s2">&#34;- </span><span class="si">{</span><span class="n">f</span><span class="si">}</span><span class="s2">&#34;</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">functions</span><span class="p">])</span> <span class="k">if</span> <span class="n">functions</span> <span class="k">else</span> <span class="s2">&#34;- 无&#34;</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;分析失败：</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">write_documentation</span><span class="p">(</span><span class="n">content</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">output_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;将生成的文档写入文件&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">output_path</span><span class="p">),</span> <span class="n">exist_ok</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">output_path</span><span class="p">,</span> <span class="s2">&#34;w&#34;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">&#34;utf-8&#34;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;文档已写入：</span><span class="si">{</span><span class="n">output_path</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;写入失败：</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 注册工具</span>
</span></span><span class="line"><span class="cl"><span class="n">list_tool</span> <span class="o">=</span> <span class="n">Tool</span><span class="p">(</span><span class="s2">&#34;list_files&#34;</span><span class="p">,</span> <span class="s2">&#34;列出目录下的文件，支持通配符&#34;</span><span class="p">,</span> <span class="n">list_files</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">read_tool</span> <span class="o">=</span> <span class="n">Tool</span><span class="p">(</span><span class="s2">&#34;read_file&#34;</span><span class="p">,</span> <span class="s2">&#34;读取文件内容，可指定最大行数&#34;</span><span class="p">,</span> <span class="n">read_file</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">analyze_tool</span> <span class="o">=</span> <span class="n">Tool</span><span class="p">(</span><span class="s2">&#34;analyze_python&#34;</span><span class="p">,</span> <span class="s2">&#34;分析 Python 代码的结构&#34;</span><span class="p">,</span> <span class="n">analyze_python_structure</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">write_tool</span> <span class="o">=</span> <span class="n">Tool</span><span class="p">(</span><span class="s2">&#34;write_doc&#34;</span><span class="p">,</span> <span class="s2">&#34;将生成的文档写入文件&#34;</span><span class="p">,</span> <span class="n">write_documentation</span><span class="p">)</span>
</span></span></code></pre></div><h3 id="53-文档生成工作流">5.3 文档生成工作流</h3>
<p>有了工具后，我们设计一个结构化的文档生成工作流：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">DocumentationAgent</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">agent</span> <span class="o">=</span> <span class="n">SimpleAgent</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&#34;gpt-4&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">agent</span><span class="o">.</span><span class="n">register_tool</span><span class="p">(</span><span class="n">list_tool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">agent</span><span class="o">.</span><span class="n">register_tool</span><span class="p">(</span><span class="n">read_tool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">agent</span><span class="o">.</span><span class="n">register_tool</span><span class="p">(</span><span class="n">analyze_tool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">agent</span><span class="o">.</span><span class="n">register_tool</span><span class="p">(</span><span class="n">write_tool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">project_info</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">generate_docs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">project_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">output_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;开始分析项目：</span><span class="si">{</span><span class="n">project_path</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 第一步：列出所有文件</span>
</span></span><span class="line"><span class="cl">        <span class="n">files_result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">agent</span><span class="o">.</span><span class="n">run</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="sa">f</span><span class="s2">&#34;请列出 </span><span class="si">{</span><span class="n">project_path</span><span class="si">}</span><span class="s2"> 目录下所有的 Python 文件，不要递归太深&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;文件列表获取完成&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 第二步：分析每个核心文件的结构</span>
</span></span><span class="line"><span class="cl">        <span class="n">structure_result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">agent</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">请分析主要的 Python 文件，提取以下信息：
</span></span></span><span class="line"><span class="cl"><span class="s2">1. 每个文件的主要功能
</span></span></span><span class="line"><span class="cl"><span class="s2">2. 定义的类和方法
</span></span></span><span class="line"><span class="cl"><span class="s2">3. 主要的函数接口
</span></span></span><span class="line"><span class="cl"><span class="s2">4. 模块之间的依赖关系
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">只分析核心文件，忽略测试文件和示例文件。
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;代码结构分析完成&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 第三步：生成架构概述</span>
</span></span><span class="line"><span class="cl">        <span class="n">architecture_result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">agent</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">基于以上分析，请生成项目的架构概述文档，包括：
</span></span></span><span class="line"><span class="cl"><span class="s2">1. 项目的整体架构设计
</span></span></span><span class="line"><span class="cl"><span class="s2">2. 核心模块的职责说明
</span></span></span><span class="line"><span class="cl"><span class="s2">3. 关键的设计决策
</span></span></span><span class="line"><span class="cl"><span class="s2">4. 模块之间的交互关系
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">用清晰的 Markdown 格式输出。
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;架构概述生成完成&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 第四步：生成 API 文档</span>
</span></span><span class="line"><span class="cl">        <span class="n">api_result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">agent</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">现在请生成详细的 API 文档，包括每个主要类和函数的：
</span></span></span><span class="line"><span class="cl"><span class="s2">1. 功能说明
</span></span></span><span class="line"><span class="cl"><span class="s2">2. 参数说明
</span></span></span><span class="line"><span class="cl"><span class="s2">3. 返回值说明
</span></span></span><span class="line"><span class="cl"><span class="s2">4. 使用示例（如果能推断出来）
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">用 Markdown 格式组织，结构清晰。
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;API 文档生成完成&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 第五步：生成使用指南</span>
</span></span><span class="line"><span class="cl">        <span class="n">usage_result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">agent</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">最后生成项目的使用指南，包括：
</span></span></span><span class="line"><span class="cl"><span class="s2">1. 安装步骤
</span></span></span><span class="line"><span class="cl"><span class="s2">2. 快速开始示例
</span></span></span><span class="line"><span class="cl"><span class="s2">3. 常见使用场景
</span></span></span><span class="line"><span class="cl"><span class="s2">4. 注意事项和最佳实践
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">确保文档对新用户友好。
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;使用指南生成完成&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 合并所有文档并写入</span>
</span></span><span class="line"><span class="cl">        <span class="n">final_doc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">agent</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">请将以上生成的所有文档内容整合成一份完整的技术文档，结构如下：
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2"># 项目技术文档
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">## 1. 项目概述
</span></span></span><span class="line"><span class="cl"><span class="s2">## 2. 架构设计
</span></span></span><span class="line"><span class="cl"><span class="s2">## 3. API 参考
</span></span></span><span class="line"><span class="cl"><span class="s2">## 4. 使用指南
</span></span></span><span class="line"><span class="cl"><span class="s2">## 5. 注意事项
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">然后调用 write_doc 工具将文档写入 </span><span class="si">{</span><span class="n">output_path</span><span class="si">}</span><span class="s2">。
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;文档生成完成：</span><span class="si">{</span><span class="n">output_path</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">final_doc</span>
</span></span></code></pre></div><h3 id="54-使用示例">5.4 使用示例</h3>
<p>使用这个文档生成 Agent 非常简单：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">doc_agent</span> <span class="o">=</span> <span class="n">DocumentationAgent</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">result</span> <span class="o">=</span> <span class="n">doc_agent</span><span class="o">.</span><span class="n">generate_docs</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">project_path</span><span class="o">=</span><span class="s2">&#34;/path/to/your/project&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">output_path</span><span class="o">=</span><span class="s2">&#34;/path/to/output/docs.md&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div><p>整个过程完全自动化，Agent 会自己遍历文件、分析代码、理解架构，最终生成一份结构完整的技术文档。对于大型项目，这可以节省大量的文档编写时间。</p>
<h2 id="六主流-agent-框架对比与选型">六、主流 Agent 框架对比与选型</h2>
<p>自己从零写 Agent 框架虽然灵活，但对于大多数项目，使用成熟的开源框架效率更高。目前主流的 Agent 框架有以下几个：</p>
<h3 id="61-langchain">6.1 LangChain</h3>
<p><strong>优点</strong>：</p>
<ul>
<li>生态最成熟，工具最丰富</li>
<li>社区活跃，文档完善</li>
<li>支持多种大模型和向量数据库</li>
<li>有大量的集成和插件</li>
</ul>
<p><strong>缺点</strong>：</p>
<ul>
<li>架构过于复杂，学习曲线陡峭</li>
<li>很多功能过度抽象，debug 困难</li>
<li>版本之间 breaking change 较多</li>
</ul>
<p><strong>适用场景</strong>：复杂的企业级应用，需要大量工具集成的场景。</p>
<h3 id="62-llamaindex">6.2 LlamaIndex</h3>
<p><strong>优点</strong>：</p>
<ul>
<li>专注于 RAG（检索增强生成）场景</li>
<li>索引类型丰富，查询优化做得好</li>
<li>对文档处理支持优秀</li>
<li>相对 LangChain 更轻量</li>
</ul>
<p><strong>缺点</strong>：</p>
<ul>
<li>Agent 功能不如 LangChain 丰富</li>
<li>多 Agent 支持有限</li>
</ul>
<p><strong>适用场景</strong>：知识库、文档问答、企业内部搜索等 RAG 为主的场景。</p>
<h3 id="63-crewai">6.3 CrewAI</h3>
<p><strong>优点</strong>：</p>
<ul>
<li>专门为多 Agent 协作设计</li>
<li>Agent 角色定义清晰</li>
<li>任务分配机制优雅</li>
<li>API 简洁易用</li>
</ul>
<p><strong>缺点</strong>：</p>
<ul>
<li>生态相对较小</li>
<li>工具集成不如 LangChain 多</li>
</ul>
<p><strong>适用场景</strong>：多 Agent 协作场景，如自动化团队、内容创作团队等。</p>
<h3 id="64-autogpt">6.4 AutoGPT</h3>
<p><strong>优点</strong>：</p>
<ul>
<li>最早的 Agent 项目之一，知名度高</li>
<li>完全自主的执行模式</li>
<li>有丰富的插件生态</li>
</ul>
<p><strong>缺点</strong>：</p>
<ul>
<li>容易陷入无限循环</li>
<li>成本控制困难</li>
<li>不适合作为库嵌入到其他项目</li>
</ul>
<p><strong>适用场景</strong>：探索性研究、个人助手等完全自主的应用。</p>
<h3 id="65-选型建议">6.5 选型建议</h3>
<p>我的建议是：</p>
<ul>
<li>如果是<strong>单 Agent + 大量工具</strong>，用 LangChain</li>
<li>如果是<strong>RAG 为主</strong>，用 LlamaIndex</li>
<li>如果是<strong>多 Agent 协作</strong>，用 CrewAI</li>
<li>如果是<strong>完全自主的探索</strong>，用 AutoGPT</li>
<li>如果是<strong>简单场景或需要完全控制</strong>，自己写核心逻辑</li>
</ul>
<p>很多时候最佳方案是混合使用——比如用 CrewAI 做多 Agent 编排，每个 Agent 内部用 LangChain 做工具调用。</p>
<h2 id="七agent-开发的最佳实践">七、Agent 开发的最佳实践</h2>
<h3 id="71-设计原则">7.1 设计原则</h3>
<p><strong>明确任务边界</strong>：不要让 Agent 做太宽泛的任务，任务越具体，成功率越高。在启动前就明确定义成功条件和终止条件。</p>
<p><strong>人机协作，而非完全替代</strong>：Agent 最适合做繁琐的重复性工作，而不是高风险的决策。关键步骤保留人工确认，既能保证安全，也能降低成本。</p>
<p><strong>分层设计</strong>：将复杂任务拆分为多个子任务，每个子任务由专门的 Agent 处理，而不是让一个 Agent 做所有事情。</p>
<p><strong>可观测性优先</strong>：每一步执行都要留下详细日志，包括思考过程、工具调用、返回结果。没有好的可观测性，出了问题根本无法调试。</p>
<h3 id="72-调试技巧">7.2 调试技巧</h3>
<p>Agent 的调试比普通程序难得多，因为问题往往出在大模型的&quot;思考&quot;层面。分享几个实用的调试技巧：</p>
<p><strong>1. 日志可视化</strong>：将 Agent 的执行历史可视化展示，清晰地看到每一轮的思考、行动、观察。我自己开发时会生成一个 HTML 日志，彩色区分不同类型的信息。</p>
<p><strong>2. 回放功能</strong>：保存完整的执行轨迹，支持从任意步骤重新执行。这对于复现问题和测试不同策略非常有用。</p>
<p><strong>3. 人工干预点</strong>：在关键决策点设置暂停，允许人工查看并修正 Agent 的决策。这不仅能提高成功率，还能帮你理解 Agent 为什么会做出某个决策。</p>
<p><strong>4. 对比实验</strong>：同样的任务，用不同的 prompt、不同的模型、不同的参数多跑几次，对比结果差异。你会惊讶地发现，有时候一个词的改动就能带来巨大的效果提升。</p>
<h3 id="73-prompt-工程的经验">7.3 Prompt 工程的经验</h3>
<p>好的 prompt 是 Agent 成功的一半。这里分享几个专门针对 Agent 的 prompt 技巧：</p>
<p><strong>给角色，给例子</strong>：不要只说&quot;你是一个助手&quot;，要说&quot;你是一个有10年经验的资深Python开发者，擅长编写健壮的生产级代码&quot;。然后给1-2个正确的执行示例。</p>
<p><strong>明确输出格式</strong>：用 JSON Schema 严格定义输出格式，然后说&quot;严格按照以上格式输出，不要输出任何解释性文字&quot;。这能大幅减少解析错误。</p>
<p><strong>约束行为边界</strong>：明确告诉 Agent 什么不能做。比如&quot;如果遇到需要修改生产环境配置的情况，必须先询问用户确认，不要直接执行&quot;。</p>
<p><strong>嵌入元指令</strong>：在 prompt 中加入一些元规则，比如&quot;如果你发现自己在重复同样的行动超过3次，停止并反思是不是策略有问题&quot;。</p>
<h3 id="74-成本优化策略">7.4 成本优化策略</h3>
<p>Agent 的成本很容易失控，这里有几个实用的优化方法：</p>
<p><strong>模型分层</strong>：简单的决策用 GPT-3.5-turbo，复杂的推理用 GPT-4。90%的任务其实不需要 GPT-4，关键是识别出那10%真正需要的场景。</p>
<p><strong>结果缓存</strong>：同样的输入，同样的工具调用，结果应该是一样的。加一层缓存能省很多钱。</p>
<p><strong>上下文压缩</strong>：如前面讲的分层记忆，不重要的信息摘要处理，只保留关键信息。</p>
<p><strong>批量处理</strong>：如果有多个独立的小任务，批量交给模型处理，而不是一个一个来。</p>
<h2 id="八未来展望与挑战">八、未来展望与挑战</h2>
<p>AI Agent 还处于非常早期的阶段，未来几年会有巨大的发展。我认为以下几个方向特别值得关注：</p>
<h3 id="81-更小更专门的-agent">8.1 更小、更专门的 Agent</h3>
<p>现在的趋势是模型越来越大，但未来我们可能会看到大量小型的、专门化的 Agent。每个 Agent 只擅长一件事，通过协作完成复杂任务。这就像人类社会的分工，专业化带来效率提升。</p>
<h3 id="82-agent-市场与经济系统">8.2 Agent 市场与经济系统</h3>
<p>未来会出现 Agent 的交易市场，开发者可以出售自己开发的专门 Agent，用户可以按需购买。Agent 之间也会形成经济系统，互相付费购买服务。这会催生全新的商业模式。</p>
<h3 id="83-多模态-agent">8.3 多模态 Agent</h3>
<p>目前的 Agent 主要处理文本，未来会出现能看、能听、能说的多模态 Agent。这会极大扩展 Agent 的应用场景，比如视频内容分析、实时语音对话、图像理解等。</p>
<h3 id="84-仍然存在的挑战">8.4 仍然存在的挑战</h3>
<p>尽管发展很快，Agent 还有很多根本问题没有解决：</p>
<p><strong>可靠性问题</strong>：如何保证 Agent 在长时间运行中不出错？现在的成功率对于很多应用来说还不够。</p>
<p><strong>可解释性问题</strong>：Agent 为什么做出某个决策？很多时候我们自己也说不清。</p>
<p><strong>安全性问题</strong>：如何防止 Agent 被利用做坏事？如何保证它不会意外造成损害？</p>
<p><strong>对齐问题</strong>：如何确保 Agent 的目标和人类的价值观真正对齐？</p>
<p>这些问题不是短期内能解决的，需要整个社区持续的努力。</p>
<h2 id="总结">总结</h2>
<p>AI Agent 代表了人工智能应用的新阶段——从被动的问答工具，变成主动的任务执行者。本文我们从最基础的原理讲起，从零实现了一个完整的 Agent 框架，介绍了记忆管理、错误处理、反思机制等高级特性，探讨了多 Agent 协作的设计，最后给出了实战项目和最佳实践。</p>
<p>掌握了这些知识，你已经可以开始构建自己的 Agent 应用了。但请记住，这个领域发展非常快，今天的最佳实践可能明天就过时了。保持学习，保持实践，这是最好的时代，也是最坏的时代——技术变化很快，但能跟上变化的人总能获得最大的回报。</p>
<p>不要追求完美的 Agent，先从解决一个具体的小问题开始。让你的第一个 Agent 跑起来，然后在使用中不断迭代优化。这才是最快的学习路径。</p>
<p>（全文完，约7200字）</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
