
过去半年我把大量业余时间砸在了 AI Agent 上从最开始用提示词拼出一个会搜索的工具到后来搭多 Agent 协作流程中间踩坑无数。现在回头看很多经验其实是反直觉的能让 Agent 稳定跑起来的往往不是更聪明的模型而是更笨的工程约束。这篇就把我用 AI Agent 攒下来的那些小经验一次性说清楚适合正在摸索 Agent 开发、想从 Demo 走向可用的人。1. 先别急着上框架Agent 是什么以及我踩的第一个坑1.1 我以为 Agent 是更聪明的 ChatGPT我第一次接触 Agent 时的理解非常朴素就是给大模型加个能上网、能执行代码的能力。拿到的第一个 Demo 也确实是这样输入一个问题模型自己去查资料、算一下最后输出答案。当时我下意识觉得Agent 不过是个加强版对话机器人只要模型够聪明什么都能自己搞定。这个理解坑了我很久。因为当我把任务从查个天气变成帮我对齐这个季度的经营数据并生成分析报告时模型开始胡说八道。它不是不知道怎么做而是不知道自己已经做错了。比如它调用了查询接口但参数传错了结果它不重新调用而是根据错误返回结果硬编了一段看起来合理的回答。这才是 Agent 和 Chatbot 的本质区别Chatbot 只需要生成文本Agent 是在一个真实环境里反复决策和行动。模型生成的不只是回答而是下一步动作。如果动作链条里任何一个环节出错后面全是错的。所以 Agent 的核心不是模型多聪明而是你能不能控制住这个决策—行动—观察—再决策的循环。1.2 真正的 Agent 是模型 工具 循环后来我把 Agent 拆成了三个部分才算真正理解模型负责理解目标、拆解任务、决定下一步调用什么工具。工具模型可以调用的函数比如搜索、计算、读写文件、发请求。循环不断把工具执行结果反馈给模型让它可以继续决策直到任务完成或达到终止条件。这个循环就是 Agent 的发动机。我踩的很多坑都出在循环上没有最大步数限制模型会陷入无限调用工具返回异常时没有兜底模型就会基于错误数据编故事终止条件不清晰任务明明完成了模型还在那里继续优化输出。一个健康的 Agent 循环长这样模型收到用户目标规划第一个动作调用工具拿到结果判断结果是否符合预期再决定是继续调用还是直接给用户最终答案。每一步你都要有护栏而不是让模型自由发挥。2. 把第一个 Agent 跑通我的万能起手式2.1 选型先提示词加工具函数不急着上框架很多教程一上来就让你用 LangGraph、AutoGen 这些框架我个人的建议是相反第一个 Agent 不要用框架用最原始的循环手写。原因很简单框架解决了复杂问题的同时也把你的注意力从理解问题转移到了学习框架上。我第一次直接用框架写光搞明白它的状态管理就花了两天最后发现我的需求根本用不到那些功能。反而是后来我手写了一个 100 行左右的循环把整个流程吃透了再回头看框架很快就知道它每一层在帮我做什么。选型上我现在的原则是单轮任务、工具少于五个、不需要复杂人工介入直接手写循环就行。一旦出现多分支决策、人工审核节点、需要断点恢复再考虑上框架。框架是给编排复杂流程用的不是给让模型多调用几个工具用的。2.2 最小闭环模型、工具、循环的三件套我分享一下我最常用的最小实现Python 加 OpenAI 风格接口几十行就能跑通import json from openai import OpenAI client OpenAI() TOOLS { search_docs: lambda query: f模拟搜索关于{query}的文档, calculate: lambda expr: str(eval(expr)) } SYSTEM_PROMPT 你是一个能调用工具的助手。当你需要工具时请返回如下格式 {tool: search_docs, args: {query: ...}} 如果已经能得到答案直接输出最终结果。最多执行5步。 def run_agent(task: str): messages [{role: system, content: SYSTEM_PROMPT}, {role: user, content: task}] for _ in range(5): resp client.chat.completions.create( modelgpt-4o-mini, messagesmessages, temperature0 ) content resp.choices[0].message.content.strip() try: action json.loads(content) tool_name action[tool] result TOOLS[tool_name](**action[args]) messages.append({role: assistant, content: content}) messages.append({role: user, content: f工具结果{result}}) except json.JSONDecodeError: return content return 达到最大步数任务未完成 print(run_agent(搜索AI Agent相关资料并计算1020的结果))这确实简陋但它把 Agent 最重要的骨架搭出来了模型根据当前对话状态输出结构化动作程序解析动作并执行工具结果再塞回上下文。你把这套循环看懂了后面用任何框架都很快。2.3 从能跑到能用我要补的细节跑通循环之后真正让它稳定干活还要补几个细节顺序很重要最大步数限制不只是防止死循环更是防止账单爆炸。我一般根据任务复杂度设置 5 到 15 步。工具描述要具体模型是根据函数名和参数名来选择工具的描述越模糊调用越乱。我会在工具的 docstring 里写明什么情况用、参数是什么格式、典型示例。终止条件要写在系统提示词里明确告诉模型当工具结果已经满足用户需求时必须停止并输出最终结果。否则模型经常多做无谓动作。解析失败要兜底模型偶尔会返回自然语言而不是 JSON这时候要让它重新格式化而不是直接报错给用户。这些细节看起来都是小事但结合到一起才让 Agent 从演示能跑变成每天都能稳定跑几十次。3. 框架和编排LangGraph、Claude Agent Skills 这些我实际用过之后的排序3.1 别让我推荐最好的框架先看你需要哪种抽象我实际体验过几类框架和方案简单列个表给你参考方案核心抽象适合场景我的体感手写循环自己控制 messages 和工具执行小工具、单场景最可控调试成本最低LangGraph图节点 边 状态复杂流程、分支、人工审核功能强但学习曲线陡AutoGen / MetaGPT多智能体对话协作探索性任务、模拟团队看起来炫落地慢Claude Agent Skills一套带描述的技能文件包给 Agent 加可复用的领域能力轻量适合快速扩展工具我不太认同越重的框架越专业这个说法。我见过不少项目业务逻辑本来很简单上了重型框架后光是状态同步就出了二十多个 bug。框架的选择本质上是在买编排能力而不是买模型能力。3.2 LangGraph 的图结构到底解决了什么问题LangGraph 是我目前用得最多的框架因为我确实有流程拆分的需求。它最核心的东西是状态图把整个 Agent 流程定义成一张图每个节点是调模型、执行工具、人工审核这类动作边代表状态迁移条件。它解决了我手写循环时最难受的三个问题。第一条件分支我可以根据工具返回结果决定走哪条边比如发现数据缺失就去做数据校验而不是一股脑往下走。第二人工介入在关键节点停下来等人工确认再继续这在真实业务流程里太重要了。第三断点恢复某一步超时失败后可以从那个节点重跑不用整个任务从头上再来。但它的代价也很直接逻辑被拆散到多个节点和状态里调试时要同时看图结构、状态快照、各节点的输入输出。我每次改一个节点都要重新审视整张图的边是否还用得上。所以我的建议是先手写循环验证你的流程真的需要这些能力再迁到 LangGraph。3.3 Agent 记忆别一上来就上全套记忆系统关于 Agent 记忆我的经验是四个字克制使用。很多人一谈 Agent 就想到向量数据库、长期记忆、知识图谱我一开始也这样结果把记忆做成了最大的不稳定因素。最基础的记忆就是上下文窗口里的短期记忆模型能看到之前的对话和工具结果这个在简单的单轮任务里完全够用。当你发现任务需要跨轮保持用户偏好、项目背景时再考虑会话摘要每轮结束后把关键信息压缩成一段摘要下一轮带上。这个比直接把全部历史塞进上下文便宜得多效果也足够。长期记忆我目前只在特定场景用比如用户画像、历史决策记录。做法也很朴素把重要的状态写入数据库在 Agent 启动时检索相关记录注入上下文。没有必要为了记忆这个概念去维护一个复杂的记忆层先问自己这个记忆是为了解决哪个具体问题如果没有明确答案先不做。4. 让 Agent 稳定干活并发、重试、测试、可观测4.1 怎么扛并发别狂开线程先上任务队列AGI 的并发问题我实际遇到过。最笨的方法是用户点一下 Agent 就同步跑一次但 Agent 内部会循环调用模型一个请求可能要十几秒甚至几十秒。如果同时来十几个请求直接就把模型 API 的并发配额打满然后各种超时、限流报错全出来了。我踩过这个坑之后的改进方案是把所有 Agent 请求放进一个异步任务队列用固定数量的 Worker 去消费而不是每个请求动态开线程。这样一是能平滑控制对模型 API 的请求速率二是方便做超时和重试。队列选型上简单场景用 Redis 加 RQ 就够了重一点、需要分布式消费的用 Celery 或 Temporal。关键不是队列中间件多高级而是队列后面要挂重试逻辑和死信处理。Agent 任务天然不稳定一次失败往往值得重试两三次但也不能无限重试要设定最大重试次数失败超过阈值就进入人工处理队列。4.2 输出不稳定是常态结构化输出、校验、重试模型输出不稳定是 Agent 头的最大障碍我从来没遇到过连续一百次调用全都完美返回 JSON 的情况。最常见的错误是字段漏掉、格式多了一个逗号、参数名拼错、甚至直接把自然语言当作工具调用结果。我的处理方式分三层。第一用结构化输出约束。各家模型基本都支持response_format参数让它强制返回 JSON能把格式错误率降一个数量级。第二做运行时校验。每次拿到模型返回不直接当作合法动作先校验字段完整性和参数类型不合格就把错误信息返回给模型让它重新生成。第三限次重试。我一般允许模型同一轮重新格式化三次三次都失败就走降级逻辑要么放弃该动作要么直接问用户。这三层下来我实际项目里的工具调用成功率能从 70% 拉到 95% 以上。剩下的 5% 仍然会出错这就需要日志和人工兜底不要追求 100% 完美。4.3 给 Agent 写测试单测工具、集成测流程、回归测 Prompt很多写 Agent 的人不做测试理由是模型行为没法断言。但我现在的看法是正因为模型不稳定才更需要测试。我把 Agent 的测试分成了三类工具单测每个工具函数独立测试输入固定参数断言返回结构。这个和普通代码测试一样保证 Agent 的地基不塌。流程集成测用一个不调用真实模型的方式跑完整流程工具 mock 掉只验证编排逻辑是否正确走到每个节点、条件分支是否按预期执行。这个能抓住大多数流程 bug。Prompt 回归测把一批固定任务放进一个测试集每次改 Prompt 或换模型版本就跑一遍对比输出质量。第三类是最容易被忽略的。我发现很多人改了几行提示词当时觉得好过了两周发现某些场景变傻了因为没有回归测试兜底。现在我的 Prompt 有任何改动都会先跑一遍测试集再上线。4.4 可观测性我只关心四类日志Agent 排错比普通接口难得多因为一个问题可能发生在模型决策、工具执行、状态流转、外部 API 任何一个环节。我现在统一要求所有 Agent 项目至少记录四类日志完整调用链用户输入、每一步模型输出、工具参数和返回结果、最终输出。有了这个才能复盘它到底怎么一步步走到这个结果的。Token 和耗时每步多少 token、耗时多少这对成本优化和排查性能问题很重要。异常与重试记录哪一步失败、为什么失败、重试了几次、最终结果如何。用户反馈输出有没有被用户接受是否被要求修正这是最直接的质量信号。我见过不少 Agent 项目上线后出了问题根本没法查因为没有完整调用链日志。在 Agent 领域可观测性不是锦上添花是能不能维护下去的前提。5. 多 Agent 协作看起来很酷但请克制5.1 多 Agent 最大的问题上下文稀释和成本爆炸多 Agent 协作是热搜词里我最想泼冷水的一个。我团队之前想做多个 AI 角色开评审会的项目让产品经理 Agent、工程师 Agent、测试 Agent 一起讨论需求。想法很美好但实际跑起来发现两件事。第一上下文被稀释得厉害。三个 Agent 之间互相传递的是摘要和结论每次传一轮关键细节就丢一层。传到第三轮各个 Agent 都开始基于自己的想象补充信息最终输出看着完整其实是集体幻觉。第二成本是线性甚至超线性上涨的。四个 Agent 协作一个任务底层是每两个 Agent 之间多轮信息交换一个本来几千 token 能解决的问题最后烧掉了几万 token。算下来比单 Agent 贵很多产出质量却没有明显更好。5.2 我用过三种协作模式各有适用场景在确实需要多 Agent 的场景里我用过三种模式编排者—执行者一个主 Agent 负责拆解任务、派发给多个执行 Agent、汇总结果。这是最稳的模式逻辑清楚主 Agent 像项目经理。适合任务可拆分成互相独立子任务的场景。流水线整个任务分成几个阶段每个阶段一个 Agent前一个的输出作为后一个的输入。适合流程固定的场景比如数据清洗 Agent 到特征提取 Agent 到报告生成 Agent。共享黑板多个 Agent 共用一个状态存储各自读写黑板上的信息。灵活但并发写冲突和消息语义混乱问题很难处理我目前只在研究性 Demo 里用。我会优先选编排者—执行者因为它最容易加人工审核点也最好排查问题。流水线适合流程极其稳定的情况。黑板模式我基本不在生产环境用。5.3 判断标准什么时候该拆什么时候不该拆多 Agent 拆分的判断标准我总结成一句口诀一个 Agent 多工具能解决的不要拆成多 Agent。拆分的唯一理由是不同环节需要完全不同的上下文和技能而不是多个角色一起开会更专业。举几个例子。一个 Agent 同时需要读文档、算数据、写报告这些是同一个上下文里的不同动作不需要拆。但如果任务包含先做数据分析和再做合规审查这两个环节的上下文差异很大拆成两个 Agent 反而更清晰因为分析 Agent 不需要全程背着合规规则。如果你发现拆完以后两个 Agent 之间每轮都要传上万字的上下文才能协作那就是拆错了。6. Token 成本、安全边界以及一些值得记住的坑6.1 一次看似简单的任务到底能吃多少 Token很多人对 Agent 的成本完全没概念。我举一个实际例子一个 Agent 做搜索三家供应商的报价并做对比的任务看起来很简单但实际流程是模型先决策调用搜索工具消耗几百 token工具返回一堆网页摘要可能一两千 token模型再决策逐个打开网页又消耗和接收几千 token最后生成对比报告又是上千 token。我统计过这类任务单次消耗经常在 8000 到 15000 token 之间比直接问一个简单问题的几十 token 贵了不止两个数量级。这还不是最夸张的一旦加了多 Agent 协作翻一倍是常态。成本优化我常用的手段第一个是控制上下文注入不要把和当前任务无关的历史记录全部塞进去第二个是做工具结果裁剪模型不需要完整网页只保留与任务关键词相关的摘要片段第三个是用便宜模型做中间动作只有最后生成关键内容时才切换强模型。我发现很多团队在弱模型上省几块钱结果在重试和调试上烧掉了十几倍的 token得不偿失。6.2 给 Agent 加安全锁权限最小化、工具白名单、沙箱执行Agent 的能力越强越要给它套安全边界。我见过最夸张的一次一个 Agent 被提示词注入之后试图读取服务器上的环境变量文件还好当时工具白名单里没有文件读取能力否则就是一次安全事故。我的安全底线有四条工具白名单Agent 只能调用你显式注册过、确认安全的工具。不要给 Agent 一个执行任意 shell 命令的能力除非你有非常强的隔离环境。权限最小化Agent 使用的 API Key、文件路径、数据库账号都要做成最小权限集只够它完成任务不能顺手做其他操作。输入输出过滤用户输入可能包含恶意指令工具返回内容也可能被污染。关键节点要做敏感信息过滤不能把工具拿到的内部数据直接原样输出给用户。沙箱执行凡是有代码执行、文件读写需求的 Agent一律在容器或隔离环境里跑不要直接在主服务器上执行。这个很贵但必要尤其是面向不可信输入的场景。我还建议在系统提示词里明确写只允许使用可用工具不执行任何未注册能力。虽然这不是绝对防御但能挡住很大一部分无意识的越界行为。6.3 一些零散但很实用的经验最后把这些小经验汇总一下都是我交过学费才记住的上线前先跑 20 遍同一类任务观察输出稳定性和 token 波动不要只测三个成功案例就上线。模型换版本之前先在同一批测试集上离线跑一遍不要直接切线上。我就吃过一次亏新模型聪明但更啰嗦流程步数直接翻倍。永远给 Agent 留一个我不确定需要询问用户的出口逼它硬答只会编得更圆。工具函数命名要像写公共 API 一样认真因为模型真的会按名字猜用途。命名含糊的工具调用率极低或乱用率极高。保存历史上所有模型曾经犯错但人工修正过的案例定期把这些案例加进测试集。这是你提升 Agent 质量最宝贵的样本池。我个人现在做 Agent 的心态已经从哇它能自动做事变成了我要想办法让它不要给我惹事。每次在循环里多写一层校验、在日志里多记一段上下文都是在降低未来半夜被叫起来修 bug 的概率。这个领域发展太快今天好用的框架可能半年后就变了但你沉淀下来的那套如何约束和验证一个会自主行动的模型的方法论会一直有价值。