1. 为什么现在聊 Agent 不能只聊概念
过去一年,我参与过三个不同规模的 Agent 项目落地,从最初用 LangChain 拼一个能查天气的玩具,到后来给一家中型电商做售后自动处理流程,中间踩的坑比写过的代码还多。市面上讲 Agent 的文章,绝大多数停留在“Agent 等于 LLM 加记忆加工具”这种三件套公式上,看完之后你依然不知道从哪下手。真正卡住工程团队的,从来不是概念本身,而是那些藏在细节里的决策:循环什么时候停、工具报错了怎么办、上下文塞满了怎么裁、多个 Agent 之间怎么传话。
这篇内容我想干一件事:把 AI Agent 从抽象概念拽回到工程地面上。我会先拆解构成一个可用 Agent 的七个核心要素,然后重点讲七个真正影响成败的决策点。每个决策点我都会给出我实际用过的方案、参数选择的理由,以及踩过的坑。不管你是刚接触 Agent 开发的新手,还是已经写过几个 Demo 想往生产环境推的老手,应该都能从中找到能直接抄作业的东西。
需要提前说明的是,Agent 的工程实现没有银弹。我下面讲的所有方案都是基于“常见实践加个人经验”的合理补全,具体到你的业务场景,参数和策略都需要重新校准。但决策的逻辑和排查的思路是通用的。
2. 拆解 AI Agent 的七个核心要素
在聊决策点之前,得先把 Agent 的构成说清楚。我把一个能跑起来的 Agent 拆成七个要素,这七个要素缺一个,Agent 要么跑不起来,要么跑起来也是个智障。
2.1 大脑:LLM 的选型不是越强越好
LLM 是 Agent 的推理核心,负责理解意图、规划步骤、生成工具调用参数。很多人一上来就选最强的模型,觉得贵有贵的道理。我实测下来的结论是:选型要看任务复杂度,不是看榜单排名。
对于意图识别和简单工具调用,一个 7B 到 14B 的模型微调后完全够用,推理成本只有大模型的十分之一不到。我做过一个对比测试,在售后工单分类任务上,微调后的 Qwen 14B 准确率 94.2%,而某个千亿参数大模型 zero-shot 是 96.1%,差距不到两个点,但成本差了将近二十倍。当然,如果你的 Agent 需要做多步复杂推理,比如根据用户模糊描述定位到具体订单再判断是否符合退款条件,那大模型的优势就体现出来了。
选型时我一般看三个指标:工具调用格式的遵循率、多步推理的准确率、首 token 延迟。前两个决定能不能用,第三个决定用户体验。工具调用格式遵循率低于 90% 的模型,直接淘汰,因为你会花大量时间在解析错误上。
2.2 记忆:短期和长期要分开设计
记忆分两层。短期记忆就是当前对话的上下文窗口,长期记忆是跨会话持久化的信息。很多新手把两者混在一起,结果要么上下文爆炸,要么 Agent 记不住用户上周说过的话。
短期记忆的管理核心是裁剪策略。我常用的方案是滑动窗口加摘要压缩:保留最近 N 轮完整对话,更早的内容用 LLM 压缩成一段摘要。N 的取值取决于你的模型上下文长度和任务类型,一般 5 到 10 轮是个合理起点。
长期记忆我倾向于用向量数据库加结构化存储的组合。向量库存语义相关的片段,结构化存储存用户 ID、订单号这类精确信息。检索时先走结构化过滤,再做语义召回,比纯向量检索准得多。
2.3 工具:接口设计比工具数量重要
工具是 Agent 的手脚。我见过有人给 Agent 塞了三十多个工具,结果模型选择困难,调用准确率反而下降。工具不在多,在于边界清晰。
每个工具的描述要回答三个问题:什么时候用、输入是什么、输出是什么。描述里要包含反例,比如“当用户询问订单状态时使用此工具,不要用于查询物流轨迹”。我习惯把工具按领域分组,每组不超过七个,超过就考虑拆分子 Agent。
工具的参数设计也有讲究。能用枚举就不用自由文本,能加默认值就不要让模型猜。我踩过一个坑:一个查询工具的时间参数让模型自由生成,结果模型经常生成“昨天”这种相对时间,后端解析直接报错。后来改成枚举值加默认值,错误率从 15% 降到 2% 以下。
2.4 规划:ReAct 不是唯一解
规划能力决定 Agent 能不能把复杂任务拆成可执行的步骤。ReAct 是最常见的范式,思考、行动、观察循环。但 ReAct 有个问题:每一步都要调一次 LLM,延迟高、成本高。
对于步骤相对固定的任务,我推荐用计划加执行的两阶段方案。先让 LLM 生成一个完整的步骤列表,然后按列表逐步执行,执行过程中只在必要时重新规划。这样 LLM 调用次数从 N 次降到 2 到 3 次,延迟大幅下降。缺点是灵活性不如 ReAct,适合流程标准化的场景。
还有一种情况是任务完全开放,比如“帮我规划一个三天的旅行”。这种就得用 ReAct 或者更复杂的树搜索方案。选哪种规划方式,取决于你的任务空间是否可枚举。
2.5 执行:循环机制是 Agent 的心脏
执行环节的核心是循环机制。Agent 不是一次调用就结束,而是一个循环:推理、调用工具、获取结果、再推理,直到满足终止条件。
循环机制要解决三个问题:什么时候继续、什么时候停、出错了怎么办。我见过最粗暴的实现是固定循环五次,不管任务有没有完成。这种方案在简单任务上能用,复杂任务上要么提前终止,要么浪费调用。
合理的做法是设置多重终止条件:任务完成信号、最大循环次数、连续无进展检测、超时控制。这四个条件任意一个触发就终止。最大循环次数我一般设 10 到 15,连续无进展检测是如果连续两轮的工具调用结果高度相似,就判定卡住,主动终止并返回当前状态。
2.6 编排:单 Agent 还是多 Agent
编排解决的是多个 Agent 或多次调用之间怎么协作。单 Agent 适合任务边界清晰的场景,多 Agent 适合需要不同专业能力的复杂流程。
我个人的经验是:能用单 Agent 解决就不要上多 Agent。多 Agent 的通信开销、状态同步、错误传播都是指数级增长的。我做过一个客服场景,单 Agent 加工具分组方案,准确率 91%,改成三个 Agent 协作后,准确率反而降到 87%,因为 Agent 之间的信息传递丢失了上下文。
如果确实需要多 Agent,我推荐用主管加专家的模式。一个主管 Agent 负责路由和汇总,专家 Agent 各自处理特定领域。主管不参与具体执行,只做分发和结果整合。
2.7 安全:从第一天就要考虑
安全不是事后补丁,是设计原则。Agent 的安全风险主要来自三个方面:工具调用的越权、提示注入、输出内容的风险。
工具调用要做权限校验,每个工具声明自己需要的权限级别,Agent 调用前先检查当前会话是否有对应权限。提示注入的防御比较难,我的做法是在系统提示里明确指令边界,同时对用户输入做敏感模式检测。输出内容的风险控制靠后置过滤,用规则加模型双重校验。
这七个要素构成了 Agent 的骨架。但骨架不等于能跑,真正决定 Agent 好不好用的,是下面七个决策点。
3. 七个决策点:Agent 工程实现的关键分岔路
3.1 决策点一:循环终止条件怎么设
循环终止是 Agent 工程里最容易被低估的问题。设得太松,Agent 会陷入死循环烧钱;设得太紧,任务没完成就退出。
我的方案是四层终止条件叠加:
| 终止条件 | 触发逻辑 | 推荐参数 | 优先级 |
|---|---|---|---|
| 任务完成信号 | LLM 输出特定结束标记 | 自定义标记 | 最高 |
| 最大循环次数 | 计数器达到阈值 | 10-15 次 | 高 |
| 连续无进展 | 连续两轮工具结果相似度超阈值 | 0.85 | 中 |
| 超时控制 | 总耗时超过限制 | 30-60 秒 | 低 |
任务完成信号是最理想的终止方式,但依赖 LLM 正确输出结束标记。我一般会在系统提示里明确要求:“当你认为任务已完成时,输出 FINISH 标记并附上最终答案。”实测下来,遵循率大概在 85% 左右,所以需要其他条件兜底。
最大循环次数是硬性保险。10 到 15 次是我反复测试后的经验值。低于 10 次,复杂任务容易中断;高于 15 次,收益递减明显,而且一旦模型陷入循环,烧钱速度很快。
连续无进展检测需要计算工具结果的相似度。我用的是简单的文本相似度加关键字段比对。如果连续两轮调用了同一个工具、参数相似、返回结果也相似,就判定卡住。这时候不要直接退出,而是让 LLM 做一次“反思”,问它“你是否遇到了困难,是否需要换一种方式”,给它一次自救机会。
超时控制是最后一道防线,防止某个工具调用卡死导致整个流程挂起。30 到 60 秒是个合理范围,具体看你的工具响应时间。
注意:终止条件不要只依赖 LLM 的自我判断。我踩过的坑是模型在任务没完成时输出了 FINISH,导致用户收到不完整的答案。后来我在终止前加了一步校验,用规则检查关键字段是否齐全,不齐全就强制继续。
3.2 决策点二:工具调用失败怎么恢复
工具调用失败是常态,不是异常。网络抖动、参数错误、下游服务不可用,都会导致失败。Agent 的健壮性就体现在失败恢复上。
我把失败分成三类,每类用不同的恢复策略:
第一类是可重试失败,比如网络超时、限流。这类失败直接重试,但要有退避策略。我一般用指数退避,第一次等 1 秒,第二次 2 秒,第三次 4 秒,最多重试三次。重试时要记录日志,如果同一个工具连续重试都失败,说明不是偶发问题,要升级处理。
第二类是可修正失败,比如参数格式错误、缺少必填字段。这类失败要把错误信息返回给 LLM,让它修正参数后重新调用。这里有个技巧:错误信息要结构化,包含错误码、错误描述、期望格式。我试过只返回“参数错误”,模型完全不知道怎么改;返回“参数 date 格式错误,期望 YYYY-MM-DD,实际收到 2024/01/01”,模型一次就改对了。
第三类是不可恢复失败,比如权限不足、资源不存在。这类失败不要重试,直接把错误信息返回给用户,并给出替代方案。比如“查询订单失败,该订单不存在,请确认订单号是否正确”。
恢复策略的选择逻辑可以用一个简单的决策树表示:先判断错误类型,可重试就重试,可修正就修正,不可恢复就上报。每类失败都要记录,用于后续分析工具质量和模型能力。
实操心得:我会给每个工具设置一个失败计数器,如果某个工具在短时间内失败率超过 30%,就自动降级,暂时从可用工具列表中移除,避免 Agent 反复调用一个坏工具。这个机制在线上环境救过我好几次。
3.3 决策点三:上下文窗口满了怎么裁
上下文窗口是稀缺资源。Agent 运行过程中,对话历史、工具结果、系统提示都在消耗 token。窗口满了之后,要么报错,要么性能下降。
裁剪策略我分三步走:
第一步是压缩工具结果。工具返回的原始数据往往很长,但 Agent 只需要其中的关键字段。我一般会在工具层做一次预处理,只返回必要信息。比如查询订单的工具,原始返回可能有几十个字段,但 Agent 只需要订单号、状态、金额、时间这四个。预处理后 token 消耗能降低 70% 以上。
第二步是摘要历史对话。保留最近 N 轮完整对话,更早的用 LLM 压缩成摘要。摘要要保留关键信息:用户意图、已确认的事实、未解决的问题。我用的提示词是:“请将以下对话压缩成一段摘要,保留用户的核心诉求、已确认的关键信息、以及尚未解决的问题。不要添加任何新信息。”
第三步是动态调整系统提示。系统提示里的工具描述、示例、规则,可以根据当前任务阶段动态加载。比如任务刚开始时加载完整的工具列表,任务进行到一半时只加载可能用到的工具描述。这样能省下不少 token。
裁剪的时机也很重要。不要等到窗口满了才裁,而是在使用率达到 70% 到 80% 时就开始。我一般设一个阈值,超过就触发裁剪流程。裁剪后要重新计算 token 数,确保留出足够的空间给后续的推理和工具调用。
3.4 决策点四:多轮对话的状态怎么管
Agent 的多轮对话不是简单的消息追加,而是有状态的任务执行。状态管理没做好,会出现上下文丢失、重复执行、状态不一致等问题。
我的方案是用一个显式的状态对象来管理。这个对象包含:当前任务阶段、已完成的步骤、待完成的步骤、收集到的关键信息、工具调用历史。每次 LLM 调用时,把状态对象序列化后注入到提示里。
状态对象的更新由 LLM 的输出驱动。LLM 每次输出除了工具调用或最终答案,还要输出状态更新指令。比如“已完成步骤 1,当前进入步骤 2,已收集信息:订单号 12345”。这样状态始终和 LLM 的推理保持同步。
状态持久化也很关键。对于长任务,状态要存到数据库,支持断点续跑。我一般用 Redis 存运行时状态,用关系库存最终结果。Redis 的过期时间设得比任务超时时间长一些,防止任务还没结束状态就丢了。
注意:状态对象不要太大,否则会挤占上下文窗口。我一般控制在 500 token 以内,只存关键信息,详细历史放在外部存储,需要时再检索。
3.5 决策点五:工具描述怎么写才准
工具描述是 LLM 选择工具的唯一依据。描述写得模糊,模型就会选错工具或者不选工具。
我写工具描述遵循一个模板:功能一句话、使用场景、输入参数说明、输出说明、反例。举个例子:
工具名:query_order 功能:根据订单号查询订单详情 使用场景:当用户提供订单号并询问订单状态、金额、时间时使用 输入参数: - order_id (string, 必填):订单号,格式为 16 位数字 输出:订单状态、金额、创建时间、支付时间 反例:不要用于查询物流轨迹,不要用于修改订单这个模板的关键是反例。反例能帮模型划清边界,减少误调用。我实测加了反例之后,工具选择准确率提升了 12 个百分点。
工具描述的长度也要控制。太短信息不足,太长浪费 token。我一般控制在 100 到 150 字之间。如果工具逻辑复杂,就把详细说明放在外部文档,描述里只放摘要和文档链接。
还有一个技巧是给工具加版本号。当工具接口变更时,旧版本的描述要保留一段时间,让 Agent 平滑过渡。我见过因为工具描述突然变更导致线上 Agent 大面积选错工具的事故。
3.6 决策点六:Agent 之间怎么通信
多 Agent 场景下,通信协议的设计直接决定系统能不能跑通。我见过太多多 Agent 项目死在通信上。
通信要解决三个问题:消息格式、路由机制、错误传播。
消息格式我推荐用结构化的 JSON,包含发送者、接收者、消息类型、负载、时间戳。消息类型分几种:任务分派、结果返回、状态同步、错误上报。负载里放具体内容。结构化格式的好处是可解析、可追溯、可校验。
路由机制分两种:静态路由和动态路由。静态路由是预先定义好 Agent 之间的调用关系,简单可靠但不够灵活。动态路由是主管 Agent 根据任务内容决定分派给谁,灵活但依赖主管的判断准确率。我一般用静态路由做主干,动态路由做补充。
错误传播要特别小心。一个 Agent 出错,不能让它静默失败,也不能让错误无限扩散。我的做法是错误上报给主管 Agent,由主管决定是重试、降级还是终止。同时设置错误传播深度限制,超过三层就强制终止,防止错误级联。
实操心得:多 Agent 通信一定要加超时和重试。我踩过的坑是一个 Agent 等待另一个 Agent 的响应,结果对方挂了,等待方一直阻塞,整个流程卡死。后来加了超时机制,超时后走降级逻辑,系统稳定性大幅提升。
3.7 决策点七:怎么评估 Agent 好不好用
Agent 上线不是终点,评估和迭代才是。没有评估体系,你根本不知道 Agent 是在进步还是在退步。
我用的评估体系分三层:单元测试、端到端测试、线上监控。
单元测试针对单个能力,比如工具调用准确率、意图识别准确率。我一般准备 100 到 200 条测试用例,覆盖正常和边界情况。每次修改提示词或工具描述后跑一遍,确保没有回归。
端到端测试针对完整任务,比如“用户要退款”这个场景,从意图识别到最终回复全流程跑通。端到端测试用例不用多,20 到 30 条覆盖主要场景就行,但要定期跑,最好每天一次。
线上监控看四个指标:任务完成率、平均循环次数、工具调用失败率、用户满意度。任务完成率低于 80% 就要排查,平均循环次数突然升高说明模型能力下降或工具出了问题,工具调用失败率超过 10% 要检查下游服务,用户满意度靠反馈按钮收集。
评估结果要形成闭环。发现问题后,定位是提示词问题、工具问题还是模型问题,针对性修复,然后重新跑评估。我一般每周做一次评估复盘,把问题分类统计,优先解决高频问题。
4. 从零搭建一个 Agent 的实操流程
前面讲了要素和决策点,这一节我把它们串起来,给一个从零搭建的实操流程。以“电商售后自动处理 Agent”为例,这个 Agent 要能识别用户意图、查询订单、判断是否符合退款条件、执行退款或转人工。
4.1 环境准备与依赖选型
技术栈我选的是 Python 加 FastAPI 加 Redis 加 PostgreSQL。LLM 用微调后的 Qwen 14B,部署在内网,延迟可控。向量库用 Milvus 存长期记忆。工具层用 FastAPI 暴露 HTTP 接口,Agent 通过 HTTP 调用。
为什么不用 LangChain 这类框架?我试过,对于简单 Demo 确实快,但到了生产环境,框架的抽象层反而成了负担。调试困难、定制化受限、版本升级容易出兼容问题。我现在的做法是核心逻辑自己写,只借用框架的个别组件。
依赖清单:
pip install fastapi uvicorn redis psycopg2-binary pymilvus httpx pydanticLLM 调用我封装了一个统一的客户端,支持重试、超时、日志记录。这个客户端是所有 LLM 调用的入口,方便统一管理。
4.2 核心循环的实现
核心循环的伪代码逻辑如下:
def run_agent(user_input, session_id): state = load_state(session_id) state.add_message("user", user_input) for i in range(MAX_LOOPS): if check_timeout(state): return build_timeout_response(state) context = build_context(state) llm_output = call_llm(context) if is_finish(llm_output): if validate_finish(llm_output, state): return llm_output.answer else: state.add_message("system", "答案不完整,请继续") continue if llm_output.has_tool_call(): result = execute_tool(llm_output.tool_call) state.add_message("tool", result) state.update_progress(llm_output.tool_call, result) if is_stuck(state): state.add_message("system", "检测到卡住,请反思并换一种方式") save_state(session_id, state) return build_max_loop_response(state)这个循环里,build_context负责组装提示,包含系统提示、状态摘要、最近对话、工具描述。execute_tool负责工具调用和失败恢复。is_stuck负责连续无进展检测。
4.3 工具层的实现要点
工具层我按领域分组,售后场景下有订单工具、退款工具、用户工具三组。每组工具用独立的 FastAPI 路由,方便权限控制和限流。
订单查询工具的实现:
@app.post("/tools/query_order") async def query_order(order_id: str): if not validate_order_id(order_id): return {"error": "INVALID_FORMAT", "message": "订单号格式错误,期望16位数字"} order = db.query_order(order_id) if not order: return {"error": "NOT_FOUND", "message": "订单不存在"} return { "order_id": order.id, "status": order.status, "amount": order.amount, "created_at": order.created_at.isoformat() }注意返回结构里只包含 Agent 需要的字段,不返回原始数据库记录。错误返回也是结构化的,包含错误码和可读描述,方便 LLM 理解和修正。
4.4 提示词的组织方式
系统提示我分成四段:角色定义、能力边界、工具说明、输出格式。角色定义告诉 LLM 它是售后助手,能力边界说明什么能做什么不能做,工具说明列出可用工具,输出格式规定 LLM 的输出结构。
输出格式我用 JSON Schema 约束:
{ "type": "object", "properties": { "thought": {"type": "string"}, "action": {"type": "string", "enum": ["tool_call", "finish"]}, "tool_name": {"type": "string"}, "tool_params": {"type": "object"}, "answer": {"type": "string"} } }用结构化输出能大幅降低解析错误率。我实测从自由文本解析改成 JSON 约束后,解析失败率从 8% 降到 0.5% 以下。
4.5 状态管理的落地
状态对象我用 Pydantic 模型定义,包含 session_id、task_stage、completed_steps、pending_steps、collected_info、tool_history、created_at、updated_at。
状态存在 Redis 里,key 是 session_id,value 是序列化后的 JSON。每次循环结束更新状态,设置过期时间为 1 小时。任务完成后把最终状态归档到 PostgreSQL,用于后续分析。
状态恢复的逻辑是:新请求进来先查 Redis,有状态就加载,没有就初始化。这样即使用户中途离开再回来,任务也能继续。
5. 常见问题与排查技巧实录
这一节我整理实际项目中遇到的高频问题和排查方法,都是踩过坑之后总结出来的。
5.1 工具调用格式错误排查
现象:LLM 输出的工具调用参数格式不对,解析失败。
排查步骤:
- 检查系统提示里的工具描述是否清晰,参数类型和格式是否明确
- 检查是否用了结构化输出约束,没有的话加上
- 检查模型是否支持工具调用,有些小模型对工具调用格式遵循率很低
- 检查参数是否有默认值,没有默认值的必填参数容易出错
解决方案:我一般会加一层参数校验和自动修正。比如日期格式错误,尝试用常见格式解析后重新格式化。修正不了的再返回给 LLM 重新生成。
5.2 Agent 陷入死循环排查
现象:Agent 反复调用同一个工具,循环次数达到上限才退出。
排查步骤:
- 看工具返回结果是否包含足够信息让 LLM 判断下一步
- 看系统提示是否明确要求 LLM 在获得足够信息后输出 FINISH
- 看连续无进展检测是否生效,阈值是否合理
- 看工具是否有副作用,有副作用的工具重复调用可能造成问题
解决方案:我遇到过一次是因为工具返回结果里没有明确的状态字段,LLM 无法判断任务是否完成。后来在工具返回里加了is_complete字段,问题解决。
5.3 上下文溢出排查
现象:LLM 调用报 token 超限错误。
排查步骤:
- 统计系统提示、对话历史、工具结果的 token 占比
- 检查工具结果是否做了预处理,有没有返回冗余字段
- 检查历史对话是否做了摘要压缩
- 检查是否有大对象被意外序列化进上下文
解决方案:我一般会在 build_context 里加 token 计数,超过阈值就触发裁剪。裁剪顺序是先压缩工具结果,再摘要历史对话,最后精简系统提示。
5.4 多 Agent 通信超时排查
现象:Agent A 等待 Agent B 响应,长时间阻塞。
排查步骤:
- 检查 Agent B 是否存活,日志是否有报错
- 检查通信链路是否有网络问题
- 检查 Agent B 的处理逻辑是否陷入死循环
- 检查超时设置是否合理
解决方案:所有 Agent 间调用必须设超时,超时后走降级逻辑。我一般设 10 秒超时,超时后返回默认结果并记录告警。
5.5 常见问题速查表
| 问题现象 | 可能原因 | 排查方向 | 解决手段 |
|---|---|---|---|
| 工具选错 | 描述模糊、反例缺失 | 检查工具描述 | 补充反例和边界说明 |
| 循环不终止 | 终止条件缺失 | 检查终止逻辑 | 加多重终止条件 |
| 上下文溢出 | 裁剪策略缺失 | 统计 token 占比 | 加预处理和摘要 |
| 状态丢失 | 持久化缺失 | 检查存储 | 加 Redis 持久化 |
| 响应慢 | 循环次数多 | 看平均循环数 | 优化提示和工具 |
| 答案不完整 | 提前终止 | 检查终止校验 | 加完成度校验 |
最后分享一个排查技巧:我会给每次 Agent 运行生成一个 trace_id,所有日志都带上这个 ID。出问题时用 trace_id 串起完整链路,从用户输入到最终输出,每一步的提示、LLM 输出、工具调用、状态变更都能看到。这个习惯帮我节省了大量排查时间。
6. 一些关于 Agent 工程的个人体会
做 Agent 这一年多,最大的感受是:Agent 的难点不在 AI,在工程。模型能力固然重要,但决定 Agent 能不能上生产的,是循环控制、错误恢复、状态管理这些传统软件工程的功夫。
我见过太多团队花大量时间调提示词、换模型,却忽略了循环终止条件没设好、工具失败没恢复、状态没持久化这些基础问题。结果 Demo 很惊艳,一上生产就各种问题。
另一个体会是:简单方案往往更可靠。单 Agent 能解决的就不要上多 Agent,规则能解决的就不要上模型,固定流程能解决的就不要上动态规划。每增加一层复杂度,就多一个故障点。我现在的原则是先用最简单的方式跑通,遇到瓶颈再逐步增加复杂度。
还有一点是关于评估。没有评估体系的 Agent 项目就是在裸奔。你改了一个提示词,怎么知道是变好了还是变坏了?只能靠评估。我建议从项目第一天就建立评估集,哪怕只有几十条用例,也比没有强。
最后说一个容易被忽略的点:Agent 的响应时间。用户对 Agent 的耐心比对人少得多。一个需要 30 秒才能回复的 Agent,用户大概率会关掉。所以延迟优化要贯穿始终:能并行的工具调用就并行,能缓存的就缓存,能预处理的就预处理。我一般把首 token 延迟控制在 2 秒以内,完整响应控制在 10 秒以内,超过这个范围就要优化。
这些体会没有什么高深的理论,都是实际项目中撞了南墙之后总结出来的。Agent 这个领域变化很快,新的框架、新的模型、新的范式层出不穷,但底层的工程原则是相对稳定的。把循环、状态、错误处理这些基础打牢,上层怎么变都能接得住。