ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从七要素到七决策:Agent工程化落地全指南

从七要素到七决策:Agent工程化落地全指南 做 Agent 做了差不多两年从最初的套个 Prompt 调 API到现在自己搭了一套偏生产的框架中间踩过的坑和绕过的弯比预期多不少。最近不少朋友在选型或者在 demo 跑通后不知道怎么继续往下走问的问题都很相似Agent 到底该有什么、不该有什么模型已经很强了为什么工程上还是一团乱麻所以我想从一个工程实现者的角度把 Agent 系统拆成两部分来讲第一部分是构成 Agent 的七要素第二部分是实现时绕不开的七个决策点。掌握这两块基本就能回答Agent 是怎么做出来的以及我的 Agent 为什么需要做成这样。这七年里我自己的体会是Agent 并不神秘它本质上就是一套模型状态工具策略的组合。难点不在模型选择而在于你得在七个关键节点上做出取舍每一步取舍都会影响最终系统的稳定性、成本和用户体验。下文会尽量把每个要素和决策点讲透并附上我实际项目中的做法希望能帮你少走点弯路。1. 先从根上想清楚Agent 到底是一个新东西还是换了个说法的老系统很多团队把 Agent 想成一个超级聪明的大模型能听懂人话然后直接干活。这个描述不完全错但它在工程上是没法落地的。真正落地的时候你会发现 Agent 是一个由若干组件组成的执行系统LLM 只是其中那个负责思考的部件。你还需要给这个部件提供信息、提供工具、提供反馈还要管它什么时候停下。1.1 如果你还分不清 Workflow 和 Agent就先别急着画架构现在业界关于 Agent 跟 Workflow 的区别吵得很厉害。我的简化理解是这样的Workflow 是预先定义好的固定路径每一步做什么、调用什么工具、如果出错走哪条分支都是写死的而 Agent 则是把路径选择权交给模型让模型根据输入动态决定下一步调用什么动作。说白了Workflow 是考勤打卡Agent 是自由职业者。但在工程里这两者不是对立的往往是一个 Agent 系统内部既包含固定 Workflow又包含动态决策。比如用户请求进来先做意图识别这是 Workflow识别完以后决定调哪个 API、要不要追问上下文这是 Agent 的能力。把认为所有逻辑都应该动态化和认为动态化就是玄学两种观点融合起来才能做出既能跑得稳定又能应对不确定性的系统。1.2 从会聊天到会干活真正变化的是控制流普通聊天机器人只有理解-生成两个步骤Agent 多了一个关键循环理解 – 规划 – 执行 – 观察 – 再规划。也就是常说的 ReAct 循环。这个循环里最重要的不是模型厉害而是观察这一步。很多 Agent 应用做得很笨是因为模型输出一个工具调用结果后系统没有认真观察返回值就直接进下一步。观察这一步承担的是把外部世界的信息变成模型可读的反馈没有它Agent 就缺少了闭环容易在错误的假设上一路狂奔。我见过很多失败的 Agent 项目本质都是把循环建错了。要么循环得太狠模型反复调用同一个失败工具却停不下来要么循环得太浅调完一个工具就把结果甩给用户不去判断结果是否满足需求。这个度怎么控制我放到后面的推理循环决策点里细讲。1.3 为什么要专门提出七要素所谓七要素是我跟团队复盘了多个 Agent 项目之后总结出来的一套零件清单。它不是学术定义更像一个工程 checklist。当你准备开发或者评估一个 Agent 方案时拿这七个名字去对照就能快速发现系统里缺了哪块。它们分别是模型底座、指令与角色、推理模块、工具集、记忆系统、上下文管理、行动与反馈。这七个要素缺了任何一个都会有明显的问题没有记忆Agent 是金鱼没有推理模块Agent 是简单的命令解释器没有行动反馈Agent 只是一个更贵的聊天机器人。很多人把 Agent 做挂了恰恰是因为只盯着模型工具两个要素其他五个全在裸奔。2. 七要素拆开看每个零件在系统里到底是干什么的既然确定了 Agent 是一套组合系统接下来就要把每一个要素讲透。注意我这里没有用模块来称呼因为它们不一定是独立模块有的要素可能是模型行为的一部分有的要素需要你专门写代码来实现。理解这一点对后续决策非常重要。2.1 模型底座不是越强越好而是越合适越好模型底座是整个 Agent 的脑负责理解输入、生成推理步骤、输出指令。常见的可选范围包括通用大模型、代码专用模型、轻量级模型等。我和团队在做 Agent 时总结过一个简单粗暴的选型标准如果 Agent 的重心是会使用复杂工具那么模型本身的工具调用能力Function Calling必须强至少不能频繁出现参数幻觉如果 Agent 的重心是长文本分析那模型上下文长度和遵循指令的能力比工具调用更关键如果 Agent 运行在边缘端那模型参数量就得小到能塞进设备内存。很多人一上来就上最强的模型结果延迟高、成本高精度提升比例却非常有限。更好的做法是分层场景复杂度低的对话走小模型需要深度推理和大量工具组合的任务走大模型。成本优化这件事从 Agent 选型的第一天就要开始想。2.2 指令与角色这道工序是规则的第一道闸门指令与角色不是给模型写一段你是一个乐于助人的 Agent就完了。指令承担的作用是约束模型的输出格式、决策边界和语气偏向。它决定了 Agent像谁和能做什么、不能做什么。工程上我会把指令拆成两层。静态层是固定的 system prompt里面写好全局规则、输出格式、敏感话题处理策略。动态层则由代码根据当前会话状态、用户画像、上下文片段实时生成。你不应该在代码里把所有情况都写死在 system prompt 里那样 prompt 会膨胀到几千字模型反而失去焦点。动态拼装的能力往往被忽视但它才是 Agent 工程化的重要一步。2.3 推理与规划让模型想几步的机制设计推理与规划是 Agent 区别于普通聊天机器人的核心。它可以是简单的先调用搜索搜索不到再调用知识库查询也可以是复杂的任务分解把帮我订机票拆成查航班、选座位、支付、发送确认单等子任务。工程实现推理这一要素有几种不同的方案一是直接依赖模型本身的 zero-shot 规划能力Prompt 里写一句请一步步规划二是引入 CoT思维链示例让模型按照给出的样板去推理三是用结构化规划比如让模型输出一个 JSON 计划数组再由代码去逐项执行。这三种方案的稳健性依次递增但灵活度依次递减。最让我难受的项目经历是团队迷信模型的自主规划能力让模型完全自由输出规划步骤结果模型生成了一个只有它自己懂的步骤列表。后来我们改成模型先输出意图和可选动作代码再决定执行顺序整个系统一下就稳定了。2.4 工具集Agent 与外部世界交互的双手工具集就是你提供给模型的一组函数。每个工具至少要有名称、描述、输入参数 JSON Schema 和实际执行函数。很多人有一个误解认为工具越多越好。其实工具越多模型选错工具的几率越大。工程上需要的是让模型看得懂每个工具是干什么的。我通常给工具描述加一行使用场景提示例如当用户需要查询实时天气时使用注意城市名需要标准化后传入这样工具调用的准确率会有明显提升。另外工具之间的边界要尽可能清晰尽量避免两个工具的职责重叠否则模型会把简单问题分流到复杂的工具上。2.5 记忆系统短期上下文与长期档案要分开管理记忆系统解决的是 Agent 的连续性问题。短期记忆就是当前会话的上下文窗口长期记忆则是以某种形式存储的用户历史偏好、历史任务记录、知识条目等。在工程实现里我倾向于把记忆分三个层次会话级记忆存在于单次会话中通常存对话摘要或轮次状态。用户级记忆跨会话存储用户偏好、已验证身份、常用地址等。业务级记忆与用户无关但属于领域知识的一部分比如产品说明书、政策文档片段。工程实现长期记忆最常用的方案是向量数据库 语义检索把一段长期记忆切成片段用 embedding 存储然后在需要时检索 top-k 拼进上下文。这里最常踩的坑是把原始内容全部塞进向量库而不考虑隐私和时效导致我记得的用户信息里混入了过期的、甚至错误的信息。记忆系统必须支持读取、写入、校验和删除不然越积累越混乱。2.6 上下文管理token 是资源不是垃圾场上下文管理是被低估得最厉害的一环。LLM 的上下文窗口是有限的即使现在很多模型支持几十万 token也不代表你该把所有内容都堆进去。Token 就是成本Token 就是延迟Token 更是注意力分散的根源。做上下文管理需要考虑四件事内容选择把检索回来的记忆、工具输出、历史对话按要求截断、摘要、重排。优先级系统指令优先级最高其次是当前任务说明再是近期对话最后才是长尾记忆。遗忘机制旧对话需要自动归档不能让一条三个月前的聊天记录占用上下文。长度估算不是数文字个数而是按 tokenizer 估算 token 数量达到阈值就触发裁剪。我最常推荐的做法是摘要 原始窗口两级管理。每轮对话结束以后把这一轮的关键信息压成一个摘要存好后序备用但当前窗口仍保留最近几轮原始内容。这样既保证模型能感知最近细节又不会让上下文无限膨胀。2.7 行动与反馈Agent 和环境的闭环行动与反馈是 Agent 执行动作、观察结果、判断是否完成的机制。一个简单的动作是调用工具一个复杂的动作是等待用户授权。行动不一定总是立刻执行还可能涉及异步工单、人工审批、长时间运行任务。反馈回路在真实系统中很关键。比如你调用支付工具工具返回一个支付成功的状态Agent 需要据此判断任务是否结束。但如果工具返回超时未知状态Agent 应该怎么处理是要重试还是转人工这就是行动与反馈在实际工程里最考验人的地方。一定要把工具返回的信息归类为成功、失败、未知三态并对未知单独制定策略。3. 七个决策点从能跑通的 Demo 到能上生产的 Agent讲完有哪些零件接下来就要回答怎么装起来的问题。我在实践中总结了七个决策点这七个点凡是有一个考虑不周都会在线上给你颜色看。它们没有绝对正确的答案但每一个决策你都得有依据、有预案。3.1 决策点一什么逻辑交给模型什么逻辑交给代码第一个决策点最底层它会直接影响项目的进度和稳定性。很多人倾向于能用模型就用模型这是错的。模型擅长的是语义理解、文本生成、复杂条件下的模糊决策而模型不擅长的是精确计算、强约束校验、重复百次不变的规则。我从一个真实场景说起。当时做的是一个文案创作 Agent用户提交产品信息Agent 自动出一版营销文案。最开始我们把判断文案是否包含违禁词也交给模型去做结果模型偶尔会漏掉上线后出现了一丝风险。后来把违禁词校验改成代码层的敏感词库扫描模型只负责写得好不好不负责合规性。这个小改动让系统稳定性提升了一个数量级。所以在做 Agent 时你先画一条线凡是结果可以确定性验证的尽量走代码凡是结果必须靠语义理解的才交给模型。不要在模型身上赌它永远不会出错模型只负责从可选动作集合里做选择至于这个动作是否合法应该是规则前置判断。3.2 决策点二记忆存到哪里、存多久、怎么召回记忆这个决策点很容易在项目初期被忽略因为 demo 阶段不需要记忆跑几轮对话看不出什么问题。但一旦用户量上来你必然要面对不同的用户继续上一次任务这类需求。我的建议分两步。第一步先把短期记忆策略定下来至少你的 Agent 要能记住当前会话里的关键状态比如已经完成哪些步骤、有哪些待确认字段。第二步再考虑长期记忆。长期记忆在初版不需要做得特别重用一个 KV 表存 user_id - user_preference_json 就够用了只有当记忆条目需要语义检索时才引入向量库。还要想好记忆的生命周期。像支付信息这种敏感数据不仅不能进长期记忆甚至短期记忆里也应当做脱敏。我在项目里一般会给记忆数据加上过期时间比如对话摘要保留 7 天用户偏好保留 30 天领域知识永久但支持版本更新。这听上去不性感但生产环境最需要的就是这种无聊的确定性。3.3 决策点三工具集到底开放到什么程度工具集问题的本质是 Agent 的能力边界。一个 Agent 可以拥有一百个工具也可以只拥有三个。决定这个度的因素不是你能调多少 API而是你能否保证每个工具描述清晰、输出可控、调用成本可接受。我在实践里总结了一个工具准入标准工具必须有明确的成功/失败返回结构不能返回裸字符串。工具的副作用要可控。比如发送邮件和获取邮件列表都是工具但前者有副作用必须配合用户确认动作后者可以直接执行。工具的调用频率必须统计。如果某个工具一周都没有被调用过说明它的入口太深或者描述不清楚应重新设计。工具要遵循最小权限原则。Agent 不应该持有它用不到的管理接口权限。我在一个内部客服 Agent 项目里一开始把全部 60 多个内部系统 API 都暴露给模型结果模型经常调错。后来我们重新梳理成 12 个聚合工具比如查询订单这一个工具内部去聚合订单状态、物流信息、售后入口模型只需要选择查询订单就可以了。工具调用准确率从 74% 提升到 96% 左右代价只是每个工具的实现里多加了一些内部逻辑。3.4 决策点四Agent 自主循环到哪里停推理循环是 Agent 的灵魂也是导致线上事故最多的点。你需要明确设置最大迭代步数否则一个 Agent 可能在一个问题上循环调工具直到超时。我们项目里默认最大步数是 5复杂任务可以放宽到 8超过阈值后直接降级为无法完成任务请转人工。除了步数限制还要给推理循环加条件终止器。条件终止器可以是一个函数它检查当前状态是否已经满足用户目标。比如目标是查询订单状态终止条件是工具返回了 order_status 字段如果工具返回的是用户未登录这类非目标状态Agent 应转为提问而不是再调一次查询接口。这里有个工程细节不要在每轮推理后把完整历史对话都塞回去。应该维护一个状态快照比如当前目标、已完成步骤、未解决障碍、最新观察结果。模型基于快照做下一步决策比读几千字的聊天记录更高效也更不容易跑偏。3.5 决策点五并发场景下怎么扛住流量热搜词里很多人问AI Agent 怎么扛并发这确实是最现实的工程问题。大多数 Agent 的瓶颈不在 LLM 本身而在 Agent 内部的编排和工具调用。一个简单的链式调用往往涉及多个外部 API接口响应慢一点、超时重试多一点整体吞吐就上不去了。要做高并发的 Agent我建议从三个方面下手一是用异步而非同步。不要让一个 HTTP 长连接把整个 Agent 执行过程全占住。把耗时工具调用变成异步任务用队列通信Agent 执行器与 HTTP 服务解耦。我们最初的实现是 FastAPI 同步处理压测到 20 并发就有大量请求排队后来改成将任务提交给内部队列由 worker 池执行把 LLM 调用和工具调用都用 asyncio 协程并行等待单实例能扛的并发直接翻了 5 倍。二是给 LLM 调用加缓存和限流。对同一问题的相似请求可以在一段时间内直接返回缓存结果。每次调用前估算当前模型 provider 的速率限制超阈值时排队而不是并发轰炸。扣子、LangChain 这类框架都有各自的限流策略但我们自己实现时会更细区分用户级限流和全局限流。三是瘦 Agent架构。把重计算放到单独的服务里执行Agent 编排层只负责调度。比如一个文档分析 Agent真正耗时的 embedding 和解析工作抽出去做成独立服务Agent 编排层拿到结果再排版。这样编排层能更轻松扛并发因为它的逻辑变薄了。3.6 决策点六失败降级与安全边界怎么设Agent 的失败形式比普通接口多得多。除了网络错误、超时还有模型输出 JSON 解析失败、工具参数校验不过、模型幻觉式地调了一个不存在的工具、上下文超长等等。每一类失败都要有预案。我的默认策略是三级降级一级降级模型输出异常时自动重试一次并给模型附加上一次错误的详细信息。二级降级放弃模型决策走兜底规则。比如用户的问题无法被工具覆盖则返回统一的我不能回答这类问题话术。三级降级转人工把当前上下文摘要和已尝试的动作发给人话务系统。安全边界也是 Agent 生产化的重中之重。我强烈建议 Agent 在执行任何有副作用的工具前都通过一个审批机制。最简单的审批是用户二次确认复杂一些的是风险分级 自动审批。资金支付、对外发布、删除数据这三类动作绝不能让 Agent 一口气执行完。即便用户明确说帮我支付也最好在支付前展示订单详情并要求确认一次因为 Agent 可能理解错了订单 id。3.7 决策点七可观测性和评测体系不会让你失望Agent 最难调试的一点是路径的不确定性。传统的日志只能看到接口入参和出参但 Agent 中间经历了什么推理过程、为什么选择这个工具、哪一步导致偏离预期都需要可观测性工具去还原。我在项目里会为 Agent 专门设计一份轨迹日志记录以下内容每一轮推理的 input tokens / output tokens。模型输出的原始内容已经过脱敏。工具名称、入参、耗时、返回值摘要。本轮决策依据的当前状态快照。最终退出原因正常结束 / 步数超限 / 触发安全策略。有了轨迹日志才好做评测。Agent 评测不是只看最终答案对不对还要看路径是否合理。我用多维度的指标来打分任务成功率、工具调用正确率、平均步数、超时率、用户干预率。每周固定跑一批回归用例看新改动有没有让关键指标恶化。不要相信模型变聪明了所以不需要评测这种话模型一升级Agent 的行为就可能变。4. 案例用 FastAPI LangGraph 实现一个轻量客服 Agent理论讲得再多不如看一个具体案例。这里我分享一个我在公司内部搭过的客服 Agent 简化版用来演示七要素和七个决策点是怎么落到代码里的。技术栈是 FastAPI LangGraph因为 LangGraph 的图结构很适合管理推理循环。4.1 系统结构与状态定义先定状态。LangGraph 会让每个节点共享一个状态字典我们把它定义成from typing import TypedDict, Annotated from operator import add class AgentState(TypedDict): messages: Annotated[list, add] # 对话历史 user_id: str task: str plan: list current_step: int tools_result: dict finish: bool这个状态字典就是整个 Agent 的白板七要素中的记忆、上下文、行动反馈都会在这个白板上留下痕迹。节点的顺序由 LangGraph 的边来控制模型和工具引擎各占一个节点。4.2 三个核心节点规划、执行、反思LangGraph 里可以画三个节点对应 Agent 循环。我先定义只负责调用大模型并输出结构化决策from langchain_openai import ChatOpenAI from langgraph.graph import StateGraph, END llm ChatOpenAI(modelgpt-4o-mini, temperature0) def planner_node(state: AgentState) - dict: # 构造精简的决策 prompt只让模型输出下一步动作 system 你是一个客服助手。根据当前任务、工具列表和已观察到的结果输出下一步决策。 输出必须是JSON{action: 工具名或reply, args: {...}, reason: 简短理由} user_content f任务{state[task]}\n当前步骤{state[current_step]}\n工具结果{state[tools_result]}\n对话历史摘要{state[messages][-3:]} resp llm.invoke([{role: system, content: system}, {role: user, content: user_content}]) # 解析 JSON失败则走兜底回复 import json try: decision json.loads(resp.content) except json.JSONDecodeError: decision {action: reply, args: {message: 抱歉我没有理解请重新描述。}} return {messages: [(assistant, resp.content)], plan: [decision]}第二步是执行节点根据决策调用工具def tool_executor(state: AgentState) - dict: decision state[plan][-1] action decision[action] if action reply: return {messages: [(assistant, decision[args][message])], finish: True} if action in tool_registry: try: result tool_registry[action](**decision[args]) status success except Exception as e: result str(e) status error return {tools_result: {action: {status: status, result: result}}, current_step: state[current_step] 1} # 工具不存在状态设成 error return {tools_result: {action: {status: error, result: unknown tool}}, current_step: state[current_step] 1}第三步是反思节点让模型根据工具结果判断任务是继续还是结束def reflect_node(state: AgentState) - dict: last_tool list(state[tools_result].keys())[-1] last_result state[tools_result][last_tool] if last_result[status] success and state[current_step] len(state.get(plan, [])): return {finish: True} return {}然后把节点和边关系组合起来加上最大步数限制graph StateGraph(AgentState) graph.add_node(planner, planner_node) graph.add_node(executor, tool_executor) graph.add_node(reflect, reflect_node) graph.set_entry_point(planner) graph.add_edge(planner, executor) graph.add_edge(executor, reflect) graph.add_conditional_edges(reflect, lambda state: finish if state[finish] else planner, {finish: END, planner: planner}) app graph.compile()你可以看到整个推理循环被显式地用状态机管理而不是让模型在一个巨长的 prompt 里自由发挥。这就是决策点四循环刹车的实际落地。4.3 并发与部署FastAPI 作为接入层FastAPI 层只负责接收 HTTP 请求、构建设备初始状态、然后调用上面编译好的 graph。组件并行方面如果工具调用是 IO 密集的我会把它们全部定义成 async 函数并在 executor 节点里用 asyncio.gather 并发执行减少总耗时。LangGraph 在较新版本里支持 async 节点所以执行层能进一步提高并发能力。部署时我们需要给工作设定超时。FastAPI 请求的 timeout 跟 Agent 的执行 timeout 要分开一般一个 Agent 任务最长运行 30 秒超过就返回任务正在处理中并异步上报结果。这个异步化设计能让接口不被长任务拖死也是扛并发的关键。4.4 评测阶段我们做了哪些回归上线之前我们准备了 200 条人工标注测试语料每条语料包含用户提问、期望最终答案、期望调用工具、允许的步数范围。评测脚本自动跑一遍 Agent 并对比期望结果统计工具调用正确率。每次更换模型、调整 prompt 或增删工具都先跑这个测试集。这个习惯养成了以后Agent 行为漂移的次数大幅减少算是长期主义的回报。5. 常见误区与踩坑后的个人心得写到这里我想把实战里最容易翻车的几个误区集中分享一下很多都是我们线上真实出现过的希望能给后来者一些提示。5.1 误区把 Agent 当成纯模型能力忽视工程约束有些团队测试时觉得哇模型自动调工具好智能于是把所有逻辑都丢给模型。但一到生产用户会输入各种奇怪的表达模型会突然改变输出格式工具 API 会升级导致参数变化这种情况下没有工程约束的 Agent 就是灾难。我的经验是Agent 本质是一个带 AI 大脑的确定性系统。大脑负责理解与决策但系统骨架、状态流转、失败兜底都必须由代码掌控。我们可以把大脑替换成不同模型而骨架应该保持稳定。这才是 Agent 能落地的关键。5.2 误区上下文越长越好记忆全存下来我们曾经在一个数据分析 Agent 里把用户的全部历史查询都塞进上下文结果 token 爆了延迟从 2 秒变成 12 秒而且模型生成的结论因为被太多噪声干扰反而更不准确。后来我们改成只保留当前任务相关摘要 最近三条查询效果显著提升。这里顺便提一下AI Agent token是什么意思这个问题token 是模型处理文本的基本单位一个 token 大约相当于一个英文单词的四分之三、一个中文汉字的一到两个。你给模型发多少 token、模型回答多少 token都直接影响成本和速度。所以省 token 不是抠门而是对系统健康负责。5.3 误区Agent 不需要人审、不需要安全机制我见过最吓人的一次是某个 Agent 在没有二次确认的情况下连续调用了三次发送短信工具给用户发了一堆重复短信。模型不觉得自己做错了因为它只是按指令执行。如果你不给 Agent 加副作用操作确认机制它迟早会在某个巧合下做出让你头疼的事。现在我做所有的 Agent 系统都会默认加一套安全规则引擎把发短信、发邮件、支付、删除、修改权限这类操作标记为高风险。高风险工具执行前必须经过用户确认或至少通过内部审核接口。安全机制的优先级永远高于智能。最后分享一个实战里的小经验在所有 Agent 项目中对我帮助最大的一个动作是强制保存完整的决策轨迹。不管模型最终答没答对只要轨迹完整问题就能被快速定位。项目初期大家都急着调 prompt、换模型但不少人忽略了真正决定 Agent 稳定性上限的往往就是那些不起眼的状态管理和失败兜底逻辑。如果你现在正要开始做一个 Agent我建议先拿出一张纸把这七要素和七个决策点全部过一遍圈出你还没想清楚的地方。把这些地方想明白再动手后面返工的概率会小很多。
返回列表