资讯详情

Agent开发核心五件事:从框架依赖到生产级能力内化

📅 2026/11/2 17:57:11 | 华诺云谱 👁 阅读
Agent开发核心五件事:从框架依赖到生产级能力内化
1. 为什么“五件事”比“五十个框架”更值得聊做了快两年 Agent 开发我最大的感受不是“要学的东西太多了”而是“真正要学的东西其实很少”。刚入行那会儿我也经历过疯狂收藏框架的阶段——今天看到 Spring AI 出了新版本明天听说 LangGraph4j 更适合编排后天又刷到某个 Python 轻量 Agent 框架号称三行代码跑通。结果呢收藏夹里躺了三十多个项目真正跑通并且用到生产里的一只手数得过来。Agent 开发这个领域有个很迷惑人的特点表面上的技术栈更新极快底层的核心能力却异常稳定。你去看那些真正把 Agent 跑在生产环境里的团队会发现他们用的框架可能很朴素但对几个关键问题的理解深得吓人。反过来那些天天追新框架的往往卡在“Demo 很惊艳上线就翻车”的循环里出不来。这篇内容我想聊的就是这个剥掉框架的外壳Agent 开发真正要掌握的是哪五件事。不管你是用 Python 还是 Java用 Spring AI 还是自己手搓这五件事都是绕不过去的。适合已经写过几个 Demo、准备往生产环境推进的开发者也适合刚入门、想少走弯路的同学。我会把每一件事拆开讲清楚它解决什么问题、为什么框架帮不了你、具体怎么做、以及我在实操中踩过的坑。先给个全局视角。这五件事分别是任务拆解与规划能力、上下文工程、工具调用的可靠性设计、状态与记忆管理、以及评估与可观测性。你会发现框架能帮你的是“调用大模型的接口封装”而这五件事框架基本只能给你个半成品剩下的全靠你自己想明白。2. 第一件事任务拆解与规划别指望模型一次想清楚2.1 为什么“让模型自己规划”经常不靠谱很多人做 Agent 的第一反应是给模型一个复杂目标让它自己拆步骤。这个思路在 Demo 阶段特别爽因为看起来模型真的“会思考”。但一到真实场景就露馅了——步骤漏了、顺序错了、中途跑偏了、循环调用同一个工具停不下来。根本原因在于大模型的规划能力是“局部合理、全局脆弱”的。它在每一步看起来都做了合理的决策但缺乏对整体目标的稳定把控。尤其是步骤超过五步之后错误会累积放大。这不是换个更强的模型就能解决的而是当前技术路线的固有特性。所以真正要学的第一件事是如何把规划这件事从“完全交给模型”变成“人机协作的结构化设计”。具体来说我习惯把任务拆解分成三个层次固定流程层那些步骤明确、顺序固定的部分直接写成代码逻辑不要让模型参与。比如“先查用户信息再查订单再生成回复”这种确定性流程用代码串起来比让模型规划可靠一百倍。半结构化层步骤大致清楚但分支条件需要判断的部分用“模型决策 代码执行”的方式。模型只负责在几个预设分支里选一个选完由代码执行具体动作。开放探索层真正需要模型自由发挥的部分通常只占整个任务的 20% 到 30%。这部分才需要给它规划空间而且必须加上步数上限和循环检测。2.2 一个可落地的规划模板我在实际项目里用得最多的规划结构是这样的# 伪代码示意语言无关 plan { goal: 用户目标描述, max_steps: 8, # 硬性步数上限 steps: [ {type: fixed, action: fetch_user_context}, {type: decision, options: [query_order, query_refund], criteria: ...}, {type: fixed, action: generate_response} ], fallback: 当步数超限或连续两次相同动作时走兜底逻辑 }这个结构的关键在于把“规划”从运行时的一次性行为变成设计时的结构化定义。模型在运行时只需要填充决策点的选择而不是从零开始想整个流程。注意步数上限这个参数千万别省。我见过太多 Agent 因为缺少步数限制在某个环节反复调用工具一次请求烧掉几十次模型调用。设成 8 到 10 是比较安全的范围复杂任务可以放宽到 15但一定要有。2.3 规划能力的分层训练思路如果你想让模型在开放探索层的表现更好有个被很多人忽略的技巧给模型提供“规划示例”而不是“规划指令”。与其告诉它“请仔细思考每一步”不如在提示词里放两三个高质量的规划示例让它模仿结构。实测下来示例驱动的规划质量比指令驱动稳定得多尤其是在步骤顺序和依赖关系上。另外规划这件事不要追求一次到位。我的做法是先让模型出一个粗规划然后用代码校验一遍——检查步骤之间有没有循环依赖、有没有引用了不存在的工具、有没有超出步数上限。校验不通过就打回去让它重新规划最多重试两次。这个“规划-校验-重试”的循环比单纯依赖模型一次输出靠谱得多。3. 第二件事上下文工程决定 Agent 上限的隐形战场3.1 上下文不是“塞得越多越好”如果说规划能力决定 Agent 能不能动起来那上下文工程就决定它能走多远。我见过太多项目模型选的是最好的框架用的是最新的但效果就是上不去问题几乎都出在上下文管理上。最常见的误区是“把能塞的都塞进去”。用户历史对话、知识库检索结果、工具返回内容、系统提示词一股脑全塞进上下文窗口。结果就是关键信息被淹没、模型注意力分散、成本飙升、延迟增加。更糟糕的是当上下文接近窗口上限时模型的表现会断崖式下降。上下文工程的核心就一句话在正确的时机把正确的信息以正确的形式放到正确的位置。这句话听起来像废话但拆开来看每一部分都有讲究。3.2 上下文的四个层次与处理策略我把 Agent 的上下文分成四个层次每个层次的处理策略完全不同层次内容处理策略常见错误系统层角色定义、能力边界、输出格式精简固定不超过 500 token写得又臭又长塞了一堆无关规则任务层当前目标、约束条件、可用工具动态生成按需注入把所有工具描述都塞进去历史层对话记录、之前的动作和结果摘要压缩 关键信息保留原样保留全部历史检索层知识库、文档、外部数据相关性排序 截断检索多少塞多少系统层最容易犯的错是“规则堆砌”。很多人把系统提示词写成了一本说明书什么情况都往里加规则。实际上系统提示词应该只保留最核心的角色定义和输出格式要求具体规则应该放到任务层按需注入。历史层的处理是重灾区。我的做法是滑动窗口 摘要保留最近 N 轮完整对话更早的内容压缩成一段摘要。摘要的生成也有技巧——不是简单概括而是提取“决策相关的信息”做过什么决定、为什么这么决定、产生了什么结果。这样模型在后续决策时能保持一致性。3.3 上下文位置的玄学与实测有个很少被提及但实测影响很大的点信息在上下文中的位置会显著影响模型的注意力。放在开头和结尾的信息模型利用得最好放在中间的信息容易被忽略。这个现象在长上下文里尤其明显。所以我的实操建议是关键约束放在系统提示词末尾比如输出格式要求、绝对不能做的事。当前任务目标放在用户消息开头让模型第一眼就看到。检索到的参考资料放在中间并且用明确的分隔符标出来比如--- 参考资料开始 ---。工具返回结果紧跟在工具调用之后不要攒一堆再一起给。提示如果你用的是支持长上下文的模型也别真的把窗口塞满。实测下来上下文用到 60% 到 70% 的时候模型表现最稳定。超过 80% 之后各种奇怪的问题就开始出现了。3.4 上下文压缩的实操技巧当历史对话确实很长、又不想丢失信息时压缩是必须的。我常用的压缩策略是结构化摘要而不是自由文本摘要summary { 已完成: [查询了用户信息, 确认了订单状态], 关键发现: [用户是VIP, 订单已发货], 待处理: [需要确认退款金额], 约束: [用户要求今天内回复] }这种结构化摘要的好处是信息密度高、模型容易解析、不会丢失关键决策依据。自由文本摘要容易越写越模糊几轮压缩之后就变成了一堆废话。4. 第三件事工具调用的可靠性Demo 和生产的真正分水岭4.1 工具调用为什么在生产环境频繁翻车工具调用是 Agent 最迷人的部分——让模型能查数据库、调 API、操作文件。但也是生产环境翻车最多的地方。我总结下来工具调用的问题集中在四类参数错误模型生成的参数格式不对、类型不对、缺字段。调用时机错误该调用的时候不调用不该调用的时候乱调用。结果解析失败工具返回的内容模型理解不了或者格式和预期不符。异常处理缺失工具报错了Agent 不知道怎么处理直接卡死。这四类问题框架基本都帮不了你。框架能做的就是“把工具定义转成模型能理解的格式”至于调用得对不对、错了怎么办全靠你自己设计。4.2 工具定义的“防呆设计”我的经验是工具定义要写得像给新人看的 API 文档而不是像给专家看的接口签名。具体来说参数描述要包含示例不只是说“用户ID”而是说“用户ID整数例如 12345”。枚举值要列全不要让模型猜。如果某个参数只能是几个固定值全部列出来。必填和选填要明确标注选填参数给默认值。工具描述要说明“什么时候用”和“什么时候不用”这比说明“这个工具做什么”更重要。举个例子一个查询订单的工具描述应该这样写查询订单信息。 使用场景当用户询问订单状态、物流信息、订单金额时使用。 不要使用当用户询问退款进度时应该用 query_refund 工具。 参数 order_id (必填, 字符串): 订单编号格式为 ORD 开头的12位字符串例如 ORD20240101001 include_logistics (选填, 布尔): 是否包含物流信息默认 false这种写法看起来啰嗦但实测能大幅降低参数错误率。4.3 工具调用的校验与重试机制模型生成的工具调用参数绝对不能直接传给真实工具。中间必须加一层校验def validate_tool_call(tool_name, params): # 1. 工具是否存在 if tool_name not in available_tools: return False, 工具不存在 # 2. 必填参数是否齐全 for required in tool_schema[tool_name][required]: if required not in params: return False, f缺少必填参数 {required} # 3. 参数类型和格式校验 # ... 具体校验逻辑 return True, OK校验不通过时不要直接报错给用户而是把错误信息返回给模型让它重新生成。这个重试循环最多两到三次超过就降级处理。工具执行本身也要有超时和异常捕获。我习惯给每个工具调用设一个超时时间比如 5 秒超时就返回“工具调用超时”让模型决定下一步。异常也要捕获后转成模型能理解的文本而不是直接抛栈。4.4 工具调用结果的“翻译”工具返回的原始数据往往不适合直接给模型看。比如数据库返回的时间戳、API 返回的嵌套 JSON模型理解起来容易出错。我的做法是加一层结果格式化时间戳转成人类可读格式。嵌套结构拍平成键值对。长列表截断只保留前 N 条并标注“共 X 条”。空结果明确说明“未找到相关数据”而不是返回空对象。这层“翻译”看起来是小事但对 Agent 的决策质量影响很大。模型看到清晰的结果后续动作的准确率会明显提升。注意工具返回结果里如果包含用户输入的原始内容一定要做转义处理防止提示词注入。这个坑我在早期项目里踩过用户在一个查询字段里塞了指令结果模型真的去执行了。5. 第四件事状态与记忆管理让 Agent 不再“金鱼脑”5.1 状态管理的三种模式Agent 的状态管理说白了就是“记住什么、记多久、怎么用”。我把它分成三种模式无状态模式每次请求都是独立的不保留任何历史。适合简单的单轮任务比如分类、提取。会话状态模式保留当前会话的上下文会话结束就清空。适合多轮对话类 Agent。持久记忆模式跨会话保留关键信息比如用户偏好、历史决策。适合需要长期陪伴的 Agent。大部分项目其实只需要前两种但很多人一上来就搞第三种结果复杂度爆炸。我的建议是从无状态开始需要多轮就加会话状态确实有跨会话需求再上持久记忆。不要提前设计。5.2 会话状态的设计要点会话状态最容易出的问题是“状态膨胀”——什么都往里存最后变成一个巨大的对象每次请求都要序列化反序列化性能差还容易出错。我的做法是状态分层session_state { core: { # 核心状态每次请求都带上 user_id: ..., current_goal: ..., step_count: 3 }, working: { # 工作状态当前任务相关 last_tool_result: ..., pending_decision: ... }, history: [...] # 历史记录按需加载 }核心状态永远带着工作状态按需注入历史记录只在需要时检索。这样既保证了连续性又控制了上下文大小。5.3 持久记忆的存储与检索持久记忆的核心问题是“存什么”和“怎么取”。存太多检索不准存太少记不住事。我的经验是只存“决策相关”的信息用户的明确偏好“我喜欢简洁的回答”。重要的历史决策“上次选择了方案 A”。长期有效的约束“用户是 VIP优先处理”。存储用向量数据库或者简单的键值存储都行关键是检索时要带上下文。不要只按相似度检索还要结合当前任务类型、时间范围做过滤。比如查用户偏好时优先返回最近三个月的记录。5.4 记忆的更新与遗忘记忆不是只增不减的。我见过一个 Agent 因为记住了用户三个月前的一句抱怨在后续对话里反复提及体验极差。所以记忆必须有更新和遗忘机制冲突更新新记忆和旧记忆冲突时以新的为准旧标记为过期。时间衰减超过一定时间的记忆检索权重降低。显式遗忘用户明确说“忘记这个”时真的删掉。这些机制听起来简单但需要在设计阶段就想清楚后期补很麻烦。6. 第五件事评估与可观测性没有度量就没有优化6.1 为什么 Agent 的评估这么难传统软件的测试是“输入确定输出确定”。Agent 的测试是“输入确定输出不确定过程也不确定”。这让很多人直接放弃了评估靠“感觉”来判断好坏。结果就是改了一个提示词不知道是变好了还是变坏了换了一个模型不知道哪些场景退化了。Agent 评估难但不是不能做。关键是要把评估拆成可度量的维度而不是追求一个总分。6.2 四个可落地的评估维度我常用的评估维度有四个维度度量方式目标任务完成率成功完成的任务数 / 总任务数越高越好核心指标步骤效率平均消耗步数 / 理论最少步数越接近 1 越好工具准确率正确工具调用数 / 总调用数越高越好异常恢复率异常后成功恢复数 / 总异常数越高越好这四个维度不需要复杂的评估系统用日志就能算出来。关键是每次改动后都跑一遍固定的测试集对比数据变化。6.3 可观测性的最小实现可观测性不需要一上来就上全套 APM。我的最小实现是结构化日志log_entry { trace_id: ..., step: 3, action: tool_call, tool: query_order, params: {...}, result_summary: ..., duration_ms: 234, model_tokens: 1500 }每次请求一个 trace_id串起所有步骤。这样出问题时能快速定位是哪一步、哪个工具、什么参数出的问题。日志存到文件或者简单的数据库都行关键是格式统一、字段完整。6.4 回归测试集的建立Agent 的回归测试集不需要很大20 到 50 个典型场景就够用。关键是要覆盖正常流程占 60%。边界情况占 20%比如空结果、超长输入。异常情况占 20%比如工具报错、参数缺失。每次改提示词、换模型、调参数都跑一遍这个测试集记录四个维度的数据。坚持下来你会对自己的 Agent 有非常清晰的认知而不是靠感觉。提示测试集里的场景要定期更新。我一般每个月 review 一次把线上发现的新问题加进去把已经稳定的场景精简掉。保持测试集“新鲜”评估才有意义。7. 框架选型的实话Spring AI、LangGraph4j 还是自己写聊完五件事回到框架选型这个绕不开的话题。经常有人问“现在到底用 Spring AI 还是 LangGraph4j”我的回答通常是先想清楚你的五件事做到什么程度了再选框架。如果你只是做 DemoSpring AI 和 LangGraph4j 都能让你快速跑起来。Spring AI 的优势是和 Java 生态无缝集成如果你本来就在用 Spring Boot 做业务系统接入成本极低。LangGraph4j 的优势是编排能力强适合流程复杂的场景。但如果你要做生产级 Agent我的建议是框架只用来做“模型调用封装”和“基础工具调用”核心的规划、上下文、状态、评估逻辑自己写。原因很简单这五件事每一件都需要根据你的业务深度定制框架给的通用方案往往不够用改框架的成本比自己写还高。Python 生态也是同理。LangChain 这类框架适合快速验证但生产环境里我见过太多团队最后把框架一层层剥掉只留下最核心的调用逻辑。这不是框架不好而是 Agent 开发的本质决定了核心能力必须内化不能外包给框架。8. 一些踩坑之后的个人体会最后分享几个我在实际项目里踩过坑才明白的点都是那种“文档里不会写、但真的很重要”的经验。关于模型选择不要迷信“最强模型”。Agent 场景里模型的指令遵循能力和工具调用稳定性比纯粹的推理能力更重要。我实测过一些中等规模的模型在结构化任务上的表现比大模型还稳因为大模型有时候“想太多”反而不按套路出牌。关于提示词提示词不是越长越好也不是越短越好。关键是信息密度。每一句话都要有明确的作用删掉之后效果会变差的才保留。我习惯写完提示词后逐句问自己“这句删了会怎样”删了没影响的就删掉。关于并发Agent 的并发和普通接口的并发完全是两回事。普通接口并发上不去加机器就行。Agent 并发上不去往往是模型调用配额、工具调用限流、状态存储锁竞争这些原因。设计阶段就要考虑并发场景别等上线了才发现。关于成本Agent 的成本很容易失控因为一次用户请求可能触发十几次模型调用。我的做法是给每个请求设 token 预算超了就降级处理。同时监控“单次任务平均 token 消耗”这个指标涨了说明某处逻辑出问题了。关于测试Agent 的测试不能只测“正常路径”。我见过太多项目正常流程跑得飞起一遇到工具报错就整个卡死。异常路径的测试要占至少 30% 的测试用例而且要覆盖各种异常组合。这五件事每一件都值得单独深挖。但如果你能把它们都做到 70 分你的 Agent 就已经超过市面上大部分 Demo 了。剩下的 30 分靠的是在具体业务场景里的持续打磨没有捷径。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