AI Agent架构设计:从直觉到工程的Plan-and-Execute模式解析

📅 发布时间:2026/8/9 3:45:31
AI Agent架构设计:从直觉到工程的Plan-and-Execute模式解析
1. 从直觉到架构为什么“边想边干”在AI Agent里行不通聊到AI Agent很多人脑子里蹦出来的第一个画面可能就是ChatGPT那种一问一答或者让它写个邮件、改个代码它“思考”一下也就是生成一段文本然后直接给出结果。这种模式我们姑且称之为“直接执行”或者“一步到位”。乍一看这很符合我们对“智能助手”的直觉我下指令它干活干净利落。但当你真的想把一个AI Agent部署到生产环境去处理一个稍微复杂点的业务流程——比如自动分析一份几十页的合同、协调多个外部API完成一个订单、或者作为客服处理包含多个意图的用户对话时你就会发现这种“直接执行”的模式脆弱得就像用纸牌搭高楼。为什么核心矛盾在于任务的复杂性与模型能力的局限性之间的冲突。当前的大语言模型LLM本质上是一个基于概率的、擅长“续写”的文本生成器。给它一个明确的、上下文短的指令它能做得很好。但面对一个需要多步骤、有条件判断、有状态依赖的复杂任务时让它一次性生成一个完美无缺的“行动计划执行结果”就相当于让一个顶尖的象棋棋手在看不到棋盘、只能凭记忆的情况下一次性口述出接下来二十步的所有走法以及每一步之后棋盘的确切状态。这几乎是不可能的因为任何一步的微小偏差都会导致后续全盘计划的失效。举个例子你让Agent“帮我查一下明天北京飞上海的航班选最便宜的那个然后看看这个航班对应的酒店有没有特价有的话一起预订。” 这个任务包含了至少四个子步骤1) 查询航班信息2) 筛选最便宜航班3) 根据选定航班的时间和地点查询酒店4) 判断是否有特价并执行预订。如果让模型“一步到位”它很可能会在生成查询航班指令时就“脑补”了一个不存在的航班号然后基于这个错误的航班信息去查询酒店最终给你一个完全虚构的预订结果。整个过程没有纠错机制一旦出错全盘皆输。Plan-and-Execute规划与执行分离架构就是为了解决这个根本矛盾而生的。它的核心思想非常朴素却极其有效把复杂的“思考”规划和具体的“动手”执行拆成两个相对独立的阶段并让它们循环迭代。规划器Planner负责“仰望星空”拆解任务、制定步骤、理清逻辑执行器Executor负责“脚踏实地”调用工具、操作数据、完成动作。执行器每完成一步都会把结果和当前状态反馈给规划器规划器再根据实际情况决定下一步该怎么走或者是否需要调整原计划。这就好比一个经验丰富的项目经理规划器带着一个执行力超强的团队执行器做事。项目经理不会在项目启动第一天就把未来三个月每天要写的每一行代码都规定死而是先制定一个里程碑计划高层规划然后团队每完成一个模块项目经理就根据完成情况、遇到的坑来调整和细化下一个阶段的任务。这种“规划-执行-观察-再规划”的闭环是应对复杂、不确定环境的黄金法则。在AI Agent的语境下它带来了几个决定性的优势提升了任务的可靠性与成功率因为每一步都有检查点增强了系统的可解释性与可调试性你可以清晰地看到Agent的“思考链”实现了更好的错误隔离与恢复某一步工具调用失败不会导致整个任务崩溃规划器可以尝试备用方案。所以当我们谈论生产级Agent时把规划和执行拆开不是一个可选的“优化项”而是一个关乎系统能否稳定、可靠工作的“架构必选项”。它是对大模型能力边界的一种务实承认也是构建真正可用、可控的智能体的工程基石。2. Plan-and-Execute 架构的核心组件与工作流拆解理解了“为什么要拆”我们再来深入看看“拆开了是什么样”。一个典型的 Plan-and-Execute Agent 架构通常由几个核心组件构成它们像精密齿轮一样咬合驱动整个任务流程。这里我们抛开那些花哨的学术名词用最直白的工程视角来拆解。2.1 大脑规划器Planner的职责与实现规划器是整个Agent的“总指挥”。它的输入是用户的初始请求和当前的世界状态比如已有的对话历史、数据库查询结果等输出是一个或多个明确的、可执行的“下一步动作”指令。注意它输出的不是最终答案而是“行动计划”。规划器的核心职责包括任务理解与分解将用户模糊的、高层的目标“帮我安排一个周末旅行”解析并分解成一系列具体的、原子性的子任务[查询天气 查询航班/车次 查询酒店 生成行程单]。逻辑排序与依赖分析确定这些子任务之间的先后顺序和依赖关系。例如必须先确定目的地和日期才能查询酒店或者必须等A API返回了数据才能将其作为参数调用B API。工具选择与参数绑定为每个子任务分配合适的“工具”Tool。工具可以是查询数据库的函数、调用第三方API的接口、操作本地文件的程序等。规划器需要知道每个工具能干什么、需要什么输入并把当前上下文中的信息绑定成正确的参数格式。异常处理与重规划当接收到执行器反馈的错误或意外结果时规划器需要分析原因并决定是重试当前步骤、更换工具、还是调整整个任务计划。实现一个规划器目前主流有两种思路基于提示工程Prompt Engineering这是最直接、最常用的方法。我们设计一个详细的系统提示词System Prompt引导大模型扮演“规划者”的角色。这个提示词通常会包含Agent的职责描述、可用工具列表及其详细说明功能、输入输出格式、输出格式的严格规定例如必须输出JSON包含thought,action,action_input等字段、以及一些规划原则如“一次只规划一步”、“优先使用简单工具”。提示基于提示的规划器其效果严重依赖于提示词的质量和模型的推理能力。实践中需要大量的“调参”调整提示词和测试才能让模型稳定输出结构化的规划指令。一个常见的技巧是使用“少样本示例”Few-shot Examples在提示词中给出几个正确规划的例子让模型模仿。基于代码/状态机Code/State Machine对于业务流程极其固定、逻辑非常明确的场景可以用硬编码的状态机或业务流程引擎来充当规划器。这完全规避了大模型的不确定性稳定性和性能极高但失去了灵活性和泛化能力。通常我们会结合两者用大模型处理灵活的自然语言理解和初步分解然后用预定义的业务规则引擎来细化具体的执行步骤。2.2 手脚执行器Executor与工具Tools生态执行器是“干脏活累活”的。它接收规划器发来的明确指令如{“action”: “search_flights”, “action_input”: {“from”: “北京”, “to”: “上海”, “date”: “2024-05-20”}}然后找到对应的工具函数传入参数运行它并捕获返回结果或异常。执行器的核心职责很纯粹工具路由根据action字段在注册的工具列表中查找对应的函数。参数验证与安全调用检查action_input的参数是否符合工具要求并在一个安全的沙箱或环境中调用工具防止工具执行产生副作用或安全风险。结果封装与传递将工具执行的结果成功或失败封装成一个标准的观察Observation格式返回给规划器。工具Tools是Agent能力的扩展。一个Agent的强大与否很大程度上取决于它的工具库是否丰富、可靠。工具本质上就是一个个函数它们封装了Agent与世界交互的所有能力信息获取工具搜索引擎API、数据库查询、知识图谱查询。计算与处理工具计算器、数据格式转换器、文本分析器。操作与控制工具发送邮件、操作文件、调用业务系统API、控制智能设备。专用领域工具代码解释器、绘图模型、专业领域法律、医疗的查询接口。注意工具的设计至关重要。每个工具应该有清晰、单一的职责稳定的输入输出接口以及良好的错误处理。避免设计“巨无霸”工具这会让规划器难以正确使用。2.3 记忆与状态管理让Agent拥有“上下文”一个健壮的Agent必须有记忆。它需要记住之前的对话、已经执行过的步骤及其结果、以及用户可能提供的额外约束。这通常通过记忆Memory模块来实现。短期记忆/对话记忆保存当前会话的完整历史。这是规划器进行每一步决策时最重要的上下文来源。通常以列表形式存储(Human Input, Agent Thought/Action, Observation)这样的三元组。长期记忆/向量存储对于一些需要记住跨会话知识或从大量文档中检索信息的场景会引入向量数据库。将知识片段向量化存储当规划器需要时通过语义相似度检索相关的信息注入到上下文中。状态State这是一个更工程化的概念指代当前任务执行过程中的所有变量和上下文。它可能包括用户提供的原始目标、已完成的子任务列表、中间生成的数据如查询到的航班列表、以及当前步骤的索引等。良好的状态管理是支持复杂、多轮任务的基础。2.4 完整工作流一次任务的生命周期让我们把上述组件串起来看一个任务从开始到结束的完整流程初始化用户输入请求。系统加载记忆如有初始化任务状态。规划阶段规划器被触发。它结合用户请求、当前记忆和状态进行“思考”。输出格式可能是{thought: 用户想订机票。我需要先查询航班然后筛选。, action: search_flights, action_input: {...}}。执行阶段执行器收到规划结果。它解析action找到search_flights工具用action_input中的参数调用该工具例如调用一个真实的航班查询API。观察阶段工具执行完毕。如果成功返回航班列表JSON如果失败返回错误信息如“网络超时”。执行器将这个结果封装为observation。反馈与再规划observation被送回到规划器。规划器结合之前的“思考”和新的观察决定下一步。如果成功拿到航班列表它下一步可能是{thought: 已获得航班列表现在需要按价格排序并选择最便宜的。, action: filter_and_sort, action_input: {data: [航班列表], by: price, order: asc}}。如果收到“网络超时”它可能会{thought: 航班查询API超时我将重试一次并使用更长的超时时间。, action: search_flights, action_input: {...}, retry_config: {timeout: 10}}或者尝试备用API。循环步骤3-5不断循环直到规划器认为任务已经完成输出最终答案给用户或者任务因无法解决而失败。这个“感知-思考-行动”的循环是Plan-and-Execute架构的灵魂它让AI Agent从一个静态的文本生成器变成了一个动态的、能适应环境变化的自主系统。3. 生产级挑战从Demo到稳定服务的鸿沟在Jupyter Notebook里跑通一个Plan-and-Execute的Demo可能只需要几十行代码。但当你准备把它部署上线接受真实用户和复杂场景的考验时一大堆在Demo里被忽略的问题就会扑面而来。这一章我们就来聊聊那些让工程师们掉头发的生产级挑战。3.1 稳定性第一关规划器的“幻觉”与不可控输出大语言模型作为规划器最大的问题是输出不稳定。你期望它输出一个规整的JSON它可能突然开始写散文你让它选择action它可能发明一个不存在的工具名。这种“幻觉”在生产环境是致命的。应对策略输出格式的强制约束这是底线。不能只靠提示词说“请输出JSON”。必须使用像Pydantic这样的库在代码层定义严格的输出模型Output Parser。当模型的输出无法被解析成预定的结构时立即触发重试或降级处理。例如LangChain框架中的StructuredOutputParser就是干这个的。重试与降级机制一次规划失败不代表任务失败。需要设计分层重试策略首先尝试让模型重新规划可能附带更严格的指令其次可以尝试简化任务或拆解得更细最后降级到预设的故障处理流程比如转人工或返回一个保守的结果。规划验证与过滤在将规划结果交给执行器前增加一个验证层。检查action是否在已注册的工具列表中检查action_input的参数类型和值是否在合理范围内例如日期格式是否正确城市名是否存在。这是一个简单的规则引擎能拦截大部分“低级错误”。给模型“刹车”必须设置最大步数Max Steps限制。防止Agent陷入死循环因为一个逻辑错误而不断规划-执行同一个无意义的动作消耗大量API调用和计算资源。3.2 工具调用的可靠性网络、超时与错误处理执行器调用外部工具尤其是网络API是另一个故障高发区。网络抖动、第三方服务不可用、响应超时、返回数据格式突变……这些问题都需要被妥善处理。应对策略完善的超时与重试为每一个工具调用设置合理的连接超时和读取超时。使用指数退避算法进行重试避免对故障服务造成雪崩。对于非幂等的操作如支付、创建订单重试要格外小心可能需要结合唯一ID来防止重复执行。结果解析与异常封装工具返回的原始数据可能是JSON、XML、HTML需要被稳健地解析。解析失败本身也是一种重要的observation应该被清晰地反馈给规划器例如{error: API响应格式异常无法解析价格字段}而不是一个笼统的“调用失败”。工具健康度检查与熔断实现一个简单的健康检查机制。如果某个工具连续失败多次将其标记为“不健康”暂时从可用工具列表中移除熔断并定期探测其恢复情况。这能防止系统持续向一个宕机的服务发送请求。模拟工具与降级对于关键路径上的非核心工具准备一个模拟Mock版本。当真实工具不可用时可以快速切换到模拟工具返回一个预设的、虽然不精确但可用的结果保证主流程能继续走下去。3.3 成本与延迟在效果和效率间寻找平衡Plan-and-Execute架构意味着多次调用大模型每一步规划都可能是一次LLM API调用和多次工具调用。这直接转化为真金白银的API成本和用户感知的延迟。优化策略规划粒度控制不是所有步骤都需要让大模型规划。对于一些简单的、固定的序列操作可以用预定义的工作流Workflow来替代。例如“查询-过滤-排序”这个组合可以封装成一个复合工具一次规划就触发一个固定的子流程减少LLM调用次数。缓存无处不在LLM响应缓存对于相同的输入提示词其输出规划很可能相同。可以使用缓存如Redis存储(prompt_hash) - response有效降低成本和延迟。工具结果缓存对于一些查询类工具如果参数相同且数据更新不频繁可以缓存其结果。例如查询“北京今天天气”在短时间内结果是相同的。异步执行与流式响应对于耗时较长的任务不要让用户同步等待。可以采用异步任务队列如Celery。Agent快速返回一个任务ID然后在后台执行规划-执行循环并通过WebSocket或轮询向用户推送进度和最终结果。对于生成类任务可以使用流式输出让用户尽快看到部分内容。模型选型与蒸馏在规划阶段可以使用能力足够但更便宜、更快的模型例如GPT-3.5-Turbo对比GPT-4。只有在复杂推理或关键决策时才切换到更强大的模型。甚至可以考虑对提示词进行优化使用思维链Chain-of-Thought等技术用更少的Token达到更好的规划效果。3.4 安全、隐私与合规不可逾越的红线Agent能调用工具意味着它拥有了“行动力”。这同时也打开了潘多拉魔盒。工具权限管控必须实行最小权限原则。不是每个Agent都能调用所有工具。需要根据Agent的角色、用户权限来动态管理工具访问列表。一个处理公开信息的客服Agent绝不应该有访问数据库删除操作的权限。输入输出审查与过滤在用户输入传递给规划器之前以及规划器的输出传递给执行器之前都需要进行安全检查。防止提示词注入Prompt Injection攻击防止模型被诱导执行危险操作或泄露敏感信息。对工具返回的内容也要进行过滤防止恶意内容流向用户。隐私数据保护确保Agent在处理过程中不会将用户的个人身份信息PII不必要地记录在日志或传递给不相关的工具。对于需要用到PII的场景要考虑数据脱敏或使用隐私计算技术。可审计性整个Agent的决策过程规划历史、执行记录、工具输入输出必须被完整地日志记录。这在出现问题时用于复盘在涉及合规审查时作为证据。日志需要结构化便于查询和分析。跨越这些鸿沟没有银弹靠的是细致的工程设计、大量的测试以及一套完整的运维监控体系。一个生产级的Agent系统其复杂度往往不亚于一个微服务架构的Web应用。4. 实战架构选型LangChain与自主构建的深度对比当我们决定要搭建一个Plan-and-Execute Agent时第一个面临的选择就是用现成的框架还是自己从头造轮子目前LangChain无疑是这个领域最流行的框架它提供了丰富的组件和抽象。但“流行”不等于“最适合”。我们来一场深入的对比分析帮你做出选择。4.1 LangChain方案快速上手与生态红利核心优势开箱即用集成度高LangChain最大的优点就是“全”。它预置了与各种LLMOpenAI, Anthropic, 本地模型等、向量数据库Chroma, Pinecone、工具搜索引擎、计算器、Python REPL的集成。你几乎可以用声明式的方式像搭积木一样快速组合出一个可用的Agent。这对于原型验证、概念演示PoC和中小型复杂度的项目来说效率极高。丰富的抽象与模式LangChain定义了Agent、Tool、Memory、Chain等一套清晰的概念。其Plan-and-Execute模式也有现成的实现如PlanAndExecuteAgentExecutor。这强制你遵循一种相对良好的架构实践避免了早期设计上的重大失误。活跃的社区与迭代社区庞大遇到问题时容易找到解决方案或类似案例。框架本身也在快速迭代不断吸收新的研究和工程实践。潜在陷阱与挑战抽象泄漏与黑盒感为了提供通用性LangChain的抽象层有时比较厚。当你想实现一个非常定制化的逻辑或者调试一个深层错误时可能会觉得像是在和框架“搏斗”需要深入理解其内部工作机制学习成本不低。性能开销每一层抽象都意味着额外的函数调用和对象封装。在超高并发或对延迟极其敏感的场景下这部分开销可能变得不可忽视。它的某些设计如大量使用同步操作在纯异步高性能环境下可能需要改造。版本迭代的破坏性更新LangChain发展很快但有时版本间的API变化较大可能导致升级成本较高。对于追求长期稳定的生产系统这需要谨慎评估。“过度设计”风险对于需求非常明确、简单的Agent使用全功能的LangChain可能会引入不必要的复杂性。适用场景快速原型开发、研究探索、对开发速度要求高、团队LLM工程经验不足、以及复杂度中等且不需要极端性能优化的生产项目。4.2 自主构建方案极致控制与深度定制核心优势完全的控制权从网络请求库的选择、到错误处理的重试策略、再到记忆模块的数据结构每一个细节都可以按照你的业务需求和技术栈进行量身定制。你可以打造一个极其轻量、高效、与现有系统无缝集成的Agent内核。性能优化到极致没有中间层你可以采用最直接的异步编程模型如asyncio精细控制缓存策略优化Token的使用将延迟和成本降到理论最低。技术栈统一与简化你的Agent可以直接使用公司内部现有的工具库、监控系统、配置中心无需为LangChain做适配。依赖更少部署和运维也更简单。长期可维护性自己写的代码逻辑清晰可见没有“魔法”。当业务逻辑变更或需要深度优化时修改起来心里有底耦合度低。高昂的成本与风险巨大的前期投入你需要从零开始设计和实现规划器、执行器、记忆、工具管理、错误处理、状态机等所有组件。这是一个不小的软件工程任务需要团队具备较强的架构设计和LLM领域知识。重复造轮子很多LangChain已经解决好的问题比如工具描述的自然语言化、复杂的输出解析、与各种后端的连接器你都需要自己实现一遍。缺乏最佳实践引导自己构建容易在早期陷入错误的设计比如规划与执行耦合过紧、状态管理混乱等导致后期难以扩展。社区支持弱遇到问题只能靠自己或团队内部解决。适用场景超高性能要求的场景如高频交易辅助、与现有复杂系统深度集成、业务逻辑极其特殊且固定、或者团队拥有强大的LLM工程能力并追求长期技术掌控的核心业务。4.3 混合策略与渐进路径在实际项目中纯LangChain或纯自研往往不是非此即彼的选择。一个更务实的策略是“基于框架逐步替换”。第一阶段用LangChain快速验证。在项目初期使用LangChain快速搭建原型验证Agent在业务场景下的可行性。这个阶段的目标是跑通流程收集数据明确需求。第二阶段识别瓶颈局部替换。在原型运行过程中通过监控和 profiling识别出性能瓶颈或功能不适配的地方。例如发现某个自定义工具在LangChain下调用效率很低或者其记忆模块不符合你的需求。这时你可以保留LangChain的核心调度框架但用自己实现的高性能组件替换掉那个特定的模块。第三阶段核心重构走向自主。当业务模式被验证且你对Agent的各个环节都有了深刻理解后如果确实有强烈需求可以考虑以LangChain的设计为参考蓝本用更轻量、更贴合自身技术栈的方式重写核心的执行引擎。此时你重写的是“经过验证的设计”而非盲目创造。这个路径平衡了速度、灵活性和长期利益是很多团队从探索走向成熟生产的真实写照。无论选择哪条路关键在于清晰地认识到框架是工具不是目的。最终的目标是构建一个稳定、高效、可维护的Agent系统来服务业务。5. 避坑指南我在构建Plan-and-Execute Agent时踩过的那些坑理论很美好架构很清晰但真到动手时坑是一个都不会少。这里分享几个我亲身经历或见同行踩过的典型大坑以及填坑的思路。5.1 规划器提示词设计模糊的指令导致混乱的行动坑的描述最初设计规划器提示词时写得很笼统“你是一个助手请根据用户请求和可用工具决定下一步做什么。” 结果发现Agent的行为极其不稳定有时一步规划太多动作有时在一个简单步骤上徘徊不前有时干脆不输出指定格式。根因分析大模型需要极其明确的指令和约束。模糊的指令给了模型太大的“自由发挥”空间而它的“发挥”往往不符合程序逻辑。填坑方案角色扮演与任务边界在提示词开头就明确角色。“你是一个任务规划专家。你的唯一职责是将复杂任务分解为单个可执行的步骤并指定每个步骤使用的工具。”严格输出格式规定使用JSON Schema或类似语法在提示词中明确规定输出格式。并给出2-3个清晰的示例Few-shot Learning。你必须严格按照以下JSON格式输出且只输出这个JSON对象 { thought: 你的推理过程解释为什么选择这个动作, action: 工具名称必须是以下列表中的一个[search_web, calculator, ...], action_input: 传递给工具的输入参数通常是一个字典 }规划原则约束明确告诉模型一些基本原则。例如“一次只规划一个动作。”、“优先使用提供的信息不要捏造参数。”、“如果上一步执行失败分析原因并尝试替代方案。”工具描述清晰化为每个工具提供准确、无歧义的名称、功能描述和参数示例。避免使用语义相近的工具名。5.2 状态管理混乱在多轮对话中迷失自我坑的描述Agent在处理一个多轮对话的长任务时比如边聊边订机票经常“忘记”之前已经执行过的步骤或者把不同用户会话的状态搞混。根因分析没有设计清晰、隔离的状态管理机制。简单地把所有对话历史扔进上下文导致上下文过长、信息过载且不同会话间相互污染。填坑方案设计专用的状态对象定义一个SessionState或TaskState类结构化地存储当前任务的核心信息。例如class BookingState: task_id: str user_goal: str # 原始目标“订北京到上海机票” current_step: int completed_steps: List[StepRecord] # 记录已完成的步骤和结果 extracted_data: Dict # 如 {“flights”: [...], “selected_flight”: {...}} constraints: Dict # 用户后续增加的约束如“不要早班机”状态驱动规划规划器的输入不仅是当前用户消息和对话历史更重要的是这个结构化的State。规划器根据State来决定下一步执行后更新State。会话隔离为每个用户或每个对话线程创建唯一ID并以此作为键来存储和检索状态。使用Redis或数据库进行持久化确保服务重启后状态不丢失。5.3 工具设计不当要么太胖要么太瘦坑的描述工具太“胖”设计了一个handle_travel_booking的工具它内部自己完成了查询、筛选、支付所有逻辑。这导致规划器无法进行精细控制出错时也难以定位。工具太“瘦”把add(加法)和multiply(乘法)分成两个工具。这导致规划器需要多步无意义的规划来完成一个简单计算(ab)*c增加了延迟和出错概率。根因分析对“单一职责”原则的理解偏差。工具的粒度需要与规划器的“决策粒度”相匹配。填坑方案原子性与可组合性一个工具应该完成一个原子性的、不可再分的操作并且其输出应该能作为其他工具的输入。例如search_flights查询航班、filter_by_price按价格过滤、select_item选择一项就是一组粒度合适的工具。识别业务逻辑单元工具的边界应该围绕业务逻辑的自然单元来划分。对于(ab)*c这样的纯计算一个calculate工具接受一个表达式字符串是更合理的设计。提供复合工具可选对于一些非常高频、固定的操作序列可以封装成“复合工具”或“子流程”。但这应该在规划器之上的一层进行管理或者作为特殊工具提供给规划器选择而不是取代细粒度的规划。5.4 无限循环与资源耗尽忘记给Agent上“保险丝”坑的描述Agent在遇到一个它无法解决或逻辑矛盾的任务时陷入了“规划-执行-失败-再规划-再执行”的死循环直到API调用配额耗尽或超时。根因分析没有设置任何安全护栏。Agent像一辆没有刹车的车一旦启动就只能撞墙停下。填坑方案设置硬性步数限制这是最基本的保险丝。在Agent执行循环外设置一个计数器比如最大50步。达到上限后强制终止任务并返回友好错误信息。检测重复与无进展在状态中记录最近N步的(action, action_input)组合。如果检测到完全相同的动作序列在循环说明陷入了死胡同应主动终止或尝试重置。成本预算监控实时累计本次任务消耗的Token数特别是输入给大模型的Token和外部API调用费用。设置一个预算上限超标即止。超时控制为整个任务设置一个总执行时间上限防止长时间挂起。踩过这些坑之后我最大的体会是构建生产级Agent五分在算法五分在工程。你需要像对待一个分布式微服务系统一样去考虑它的稳定性、可观测性、安全性和成本。那些在Demo里运行流畅的代码一旦放到真实流量下每一个假设都可能被打破。而Plan-and-Execute架构的价值正是在于它通过清晰的分离让这些工程问题变得更容易被定位、被监控、被解决。它为你提供了一个坚实的框架让你可以把精力更多地花在解决业务逻辑本身而不是在混乱的代码中挣扎。