☰
Agent工程化落地指南:拆解七要素与七个决策点
2026/10/7 5:45:23 网站建设 项目流程

最近被问得最多的一个问题,不是“Agent 能干什么”,而是“Agent 到底怎么落地”。市面上的教程大多把 Agent 讲成了魔法:一段提示词、一个循环、调几个工具,任务就自动完成了。可一旦真去工程化,事情马上变味——状态放哪、记忆怎么管、模型调用超时怎么办、并发一上来 token 成本怎么压,这些问题教程基本不提。

我自己的做法,是先把 Agent 拆成七要素,再从七个决策点去约束实现。所谓七要素,是目标、感知、记忆、规划、工具、执行、反思;所谓七个决策点,是在工程侧必须拍板的七个选型:目标如何注入、状态归谁持有、记忆如何分层、规划器用什么、工具如何暴露、失败怎么恢复、链路如何观测。这篇文章就是把这套思路完整展开,适合正在从 demo 走向生产的团队参考,也适合刚接触 Agent 开发、想避开常见坑的读者收藏着看。

1. 七要素:Agent 的骨架到底由什么组成

1.1 我为什么把 Agent 拆成“目标、感知、记忆、规划、工具、执行、反思”七块

我见过不少团队做 Agent,上来就写 while 循环:把 LLM 输出、解析、调工具、再喂回去。跑几个 case 没问题,一换场景就崩。原因很简单:Agent 不是一个循环,而是一个信息处理系统。把系统拆成七要素,不是为了学术好看,是为了让每一层都有对应的工程落点。

目标决定了提示词怎么写、评判函数怎么定;感知决定了输入怎么清洗、多模态内容怎么统一进上下文;记忆决定了哪些信息要在上下文里保留、哪些丢到外部存储;规划决定了模型是先想再做还是边做边想;工具决定了外部能力以什么契约暴露给模型;执行决定了模型输出的解析、工具结果回填、异常兜底;反思决定了错误怎么被发现、反馈怎么回到下一轮。七块都有对应的工程组件,缺一块,系统就只能在特定场景下勉强工作。

1.2 两个闭环:规划执行闭环与反思反馈闭环

七要素不是线性管线,真正跑起来是两个闭环。

第一个闭环是“规划-执行”闭环:模型拿到目标与当前状态,生成下一步操作,执行器调用工具,拿到结果后再回填到上下文,模型继续决策。这个循环对应 ReAct 一类的运行时。第二个闭环是“执行-反思”闭环:每一轮执行之后都要有检查点,工具返回报错、结果为空、模型输出格式非法,都是反思信号。要不要重试、要不要换方案、要不要直接交给人来处理,必须在实现里留好判断分支。

很多工程事故都出在第二个闭环缺失上:模型输出一个错误格式,解析器报错,系统直接崩掉,或者陷入无限重试。所以我的建议是,七要素里“反思”最容易被人忽略,但它恰恰是稳定性最关键的环节。

2. 决策点一与决策点二:目标如何注入,状态归谁持有

2.1 目标注入:写死在 system prompt 里,还是运行时传参

决策点一:目标定义。有人把目标写死在 system prompt,适合内部工具,比如“你是客服助手,负责答疑”;有人把目标作为运行时参数动态注入,适合通用平台,比如用户创建不同 Agent 时,每个 Agent 的 goals 由用户自己定义。

我在实际项目中更倾向动态注入,但要分层:系统层 prompt 写死行为边界,比如不许编造、不许越权;应用层 prompt 作为参数动态拼装。目标本身还要结构化,最好有 goal 加 success_criteria。如果只写一小段自然语言“帮我订机票”,最后很难判断 Agent 是否真的做对了。目标定义得越可判定,后面的评估环节就越扎实,也能直接拿 success_criteria 当自动化评测的评分依据。

2.2 状态管理:内存、Redis 还是数据库

决策点二:状态归谁持有。Agent 每次执行都在产生状态:已完成的规划步骤、工具返回的中间结果、用户会话的上下文。最省事的做法是把全部状态塞在内存里,单进程 demo 没问题;一旦上多副本、并发一高,内存态立刻变成定时炸弹。

我处理过一个线上事故:两个副本同时处理同一会话,各自维护自己的 plan,最终结果互相覆盖。后来改成 Redis 持有会话状态,所有副本读取同一份快照,才稳定下来。但 Redis 也不是万能的,长任务需要落库,至少要能看到历史版本。结论是:demo 用内存没问题,生产环境先想清楚状态归属,优先选可共享、可持久化的存储。

2.3 用表格快速对比状态存储选型

