
先说一个现象打开任何技术社区刷三屏必有一个帖子在聊智能体。人人都在写 Agent但以我在实际项目里看到的大部分所谓“智能体”其实只是给大模型套了个 if-else 循环本质上还是硬编码流程。直到 Anthropic 把《Building Effective Agents》这篇工程笔记发出来很多人才第一次意识到智能体工程里的坑从第一天就埋下了。这篇笔记不长但信息密度很高里面没有炫技全是工程取舍。今天我就把里面的架构要点挑出来结合我自己在多个项目里踩过的坑把它彻底讲清楚。这篇文章适合谁如果你正在做大模型应用开发准备把业务接到 LLM 上或者你已经被“智能体”这个词绕晕了那这篇就是给你扫盲的。我尽量用大白话配上可复用的代码片段和避坑清单读完你至少能搞清楚一个问题到底什么样的系统值得做成智能体什么样的系统老老实实写成工作流就行。1. 先把概念理清工作流和智能体到底差在哪里1.1 大模型原生能力与工程补丁先回顾一个底层事实大模型本身只是一个概率模型输入一串 token输出一串 token。聊天、写作、翻译这些场景模型直接干就行。但一旦你要让模型去查数据库、调接口、操作文件、做决策模型天然做不到因为它只能“说”不能“做”。所以所有智能体项目本质上都在做一件事给大模型补上执行能力然后在外面套一层控制逻辑。这层控制逻辑怎么设计直接决定了你这个系统到底算工作流还是算智能体。Anthropic 的笔记里给了一个很朴素但极好用的定义工作流Workflow是预定义代码路径的编排智能体Agent是模型自主决定流程和工具使用的系统。关键区别不在有没有工具而在决策权在谁手里。如果一段流程你事先就知道该怎么走比如“先总结用户问题再查知识库再生成回复”这就是工作流。如果一个问题你根本不知道要调几个工具、按什么顺序调需要模型自己边试边调整那才是智能体。1.2 Anthropic 给出的划分标准Anthropic 原文把系统分成了五类工作流加一类真正的 Agent这个分类我建议你直接背下来Prompt Chaining提示链把一个复杂任务拆成多个步骤前一步的输出是后一步的输入。Routing路由先把输入分类再分发给不同的处理流程。Parallelization并行化同一个任务拆成多个子任务并行处理或者多个模型同时给答案然后投票。Orchestrator-Workers编排者-工作者一个主模型拆分任务多个子模型或工具分别执行再由主模型汇总。Evaluator-Optimizer评估器-优化器一个模型生成另一个模型评估迭代优化。Autonomous Agent自主智能体模型在环境中自主决策多轮调用工具处理复杂独立任务。这套分类最大的价值是给你一颗定心丸不是所有任务都要上 Agent大部分场景用前五种工作流就够了而且更稳、更便宜、更容易排查。1.3 什么时候不该做自主智能体我见过最典型的问题是产品经理一听“Agent 能做决策”立刻想把所有功能都改成自动决策。后果就是系统变得不可预测用户骂街开发天天救火。Anthropic 在笔记里反复强调一个观点简单任务用最直接的方式解决不要为了智能体而智能体。如果用户问一句“我的订单到哪了”你根本不需要一个能自主决定调用工具顺序的 Agent只需要一个路由把订单查询请求转发给订单系统把售后请求转发给客服系统这比任何花哨的 Agent 都稳定。什么时候该上自主智能体Anthropic 给了一个条件当任务的步骤不可预测、需要动态调整工具选择时。比如“帮我整理一份行业研究报告包含主要玩家的策略对比”这个过程可能要搜网页、读 PDF、对比数据、写摘要顺序不定工具不固定这才适合 Agent。2. 构建前的底层能力检索、工具、记忆2.1 检索增强不是模型能力而是工程外挂很多文章把检索增强生成RAG当成模型能力来吹但从架构角度说RAG 就是你给模型挂了一个外部硬盘。Anthropic 的笔记明确把检索列为增强 LLM 的三种基本能力之一另外两个是工具和记忆。工程实现上RAG 的核心是三个问题文档怎么切、向量怎么建、结果怎么筛。我在项目里常用的做法是先按章节或语义段落切分控制在 500 到 1000 个 token 一段然后建向量索引。检索的时候不要只取 top1取 top5 到 top10让模型自己判断哪些相关内容有用。这里有个容易踩的坑检索结果长度要把控别把几万字的资料一股脑塞进上下文模型会迷失在噪声里回答质量反而下降。2.2 工具调用是智能体的“手”工具调用Tool Use / Function Calling是所有 Agent 的物理基础。Anthropic 说得直白没有工具调用能力模型就只能聊天不能干活。所以在 Claude 的 API 里工具是通过 JSON Schema 定义的模型在回答中会输出一个结构化的工具调用指令然后由你的代码去真实执行。这里我放一个最基础的例子用 Anthropic 官方 Python SDK 定义一个查询天气的工具import anthropic client anthropic.Anthropic(api_keyyour-api-key) def get_weather(location: str, unit: str celsius) - str: # 实际项目中这里对接真实天气 API return f{location} 当前温度25{unit} tools [ { name: get_weather, description: 查询指定城市的实时天气。location 必须是城市名unit 可选 celsius 或 fahrenheit。, input_schema: { type: object, properties: { location: {type: string}, unit: {type: string, enum: [celsius, fahrenheit]} }, required: [location] } } ] response client.messages.create( modelclaude-3-5-sonnet-20241022, max_tokens1024, toolstools, messages[{role: user, content: 北京现在多少度}] ) # 解析返回结果判断模型是否要求调用工具 if response.stop_reason tool_use: for block in response.content: if block.type tool_use: result get_weather(**block.input) # 把工具结果回传给模型 print(f工具返回{result})这里有三个细节值得注意。第一description一定要写清楚工具的适用场景和参数规则模型就是靠这段描述来判断何时调用它的第二工具执行的结果要返回给模型继续推理这是多轮工具调用的基础第三工具函数要做好异常处理出错时把错误信息也返回给模型让它自己决定下一步怎么处理。2.3 记忆上下文管理才是真门槛记忆这件事Anthropic 在笔记里讲得并不复杂但在实际工程里是最难伺候的一块。模型本身有上下文窗口限制你不能把所有历史对话都塞进去成本高、响应慢、效果还会下降。我的做法是把记忆拆成两层。短期记忆放在对话上下文中只保留最近几轮超过之后做摘要压缩长期记忆存在外部存储里比如向量数据库需要时通过检索拉回。这其实就是给模型做了一个“人”一样的记忆结构工作记忆有限长期记忆靠检索触发。有一个很反直觉的经验不是所有历史都值得记住。有些团队拼命做记忆模块把所有对话都存下来结果模型被一些无关信息带偏。正确的做法是给记忆打上结构化标签比如用户意图、业务状态、关键偏好只有这些内容值得沉淀。3. 五种工作流模式的逐个拆解3.1 Prompt Chaining把复杂任务拆成流水线Prompt Chaining 的逻辑最好理解一个任务太复杂一个 prompt 做不了就拆成多个步骤每步一个 prompt串行执行。Anthropic 用了一个很好的比喻每一步都像一个工序前一步的输出是后一步的原料。我实际用过的一个场景是内容生成流水线第一步写大纲第二步根据大纲展开内容第三步润色。每一步都是独立的 LLM 调用输出单独校验发现问题可以直接定位到具体环节。伪代码大概是这样的def generate_article(topic): outline llm_call(规划文章大纲, topic) draft llm_call(根据大纲写初稿, outline) polished llm_call(润色初稿, draft) return polished这种模式胜在可预测、易调试。缺点是每一步都在增加延迟和 token 成本而且如果第一步的输出质量差后面所有步骤都会跟着崩。所以使用 Promp Chaining 时我强烈建议在关键节点加入校验逻辑比如第一步输出大纲后先检查是否包含目标章节不合格就直接重试不要进入下一步。3.2 Routing给问题分诊台Routing 是解决“一类请求多种处理路径”问题的标准方案。Anthropic 是把 Routing 单独列出来的但我理解它更像一个分诊台先让模型判断输入属于哪一类然后把它分发到对应的处理流程里。一个我经常举的例子是客服系统。用户消息进来先让模型判断意图是投诉、退款、物流查询还是商品咨询然后不同意图走不同的处理链。这比让一个 prompt 处理所有类型要稳定得多因为每一类问题的处理逻辑、工具、话术都不一样。关键实现细节在于分类方式。Anthropic 在笔记里特意提了一个小技巧给模型 N 个固定分类选项并且一定加一个“其他”选项这比让模型自由发挥打标签要可靠得多。我测试过固定分类的准确率明显更高因为模型本质上是做选择题而不是做填空题。3.3 Parallelization同时开工互不干扰Parallelization 适用于子任务之间没有严格依赖的场景。Anthropic 把它分成两类一是把一个任务切成独立子任务分别执行最后汇总二是多个模型做同一件事最后投票选出最优答案。切分子任务这种并行方式我常用于代码审查场景。比如我给代码同时跑三个检查一个看安全漏洞一个看性能问题一个看代码风格三个检查互相独立可以并行调用最后把结果合并成一份审查报告。这样比单线程串行检查快得多而且每个检查的 prompt 都很专一质量也明显更高。投票式并行更奢侈适合对准确性要求极高的场景。比如翻译任务同时让三个不同参数的模型翻译同一段话再让第四个模型选出最好的一版。效果确实更好但 token 成本大概翻三倍你自己算算值不值。3.4 Orchestrator-Workers主模型当项目经理Orchestrator-Workers 的结构是一个主模型负责拆任务、派活、汇总子模型或工具负责干活。这是很多人心中“智能体”的雏形很多 Agent 框架的核心就是这个模式。Anthropic 给出的适用场景是任务可以切分成多个子任务且子任务的边界不可预知需要动态规划。比如“帮我分析这份财报”主模型先判断需要做哪些步骤提取关键指标、对比上期数据、查询行业新闻、生成分析结论然后派给不同的 Worker最后汇总。这里最需要注意的一个问题拆分任务的质量决定了整个系统的上限。如果主模型拆出来的子任务本身含糊不清Worker 再强也做不出好结果。我习惯于在 prompt 里明确要求主模型按“任务目标-子任务清单-每个子任务的明确交付物”格式输出同时限定子任务数量不要拆得太碎。3.5 Evaluator-Optimizer生成与反馈的循环Evaluator-Optimizer 是一个很有意思的模式一个模型负责生成内容另一个模型负责挑毛病迭代几轮直到满意。Anthropic 把它形容成一个人写稿、另一个人审稿的过程。我常用它来做文案优化。生成初稿之后让评估模型按几个维度打分语气是否友好、信息是否完整、专业度是否足够然后给出修改意见再让生成模型根据意见修改。每次循环多花一份 prompt 的钱但输出质量确实肉眼可见地提升。不过这个模式很容易陷入无限循环。我的做法是设置最大迭代次数比如最多三轮同时把评估标准写具体不要让评估模型输出“整体还行”这种空话逼它给出可执行的修改建议。评估模型输出质量不行整个循环就是浪费钱。下表把这五种工作流模式做个对比方便你快速选型模式核心逻辑适用场景主要风险Prompt Chaining串行分步内容流水线、数据处理前序错误会传播Routing先分类再分发客服分流、意图识别分类错误会被放大Parallelization并行子任务或投票代码审查、多方案对比token 成本高Orchestrator-Workers主模型调度子任务复杂分析、研究任务任务拆分质量难保证Evaluator-Optimizer生成-评估-迭代文案润色、翻译优化可能陷入无限循环4. 自主智能体的设计与边界4.1 什么任务真的需要自主智能体Anthropic 在笔记里很谨慎自主智能体不是默认选项而是最后手段。什么任务才够格关键判断标准是任务路径本身不可预测且需要模型根据环境反馈动态调整。我举一个实际项目写自动化研究报告。这个任务的步骤确实没法提前固定。今天用户要研究“新能源汽车市场”明天要研究“半导体供应链”需要搜什么、需要读哪些报告、需要对比哪些数据全都未知。这种场景我确实用了 Agent 架构让模型自己规划检索路径根据已获得的信息决定下一步做什么。但如果你问他“帮我查一下明天天气”这种任务永远不该用 Agent。一眼就能看到终点直接调工具取数返回就好。4.2 工具集设计与环境搭建自主 Agent 的能力边界完全由工具集决定。工具多不代表好工具杂反而让模型选择困难。Anthropic 的建议非常实际每个工具都要有清晰、完整的描述并确保工具实现足够简单可靠。工具本身的 bug 会直接表现为 Agent 行为的不可预测这是最难排查的。环境搭建也要注意。如果 Agent 需要执行代码一定要跑在沙箱里限制网络和文件系统访问。如果 Agent 需要访问外部系统尽量用只读权限起步确认行为稳定后再逐步放开。这个原则我吃了很大教训早期一个 Agent 因为环境未加沙箱执行了一段意外代码把测试库的数据改乱了。4.3 护栏设计给 Agent 戴上笼头自主智能体最让人不安的是它的“自主性”所以护栏不是可选而是必须。Anthropic 在笔记里强调的护栏和我在工程里的做法基本一致归纳起来就几条最大步数限制给 Agent 设一个工具调用次数的上限比如 15 次超过就停止并向用户解释。关键动作人工确认涉及资金操作、删除操作、对外发布等高危动作必须停下来等人工批准。Token 预算限制每个 Agent 会话设置 token 上限防止单个任务耗尽配额。输出结构约束要求 Agent 在关键节点输出结构化中间结果而不是自由文本便于程序校验。有一个经验也很重要Agent 的任务目标要写得足够具体。给它一个模糊指令它会给你一个模糊的结果而且还会自作主张做一堆你没要求的操作。任务描述越清晰Agent 才越像专业员工而不是一个兴奋的实习生。5. 工程化落地框架怎么选API 怎么用5.1 框架与原生 API 之争Anthropic 在笔记里对框架的态度非常务实框架能帮你快速起步但隐藏了底层细节遇到问题排查困难而直接调用模型 API 写代码起初慢但完全可控。所以它的建议是先从直接调用 API 开始理解每一步发生了什么再决定要不要用框架。我自己同意这个方向。现在市面上的 Agent 框架很多有些确实方便但你得付出“黑盒”的代价。框架帮你封装了循环调度、记忆管理、工具分发出了问题你根本不知道卡在哪一环最后还得去翻框架源码。如果你追求的是业务的稳定性建议核心逻辑自己写把框架只当成一个辅助工具。不过我也要补充一点如果你只是做原型验证用现成的开源框架或者商业化平台比如 Coze、Dify确实快得多。平台帮你解决了模型接入、工具配置、可视化编排适合快速试错。但一旦要上线生产、做深度定制还是要回到代码层面。5.2 工具描述写法细节决定成败工具调用的可靠性很大程度上取决于工具描述写得怎么样。Anthropic 在笔记里明确提醒工具描述要完整、清晰让模型知道该在什么时候使用它。这段描述是模型做决策的重要依据绝不是随便写写的注释。我建议描述里至少要包含这几部分工具做什么、什么场景下用、参数是什么格式、有没有限制条件、错误返回长什么样。举个例子{ name: search_documents, description: 在内部知识库中搜索与用户问题相关的文档。适用于查询公司制度、产品手册、技术规范。搜索关键词越具体结果越准确。返回最多5条结果每条包含标题和摘要。, input_schema: { type: object, properties: { query: {type: string, description: 搜索关键词尽量使用原文中的专业术语} }, required: [query] } }注意最后我给 query 参数也加了描述。参数描述不要偷懒它直接决定模型能不能正确填参数。我还见过一个更高级的玩法在描述里写“当用户问到 X 时使用”等于给模型做了一次 few-shot 提示。实测这方法在工具数量超过 10 个时特别管用。5.3 结构化输出与中间校验很多人忽略一个问题模型输出自由文本你怎么判断它做得好不好Anthropic 的建议是让模型在关键节点输出结构化数据比如 JSON然后用代码去校验。这比让模型自己说“我完成了”可靠得多。我在每一个工作流模式的组件里都加了中间校验。比如生成文章大纲后要求模型必须输出 JSON包含“title”“sections”两个字段然后我用代码校验 sections 是否为空、是否满足模板。不满足就让模型重写。这一招能拦下大部分低级错误从源头减少故障。实现结构化输出有几种方式最简单的是在 prompt 里指定输出格式高级一点可以用 Claude 的强制 JSON 输出。但注意格式越复杂模型越容易出错所以中间结构尽量精简只在业务关键节点使用。5.4 测试与追踪没有观测就没有优化智能体系统的测试和传统软件测试很不一样。传统程序是确定性的输入相同输出一定相同智能体系统是概率性的同一个输入跑三次可能三个结果。所以测试策略要换思路。核心方法是建立回归评测集准备 20 到 50 个代表业务场景的测试用例固定测试参数每次代码改动都跑一遍人工打分会话质量。Anthropic 在笔记里也提到了类似做法把人类的反馈和评估结果加入到提示词和测试样例里持续迭代。另外一定要做好日志追踪。每次 LLM 调用、每个工具调用、每一步决策都要记录上下文摘要、模型响应、耗时、token 数。没有这些数据出了问题你连定位都做不到。我见过很多团队连日志都不打Agent 出错了只能靠猜这种项目基本走向是推倒重来。6. 常见问题与排查实录6.1 智能体陷入死循环这是我遇到最多的一个问题Agent 反复调用同一个工具每次得到结果都继续调始终无法收敛。核心原因是任务目标定义模糊或者工具结果不符合模型的预期。我的排查步骤很固定。先看日志确认循环调用的是哪个工具然后检查这个工具的返回格式是否与描述一致最后检查任务 prompt 是否明确告诉模型“什么情况下算完成”。多数时候不是模型笨是你没告诉它终点在哪。如果真出现死循环直接靠护栏兜底设置最大迭代次数到次数强制退出并返回已做的部分结果。这一步必须在架构初期就设计进去别等出问题再补。6.2 工具调用返回格式解析失败模型输出的工具调用参数偶尔会出现格式不完整或者类型不对尤其是参数很多的情况下。我的缓解方案是解析工具调用参数时用容错解析失败后把错误信息返回给模型要求它重新生成合法的工具调用参数。这里有个细节不要对模型的 JSON 输出做太苛刻的校验。它偶尔会在 JSON 里夹带一些多余字段或注释如果直接报错整个链路就断了。宽容一点用解析库尽量提取可用字段解析失败才重试。Anthropic 的 SDK 本身也做了容错处理但业务代码里再兜一层更稳。6.3 模型不调用该用的工具有段时间我做测试发现模型经常答非所问明明需要查数据它却凭记忆回复。排查后定位到原因工具描述写得不够明确模型根本不知道有这回事。解决办法有两条路。首选是加强描述在工具描述里增加“当用户问到时必须调用此工具禁止根据已有知识回答”这种强约束。如果加了强约束还是无效就使用 few-shot 示例在 prompt 中给一个对话样例明确展示调用工具的时机。这两招能解决绝大多数工具选择问题。6.4 上下文爆炸导致效果崩塌Agent 每多一轮工具调用工具返回结果就多占一段上下文。几十轮下来早期信息被淹没模型忘掉了最初的用户意图回答质量严重下降。在 Anthropic 笔记里虽然没有展开但这是 Agent 架构最普遍的工程问题之一。我的处理方式是分层摘要每几轮对话后把前面的内容压缩成一个摘要只保留关键事实、中间决策、未完成目标。工具调用结果也要摘要化只保存提取后的结构化数据不要把原始大文件留在上下文中。预算敏感的项目可以把长期信息外置到向量库里不再直接暴露给上下文。6.5 稳定性不足时的降级策略确定一个原则没有一个 Agent 是永远稳定的必须设计降级路径。我的做法是给每个 Agent 任务都预设一个传统工作流兜底版本。比如 Agent 自动分析投资数据失败时可以降级为让用户手动选择图表模板由提示链生成报告。这样即使 Agent 表现不佳业务也不至于完全不可用。我对智能体开发的整体体会Anthropic 这份架构笔记最让我服气的地方是它把“克制”讲成了方法论。现在的行业氛围总喜欢把一个单词往天上吹好像不用 Agent 就显得不够先进。但真实世界里90% 的业务任务其实用一个结构良好的工作流就能解决剩下 10% 才需要上自主 Agent。从我个人的实际工程经验看更靠谱的路线是反着来的先用最简单的 Prompt Chaining 和 Routing 把主流程跑起来观测模型在哪些环节出错再逐步引入更复杂的编排模式。如果你一上来就搭一个全自主 Agent最后大概率会花大量时间对付不可控性而不是解决业务问题。最后再分享一个小技巧每天盯一遍日志里 Agent 的每一次决策路径比看任何架构文档都有用。你会在里面看到模型是怎么被工具描述误导的怎么被上下文带偏的这些真实个案才是你后续优化 prompt 和工具设计的最佳素材。智能体开发不是一锤子买卖它是一场持续调优的工程实践谁把观测和迭代做扎实了谁就能真正把“花架子”变成生产力。