最近一段时间,"agent-native"这个说法在技术社区里被讨论得越来越频繁。我最早以为是某个新框架的宣传词,连续被几个团队拉着聊了几轮方案才发现,大家真正关心的是一种架构取向:你做的东西到底只是"给传统系统加了个 AI 对话框",还是"把自主代理当作系统核心来设计"。这两种路线表面上都是"我们用了大模型",落地时的工程复杂度、风险点、演进路径却完全不同。这篇文章想把差别讲透,并把我自己在一个真实项目里的拆解过程、工程取舍和踩坑记录完整分享出来,给正在做 AI 应用、尤其是准备把 agent 接进真实业务流程的朋友一个可参考的坐标系。
1. agent-native 到底在说什么——先跟"套壳 LLM"划清界限
1.1 从"给系统加个 AI 入口"到"让代理成为系统主体"
我见过太多号称"AI 原生"的项目,点进去就是一个聊天框挂在 Web 应用旁边。用户问一句,模型答一句,偶尔调两个接口查个订单状态。这种形态我们内部的称呼是 chat-wrapped,直白点说就是把大模型当成一个智能客服组件嵌进原有业务流里。不能说没用,但它本质上没有改变系统结构:数据库还是那套数据库,权限还是那套权限,业务流程里的所有分支判断仍然是人写在代码里的,模型只是在最后一步提供了一段生成文本。
agent-native 则完全换了一个出发点。它的核心主张是:代理——也就是具备记忆、工具调用能力和自主决策逻辑的智能体——是系统里的一等公民。你不是在"应用里塞一个 agent",而是在设计系统时,就围绕"代理会怎么感知任务、怎么规划步骤、怎么调用工具、怎么在失败时自我修正"来搭整个架构。业务状态不再只是数据库里的行记录,而主要流转在"感知 - 规划 - 行动 - 验证"这条代理循环里。
这个区别用一张对比表来看最直观:
| 维度 | 传统 LLM 应用(LLM-powered) | agent-native |
|---|---|---|
| 模型位置 | 业务代码流程末尾的文本生成节点 | 业务决策循环中心的中枢调度者 |
| 流程控制 | 人/代码预先画好流程,模型在节点内作答 | 代理根据上下文动态编排执行步骤 |
| 状态管理 | 外部数据库 + 少量会话缓存 | 代理工作记忆 + 持久化业务状态双轨制 |
| 工具接入 | 模型偶尔被调用,传入 1-2 个固定 API | 一整套工具集,代理自主选择顺序和参数 |
| 失败处理 | 报错 → 返回兜底文案 | 代理重试、换工具、自我修正、升级给人工 |
| 迭代发布 | 改代码发版本 | 改提示词、换模型、调工具描述,都要纳入测试 |
这张表不是我凭空画的,是连续做了几个项目之后总结出来的差异点。你只要看第一条就够:如果你的系统里,用户要走的路径、每个入口的返回值、成功失败之后的跳转逻辑都是预先写死的,那不管你调用了多少次大模型,它都算不上 agent-native。反过来,如果你发现自己在写"初始化任务、让代理循环决策、检查结果是否达标、不达标就让它再来一轮"这样的代码,那你已经在接近 agent-native 了。
1.2 为什么 chat 窗口模式撑不起复杂业务
可能有人会问:chat 模式有什么不好?用户体验简单直观,开发量也小。这个问题我在做第一个企业级 agent 之前也这么想,后来被一个售后工单场景教育了。
当时客户的需求是:用户提交一段乱七八糟的设备故障描述,系统要自动判断故障类型、匹配历史维修方案、生成一条初步排障建议、如果再搞不定就转人工。用 chat 模式做,你会在对话界面里让模型"一步一步分析",然后模型抛出一大段文字,用户再手动把方案转录到工单系统里。整个过程里,判断逻辑、数据查询、方案匹配这些事仍然散落在不同的系统调用里,模型只是把最终文本"念"出来。
真实业务根本不能这么玩。故障类型必须落到工单的结构化字段里,匹配到的历史维修方案需要可点击、可溯源,转人工要有明确的 SLA 倒计时。这些都不是"生成一段话"能搞定的。所以到了第二个版本,我们才真正转向 agent-native:把一个售后助理设计成"一个代理 + 一组工具 + 一个持久化工作状态机",用户输入进来的是一段自然语言,但系统里跑的是工具调用链,每一步都有输入输出、有上下文记录、有可审计的轨迹。用户看到的可以还是一个对话框,但骨架已经不是对话,而是一个任务执行系统。这也是我对 agent-native 最简单的一条判断标准:话是给用户看的,活是代理干的,系统记录的是活,不是话。
2. 拆开 agent-native 的核心骨架:状态、工具、记忆与信任边界
2.1 状态:agent 有两套记忆,别只盯着会话上下文
做 agent-native 的头一个坎,是搞清楚状态到底放在哪。很多团队一上来就陷入"上下文里塞多少 token"的纠结,其实这只是其中很小的一部分。我把 agent 的状态拆成两层:
第一层是工作记忆。就是当前这次任务执行过程中,代理已经做了哪些步骤、拿到过哪些中间结果、下一步打算干什么。这层状态最自然的存放位置是会话上下文里,每一次决策循环都会往里追加新的观察结果和工具输出。但要注意预算问题:上下文不是无限制的,工具返回结果过大时要截断、要摘要、要淘汰过期信息。我见过不少 agent 跑着跑着就把工具返回的 JSON 原样全塞进上下文,几个来回之后光上下文就有好几万 token,决策质量肉眼可见地下降。
第二层是持久化状态。这是 agent-native 和普通聊天机器人最不一样的地方。代理执行的任务往往是长时间、跨会话的:比如一个工单处理到一半,需要等用户在第二天补充设备型号;一个审批流走到某个节点,需要停下来等经理确认。这种状态必须落到外部存储里,而不是指望对话窗口一直挂着。我通常用一个状态存储服务,存三样东西:任务的完整执行轨迹、当前处于哪个阶段、已经产生的结果快照。代理恢复执行时,不是从零开始重新理解任务,而是从存储里把快照拉回来接着跑。
这两层状态缺一不可。只有工作记忆,任务一断就全没了;只有持久化状态,代理每一次决策都缺乏"刚才到底怎么走到这一步"的完整脉络。把这两套东西分开管理之后,一个非常实际的好处是:你可以对同一个任务做分支复制。比如系统拿到一个新工单,想试试三种不同策略,那就复制三份状态,让三个代理并行跑,谁先达标用谁。这在传统流程里几乎不可能做到。
2.2 工具:agent 的"能力描述"比工具本身更决定上限
agent-native 里,工具是代理和外部世界交互的唯一通道。工具设计得好不好,直接决定了这个 agent 是聪明还是蠢。我在这里吃过最大的亏,是花了一周时间精修每个工具的底层实现,却忽略了工具的描述和入参 schema。结果模型经常在调用时乱填参数,或者明明有更合适的工具却选了错误那个。
工具调用依赖的不是代码注释,而是给模型看的结构化描述。一个工具要包含三部分:名称、功能描述、入参 JSON Schema。名称要短但语义明确,功能描述要写清楚"这个工具在什么情况下用、有哪些坑",入参 Schema 要严谨,能枚举的字段就枚举,能设置默认值就设置默认值。我举一个实际例子,下边是一个常见工单工具的 schema:
{ "name": "lookup_repair_history", "description": "按设备型号和故障关键词检索历史维修工单,返回Top5相似方案。仅用于售后排障,不要用在下单流程。", "parameters": { "type": "object", "properties": { "device_model": { "type": "string", "description": "设备型号,如 用户未提供时必须先向用户询问" }, "fault_keyword": { "type": "string", "description": "故障现象关键词,可多个用逗号分隔" }, "top_k": { "type": "integer", "description": "返回条数,默认5,最大10" } }, "required": ["device_model", "fault_keyword"] } }写这个描述的过程其实就是变相编程。你在告诉模型:什么参数是必填的、缺了应该怎么办、这个工具有什么使用边界。我现在的习惯是,每个工具写完底层逻辑之后,至少让两个不同的人去 review 工具描述,一个站在开发角度检查 schema 严谨性,一个站在业务角度检查描述是否会让模型产生误用。上生产之后,我还会把"工具被误调用的案例"收集起来,定期回填进描述里作为负面提示。这比任何提示词工程都有效,因为工具层是结构化的,模型在这里出错的纠正成本远低于在自由文本里纠正。
2.3 记忆分层:短期上下文、长期知识与外部检索的取舍
聊完状态和工具,记忆是一个绕不开的话题。很多 agent 项目翻车就翻在"什么记忆都想往提示词里塞"。我个人现在用的是三层记忆结构:
短期记忆是当前任务上下文,这个对应工作记忆,主要给模型提供决策所需的即时背景。长期记忆则是这个 agent 在多次任务之间积累下来的知识,比如"这个客户的设备历来容易出电源模块故障"这类跨会话信息。外部检索则是指 vector store 或数据库查询,用于在需要时拉取外部文档、历史工单、产品手册。
三者的取舍核心是一个词:成本。短期记忆越厚,模型每次决策的延迟和 token 费用越高,而且注意力可能被稀释。外部检索虽然准,但每次都要多一跳网络开销和召回质量风险。我的实践原则是:跟当前任务无关的上下文一律不进提示词;跨会话的客户画像只在任务开始时加载一次摘要;具体细节全部通过工具查询,而不是预填进上下文。
一个反直觉的发现是:让模型"记得"某件事,不一定要把这件事写进上下文。只要把检索做成一个极其好用的工具,模型需要时会自己来查,效果通常比硬塞上下文更好。有一次我把一个超长的产品手册直接塞进上下文,模型反而把型号参数搞混了;改成摘要 + 按需检索之后,准确率反而上去了。这说明 agent-native 里,模型的推理质量和它"主动获取信息"的能力是强相关的,而不仅仅是"信息在不在眼前"的问题。
2.4 信任边界:高风险操作要设审批闸门
agent-native 赋予代理自主决策的权力越大,信任边界就越要画清楚。我在这块的原则是:所有高影响操作都必须经过一道审批闸门,不能因为模型"看起来已经理解了任务"就让它直接执行。
什么叫高影响操作?修改核心业务数据、发送对外通知、创建正式订单、删除记录,这些都是。低影响操作则是查询类、只读类、草稿类,这些可以完全自主执行。中间地带比如"更新工单状态但保留原状态字段以便回滚",我会把它设计成需要审批但可以一键通过的低摩擦操作。
实现信任边界最常见的做法是给每个工具打一个权限标签,再加一个人工审批节点。代理走到需要审批的工具时,不会直接执行,而是生成一个决策摘要,挂到一个待审批队列里,由运营人员在界面上点通过或拒绝。拒绝时并行地把拒绝原因写回状态,让代理可以重新规划路径,而不是卡死。
我把这个机制叫"软刹车"。它不是要把代理限制成干啥都要问的傀儡,而是在保留自主性的同时,把风险最大的几个操作放进人类可控的范围里。实测下来,这个设计不会让流程变慢多少,因为真正需要人工审批的操作只占全部调用的大概 5%,但整个团队对 agent 的信任度提升非常大——运营敢把系统挂上生产,是因为知道最后一道闸在自己手里。
3. 一次真实改造:把售后工单系统重构成 agent-native 架构
3.1 业务场景与约束条件
这部分讲一下我最近做的一个完整改造案例,前文提到的售后工单系统就是它。业务背景是一个做工业设备的厂商,售后一线每天收到几百条客户报障,以前的流程是:客服手工把报障内容录入工单系统,分类打标,再由技术员根据经验查历史方案,最后给客户回电话。整个流程平均耗时四十多分钟,而且严重依赖几个老技术员。
我们接到的目标很明确:用 agent 把"录入、分类、匹配历史方案、生成初步建议"这四步自动化,做不到的再转人工。约束条件同样明确:历史工单数据非常脏,设备型号经常写错;客服话术里混杂大量口语;工单系统是老平台,只提供有限的 API 接口,很多数据只能读不能写。
这个约束条件很关键,它决定了我们不能做一个"全自主 agent 接管所有环节"的炫技方案。最终我们做的,是一个边界感很强的 agent-native 系统:代理有自主决策空间,但对于写回工单系统的操作,全部走审批闸门;对于型号匹配不确定的情况,必须向用户确认而不是猜。听起来好像限制很多,但这恰恰是它最后能稳定上线的核心原因。
3.2 三层结构:编排层、执行层、验证层
整体架构我按三个层次来搭,每层的职责非常干净:
编排层负责拆解任务、维护任务状态机、决定什么时候继续什么时候转人工。它本质上就是一个 ReAct 循环,但多了一个"当前阶段"的概念。比如一个工单任务的状态机包括:信息收集、故障分类、方案匹配、建议生成、人工复核、完成。代理每完成一步,就把状态机推进一格,任何一步卡住超过阈值,就整体升级给人工。
执行层就是那组工具。我们开放给代理的工具包括:工单读取、历史工单检索、故障代码字典查询、客户信息查询、草稿建议保存。工具按功能划分,严格区分读和写。所有写操作工具内部都带一个 dry_run 模式,代理在正式写之前必须先用 dry_run 验证参数合法性,通过之后才能真正落库。
验证层是我在这个项目里加得比较重的一层。代理生成初步建议后,不会直接发给客户,而是先跑一个独立的验证器:检查建议里引用的历史工单是否真实存在、方案步骤是否完整、是否包含不安全的操作提示。验证器本身也是一个模型,但目标函数和主代理不一样,主代理负责"把事办成",验证器负责"挑毛病"。这两者互相制衡,比单个代理既当运动员又当裁判要稳得多。
3.3 最小可运行版本的简化代码
下面给一个简化版的核心循环伪代码,它基本就是我们生产代码的骨架,只是去掉了业务细节。这个循环要表达的不是什么高深算法,而是 agent-native 最核心的执行模型:
class AgentRuntime: def __init__(self, tools, model, store, max_steps=8, approval_gate=None): self.tools = {t.name: t for t in tools} self.model = model self.store = store self.max_steps = max_steps self.approval_gate = approval_gate async def run(self, task_id, task_text): session = await self.store.load_or_create(task_id) for step in range(self.max_steps): decision = await self.model.decide( task=task_text, stage=session.current_stage, tools=[t.schema for t in self.tools.values()], history=session.recent_history(), ) session.record("decision", decision) if decision.kind == "finish": await self.store.checkpoint(task_id, session) return session.output if decision.kind == "tool": tool = self.tools.get(decision.tool_name) if not tool: session.record("error", "unknown_tool") continue if tool.requires_approval and self.approval_gate: approved = await self.approval_gate.request(decision, task_id) session.record("approval", approved) if not approved: session.record("hint", decision.approval_reason) continue try: result = await tool.execute(decision.args, dry_run=tool.is_write) session.record("tool_result", {"tool": tool.name, "result": result}) except ToolError as e: session.record("tool_error", str(e)) await self.store.mark_needs_human(task_id, session) raise NeedsHumanEscalation(task_id)这段代码里藏着几个我觉得所有 agent-native 项目都应该有的设计。第一个是 max_steps,任何任务最多跑几步,防止代理陷入死循环。第二个是 session.checkpoint,每步都落一次状态,进程崩了也能恢复。第三个是 approval_gate,高风险操作在这里被拦截。第四个是 ToolError 的处理,工具失败不会让整个任务崩掉,而是把错误记进历史,让代理下一步自己调整策略。
3.4 为什么这样分层,而不是直接上多代理
当时团队里有人提议:既然要 agent-native,不如干脆上多代理架构,一个专门做分类,一个专门做方案匹配,再来一个做质检。我没有采纳,原因到现在依然成立:多代理带来的收益是并行和分工,代价是状态一致性极难维护。两个代理如果共享同一个工单状态,很容易出现一个在改字段、另一个在覆盖字段的冲突;如果各管各的状态,那又要引入一套复杂的代理间通信协议。
单代理 + 分层验证的方案在这个场景下最合适。主代理全权负责任务推进,验证器以工具的形式存在于执行层里,其实也是一个模型调用,但不参与主循环的状态推进。这样既保留了"一个核心代理掌控全局"的清晰性,又在关键节点上引入了独立的校验力量。等以后任务量真的大到单代理撑不住,再考虑把分类这一步拆出去做成独立的子代理,到时候边界是清晰的——从"信息收集"到"故障分类"的交接点就是天然的拆分边界。
4. 上生产前必须想清楚的四个工程问题
4.1 成本与延迟:一次任务调用链到底烧多少钱
agent-native 和传统接口最大的不同是:一次任务可能要调十几次甚至几十次模型接口,成本不是"一次问答"能算的。我在第一个版本上线前做过一个估算,直接把团队吓一跳。
以一个典型工单为例:信息收集阶段可能要 3 次对话决策,分类阶段 2 次,历史工单检索后还需要 2 次分析,生成建议 1 次,验证器再跑 1 次,遇到参数不清晰要追问用户再来 2 次。加起来 10 次左右的模型调用,每次按输入 2000 token、输出 1000 token 算,如果使用中档模型,单任务成本大约是几毛钱。单看不多,但一天几百个任务,一个月下来就是四位数到五位数的成本。这还没算重试:如果工具报错让代理重新规划,一次不计成本的自我修正可能额外增加 5-8 次调用。
这个现实逼着我们在工程上做了几件事:第一,能缓存的绝不重复调用,比如同一客户的历史工单摘要缓存半小时;第二,给每一步设置独立的 token 预算,信息收集阶段不需要长篇大论就限制输出长度;第三,任务级设置熔断,如果累计调用了 25 次还没完成,直接扣住转人工,不继续烧钱。成本控制不是财务问题,它是技术架构的一部分。
4.2 可观测性:记录 agent 的"思想轨迹"
传统后端排查问题看日志、看调用链,agent-native 项目里这些都不够。代理的决策过程是模型生成的,不是代码写死的,一旦任务结果不对,你得能回答"它当时为什么这么想"。
所以我们的日志体系里多了一个专门的事件流:每个决策记录下模型收到的提示词版本、工具列表、当时的上下文摘要、模型原始返回、解析后的决策,以及这一步之后的系统状态变化。相当于给代理的每一步决策都拍了照。后期排查问题时,我先看事件流,再决定是工具问题还是提示词问题。
这个事件流的存储量很大,但我们不会存完整上下文,只存摘要和关键字段,原始数据离线归档。我建议任何 agent-native 项目从第一天就建立这种"决策轨迹"日志,不要等出事了再补。因为事后你根本没法重现模型当时的上下文状态,不记录就是黑盒。
4.3 灰度与回滚:agent 行为不是普通链路能管的
给 agent-native 系统发版本,和传统系统完全是两码事。传统系统改个接口逻辑,回滚就是把旧代码再部署一次。agent 项目里,行为由模型权重、提示词、工具描述三个变量共同决定,任何一个变了,行为都会漂移。
我的做法是给这三个维度分别做版本号,并支持独立灰度。比如换了新的提示词,只在 10% 的任务里生效,观察成功率、平均调用次数、转人工率有没有变化,再逐步放量。模型版本升级更谨慎,先在内部测试集上跑一遍,再灰度到低风险任务。工具描述修改也一样,别小看一句话的变化,它可能让代理突然改用另一个工具。
回滚机制更要提前设计。我在系统里存了每个任务的模型快照和提示词快照,一旦发现线上任务质量下降,可以一键把某个任务类型恢复到旧的提示词版本。如果没有这套机制,代理行为异常时你只能干瞪眼,想回到"上一个正常版本"都不知道那个版本长什么样。
4.4 评估与回归:没有评估集的 agent 项目迟早失控
最后这个问题是最重要的。普通开发有单元测试、回归测试,agent-native 项目的"测试"长什么样?我见过不少团队把这个环节省了,上线之后靠人工抽检,然后在一个模型升级之后突然崩盘,才发现毫无预警手段。
我的做法是建一个"任务级评估集":精选一百到两百个有标准答案的历史任务,每个任务定义清楚成功标准,比如工单分类是否准确、建议里是否引用了正确的历史工单、是否在规定步数内完成、有没有触发多余的审批流程。每次改提示词、换模型、改工具描述,先跑一遍这套评估集,用成功率、平均步数、转人工率三个指标做对比。
这套评估集的价值体现在一个具体案例里:我们试过从旧模型升到新模型,直觉上感觉新模型"聪明多了",但评估集跑下来,分类准确率确实提升了 4 个百分点,可建议生成环节的格式错误率涨了 6 个百分点,一升一降净效果是负的。如果当时没有评估集直接上线,这种隐性退化可能要过好几天才会在客诉里暴露。从那之后评估集就成了我们 agent-native 项目的强制门槛,没有评估集的改动不允许合并到主线。
5. 我踩过的坑:agent-native 实践里最常见的翻车点
5.1 坑一:给了 agent 写库能力,却没设权限边界
第一个项目里,我做了一个"更新工单状态"的工具,本意是让代理在处理过程中顺带把工单推进到下一阶段。工具本身没问题,问题出在我把 update_ticket_status 和 query_ticket 放在同一个工具集合里,没有任何审批区分,模型可以自由使用。上线第三天,代理在一次信息收集不完整的情况下,把一个"待客户确认"的工单直接改成了"已解决"。客户看到工单关闭又炸了,我们才发现状态已经被改掉。
后来我把所有写操作工具单独打标签,强制走审批闸门,并且工具内部对所有写操作记录变更前后快照。虽然增加了代理的等待时间,但再也没有出现过状态被误改的事故。这个坑的教训是:工具能力要做最小化授权,代理再聪明也不要让它拥有比必要的更大权限。权限不是给人用的,是给 Agent 用的,一样适用最小权限原则。
5.2 坑二:循环不设上限,费用和延迟一起爆
还有一次我们运行了一个批处理任务,让代理批量处理一批老工单。因为某个外部客户系统临时故障,代理每查一次客户信息就报错,但它没有放弃的意思,每次报错之后继续重试,换了不同的措辞重新调用同一个故障接口。结果一个工单被反复调用工具二十多次,整批任务跑完,费用是预算的十几倍,时间也拖到了正常情况的三倍。
这个问题的根源就是运行时没设 max_steps 上限,我之前在代码示例里写那个参数不是装饰,是真刀真枪换来的教训。修好之后,我们对同一个工具连续报错三次就进入熔断,连续失败的任务直接转人工,绝不让代理在同一个坑里反复横跳。同时我还加了一个"工具失败次数"统计,一旦某个工具在单任务里失败超过两次,下一个决策里就强制禁止再调用它。
5.3 坑三:把不确定性硬塞进确定性代码
这个坑是我一个同事踩的,踩得很典型。我们的建议生成模块外面包了一层 try-except,模型调用失败时,代码会捕获异常并返回一个写死的兜底文案:"系统暂时无法处理,请稍后重试"。听起来很常规对吧?问题出在兜底文案成了常态而不是异常:当模型输出格式稍微不规范、或者工具返回的结果不满足校验规则时,系统就会静默地给出那段兜底文案,而底层却显示"任务处理失败"。
对用户来说,他得到的体验是"系统拒绝了我但没有说明原因"。这其实是把 agent 的不确定性硬编码成了一个确定的失败结果,而且这个失败结果误导性极强。正确的做法是:agent 处理不了就明确升级,把它转给人工,并带着完整的处理轨迹一起转。宁可让用户等待人工介入,也不能用一个"假失败"把问题掩盖掉。现在我们的设计原则是:代理永远不允许"静默失败",要么给出有效产出,要么带着上下文转人工,没有第三条路。
5.4 坑四:一上来就多代理,结果状态先打架
前面写到我最终选择了单代理 + 验证器,这个选择背后还有一个踩坑故事。最早我们确实尝试过年度多代理方案,设计了客服代理、质检代理、知识库维护代理三个角色。结果客服代理从知识库维护代理那里拉数据时,两边对同一份产品资料的理解不一致,客服代理按新版本回复客户,知识库维护代理却按旧版本更新了缓存,造成短时间内对同一客户给出互相矛盾的答复。
那之后我形成了一个判断:多代理不是目标,是手段。只有当任务能拆成真正低耦合的子流程时,多代理才有价值。如果两个代理共享同一份可变的状态,那多半说明它们本质上是一个代理应该做的事情。设计 agent-native 系统,优先把单代理做扎实,等碰到清晰的并行边界再拆。老老实实、一台代理跑完的任务,正确率通常比几个代理协作高得多,出错了也好定位。
6. 关于 agent-native 我目前的判断——以及给新手的起步建议
6.1 什么业务适合 agent-native,什么业务别硬贴
做了几个项目之后,我逐渐能看出什么业务真正适合 agent-native。核心判断标准不是"业务是否先进",而是"任务的完成是否依赖不确定的探索过程"。售后排障、智能运维、流程自动化的复杂工单、需要跨多个系统查证数据的助手,这些任务天然适合 agent-native,因为结果无法用一段固定代码画出来,必须让代理根据输入动态调整路径。
反过来,内容生成、简单问答、格式转换这类任务,用传统提示词管线或者模板就能解决,硬套 agent-native 只会增加成本和延迟。比如"把一段文本翻译成英文""根据标题生成摘要",这些跟 agent 的决策循环关系不大,没有必要为了追潮流把架构做复杂。我的判断是:agent-native 的价值在于执行,不在于生成。凡是"做完一件事"比"说好一段话"更重要的场景,才值得用 agent-native 架构。
6.2 如果从头再来,我会这样起步
如果让我给一个从零开始的朋友建议,我会让他别急着搭复杂框架,先把手里的最小业务场景改造成"单代理 + 三个工具 + 一个评估集"的最小闭环。具体步骤是:选一个只有单一入口的任务,比如"根据工单标题自动归类",设计好三个工具,一个查询历史数据,一个读取分类字典,一个写结果草稿;然后用一周时间把 ReAct 循环跑通;再花一周把决策轨迹日志和评估集建起来。两周之后,你就已经拥有一个可观测、可评估、可上线的 agent-native MVP。
这个最小闭环的价值在于它强制你面对所有真正核心的问题:状态怎么存、工具怎么描述、失败怎么处理、怎么验证效果。这些问题在 demo 阶段永远暴露不出来,只有到了"要真跑业务"的时候才会一个个跳出来。等到最小闭环稳定了,再去扩展工具数量、增加验证器、考虑多代理拆分,路会顺很多。
最后说一个我最近才充分意识到的事实:agent-native 本质上是把"系统的控制权"从程序员手里转移给了模型。这带来自由,也带来责任。自由是它能处理前所未有的复杂输入,责任是你必须为它的每一个决策留下轨迹、设定边界、准备好退路。想清楚这两面,再动手写第一行代码也不迟。