存储方案优点缺点适用场景
内存延迟极低,实现简单无法跨副本共享,重启即丢单机 demo、本地调试
Redis延迟低,支持分布式锁与过期策略需要额外运维,大对象序列化有成本会话级状态、短任务、多副本共享
PostgreSQL/MySQL可靠,支持审计与回溯延迟相对高,需要设计表结构落库、长任务、敏感操作留痕
对象存储适合超大中间结果读写延迟高,不适合频繁更新文档处理、多模态文件暂存

这里的要点不是“哪种最好”,而是“你需要在哪一层做一致性”。如果多个副本并发写同一个会话状态,光是 Redis 还不够,还要考虑加锁或者用版本号防止覆盖。

3. 决策点三与决策点四:记忆分层与规划器选型

3.1 记忆分层:短期记忆本质上是 token 预算管理

先解释一下 token 是什么。一句话:token 是模型输入输出文本的切分单位,和字符不是一回事。中文大概一个汉字接近一个 token,英文一个单词经常被切成若干个 token,所以同样的上下文,不同语言的实际成本差异明显。短期记忆就是当前这个请求喂给模型的全部上下文,包括用户问题、历史对话、工具返回、模型中间输出,它的上限就是模型上下文窗口。

实际做 Agent 时,短期记忆必须管理:历史对话不是全量保留,而是摘要化;工具返回也不是全量塞进上下文,而是抽取关键字段。我常用的做法是每轮结束后,对旧对话做一次摘要压缩,只保留最近 N 轮原文。缩不缩,取决于 token 成本与信息保留的平衡。

3.2 长期记忆:向量库不是银弹

长期记忆用于跨会话的持久信息:用户偏好、历史结论、业务知识。很多教程默认用向量库,把所有内容切片、embedding、相似度检索,然后塞回上下文。但工程上这个方案有几个坑。

第一,embedding 有延迟和成本,不能每轮请求都重新 embedding 全部内容。第二,纯向量检索往往会召回一堆语义相似但无关的内容,反而污染上下文。第三,写向量库之前要先解决权限问题——用户 A 的记忆不能让用户 B 检索到。我的经验是,长期记忆按“结构化加向量”混合存:事实性信息,比如姓名、偏好、订单状态,放关系型数据库,靠业务字段精确查询;非结构化内容才走 embedding 检索。两者结合,既精准又省钱。

3.3 规划器选型:ReAct、Plan-and-Execute 还是 Graph

决策点四:规划器用什么。最轻的是 ReAct 循环,让模型在每一轮思考“下一步是什么”,适合任务不固定、需要边做边调整的场景。第二个是 Plan-and-Execute,先让模型生成完整步骤列表,再逐步执行,适合步骤可以提前确定的任务,比如报表生成、数据清洗。第三个是基于图的编排,像 LangGraph 里那样,把每个节点定义为一种能力,显式定义边与条件跳转,适合流程相对固定、需要可控性的生产系统。

我的建议是默认用 ReAct 起步,但要在外层加步骤上限。实际上,极少数任务真正需要模型做完整规划,很多场景下“固定的图加局部 ReAct”才是又稳又灵活的搭配。图的优势是可控,你把分支写死了,模型只能在关键节点做选择,出错概率大幅下降。

4. 决策点五与决策点六:工具调用与失败恢复

4.1 工具调用:原生 function calling 是最省心的契约

决策点五:工具如何暴露。模型“会”用工具,但工程上要给它一个“号码簿”。主流方案是用原生 function calling 或 tool calling 协议:把你的工具定义成 JSON Schema,模型在输出时直接返回“我要调用某个工具,参数是什么”,运行时再去执行。这样模型就不用自己练习输出 JSON 字符串,解析稳定性好得多。

如果你的模型不支持 function calling,或者你想自己控制解析,那就得让模型输出结构化 JSON,再用严格的 schema 校验。这种方案自由度更高,但很容易踩格式不稳的坑。实测下来,能用原生 tool calling 就用原生,兼容性最好;实在要自解析,务必加一个能自动纠错的层,格式错了重试一次,别直接崩。

这里还有一个工程细节:工具定义越少、参数越明确,模型越容易选对。如果工具清单变成一长串几百个函数,光 token 就吃掉一大截,还容易误调用。所以工具清单要动态裁剪,按当前场景只暴露相关的子集。

4.2 失败恢复:重试不是万能药

决策点六:失败恢复。模型调用会超时、工具会报错、解析会失败。最常见的错误处理是重试,但盲目重试会砸钱:LLM API 超时重试没问题,工具调用失败如果是因为业务逻辑错误,重试一百次也没用。正确做法是分级处理:网络级错误重试一到两次;模型输出格式错误,把错误信息反馈给模型让它修正一次;工具业务报错,应该直接把错误文本反馈给模型,让它改变策略,而不是无脑重试。

