ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

AI Agent 工程实践:七要素与七个决策点全解析

AI Agent 工程实践:七要素与七个决策点全解析 做 AI Agent 这条路我从 2023 年就开始走。那时候网上全是 LangChain 的 Demo 和 AutoGPT 的炫酷截图看起来只要把几个组件拼一拼一个能自己规划、能自己调工具、能自己干活的数字员工就冒出来了。真正上手后才发现Demo 和能上线的工程之间隔着一道鸿沟概念上讲得很清楚的 Agent 架构落到代码里全是选择——模型选哪个、框架用不用、记忆怎么存、工具怎么调、上下文怎么省、出了问题怎么兜底。这篇文章不打算再复述一遍什么是 Agent的科普而是想把拆解 Agent 的一整套思路完整交代清楚。我习惯把它拆成两个视角去看一个是它由什么组成我归纳成七要素另一个是我怎么把它实现出来我归结为七个决策点。先看构成再谈工程最后给出一套可以照着做的落地流程和排障经验。如果你想做 Python/后端方向的 Agent 开发或者已经在做 ChatBot 想升级成 Agent又或者正准备做技术选型想少踩坑这篇应该都接得住。1. 为什么从七要素讲起先搞清楚 Agent 的构成再谈实现我发现关于 Agent 的讲解大多会走向两个极端一种是给你画张特别漂亮的架构图讲感知—决策—行动的大闭环另一种是直接甩一段框架 API让你照着调。前者看完你依然不知道代码怎么组织后者换一个框架你就废了。所以我更愿意把 Agent 想成一个完整的闭环系统而这个系统绕不开七块东西。拿一个真实的小团队来打比方大模型是大脑规划器是那个负责派活的军师记忆系统是白板和档案柜工具集是工具箱执行器是手观察回路是眼睛运行环境是这家公司的规章制度和工作场地。缺了任何一块这个团队都没法独立干成一件完整的事。1.1 要素一大模型底座大模型底座是整个 Agent 的核心引擎也是通常意义上大家最先想到的部分。它的职责不是生成一篇漂亮的文章而是在给定的状态下做决策下一步该调用哪个工具、该给用户什么样的回答、该如何修正自己刚犯的错。工程上这一块最值得关注的是四点推理能力、工具调用能力、上下文窗口长度、单位成本与延迟。推理能力决定了 Agent 能解决多难的问题工具调用能力决定了它能不能稳定地拿起工具箱里的家伙上下文窗口决定了它一次性能记住多少信息成本与延迟决定了你能不能把它放在线上跑。有一个我反复强调的观点模型的能力决定了 Agent 能力的天花板工具和记忆决定它实际能落地多少。很多团队换个更强的模型之后整个 Agent 的表现瞬间上了一个台阶原因就在这。1.2 要素二规划器规划器负责把一个大目标拆解成若干小步骤。现在主流有两种形态一种是隐式规划模型在生成回复时顺着思路把下一步要做的事带出来ReAct 范式本质上就是这样另一种是显式规划先让模型单独输出一份行动计划比如第一步搜索资料第二步整理摘要第三步生成报告再按计划逐步执行。显式规划的优点是过程可控、便于人工检查和干预缺点是增加了额外一次模型调用和相应的 Token 消耗。隐式规划更灵活但遇到长链路任务时容易跑偏。我自己做项目的习惯是短任务、工具少于五个时直接用隐式规划一旦任务链条超过五步或者要求结果必须稳定就切换成显式规划让模型先把计划摆到桌面上。很多新手上来就追求全自动规划结果是模型自己把自己带进了沟里。1.3 要素三记忆系统记忆系统可以分为短期记忆和长期记忆。短期记忆就是在上下文窗口里的对话历史相当于工作台上的白板写满就得擦掉一部分长期记忆是存放在外部数据库里的信息相当于档案柜需要的时候再拿出来看。工程上做长期记忆最常见的方案是向量库加 RAG把历史对话或知识库切片后做 Embedding 存储用户在提问时检索出最相关的片段塞进上下文。但请注意向量库不是唯一方案也不是最优方案。很多业务场景用结构化数据库加关键词检索效果一点不差而且成本低得多。记忆设计真正要回答的问题是两个什么该记住什么该忘掉。全量存下来不是记忆是垃圾场只会让模型在每个轮次里被无关信息干扰。1.4 要素四工具集工具集是 Agent 触碰外界的桥梁。模型本身只会吐文本想查数据库、调接口、发通知、执行代码都得通过工具完成。工具的本质是把模型和外部世界对接起来的契约模型按约定格式发起调用工具执行后把结果回传。这个合约通常以 Function Calling 的形式体现也就是把每个工具的名称、描述、参数约束以 JSON Schema 的形式暴露给模型。工具描述写得清不清楚直接决定模型用得好不好。我见过太多失败案例不是模型不行是工具的函数名起得莫名其妙、参数说明含糊其辞模型拿着工具都不知道该传什么值。1.5 要素五执行器执行器负责真正执行动作。注意这一块和规划器有本质区别规划器只负责想执行器负责做。一次完整的工具调用里规划是模型完成的执行是代码完成的二者必须分开。工程上执行器要考虑同步和异步的问题。同步执行简单直观适合耗时短的内部调用异步执行适合那些要等外部系统回调的场景比如发起一个耗时的数据导出一类任务。执行器还有一个容易忽略的职责异常兜底。工具抛异常时不应该让整个 Agent 崩溃而应该把错误信息包装成一条可被模型理解的观察结果让模型自己决定下一步怎么办。1.6 要素六观察与反馈回路Agent 做完一个动作之后必须能看到动作的结果再决定下一步怎么做这就是观察与反馈回路。很多初版 Agent 表现极差根源就在于这个回路断了工具调完就完事结果既不回传也不总结模型在完全失真的状态下继续硬着头皮往下编。我在团队里常挂嘴边的一句话是不返回结果的工具调用等于没有调用。只要模型是在盲跑它就是在幻觉里行动后面所有的步骤都是空中楼阁。工程上做反馈有几种形式最粗的是把工具返回的原始文本直接拼进消息里好一点的是做结构化包装比如把查询结果转成固定格式注明本条结果来自哪个工具、共几条记录、是否完整再进一步是让一个轻量模型先对工具结果做摘要压缩后再喂给主模型。反馈越聚焦模型下一步的决策就越靠谱。1.7 要素七环境与边界最后一个要素是 Agent 运行的环境以及它被允许触碰的边界。环境既包括真实的外部系统比如需要调用的 API、需要操作的文件、需要推送消息的聊天工具也包括隔离的沙箱比如代码执行的容器。边界是工程上最容易拍脑袋的一环。权限太大一个错误的工具调用可能把生产库给改了权限太小Agent 又什么都干不成。我的原则是默认最小权限敏感操作一律二次确认所有外部调用接限流和审计。Agent 的本质是让模型在真实世界里行动行动的后果由你兜底这条线不能松。到这里七要素已经齐了。它们在运行时会形成一个闭环任务从环境里涌现出来模型感知后结合记忆做出规划调用工具执行器行动观察结果更新记忆然后进入下一步直到目标达成或者人为叫停。接下来要解决的就是怎么把这个闭环在工程上真正落地。2. 七个决策点把要素变成可运行系统时的关键抉择知道 Agent 有哪些部件只是第一步。真正开始实现时你面前会出现二十多个岔路口模型用什么、框架用不用、记忆存哪儿、工具怎么封装、上下文怎么省、出错怎么兜底。我把最关键的浓缩成七个决策点每个决策点没有绝对标准答案但有清晰的取舍逻辑。先放一张对照表把七要素映射到七个决策点上七要素对应决策点你真正要回答的问题大模型底座决策一模型选型与接入用什么模型、以什么方式接入规划器决策二推理范式选型用隐式推理还是显式规划记忆决策三记忆方案设计短期记忆怎么管、长期记忆存什么工具集决策四工具协议与安全边界工具怎么定义、权限怎么卡执行器决策五单体还是多体架构一个 Agent 干到底还是多 Agent 分工观察与反馈决策六上下文与 Token 治理反馈如何回流且不撑爆上下文环境决策七可观测、评估与运维线上怎么监控、怎么评估、怎么兜底2.1 决策一模型选型与接入方式模型选型是第一个要拍板的事也是影响最深远的一个决策。闭源模型胜在省心和能力上限高开源模型胜在私有化部署和数据不出域但代价是你要自己搭推理服务、自己处理并发和显存。选型时最该关注的不是排行榜分数而是它对你场景的实际表现。我一般会拿公司里真实的一批任务做小样本测试重点关注四个指标单工具调用成功率、多工具连续调用成功率、返回参数 JSON 合法率、以及拒绝错误执行的次数。这四个指标能反映出一个模型在 Agent 场景下到底可不可用。接入方式上同样有讲究。直接用模型厂商的 SDK 最快但对于稳定性和并发要求高的场景我更建议把模型接入抽象成一层独立接口内部实现不同的 provider 适配。这样换模型时不用改业务代码。一个实践中很有用的节奏先用最强最贵的模型验证你整个 Agent 的逻辑闭环确认流程能跑通之后再逐步往便宜、低延迟的模型上迁移每一步迁移都用评测集回归。用最贵的模型验证逻辑用最便宜的模型上线这是我控制成本和保证质量的核心方法。2.2 决策二推理范式选型推理范式指的是 Agent 内部思考与行动的组织方式最常见的有 ReAct、Plan-and-Execute 和 Reflection 三种。ReAct 是推理和行动交替进行模型先想一小步然后调用一个工具观察结果接着想。它是目前做 MVP 最稳妥的选择实现简单调试也直观。Plan-and-Execute 则先让模型产出整体计划再逐步执行它更适合任务链条长、要求结果稳定的场景但计划一变就需要重新规划额外开销不小。Reflection 是让模型对自己的输出做一轮自我批评和修订对代码生成、报告撰写这类质量要求高的任务效果显著代价是调用次数和 Token 消耗翻倍。我的建议是默认从 ReAct 起步等遇到长任务跑飞、步骤重复这类问题后再引入显式规划只有对输出质量有硬性要求时才上 Reflection。一上来就搞 Plan-and-Execute 加 Reflection 全家桶我见过不少初学者这么干最后调试复杂度爆炸根本没时间优化业务效果。2.3 决策三记忆方案设计记忆方案是七个决策点里最容易被过度设计的。很多人一听到 Agent 记忆下意识就要上向量库、上 RAG结果花了一周搭基础设施业务效果还没起来。我的建议是把记忆方案分成三层来考虑。第一层是短期记忆也就是把最近 N 轮对话放进上下文配一个滑动窗口窗口外的消息要么丢弃、要么压缩。第二层是摘要记忆当上下文快满时用一个轻量模型把旧对话压成几百字摘要保留关键事实和用户意图。第三层是长期记忆才轮到向量库或结构化数据库存用户画像、业务知识、历史结论这类需要跨会话复用的信息。检索时注意设好上限比如每次最多取回 5 条相关片段。检索多了模型容易犯迷糊因为在它眼里每一条都挺像那么回事。先跑通短期和摘要记忆再按需加长期记忆这个顺序能帮你省下大量无效投入。2.4 决策四工具协议与安全边界工具协议的设计直接决定模型的工具调用成功率。一个工具定义至少要包含四个方面清晰可读的名称、描述工具用途和适用场景的说明、结构化的参数 Schema、以及返回结果的格式约定。描述里建议写清楚边界条件比如单位、范围、默认值、必填项避免模型瞎猜。下面是一份典型的工具 Schema字段不多但每一处都值得推敲{ name: search_articles, description: 按关键词和日期范围检索内部文章库返回命中文章的标题和摘要。仅在需要获取最新资料时使用。, parameters: { type: object, properties: { keyword: { type: string, description: 要检索的关键词必填。 }, days: { type: integer, description: 最近 N 天内的文章取值范围 1-30默认 7。 } }, required: [keyword] } }安全边界的核心是最小权限 显式确认。工具注册时要做白名单绝不动态暴露任意函数给模型涉及写操作、删除操作或对外发送消息的工具必须在调用前加一道人工确认或条件校验所有外部调用都要记日志、做限流。Agent 的权限边界宁紧勿松因为模型的判断永远是概率性的。2.5 决策五单体还是多体架构单 Agent 结构简单、Token 开销小、链路好追踪适合大多数内部自动化任务。多 Agent 架构则由多个角色分工比如一个 Planner 负责拆任务几个 Worker 并行执行各自的专业动作一个 Critic 负责检查质量。它的优势是解耦和并行但代价也很明显Token 消耗成倍增加故障点翻倍排查问题时要对着多条链路看半天。什么时候值得上多 Agent我总结为三类场景角色之间有明确且无法合并的职责差异不同步骤需要的系统提示和权限差别很大任务可以被并行拆解且合并成本低。很多团队把多 Agent 当成了先进性的象征我见过最夸张的一个项目拆了 7 个 Agent最后 80% 的时间都在处理 Agent 之间的消息格式问题。如果你在调研 Rust 生态也可以看看 Rig 这类 Rust 语言实现的 Agent 框架它用宏定义工具签名编译期就能校验参数性能也确实好。但对绝大多数团队来说Python 生态的迭代速度仍然是最重要的选型因素。2.6 决策六上下文与 Token 治理这一条在整个 Agent 工程里最容易被忽视却直接决定你线上成本的生死线。模型上下文是按 Token 计费的而 Agent 每一轮循环都会把整个历史重新发送一遍。你每多记一轮对话后面每一轮的成本都在涨。Token 治理的核心是预算管理。我通常按三个区域切分上下文固定区存放系统提示和工具定义尽量精简到 1.5K Token 以内动态区放检索到的资料和工具结果单条结果上限控制在 2K Token 以内滚动区放最近对话默认保留最近 20 条。工具返回结果一律截断完整的原始数据进日志不进上下文。还有一个很多人不知道的技巧把一段 10000 Token 的历史对话压成 200 字摘要往往比原封不动丢给模型效果好。模型从来不是看得越多越好而是看得越聚焦越好。2.7 决策七可观测、评估与运维Agent 上线的第一件事不是抗住高并发而是先有一个能看清它在干什么的仪表盘。不可见的系统一旦出错你连排查的入口都没有。可观测至少要记录四类数据完整的步骤轨迹、每次工具调用的入参和返回、每轮对话的 Token 消耗、以及最终任务的成功或失败。现在 Langfuse、LangSmith 这类工具都做得比较成熟自研也可以先打结构化日志。评估体系是 Agent 工程里最值得提前投入的部分。我建议从上线第一周就开始攒一个真实任务的黄金评测集每次改模型、改提示词、改工具描述都用这套数据集跑回归。没有评测集你所有的调优都只是在跟着感觉走。运维层面要设计好兜底机制超时中断、最大步数限制、模型结果合法性校验、以及人工接管入口。部署架构上我强烈建议把 Agent 进程和对外服务解耦比如用 Django 这类 Web 框架只做入口和接口层Agent 作为 Worker 通过消息队列接收任务。这样即使某个任务跑飞了也不会拖垮整个 Web 服务。3. 实操从需求到最小可用 Agent 的完整落地流程理论讲了一堆回到动手。我带大家走一遍我从需求到上线的最简流程用一个具体例子说明给运营团队做一个竞品情报 Agent每天自动检索行业动态、去重整理、生成摘要报告并推送到群聊机器人。3.1 需求定义与架构草图第一步是把自然的业务需求翻译成 Agent 的可执行定义。我会把需求填进一张表里项目定义目标输入业务关键词列表每日定时触发执行动作检索资料、去重、生成摘要、推送消息输出要求结构化摘要报告最多 2000 字步骤上限8 步权限边界只读外部接口只允许推送指定群聊失败处理超时自动终止失败后重试一次再失败发告警然后确定架构单 Agent 加 ReAct 范式两个工具检索文章、发送消息短期记忆用当次会话的滑动窗口不需要长期记忆。这个项目规模完全没必要上多 Agent 和向量库先把闭环跑通最重要。3.2 核心代码骨架一个 50 行的 Agent 主循环很多框架把 Agent 主循环包装得严严实实但底层逻辑其实很统一。我把核心循环手写一遍你能看到所有 Agent 框架背后都在做同一件事。import json from typing import Callable class MiniAgent: def __init__(self, llm, tools: dict[str, Callable]): self.llm llm self.tools tools self.schemas [self._to_schema(name, tools[name]) for name in tools] self.messages [] self.max_steps 8 def run(self, prompt: str): self.messages [{role: user, content: prompt}] for _ in range(self.max_steps): resp self.llm.chat(self.messages, toolsself.schemas) if not resp.tool_calls: return resp.content self.messages.append(resp.message) for call in resp.tool_calls: fn self.tools[call.function.name] try: result fn(**call.function.arguments) content json.dumps(result, ensure_asciiFalse)[:2000] except Exception as e: content f调用异常{e} self.messages.append({ role: tool, tool_call_id: call.id, content: content }) raise TimeoutError(超过最大步数)这个循环只有五个关键点循环里先让模型带工具 Schema 回复如果模型没有发起工具调用就直接返回如果有工具调用就把模型消息追加进历史执行工具后用结果构造一条 tool 消息追加回去整个循环受最大步数限制。两个工具的实现也很直接def search_articles(keyword: str, days: int 7) - dict: # 从内部文章库或公开接口检索 return {items: [{title: ..., summary: ...}]} def send_report(report: str) - dict: # 推送到群聊机器人接口 return {status: ok}注意 search_articles 返回结果在最外层被截断到了 2000 字符这是防止工具输出把上下文撑爆的常用手段。异常也被包装成了可读消息回传给模型让模型自己决定是换个参数重试还是收尾。这套逻辑不依赖任何框架换到哪个模型 SDK 上都成立。3.3 迭代调优的具体做法代码跑通只是开始把它调得稳定可靠才是真正的活。我调优的优先级是先调工具描述和上下文结构再调提示词然后调记忆方案最后才考虑换模型。这个顺序反过来走大概率事倍功半。举一个真实例子search_articles 的 days 参数一开始描述写的是最近 N 天模型经常传字符串或者传负数。我把描述改成取值范围 1-30单位为天数值请使用整数之后参数错误率肉眼可见地降了下来。改一行描述往往比换一个模型便宜得多也有效得多。上线后每个任务我都会记录三组数字完成率、平均步数、平均 Token 消耗。完成率下降就去看失败轨迹步数异常就去查是不是陷入了无效搜索成本超标就去优化上下文管理。这些指标加起来就是你的 Agent 健康度。4. 常见问题与排查技巧实录这部分是真正的踩坑总结。下面这些问题能占到新手调试时间的 70% 以上。4.1 Agent 陷入死循环最典型的表现是模型反复调用同一个工具、传几乎一样的参数或者不停地在两个工具之间来回横跳。根因通常是模型感知不到状态变化它不知道该停甚至忘了自己刚刚做过什么。排查和处置有几步。第一步是加最大步数硬限制防止单个任务无限烧钱。第二步是做去重检测连续出现三次相同或高度相似的工具调用直接中断循环并向模型注入一条干预消息比如你刚才已经执行过相同的搜索没有获得新的有效信息请基于已有信息直接生成结论。第三步是在工具的返回结果里带上本次结果与上次相比是否有新增这类状态标记帮助模型自行判断是否该停止。4.2 Token 消耗爆炸Agent 的 Token 消耗会呈现二次增长趋势这个现象很多人第一次没想明白。每轮循环都会把完整历史重新发送如果历史每秒都在变长最后一轮的输入就包含了之前全部轮次的全部消息成本是滚雪球式的。我亲眼见过一个日活不到一千人的内部工具因为没做上下文管理单任务最高烧掉了十几万 Token。治理手段就是决策六里那套预算管理截断工具结果、滑动窗口保留最近对话、必要时用轻量模型做摘要压缩。另外一个省钱技巧是如果模型某一轮调用的工具结果和上一轮完全一样就干脆让上层逻辑拦截掉这次重复调用而不是再喂给模型一遍。4.3 工具参数错误或者调用不生效模型生成了工具调用但参数类型不对、必填字段缺失或者工具明明执行了但模型下一轮好像完全没看到结果。前者一般是 Schema 描述不够清楚后者则是反馈回路断了。处理方式分两层。第一层调用前做严格的 Schema 校验校验不过就把错误返回给模型让它自己修正不要静默吞掉。第二层确保工具调用产生的消息严格按照模型厂商要求的格式写入历史并携带正确的 tool_call_id。我在排查时见过不少工具结果丢了的案例最后发现是消息格式拼错了一个字段。4.4 规划质量差出现幻觉式行动计划模型输出了一份特别宏大的计划但里面的步骤跟现有工具毫无关系比如计划里写了访问灰产数据源自动注册账号而你的工具列表里根本没这些东西。这就是典型的幻觉式规划。治理思路是收紧约束在系统提示里明确你只能使用已注册工具不允许执行计划中不存在的操作把计划步骤数量限制在五步以内用较弱模型时必须加一道计划校验让一个独立调用去检查计划与工具列表的匹配度不匹配就要求重新规划。还有一个偏方是给工具起一看名字就知道干嘛的函数名这能显著减少模型在计划阶段脑补出不存在的工具。4.5 前一轮的错误污染了后续决策还有一种隐蔽的问题某一轮工具调用出错后错误信息里带着一堆异常堆栈模型被这部分内容带偏后面的决策全都围绕这个错误打转。这其实不是模型的问题是反馈信息设计的问题。我现在的做法是工具内部的详细异常堆栈只进日志不进模型上下文回传给模型的错误只保留一句话的摘要例如接口超时请在 10 秒后重试或参数 keyword 长度超限最大 20 个字。让模型看到它该看到的它才会做它该做的决定。下面把高频问题做成一个速查表方便你直接对照现象典型根因快速处置反复调用同一个工具模型感知不到状态未变化中断并注入请基于已有信息收尾Token 消耗过高历史全量重发 工具结果过长滑动窗口 结果截断 摘要压缩工具参数报错Schema 描述模糊缺少边界说明明确取值范围和类型错误回传自纠规划里出现不存在的工具系统提示约束不足只允许使用已注册工具列表前一轮错误带偏后续决策详细异常进入了模型上下文异常堆栈只进日志上下文只放一句摘要5. 最后聊聊我的真实体会做 Agent 工程两年多我的总结其实就一句话Agent 工程的核心是把不可控变可控。模型本身的输出是概率性的你所有的记忆设计、规划约束、工具协议、上下文管理、评估体系本质上都是在给这个概率系统加护栏让它在业务边界内稳定工作。有两条路我劝你不要走。一条是永远在追新框架今天 LangGraph 明天 CrewAI架构图换了一张又一张业务效果纹丝不动另一条是永远在手工调 Prompt调一次感觉好一点换个例子又崩了。这两条路我都走过最后发现真正管用的是评测集和可观测性先让 Agent 的每一步都看得见再让每一次修改都有数据可对照。如果你正打算把一个 ChatBot 升级成 Agent或者从零搭一个自动化助手我的建议很朴素先别急着画架构图也别急着选框架用几十行代码把你的核心任务闭环保地跑通一次哪怕跑得又慢又丑。让真实用户看到一次完整的自动闭环比任何 PPT 都有说服力。跑通之后再回来对着这篇文章里的七要素和七个决策点一项一项把系统补扎实。
返回列表