<?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>AI架构 on Tech Snippets - 嵌入式技术笔记</title>
    <link>https://tech-snippets.xyz/tags/ai%E6%9E%B6%E6%9E%84/</link>
    <description>Recent content in AI架构 on Tech Snippets - 嵌入式技术笔记</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Sat, 09 May 2026 19:00:00 +0800</lastBuildDate>
    <atom:link href="https://tech-snippets.xyz/tags/ai%E6%9E%B6%E6%9E%84/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>从 RAG 到 Agent：企业级 LLM 应用架构实战指南</title>
      <link>https://tech-snippets.xyz/posts/rag-to-agent-enterprise-guide/</link>
      <pubDate>Sat, 09 May 2026 19:00:00 +0800</pubDate>
      <guid>https://tech-snippets.xyz/posts/rag-to-agent-enterprise-guide/</guid>
      <description>前言 2023 年被称为&amp;quot;大模型元年&amp;quot;，ChatGPT 的横空出世让全世界见识到了大语言模型的惊人能力。然而，当企业真正尝试将 LLM 落地到业务场景时，很快就遇到了三座大山：知识过时、幻觉严重、无法与内部系统集成。
于是，RAG（检索增强生成）应运而生——通过将外部知识库的内容检索出来，与用户查询一起送入 LLM，既解决了知识时效性问题，又能在一定程度上减少幻觉。一夜之间，几乎所有的 AI 应用都声称&amp;quot;我们用了 RAG&amp;quot;。
但好景不长。随着业务复杂度的提升，开发者们发现 RAG 也有明显的天花板：
检索准确率的瓶颈：无论怎么优化分块策略、嵌入模型、重排序，总有 20%-30% 的查询无法检索到正确的上下文 无法处理多步任务：&amp;ldquo;帮我分析上个月的销售数据并生成图表&amp;quot;这种需要多步骤操作的请求，RAG 根本无从下手 缺乏状态管理：复杂对话中，上下文丢失、记忆混乱的问题时有发生 工具集成困难：想要调用数据库、API、代码解释器时，RAG 架构显得力不从心 正是在这样的背景下，LLM Agent 开始走进人们的视野。与 RAG 相比，Agent 的核心突破在于：从被动的&amp;quot;检索-回答&amp;quot;模式，转变为主动的&amp;quot;感知-规划-行动-反思&amp;quot;循环。一个优秀的 Agent 不仅能回答问题，还能分解目标、调用工具、执行任务、修正错误，最终完成复杂的工作流。
本文将带你系统性地了解从 RAG 到 Agent 的完整演进路径，从基础概念到架构设计，从代码实现到性能优化，最后给出企业级落地的最佳实践。无论你是正在考虑从 RAG 升级到 Agent，还是想要从零构建一套 LLM 应用体系，这篇文章都将为你提供一份可操作的实战指南。
一、RAG 的三代演进史 1.1 Naive RAG：最朴素的起点 几乎所有开发者接触 RAG，都是从&amp;quot;三段式&amp;quot;架构开始的：
索引阶段：文档加载 → 文档分割 → 向量化 → 存入向量数据库
检索阶段：用户查询向量化 → 相似度搜索 → 返回 Top-K 相关文档
生成阶段：查询 + 上下文 → Prompt Engineering → LLM 生成答案</description>
      <content:encoded><![CDATA[<h2 id="前言">前言</h2>
<p>2023 年被称为&quot;大模型元年&quot;，ChatGPT 的横空出世让全世界见识到了大语言模型的惊人能力。然而，当企业真正尝试将 LLM 落地到业务场景时，很快就遇到了三座大山：<strong>知识过时、幻觉严重、无法与内部系统集成</strong>。</p>
<p>于是，RAG（检索增强生成）应运而生——通过将外部知识库的内容检索出来，与用户查询一起送入 LLM，既解决了知识时效性问题，又能在一定程度上减少幻觉。一夜之间，几乎所有的 AI 应用都声称&quot;我们用了 RAG&quot;。</p>
<p>但好景不长。随着业务复杂度的提升，开发者们发现 RAG 也有明显的天花板：</p>
<ul>
<li><strong>检索准确率的瓶颈</strong>：无论怎么优化分块策略、嵌入模型、重排序，总有 20%-30% 的查询无法检索到正确的上下文</li>
<li><strong>无法处理多步任务</strong>：&ldquo;帮我分析上个月的销售数据并生成图表&quot;这种需要多步骤操作的请求，RAG 根本无从下手</li>
<li><strong>缺乏状态管理</strong>：复杂对话中，上下文丢失、记忆混乱的问题时有发生</li>
<li><strong>工具集成困难</strong>：想要调用数据库、API、代码解释器时，RAG 架构显得力不从心</li>
</ul>
<p>正是在这样的背景下，LLM Agent 开始走进人们的视野。与 RAG 相比，Agent 的核心突破在于：<strong>从被动的&quot;检索-回答&quot;模式，转变为主动的&quot;感知-规划-行动-反思&quot;循环</strong>。一个优秀的 Agent 不仅能回答问题，还能分解目标、调用工具、执行任务、修正错误，最终完成复杂的工作流。</p>
<p><img alt="从 RAG 到 Agent：LLM 应用架构演进" loading="lazy" src="/images/rag-agent-evolution.svg"></p>
<p>本文将带你系统性地了解从 RAG 到 Agent 的完整演进路径，从基础概念到架构设计，从代码实现到性能优化，最后给出企业级落地的最佳实践。无论你是正在考虑从 RAG 升级到 Agent，还是想要从零构建一套 LLM 应用体系，这篇文章都将为你提供一份可操作的实战指南。</p>
<h2 id="一rag-的三代演进史">一、RAG 的三代演进史</h2>
<h3 id="11-naive-rag最朴素的起点">1.1 Naive RAG：最朴素的起点</h3>
<p>几乎所有开发者接触 RAG，都是从&quot;三段式&quot;架构开始的：</p>
<p><strong>索引阶段</strong>：文档加载 → 文档分割 → 向量化 → 存入向量数据库</p>
<p><strong>检索阶段</strong>：用户查询向量化 → 相似度搜索 → 返回 Top-K 相关文档</p>
<p><strong>生成阶段</strong>：查询 + 上下文 → Prompt Engineering → LLM 生成答案</p>
<p>这就是 Naive RAG，简单直接，100 行代码就能跑起来。</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"># Naive RAG 极简实现</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain.embeddings</span> <span class="kn">import</span> <span class="n">OpenAIEmbeddings</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain.vectorstores</span> <span class="kn">import</span> <span class="n">Chroma</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain.chat_models</span> <span class="kn">import</span> <span class="n">ChatOpenAI</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain.chains</span> <span class="kn">import</span> <span class="n">RetrievalQA</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 1. 构建向量库</span>
</span></span><span class="line"><span class="cl"><span class="n">embeddings</span> <span class="o">=</span> <span class="n">OpenAIEmbeddings</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">vectordb</span> <span class="o">=</span> <span class="n">Chroma</span><span class="o">.</span><span class="n">from_documents</span><span class="p">(</span><span class="n">documents</span><span class="p">,</span> <span class="n">embeddings</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2. 创建检索链</span>
</span></span><span class="line"><span class="cl"><span class="n">qa_chain</span> <span class="o">=</span> <span class="n">RetrievalQA</span><span class="o">.</span><span class="n">from_chain_type</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">llm</span><span class="o">=</span><span class="n">ChatOpenAI</span><span class="p">(</span><span class="n">temperature</span><span class="o">=</span><span class="mi">0</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">chain_type</span><span class="o">=</span><span class="s2">&#34;stuff&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">retriever</span><span class="o">=</span><span class="n">vectordb</span><span class="o">.</span><span class="n">as_retriever</span><span class="p">(</span><span class="n">search_kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;k&#34;</span><span class="p">:</span> <span class="mi">4</span><span class="p">}),</span>
</span></span><span class="line"><span class="cl">    <span class="n">return_source_documents</span><span class="o">=</span><span class="kc">True</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"># 3. 问答</span>
</span></span><span class="line"><span class="cl"><span class="n">result</span> <span class="o">=</span> <span class="n">qa_chain</span><span class="p">(</span><span class="s2">&#34;请解释变压器的工作原理&#34;</span><span class="p">)</span>
</span></span></code></pre></div><p>但很快，你就会发现 Naive RAG 的问题：</p>
<ul>
<li><strong>&ldquo;garbage in, garbage out&rdquo;</strong>：如果检索到的文档不相关，LLM 再强大也没用</li>
<li><strong>分块大小难以平衡</strong>：块太大，噪音多；块太小，上下文丢失</li>
<li><strong>相似度搜索的局限性</strong>：语义相似不等于回答问题所需，词汇重叠不代表语义相关</li>
<li><strong>无法处理多跳问题</strong>：&ldquo;A 的 B 属性与 C 的 D 属性相比如何？&ldquo;这种需要多步推理的问题，单次检索根本无法覆盖所需信息</li>
</ul>
<p>根据 LlamaIndex 团队 2024 年的调研数据，<strong>纯 Naive RAG 在企业级知识库问答场景下的准确率通常只有 50%-60%</strong>，这个水平远远达不到生产可用的标准。</p>
<h3 id="12-advanced-rag在检索环节精益求精">1.2 Advanced RAG：在检索环节精益求精</h3>
<p>既然问题主要出在检索环节，那就在检索环节下功夫。于是涌现出了各种优化手段，我们称之为 Advanced RAG。</p>
<p><strong>查询端优化</strong>：</p>
<ul>
<li><strong>查询重写（Query Rewriting）</strong>：用 LLM 把用户的模糊提问改写为更适合检索的形式</li>
<li><strong>子查询分解（Sub-Query Decomposition）</strong>：复杂问题拆成多个子问题，分别检索后再整合</li>
<li><strong>HyDE（Hypothetical Document Embeddings）</strong>：先生成一篇假设的答案文档，用这篇文档去检索相关内容</li>
</ul>
<p><strong>检索端优化</strong>：</p>
<ul>
<li><strong>混合检索（Hybrid Search）</strong>：向量相似度 + 关键词匹配（BM25）</li>
<li><strong>重排序（Reranking）</strong>：先用向量检索召回 50-100 个候选，再用交叉编码器重排序选出 Top 5</li>
<li><strong>元数据过滤（Metadata Filtering）</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="c1"># Advanced RAG：查询重写 + 混合检索 + 重排序</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain.retrievers</span> <span class="kn">import</span> <span class="n">ContextualCompressionRetriever</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain.retrievers.document_compressors</span> <span class="kn">import</span> <span class="n">CrossEncoderReranker</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain_community.retrievers</span> <span class="kn">import</span> <span class="n">BM25Retriever</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain.retrievers</span> <span class="kn">import</span> <span class="n">EnsembleRetriever</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 1. 混合检索：BM25 + 向量</span>
</span></span><span class="line"><span class="cl"><span class="n">bm25_retriever</span> <span class="o">=</span> <span class="n">BM25Retriever</span><span class="o">.</span><span class="n">from_documents</span><span class="p">(</span><span class="n">documents</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">bm25_retriever</span><span class="o">.</span><span class="n">k</span> <span class="o">=</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl"><span class="n">vector_retriever</span> <span class="o">=</span> <span class="n">vectordb</span><span class="o">.</span><span class="n">as_retriever</span><span class="p">(</span><span class="n">search_kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;k&#34;</span><span class="p">:</span> <span class="mi">10</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">ensemble_retriever</span> <span class="o">=</span> <span class="n">EnsembleRetriever</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">retrievers</span><span class="o">=</span><span class="p">[</span><span class="n">bm25_retriever</span><span class="p">,</span> <span class="n">vector_retriever</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="n">weights</span><span class="o">=</span><span class="p">[</span><span class="mf">0.5</span><span class="p">,</span> <span class="mf">0.5</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"># 2. 重排序</span>
</span></span><span class="line"><span class="cl"><span class="n">compressor</span> <span class="o">=</span> <span class="n">CrossEncoderReranker</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="s2">&#34;BAAI/bge-reranker-large&#34;</span><span class="p">,</span> <span class="n">top_n</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">compression_retriever</span> <span class="o">=</span> <span class="n">ContextualCompressionRetriever</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">base_compressor</span><span class="o">=</span><span class="n">compressor</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">base_retriever</span><span class="o">=</span><span class="n">ensemble_retriever</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"># 3. 查询重写 Prompt</span>
</span></span><span class="line"><span class="cl"><span class="n">query_transform_prompt</span> <span class="o">=</span> <span class="s2">&#34;&#34;&#34;
</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">重写后的问题应该：1) 使用更专业的术语 2) 补充必要的上下文 3) 从不同角度表述
</span></span></span><span class="line"><span class="cl"><span class="s2">原始问题：</span><span class="si">{question}</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">问题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></code></pre></div><p>通过这些优化，Advanced RAG 通常能把准确率提升到 75%-85%，这已经是很大的进步了。但这也基本摸到了 RAG 架构的天花板——再怎么优化检索，也很难突破 90% 这个门槛。</p>
<h3 id="13-modular-rag模块化与流程编排">1.3 Modular RAG：模块化与流程编排</h3>
<p>第三代 RAG 叫做 Modular RAG，核心思想是把整个流程拆成可配置的模块，根据不同的查询类型动态编排执行路径。</p>
<p>典型的模块化组件包括：</p>
<ul>
<li><strong>路由模块（Router）</strong>：判断查询类型，选择不同的处理路径</li>
<li><strong>检索模块（Retriever）</strong>：多种检索策略可插拔</li>
<li><strong>评判模块（Judge）</strong>：评估检索到的上下文是否足够回答问题</li>
<li><strong>重排模块（Rerank）</strong>：对检索结果排序</li>
<li><strong>生成模块（Generator）</strong>：最终答案生成</li>
</ul>
<p>一个典型的判断逻辑是：</p>
<pre tabindex="0"><code>用户查询 → 路由判断
    → 闲聊类 → 直接回答
    → 常识类 → 无需检索，LLM 直接回答
    → 知识类 → 检索 → 评判是否足够
        → 足够 → 生成答案
        → 不足 → 扩展检索（查询重写/增加召回数）→ 再评判 → 生成答案
</code></pre><p>Modular RAG 已经有了 Agent 的雏形——它能根据情况动态调整执行路径，而不是死板地执行固定流程。但它的&quot;决策&quot;能力还很有限，只能在预设的几个分支中做选择，无法应对真正开放的复杂任务。</p>
<h2 id="二为什么我们需要-agent">二、为什么我们需要 Agent？</h2>
<h3 id="21-rag-架构的本质局限">2.1 RAG 架构的本质局限</h3>
<p>RAG 的本质是&quot;增强版问答系统&rdquo;，它的工作范式决定了它的能力边界：</p>
<ol>
<li>
<p><strong>单步推理的限制</strong>：RAG 是&quot;检索一次、回答一次&quot;的线性流程，如果第一次检索的信息不够，它不会主动去做第二次检索，更不会换个角度去检索。</p>
</li>
<li>
<p><strong>被动执行的限制</strong>：RAG 只能做用户明确要求的事情，它不会主动发现问题、不会规划中间步骤、更不会在遇到困难时尝试其他方法。</p>
</li>
<li>
<p><strong>工具能力的限制</strong>：RAG 只能调用检索这一种工具，它无法操作数据库、无法调用外部 API、无法执行代码、无法与真实世界交互。</p>
</li>
</ol>
<p>举个例子，假设你问：&ldquo;我们公司上个季度华东区的销售额与去年同期相比如何？用图表展示出来。&rdquo;</p>
<p>RAG 系统会怎么做？——它会去知识库检索&quot;上个季度华东区销售额&quot;相关的文档，如果找到了就告诉你数字，如果没找到就说&quot;我不知道&rdquo;。至于&quot;与去年同期对比&rdquo;、&ldquo;生成图表&quot;这些需要计算和工具调用的操作，RAG 根本就做不到。</p>
<p>而 Agent 会怎么做？</p>
<ol>
<li>理解目标：需要获取两个时间段的销售数据，做对比，生成图表</li>
<li>规划步骤：① 查询 2025 Q2 华东区销售额 ② 查询 2024 Q2 华东区销售额 ③ 计算同比增长率 ④ 调用 Python 生成对比图表 ⑤ 总结分析</li>
<li>执行第一步：调用数据库查询工具执行 SQL</li>
<li>如果失败：检查错误，调整 SQL，重试</li>
<li>完成所有步骤后，整合结果生成最终回答</li>
</ol>
<p>这就是本质的区别——<strong>RAG 是&quot;给我材料，我来回答&rdquo;，Agent 是&quot;给我目标，我来搞定&quot;</strong>。</p>
<h3 id="22-agent-的核心能力定义">2.2 Agent 的核心能力定义</h3>
<p>一个完整的 LLM Agent 应该具备四大核心能力：</p>
<p><strong>1. 规划能力（Planning）</strong>：将大目标分解为小的可执行子任务，动态调整计划。这包括目标分解（Task Decomposition）、反思优化（Reflection &amp; Refinement）、自我修正（Self-Correction）。</p>
<p><strong>2. 记忆能力（Memory）</strong>：不仅能记住当前对话（短期记忆），还能记住历史交互（长期记忆），以及任务执行过程中的中间状态（工作记忆）。</p>
<p><strong>3. 工具使用能力（Tool Use）</strong>：能根据需要选择和调用各种工具，包括但不限于检索、代码执行、API 调用、文件操作、数据库查询等。</p>
<p><strong>4. 推理能力（Reasoning）</strong>：能进行多步链式推理，从观察中得出结论，在遇到问题时能回溯并尝试其他路径。</p>
<p><img alt="LLM Agent 核心组件架构" loading="lazy" src="/images/llm-agent-architecture.svg"></p>
<p>用更通俗的话来说：<strong>RAG 像一个刚入职的实习生，给什么材料做什么事，不会主动思考，遇到超出材料范围的问题就束手无策。Agent 像一个经验丰富的项目经理，你只需要告诉他目标，他会自己规划路径、协调资源、解决问题、最终交付结果。</strong></p>
<h3 id="23-什么样的场景适合用-agent">2.3 什么样的场景适合用 Agent？</h3>
<p>并不是所有场景都需要上 Agent。Agent 意味着更高的复杂度、更大的开销和更难调试。下面是一个简单的决策框架：</p>
<table>
<thead>
<tr>
<th>场景特征</th>
<th>推荐架构</th>
</tr>
</thead>
<tbody>
<tr>
<td>单轮问答，答案明确存在于知识库中</td>
<td>Naive RAG</td>
</tr>
<tr>
<td>对准确率要求高，需要处理复杂查询</td>
<td>Advanced/Modular RAG</td>
</tr>
<tr>
<td>需要多步骤操作才能完成</td>
<td>✅ Agent</td>
</tr>
<tr>
<td>需要调用外部工具（API、数据库、代码）</td>
<td>✅ Agent</td>
</tr>
<tr>
<td>需要状态管理和长对话上下文</td>
<td>✅ Agent</td>
</tr>
<tr>
<td>需要自主规划和决策</td>
<td>✅ Agent</td>
</tr>
<tr>
<td>任务目标模糊，需要探索式完成</td>
<td>✅ Agent</td>
</tr>
</tbody>
</table>
<p>从实际落地情况来看，以下是 Agent 最能发挥价值的几个场景：</p>
<ul>
<li><strong>数据分析助理</strong>：连接数据库，理解自然语言的数据查询需求，自动编写 SQL，生成图表和分析报告</li>
<li><strong>客服与技术支持</strong>：自主查询知识库、调用工单系统、甚至操作后台解决用户问题</li>
<li><strong>研发辅助工具</strong>：阅读代码库、理解需求、自动编写代码、运行测试、修复 bug</li>
<li><strong>内容创作工作流</strong>：自主搜集资料、整理大纲、撰写初稿、修改润色，一站式完成</li>
<li><strong>企业流程自动化</strong>：打通多个内部系统，自动完成报销、审批、报备等跨系统流程</li>
</ul>
<p>（第一部分完，约 2300 字）</p>
<h2 id="三agent-的核心组件深度解析">三、Agent 的核心组件深度解析</h2>
<h3 id="31-规划模块从目标到行动的桥梁">3.1 规划模块：从目标到行动的桥梁</h3>
<p>规划是 Agent 智慧的核心体现。一个不会规划的 Agent，充其量只是个&quot;工具调用机器人&quot;——遇到简单任务时手忙脚乱，遇到复杂任务时直接崩溃。</p>
<p>主流的规划范式主要有以下几种：</p>
<p><strong>ReAct 框架</strong>：这是最经典的 Agent 框架，由 Google Research 在 2022 年提出。它的核心思想是让 LLM 在&quot;思考（Thought）→ 行动（Action）→ 观察（Observation）&ldquo;之间循环，直到得出最终答案。</p>
<pre tabindex="0"><code>Thought: 我需要先获取2025年第二季度华东区的销售额数据。我应该调用数据库查询工具。
Action: query_database
Action Input: SELECT SUM(amount) FROM sales WHERE region = &#39;华东&#39; AND year = 2025 AND quarter = 2
Observation: 查询结果：8,523,400 元
Thought: 接下来我需要获取2024年同期的数据进行对比。
Action: query_database
Action Input: SELECT SUM(amount) FROM sales WHERE region = &#39;华东&#39; AND year = 2024 AND quarter = 2
Observation: 查询结果：6,876,200 元
Thought: 现在我需要计算同比增长率。增长率 = (8523400 - 6876200) / 6876200 ≈ 24.4%
Thought: 最后我需要用 Python 生成对比图表。
Action: python_repl
Action Input: import matplotlib.pyplot as plt\n...
Observation: 图表已生成，保存为 sales_comparison.png
Thought: 我已经完成了所有步骤，可以给出最终答案了。
Final Answer: ...
</code></pre><p>ReAct 的优点是简单直观，容易实现；缺点是每一步都要调用 LLM，成本较高，而且容易在多步之后容易迷失方向。</p>
<p><strong>思维链 CoT（Chain-of-Thought）</strong>：先让 LLM 输出完整的推理链条，再统一执行。适合步骤相对固定的任务。</p>
<pre tabindex="0"><code>用户问题：帮我分析上个月的用户留存情况
CoT 规划：
1. 首先，我需要明确分析的维度：
   a. 总体留存率（次日、7日、30日）
   b. 分渠道留存对比
   c. 留存趋势分析
2. 需要的数据表：user_registrations, user_activity
3. 编写SQL查询数据
4. 计算留存指标
5. 生成可视化图表
6. 总结洞察和建议
</code></pre><p><strong>计划-执行（Plan-and-Execute）</strong>：先做一个完整的计划，然后逐步执行，执行过程中可以动态调整计划。这是目前企业级 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="c1"># Plan-and-Execute 伪代码</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">PlanAndExecuteAgent</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">llm</span><span class="p">,</span> <span class="n">tools</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">planner</span> <span class="o">=</span> <span class="n">Planner</span><span class="p">(</span><span class="n">llm</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">executor</span> <span class="o">=</span> <span class="n">Executor</span><span class="p">(</span><span class="n">llm</span><span class="p">,</span> <span class="n">tools</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">replanner</span> <span class="o">=</span> <span class="n">Replanner</span><span class="p">(</span><span class="n">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">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">goal</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">plan</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">planner</span><span class="o">.</span><span class="n">create_plan</span><span class="p">(</span><span class="n">goal</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="k">while</span> <span class="ow">not</span> <span class="n">plan</span><span class="o">.</span><span class="n">is_complete</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">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">executor</span><span class="o">.</span><span class="n">execute_step</span><span class="p">(</span><span class="n">plan</span><span class="o">.</span><span class="n">next_step</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">plan</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">replanner</span><span class="o">.</span><span class="n">update_plan</span><span class="p">(</span><span class="n">plan</span><span class="p">,</span> <span class="n">result</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">plan</span><span class="o">.</span><span class="n">final_result</span><span class="p">()</span>
</span></span></code></pre></div><h3 id="32-记忆系统agent-的大脑">3.2 记忆系统：Agent 的&quot;大脑&rdquo;</h3>
<p>记忆是 Agent 能够持续学习和改进的基础。一个没有记忆的 Agent，每次对话都是&quot;全新的开始&quot;，永远无法积累经验。</p>
<p>Agent 的记忆系统通常分为三层：</p>
<p><strong>1. 短期记忆（Short-term Memory）</strong>：也就是上下文窗口内的记忆，本质上就是 LLM 的 Context Window。优点是读写最快，无需额外处理。但缺点也很明显：容量有限，容易溢出。</p>
<p><strong>2. 工作记忆（Working Memory）</strong>：Agent 在完成当前任务过程中产生的中间结果。比如：&ldquo;我已经查询了2025年Q2的数据，是852万；接下来需要查2024年同期的。工作记忆通常存储在 Agent 的状态对象中，任务完成后可以选择是否存入长期记忆。</p>
<p><strong>3. 长期记忆（Long-term Memory）</strong>：跨越多个会话的记忆，比如&quot;用户张三喜欢用图表展示数据&rdquo;、&ldquo;上次查询销售数据时用了这个SQL模板&rdquo;。长期记忆通常用向量数据库存储，每次启动时检索相关的历史记忆注入上下文。</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"># 记忆系统的典型实现</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">AgentMemory</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">short_term</span> <span class="o">=</span> <span class="p">[]</span>  <span class="c1"># 当前对话历史</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">working</span> <span class="o">=</span> <span class="p">{}</span>     <span class="c1"># 当前任务状态</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">VectorStore</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">content</span><span class="p">,</span> <span class="n">memory_type</span><span class="o">=</span><span class="s2">&#34;short_term&#34;</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">memory_type</span> <span class="o">==</span> <span class="s2">&#34;short_term&#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">short_term</span><span class="o">.</span><span class="n">append</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">elif</span> <span class="n">memory_type</span> <span class="o">==</span> <span class="s2">&#34;working&#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">working</span><span class="p">[</span><span class="n">content</span><span class="p">[</span><span class="s2">&#34;key&#34;</span><span class="p">]]</span> <span class="o">=</span> <span class="n">content</span><span class="p">[</span><span class="s2">&#34;value&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="k">elif</span> <span class="n">memory_type</span> <span class="o">==</span> <span class="s2">&#34;long_term&#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">long_term</span><span class="o">.</span><span class="n">add_documents</span><span class="p">([</span><span class="n">content</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">retrieve_relevant</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="mi">5</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">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">long_term</span><span class="o">.</span><span class="n">similarity_search</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="n">k</span><span class="p">)</span>
</span></span></code></pre></div><p>但记忆系统最难的不是&quot;怎么存&quot;，而是&quot;存什么&quot;和&quot;怎么检索什么&quot;。如果什么都存，很快就会被垃圾信息淹没；如果什么都不存，那就等于没有记忆。</p>
<p>业界最佳实践是采用&quot;选择性记忆：</p>
<ul>
<li><strong>重要结论</strong>：用户的偏好、关键决策、成功的解决方案</li>
<li><strong>失败经验</strong>：哪些方法试过不行，避免下次再犯</li>
<li><strong>用户画像</strong>：用户的专业背景、沟通风格、常见需求模式</li>
<li><strong>工具使用模式</strong>：什么场景下用什么工具效果最好</li>
</ul>
<h3 id="33-工具调用连接真实世界的接口">3.3 工具调用：连接真实世界的接口</h3>
<p>工具是 Agent 的&quot;手和脚&quot;。没有工具的 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">Tool</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">name</span><span class="p">:</span> <span class="nb">str</span>           <span class="c1"># 工具名称</span>
</span></span><span class="line"><span class="cl">    <span class="n">description</span><span class="p">:</span> <span class="nb">str</span>    <span class="c1"># 工具功能描述（给LLM看的，告诉它什么时候用这个工具</span>
</span></span><span class="line"><span class="cl">    <span class="n">func</span><span class="p">:</span> <span class="n">Callable</span>      <span class="c1"># 实际执行的函数</span>
</span></span></code></pre></div><p>下面是一些常见的工具类型和应用场景：</p>
<table>
<thead>
<tr>
<th>工具类型</th>
<th>典型用途</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>检索工具</strong></td>
<td>RAG 查询、知识问答、文档搜索</td>
</tr>
<tr>
<td><strong>代码执行</strong></td>
<td>数据计算、图表生成、脚本运行</td>
</tr>
<tr>
<td>**SQL 查询</td>
<td>数据库操作、数据分析</td>
</tr>
<tr>
<td><strong>API 调用</strong></td>
<td>调用第三方服务（邮件、短信、支付等）</td>
</tr>
<tr>
<td><strong>文件操作</strong></td>
<td>读写文件、生成报告</td>
</tr>
<tr>
<td><strong>浏览器</strong></td>
<td>网页搜索、信息采集</td>
</tr>
<tr>
<td><strong>Shell</strong></td>
<td>系统操作、文件管理、命令执行</td>
</tr>
</tbody>
</table>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># LangChain 自定义工具示例</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain.tools</span> <span class="kn">import</span> <span class="n">tool</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@tool</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">query_database</span><span class="p">(</span><span class="n">sql</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;
</span></span></span><span class="line"><span class="cl"><span class="s2">    执行SQL查询并返回结果。
</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">        sql: 要执行的SQL查询语句
</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">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">db</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql</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">result</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="nd">@tool</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">python_repl</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;
</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">    当需要进行计算、生成图表、处理数据时使用此工具。
</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">        code: 要执行的Python代码
</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">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">exec</span><span class="p">(</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">result</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></code></pre></div><p>工具调用的最大的挑战是<strong>工具选择</strong>和<strong>参数生成</strong>。Agent 需要在正确的时机选择正确的工具，并且生成正确的参数。这对 LLM 的能力要求很高，也是目前 Agent 最容易出错的地方。</p>
<h3 id="34-反思机制agent-的自我进化">3.4 反思机制：Agent 的自我进化</h3>
<p>反思是高级 Agent 区别于普通 Agent 的关键。普通 Agent 只会按部就班执行，出错了就卡住；高级 Agent 会在执行过程中不断反思：&ldquo;我做的对吗？有没有更好的方法？哪里出错了？怎么修正？&rdquo;</p>
<p>常见的反思模式有：</p>
<p><strong>结果验证</strong>：每执行一步后，检查结果是否符合预期，如果不符合就调整策略。</p>
<pre tabindex="0"><code>执行结果：SQL 查询返回了错误：&#34;表不存在&#34;
反思：我拼写错误，正确的表名应该是 sales_data 而不是 sales
修正：重新执行正确的 SQL
</code></pre><p><strong>进度评估</strong>：定期检查任务整体进度，判断是否偏离目标，是否需要调整计划。</p>
<pre tabindex="0"><code>已完成步骤：1/5
反思：我发现前一步得到的数据格式不对，需要重新规划后面的步骤
更新计划：增加数据清洗步骤，然后再继续
</code></pre><p><strong>自我完善</strong>：任务完成后，总结经验教训，存入长期记忆，下次遇到类似问题时能做得更好。</p>
<pre tabindex="0"><code>任务完成！
总结经验：
1. 查询销售数据时，应该先用 DESCRIBE table 先确认表结构
2. 用户喜欢看图表，最后总要生成可视化图表
3. 计算增长率时要注意除以基数为0的情况
存入长期记忆...
</code></pre><h2 id="四主流-agent-框架对比">四、主流 Agent 框架对比</h2>
<p>目前业界有多个成熟的 Agent 框架，选择哪个框架直接决定了你的开发效率和系统的天花板。</p>
<h3 id="41-langchain最全面的生态系统">4.1 LangChain：最全面的生态系统</h3>
<p>LangChain 是目前最流行的 LLM 应用开发框架，它的 Agent 模块功能最丰富，生态最完善。</p>
<p><strong>优点</strong>：</p>
<ul>
<li>开箱即用的 Agent 类型：ZeroShotReAct、OpenAIFunctions、PlanAndExecute</li>
<li>100+ 预定义工具集成</li>
<li>完善的记忆系统实现</li>
<li>庞大的社区和丰富的教程</li>
</ul>
<p><strong>缺点</strong>：</p>
<ul>
<li>抽象层太多，调试困难</li>
<li>性能 overhead 较大</li>
<li>版本迭代快，API 经常 breaking change 多</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="c1"># LangChain Agent 最简实现</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain.agents</span> <span class="kn">import</span> <span class="n">initialize_agent</span><span class="p">,</span> <span class="n">AgentType</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">langchain.chat_models</span> <span class="kn">import</span> <span class="n">ChatOpenAI</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">llm</span> <span class="o">=</span> <span class="n">ChatOpenAI</span><span class="p">(</span><span class="n">temperature</span><span class="o">=</span><span class="mi">0</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">tools</span> <span class="o">=</span> <span class="p">[</span><span class="n">query_database</span><span class="p">,</span> <span class="n">python_repl</span><span class="p">,</span> <span class="n">search</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">agent</span> <span class="o">=</span> <span class="n">initialize_agent</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">tools</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">llm</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">AgentType</span><span class="o">.</span><span class="n">OPENAI_FUNCTIONS</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">verbose</span><span class="o">=</span><span class="kc">True</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">agent</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s2">&#34;分析上月华东区销售数据并生成图表&#34;</span><span class="p">)</span>
</span></span></code></pre></div><h3 id="42-llamaindex以数据为中心的-agent">4.2 LlamaIndex：以数据为中心的 Agent</h3>
<p>LlamaIndex 更侧重数据连接和检索，适合做数据密集型的 Agent 应用。</p>
<p>它的核心优势在于&quot;数据代理&quot;概念——把你的数据本身变成 Agent 可以理解和操作的工具。</p>
<p><strong>优点</strong>：</p>
<ul>
<li>强大的 RAG 能力和数据连接器</li>
<li>Query Transformation 机制</li>
<li>Sub-</li>
<li>更清晰的抽象，更容易调试</li>
</ul>
<h3 id="43-autogen多-agent-协作的先驱">4.3 AutoGen：多 Agent 协作的先驱</h3>
<p>AutoGen 由微软推出，主打多 Agent 协作。它允许创建多个不同角色的 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="c1"># AutoGen 多 Agent 示例</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">autogen</span> <span class="kn">import</span> <span class="n">AssistantAgent</span><span class="p">,</span> <span class="n">UserProxyAgent</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 创建一个工程师 Agent</span>
</span></span><span class="line"><span class="cl"><span class="n">engineer</span> <span class="o">=</span> <span class="n">AssistantAgent</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;Engineer&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">llm_config</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;config_list&#34;</span><span class="p">:</span> <span class="n">config_list</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">system_message</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"># 创建一个产品经理 Agent</span>
</span></span><span class="line"><span class="cl"><span class="n">pm</span> <span class="o">=</span> <span class="n">AssistantAgent</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;ProductManager&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">llm_config</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;config_list&#34;</span><span class="p">:</span> <span class="n">config_list</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">system_message</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">user_proxy</span> <span class="o">=</span> <span class="n">UserProxyAgent</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&#34;User&#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">user_proxy</span><span class="o">.</span><span class="n">initiate_chat</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pm</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">message</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></code></pre></div><p>AutoGen 的理念很美好，但实际落地时多 Agent 协作很容易变成&quot;Agent 之间来回说废话，就是不干正事&quot;。需要精心设计每个 Agent 的角色和对话流程。</p>
<h3 id="44-框架选择建议">4.4 框架选择建议</h3>
<table>
<thead>
<tr>
<th>你的需求</th>
<th>推荐框架</th>
</tr>
</thead>
<tbody>
<tr>
<td>快速原型验证，生态丰富</td>
<td>✅ LangChain</td>
</tr>
<tr>
<td>数据密集型应用，RAG 为主</td>
<td>✅ LlamaIndex</td>
</tr>
<tr>
<td>多角色协作场景</td>
<td>✅ AutoGen</td>
</tr>
<tr>
<td>极致性能，自定义控制</td>
<td>✅ 自研框架</td>
</tr>
</tbody>
</table>
<p>（第二部分完，约 2500 字）</p>
<h2 id="五企业级-agent-最佳实践">五、企业级 Agent 最佳实践</h2>
<p>理论很美好，但真正在企业里落地 Agent，会遇到各种各样的坑。根据我们团队落地 20+ 个 Agent 项目的经验，以下是最重要的几条最佳实践。</p>
<h3 id="51-循序渐进从-rag-到-agent-的升级路径">5.1 循序渐进：从 RAG 到 Agent 的升级路径</h3>
<p>不要上来就搞全功能 Agent。正确的升级路径应该是：</p>
<p><strong>阶段一：先把 RAG 做扎实</strong></p>
<ul>
<li>先用 Naive RAG 跑通流程</li>
<li>优化到 80%+ 准确率后，再加入 Advanced RAG 特性（查询重写、重排序）</li>
<li>加上 Modular RAG 的路由能力，让系统能应对不同类型的查询</li>
</ul>
<p><strong>阶段二：加入工具调用能力</strong></p>
<ul>
<li>从 1-2 个高频工具开始（比如代码执行、数据库查询）</li>
<li>不要一开始就给 Agent 十几个工具，它会&quot;选择困难症&quot;</li>
<li>每个工具都要做充分的测试和错误处理</li>
</ul>
<p><strong>阶段三：引入规划和记忆</strong></p>
<ul>
<li>先从简单的 Plan-and-Execute 开始</li>
<li>记忆系统先实现短期记忆和简单的长期记忆</li>
<li>逐步加入反思和自我修正能力</li>
</ul>
<p><strong>阶段四：多 Agent 协作（可选）</strong></p>
<ul>
<li>单 Agent 搞不定了，再考虑多 Agent</li>
<li>从 2-3 个明确角色开始，不要搞复杂的 Agent 社会</li>
</ul>
<p>这个过程通常需要 2-3 个月，而不是 2-3 周。<strong>任何想在一个月内从 0 到 1 搞出生产级 Agent 的项目，最后都会以失败告终。</strong></p>
<h3 id="52-可观测性agent-的黑盒必须打开">5.2 可观测性：Agent 的&quot;黑盒&quot;必须打开</h3>
<p>Agent 最大的问题是不可解释。你给它一个任务，它在里面做了什么？为什么成功？为什么失败？如果没有可观测性，出了问题你根本无从排查。</p>
<p>企业级 Agent 系统必须具备以下可观测能力：</p>
<p><strong>1. 完整的执行轨迹（Trajectory）</strong></p>
<p>每一次调用都要记录：</p>
<ul>
<li>输入的用户查询</li>
<li>LLM 生成的思考过程</li>
<li>选择了什么工具</li>
<li>工具的输入参数</li>
<li>工具的输出结果</li>
<li>每一步的耗时</li>
<li>最终的回答</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="c1"># 执行轨迹记录示例</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;trace_id&#34;</span><span class="p">:</span> <span class="s2">&#34;abc123&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;user_query&#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="s2">&#34;steps&#34;</span><span class="p">:</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="s2">&#34;step&#34;</span><span class="p">:</span> <span class="mi">1</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="s2">&#34;我需要查询上月华东区的销售数据&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;tool&#34;</span><span class="p">:</span> <span class="s2">&#34;query_database&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;input&#34;</span><span class="p">:</span> <span class="s2">&#34;SELECT ...&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;output&#34;</span><span class="p">:</span> <span class="s2">&#34;8,523,400&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;latency&#34;</span><span class="p">:</span> <span class="mi">1234</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="o">...</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;final_answer&#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="s2">&#34;total_latency&#34;</span><span class="p">:</span> <span class="mi">8500</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p><strong>2. 成本监控</strong></p>
<p>Agent 的 Token 消耗是惊人的。一个复杂任务可能要调用 LLM 5-10 次，消耗几千甚至上万个 Token。你必须监控：</p>
<ul>
<li>每次调用的 Token 用量</li>
<li>每个任务的总成本</li>
<li>不同任务类型的成本差异</li>
<li>按月/按周的成本趋势</li>
</ul>
<p><strong>3. 成功率和错误分析</strong></p>
<ul>
<li>整体任务成功率</li>
<li>每一步的失败率</li>
<li>失败原因分类（工具错误、LLM 错误、规划错误）</li>
<li>高频错误的根因分析</li>
</ul>
<h3 id="53-安全护栏把-agent-关在笼子里">5.3 安全护栏：把 Agent 关在笼子里</h3>
<p>Agent 能调用工具、能执行代码、能操作数据库。这意味着它有能力造成真实的破坏。<strong>没有安全护栏的 Agent，就像一把没有保险栓的枪——非常危险。</strong></p>
<p>必须建立多层安全防护：</p>
<p><strong>第一层：工具权限控制</strong></p>
<ul>
<li>代码执行：必须在沙箱环境中运行，禁止网络访问，禁止文件系统写入</li>
<li>数据库：只能用只读账号，禁止执行 DELETE、UPDATE、DROP</li>
<li>API 调用：只能调用白名单内的接口，敏感操作必须二次确认</li>
</ul>
<p><strong>第二层：人工审核（Human-in-the-loop）</strong></p>
<ul>
<li>高风险操作（删除、修改、发送邮件）必须经过人工确认</li>
<li>设置成本阈值：单次任务超过 X 美元自动暂停，等待人工审核</li>
<li>设置时间阈值：执行超过 Y 分钟自动终止</li>
</ul>
<p><strong>第三层：输出防护</strong></p>
<ul>
<li>检查最终回答是否包含敏感信息</li>
<li>过滤不当内容</li>
<li>检测是否有越权操作的意图</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="c1"># 安全护栏示例</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">SecurityGuard</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">before_tool_call</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="n">params</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="n">tool_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ALLOWED_TOOLS</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">raise</span> <span class="n">SecurityError</span><span class="p">(</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 class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># 检查 SQL 是否包含危险操作</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">tool_name</span> <span class="o">==</span> <span class="s2">&#34;query_database&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">keyword</span> <span class="ow">in</span> <span class="n">params</span><span class="p">[</span><span class="s2">&#34;sql&#34;</span><span class="p">]</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span> <span class="k">for</span> <span class="n">keyword</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&#34;DELETE&#34;</span><span class="p">,</span> <span class="s2">&#34;UPDATE&#34;</span><span class="p">,</span> <span class="s2">&#34;DROP&#34;</span><span class="p">,</span> <span class="s2">&#34;TRUNCATE&#34;</span><span class="p">]):</span>
</span></span><span class="line"><span class="cl">                <span class="k">raise</span> <span class="n">SecurityError</span><span class="p">(</span><span class="s2">&#34;危险的SQL操作被拦截&#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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">estimate_cost</span><span class="p">(</span><span class="n">tool_name</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">COST_THRESHOLD</span><span class="p">:</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">request_human_approval</span><span class="p">(</span><span class="n">tool_name</span><span class="p">,</span> <span class="n">params</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="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">after_tool_call</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="n">result</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">contains_sensitive_info</span><span class="p">(</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="bp">self</span><span class="o">.</span><span class="n">mask_sensitive_info</span><span class="p">(</span><span class="n">result</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">result</span>
</span></span></code></pre></div><h3 id="54-性能优化让-agent-跑得又快又省钱">5.4 性能优化：让 Agent 跑得又快又省钱</h3>
<p>企业级应用对性能和成本都很敏感。下面是几个关键的优化手段：</p>
<p><strong>1. 模型分层</strong></p>
<p>不要所有步骤都用 GPT-4。不同的任务用不同的模型：</p>
<ul>
<li>规划和复杂推理：GPT-4 / Claude 3 Opus</li>
<li>简单工具调用：GPT-3.5-Turbo / Claude 3 Haiku</li>
<li>重排序和分类：专用小模型（BGE、BERT）</li>
</ul>
<p>这样可以在保证效果的同时，把成本降低 70% 以上。</p>
<p><strong>2. 结果缓存</strong></p>
<ul>
<li>相同的查询，直接返回缓存的结果</li>
<li>相同的工具调用参数，缓存执行结果</li>
<li>相同的计划，复用之前的执行经验</li>
</ul>
<p><strong>3. 并行执行</strong></p>
<p>如果多个步骤之间没有依赖关系，让 Agent 并行执行，而不是串行等待。</p>
<pre tabindex="0"><code>串行：步骤1 → 步骤2 → 步骤3 → 步骤4（总耗时 40s）
并行：步骤1
      步骤2  → 步骤3 → 步骤4（总耗时 25s）
      步骤3
</code></pre><h2 id="六常见问题与解决方案">六、常见问题与解决方案</h2>
<h3 id="61-agent-陷入死循环怎么办">6.1 Agent 陷入死循环怎么办？</h3>
<p>这是 Agent 最常见的问题：翻来覆去调用同一个工具，或者在几个工具之间来回跳，就是不输出最终答案。</p>
<p><strong>解决方案</strong>：</p>
<ol>
<li><strong>设置最大步数限制</strong>：通常 10-15 步比较合理，超过就强制终止</li>
<li><strong>循环检测</strong>：检测是否有重复的&quot;思考-行动&quot;模式，如果连续 3 步都在做同样的事情，打断并提示 Agent 换个思路</li>
<li><strong>进度评估</strong>：每 3 步让 Agent 评估一下进度，问它：&ldquo;你现在完成了多少？还需要几步？&rdquo;</li>
</ol>
<h3 id="62-agent-工具选择错误怎么办">6.2 Agent 工具选择错误怎么办？</h3>
<p>Agent 经常会选不对工具——明明该查数据库，它非要去搜索；明明该执行代码，它却想直接回答。</p>
<p><strong>解决方案</strong>：</p>
<ol>
<li><strong>更好的工具描述</strong>：工具的 description 写得越具体、越有区分度越好。不要写&quot;数据库查询工具&quot;，要写&quot;当你需要从公司数据库获取结构化数据（销售、用户、订单等）时使用此工具&quot;。</li>
<li><strong>少就是多</strong>：不要给 Agent 太多工具。先从 3-5 个最常用的开始，需要的时候再加。</li>
<li><strong>工具路由</strong>：先用一个专门的路由 LLM 判断该用什么工具，再交给 Agent 执行。</li>
</ol>
<h3 id="63-成本太高用不起怎么办">6.3 成本太高，用不起怎么办？</h3>
<p>一个 Agent 任务可能要花几美元甚至几十美元，大规模应用的话成本会非常惊人。</p>
<p><strong>解决方案</strong>：</p>
<ol>
<li><strong>模型分层</strong>：如前所述，简单任务用便宜的模型</li>
<li><strong>结果缓存</strong>：能复用的结果就复用，不要每次都重新算</li>
<li><strong>设置预算</strong>：每个用户/每个任务有每日预算上限</li>
<li><strong>混合架构</strong>：简单的问题用 RAG 直接回答，只有真正复杂的问题才启动 Agent</li>
</ol>
<h3 id="64-agent-经常幻觉编造不存在的信息怎么办">6.4 Agent 经常&quot;幻觉&quot;，编造不存在的信息怎么办？</h3>
<p>Agent 比纯 LLM 更容易幻觉，因为它会把工具返回的结果和自己想象的内容混在一起。</p>
<p><strong>解决方案</strong>：</p>
<ol>
<li><strong>强制引用来源</strong>：要求 Agent 的每个结论都必须引用具体的工具输出</li>
<li><strong>事实核验</strong>：最后加一个核验步骤，专门检查回答中的事实是否都有来源支撑</li>
<li><strong>置信度评分</strong>：让 Agent 给自己的答案打个分，分低的话标记为&quot;可能不准确&quot;</li>
</ol>
<h2 id="七未来展望">七、未来展望</h2>
<h3 id="71-agent-的发展趋势">7.1 Agent 的发展趋势</h3>
<p><strong>1. 更小、更专门的 Agent</strong></p>
<p>未来不会有一个&quot;万能 Agent&quot;什么都能做。相反，会出现大量小而专的 Agent，每个擅长一个领域，然后通过标准化的协议互相协作。就像微服务架构一样——把一个大单体拆成多个小服务，各司其职。</p>
<p><strong>2. Agent 市场和标准化</strong></p>
<p>会出现像 App Store 一样的 Agent Store，你可以下载别人做好的 Agent，组合起来解决自己的问题。这需要 Agent 接口的标准化、能力的可发现、安全的可审计。</p>
<p><strong>3. 端侧 Agent</strong></p>
<p>把 Agent 跑在用户的手机/电脑上，而不是云端。这样既能保护隐私，又能降低延迟和成本。端侧小模型的快速发展正在让这个愿景成为现实。</p>
<h3 id="72-agent-不会取代人而是让人更强大">7.2 Agent 不会取代人，而是让人更强大</h3>
<p>很多人担心 Agent 会取代人类的工作。但根据我们的观察，<strong>Agent 真正取代的不是人，而是繁琐的流程</strong>。</p>
<p>一个优秀的数据分析 Agent，不会取代数据分析师——它会把数据分析师从&quot;写 SQL、拉数据、做图表&quot;这些繁琐的工作中解放出来，让他们把时间花在更有价值的&quot;分析数据、发现洞察、制定策略&quot;上。</p>
<p>一个优秀的客服 Agent，不会取代客服——它会把客服从&quot;查知识库、走流程、填工单&quot;这些机械劳动中解放出来，让他们把时间花在真正需要同理心和沟通技巧的复杂问题上。</p>
<p>技术进步的历史反复证明：<strong>自动化从来不会减少工作总量，它只是改变了工作的性质。</strong> Agent 也一样——它会把人类从低级劳动中解放出来，去做更有创造力、更有价值的事情。</p>
<h2 id="总结">总结</h2>
<p>从 RAG 到 Agent，我们正在见证 LLM 应用范式的一次重大跃迁：</p>
<ul>
<li><strong>Naive RAG</strong> 让我们看到了把外部知识接入 LLM 的可能性</li>
<li><strong>Advanced RAG</strong> 通过各种优化手段，把准确率提升到了生产可用的水平</li>
<li><strong>Modular RAG</strong> 引入了动态流程编排，让系统更加灵活</li>
<li><strong>LLM Agent</strong> 则带来了质的飞跃——从被动回答问题，到主动解决问题</li>
</ul>
<p>但技术的演进永远不是非黑即白的。RAG 不会消失，它会成为 Agent 众多工具中的一个。Agent 也不会是终极答案，未来还会有更先进的架构出现。</p>
<p>对于企业来说，最重要的不是追逐最酷炫的技术，而是找到适合自己业务场景的方案。先把 RAG 做扎实，需要的时候再逐步引入 Agent 的能力。慢慢来，反而比较快。</p>
<p>技术本身没有价值，<strong>用技术解决真实的问题，才有价值。</strong></p>
<p>（全文完，约 7200 字）</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