另一个关键点是设置步骤上限与循环检测。如果模型重复调用同一个工具、参数一样、结果一样,就触发中断,给出提示并请求人类确认。不问原因的重试,等于给成本开闸。我在几个项目里都吃过这个亏,最后统一给循环加了一个 global_step 计数器,超过预设上限就强制走降级路径。

4.3 并发扛得住吗:异步、限流、队列三板斧

网上经常有人问“AI Agent 怎么扛并发”。我的回答是:别先想着“扛”,先把 Agent 想成两段——调度端和调用端。调度端负责编排流程,本身是轻量的,可以多实例横向扩展;调用端是 LLM API 和工具 API,它才是真正的瓶颈。

在 FastAPI 这类异步栈里,Agent 的主循环尽量用 async,不要让模型请求阻塞 worker。对外部 API 加并发限流,用信号量或者令牌桶控制同时对 LLM 的请求数。对长任务,走消息队列:用户提交任务后立刻返回任务 ID,后台 worker 慢慢跑,前端轮询结果。这样用户不会干等,系统的峰值压力也能被队列削平,这是我在生产环境里验证过最稳的组合。

5. 决策点七:可观测性、安全与评估,生产环境的三道防线

5.1 可观测性:没有 trace,Agent 就是黑盒

决策点七:可观测性。Agent 与传统接口最大的不同是非确定性:同一个问题,两次调用可能路径完全不同。没有 trace 的情况下,线上出了问题根本没法排查。我建议从第一行代码就记录三类信息:输入输出快照,也就是问题和最终回答;调用轨迹,每一步决策、模型调用的 prompt、工具调用的参数和结果;成本时间指标,token 数量、耗时、重试次数。

现在有不少现成工具可以接,LangSmith、Langfuse 之类的,也可以用最朴素的 JSONL 日志自己记。关键是结构要统一。我用过一个很土但有效的方法:每次循环都往结构化日志里追加一条 event,包含 step、agent_id、goal、action、tool_result、latency、token_used。出问题时,按 agent_id 抽日志就能复现全部执行过程,排查效率翻倍。

5.2 安全与权限:Agent 的权限边界要最小化

Agent 拿到工具权限,等于把一个能自主行动的程序放进了系统。权限设计必须遵循最小化原则:给 Agent 的 API token 只开通它任务需要的 scope,不要直接给数据库管理员账号;工具执行要放在沙箱里,限制网络访问和文件系统访问;对敏感操作,比如下单、转账、删除数据,必须设置 human-in-the-loop 审批。

这一点我吃过亏。之前一个内部 Agent 挂了一个可以读写知识库的工具,token scope 开太宽,一次 prompt injection 就把不该暴露的内部文档给读出来了。从那以后,凡是 Agent 工具,我都坚持白名单式权限:默认拒绝,按需开通。尤其是涉及外部系统调用时,必须让 Agent 只具备“完成任务所需的最小权限”。

5.3 评估:没有评测集,优化就是拍脑袋

最后,Agent 要有自己的评测集。代码可以单测,Agent 必须放评测。准备几十条覆盖典型场景的输入,包含正常任务、边界输入、错误路径,每次改动模型、提示词或流程后跑一遍,记录成功率和 token 消耗。评测不一定要自动化,起步时人工标注结果也行,但一定要有一个固定样本集,否则你会陷在“这次好像更好,但说不清哪里好”的泥潭里。

我自己的习惯是每个 Agent 项目维护两个文件:一个是 seed_cases.json,存放典型输入和期望结果;一个是 eval_results.jsonl,存放每次评估的输出。改动任何配置后跑一次,对比前后两轮的成功率和成本,让优化有据可依。

6. 落地参考:一个 FastAPI + LangGraph 的最小骨架

6.1 骨架如何映射到七要素

这里给一个最小骨架,用 FastAPI 提供 HTTP 入口,LangGraph 做编排。先把状态定义出来:

from typing import TypedDict class AgentState(TypedDict): goal: str question: str plan: list[str] step_index: int history: list[dict] tool_results: list[dict] final_answer: str

这个 AgentState 就是决策点二的答案:状态显式定义,传给所有节点。LangGraph 会把每个节点返回的部分内容 merge 回状态,你可以理解成一份共享的“会话工作台”。然后定义目标注入函数:

def build_system_prompt(goal: str, knowledge_scope: list[str]) -> str: return ( "你是任务执行助手。当前目标:" + goal + "。允许的知识范围:" + ",".join(knowledge_scope) + "。不许越权,不许编造结果。" )

目标从请求里来,动态拼进 system prompt,对应决策点一。接着定义规划节点、工具节点、反思节点,每个节点都是纯函数:输入状态,输出一个更新后的部分状态。最后编译图:

from langgraph.graph import StateGraph, END workflow = StateGraph(AgentState) workflow.add_node("plan", plan_node) workflow.add_node("act", act_node) workflow.add_node("reflect", reflect_node) workflow.set_entry_point("plan") workflow.add_edge("plan", "act") workflow.add_edge("act", "reflect") def should_continue(state: AgentState): if state.get("need_more"): return "act" return END workflow.add_conditional_edges("reflect", should_continue) compiled_agent = workflow.compile()

这个图对应的就是七要素里的“规划-执行-反思”闭环,而不是一个大 while 循环。你可以在 reflect 节点里做停止判断、重试判断、人类审批判断,这就是决策点六和决策点七的落点。不同版本的 LangGraph API 名称略有差异,但思路是一致的。

6.2 FastAPI 入口:异步与任务化

HTTP 入口我会写两层。轻量任务同步返回:

from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class AgentRequest(BaseModel): goal: str question: str @app.post("/agent/run") async def run_agent(req: AgentRequest): result = await compiled_agent.ainvoke( {"goal": req.goal, "question": req.question} ) return {"answer": result["final_answer"]}

注意这里用 async,避免阻塞事件循环;LangGraph 的异步入口ainvoke可以配合 FastAPI 的 async 生态。如果任务可能跑几十秒甚至几分钟,就换成队列模式:先返回 task_id,后台跑任务,前端再拿 task_id 轮询结果。这就是并发问题里说的“削峰”,实测下来比硬等 HTTP 响应稳得多。

6.3 几个容易踩的坑,提前记下来

  • 模型的输出不一定每次都能被 JSON 解析,务必在解析层做容错,能纠错就纠错,纠不了就交给反思节点。
  • 工具返回内容先截断再回填,一个工具返回几十万字会瞬间打爆上下文窗口。
  • 用 total_tokens 做成本监控,线上成本异常时,第一反应先看是不是某类任务重试次数过多。
  • 别让 Agent 在循环里无限跑,给节点加 step 上限,超了就走降级路径,而不是直接报错。
  • 本地测试时可以用 mock 工具函数,把模型调用缓存成文件,能大幅加快调试速度。

7. 七要素与七个决策点映射速查表

7.1 速查表

我最后把七要素和七个决策点的对应关系整理成一张表,方便你设计和评审时对照。

七要素对应的工程问题七个决策点我常选的做法
目标Agent 要完成什么、如何判定成功决策点一:目标如何注入系统层写死边界,应用层动态拼装,目标带 success_criteria
感知输入如何清洗、上下文如何构建决策点二:状态归谁持有demo 用内存,生产用 Redis 加数据库落盘
记忆哪些信息留在上下文、哪些外置决策点三:记忆如何分层短期摘要压缩,长期“结构化加向量”混合存储
规划任务怎么拆解、步骤怎么编排决策点四:规划器用什么默认 ReAct,流程固定时换成图编排
工具外部能力以什么契约暴露决策点五:工具调用协议优先原生 function calling,工具清单动态裁剪
执行模型输出如何解析、工具结果如何回填决策点六:失败恢复策略网络错误重试,业务错误反馈给模型,设步骤上限
反思错误如何发现、反馈如何利用决策点七:有无 trace 与评测结构化日志加固定评测集,敏感操作加审批

这张表不需要背,它只是提醒你:每个要素背后都有一个必须拍板的工程问题。如果你发现某个要素在项目里没有对应的决策点,大概率说明那部分还没想清楚,后续一定会补课。

7.2 七个决策点的落地顺序建议

如果团队从零开始做一个 Agent,我推荐的顺序是:先敲定目标注入和状态管理,这是地基;再搭记忆与规划,这两个决定效果上限;然后接工具与失败恢复,这两个决定稳定性;最后再想办法做观测和评估,磨质量。反过来很容易翻车:先花大量精力优化模型提示词,结果状态一乱、工具一报错,全盘崩溃,前面的优化全白做。

说实话,Agent 工程实现的门槛不在“调用一个 LLM”,而在把这些细节逐一拍板并坚持对齐。我自己踩过的坑,几乎都集中在“以为模型能自己搞定,结果没有给人留控制点”。所以我的原则很简单:给模型足够的自由度去做规划,给系统足够的约束去兜底,给工程师足够的观测去复盘。这套从七要素到七个决策点的拆法,是我目前觉得最不容易跑偏的工程框架。如果你正在做 Agent,不妨找一个自己项目里的真实任务,按这张表从头过一遍,大概率能找到现阶段最该补的那一环。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询