
1. 从一锅炖到分层交付AI Agent 工程化的分水岭如果你最近在折腾 AI Agent大概率经历过这样的场景Demo 阶段一切丝滑模型能聊天、能调工具、能给出看起来靠谱的答案你信心满满准备上线。结果一进真实业务问题全冒出来了——同一个问题问两遍答案不一样工具调用时好时坏模型偶尔幻觉出一个根本不存在的接口日志里全是无法复现的报错。你回头一看代码发现提示词、工具定义、业务逻辑、状态管理、模型调用全糊在一个文件里改一处牵动全身。这就是典型的把智能糊进一锅。AI Agent 工程化的核心命题不是让模型更聪明而是让这套系统在真实业务里可交付、可维护、可迭代。而分层交付正是从能跑到能上线之间那道最关键的分水岭。我先把结论摆出来一个能进生产的 Agent 系统至少要拆成模型层、能力层工具/技能、编排层、状态与记忆层、交付接口层这五层。每一层有独立的职责边界、独立的测试方式、独立的迭代节奏。把它们混在一起你得到的不是 Agent是一个随时会炸的黑盒。这篇内容适合三类人一是正在从 0 到 1 搭建 AI Agent 的开发者二是被Demo 很惊艳、上线很拉胯折磨过的工程同学三是需要给团队定 Agent 开发规范的技术负责人。我会把分层交付的每一层拆开讲清楚——为什么这么分、每层具体放什么、层与层之间怎么通信、以及我在实际项目里踩过的坑。先澄清一个高频困惑Agent、LLM、AI 模型到底什么关系很多人把这三个词混着用。AI 模型是最大的范畴指所有经过训练的神经网络模型LLM大语言模型是 AI 模型里专门处理语言的那一类比如 DeepSeek、GPT 系列都属于 LLM而 Agent 是在 LLM 之上加了一层感知—决策—行动的循环结构它能调用工具、维护状态、根据结果调整下一步。打个比方LLM 是一个博学但只会动嘴的顾问Agent 是给这个顾问配了手、配了记事本、配了执行流程之后的项目经理。分层交付本质就是把这个项目经理的各个器官拆开管理而不是指望一个大脑包办所有事。2. 为什么糊成一锅的 Agent 一定会在生产环境翻车2.1 耦合带来的三个致命问题我见过太多项目一个agent.py文件里塞了三千行系统提示词写在最上面工具函数定义在中间业务分支判断散落各处模型调用参数硬编码在函数里。这种结构在 Demo 阶段跑得飞快因为改起来方便——反正都在一个文件里。但一旦进入多人协作和持续迭代三个问题会同时爆发。第一是可测试性归零。你想单独验证工具选择这个环节对不对但工具选择逻辑和提示词、和模型参数、和业务上下文全绑在一起你没法隔离测试。只能端到端跑一遍看最终输出对不对。问题是最终输出错了你根本不知道是提示词的问题、工具描述的问题还是模型本身的问题。第二是可替换性归零。业务方说我们想从 A 模型换成 B 模型试试效果你打开代码发现模型调用散落在十几个地方每个地方的参数格式还不一样。换模型这件事从改一个配置变成了重构一遍。第三是可观测性归零。线上出了问题你只能看到用户输入 X系统输出 Y中间发生了什么完全是个黑盒。是模型没理解意图是工具调用失败了是状态丢失了没有分层埋点你连排查的入口都找不到。2.2 一个真实的翻车案例我之前参与过一个客服 Agent 项目早期版本就是典型的一锅炖。上线第一周用户投诉同一个退款问题Agent 给的答复前后矛盾。排查过程极其痛苦日志里只有输入输出没有中间态。我们花了整整两天最后定位到根因——记忆层和编排层耦合。Agent 在处理多轮对话时把上一轮的临时工具返回结果错误地写进了长期记忆导致下一轮对话时模型读到了过期的上下文。如果当初做了分层这个问题在架构上根本不会发生记忆层有明确的写入策略和读取策略临时结果和长期记忆物理隔离编排层只负责调度不负责存储。分层不是为了好看是为了让某类 bug 在结构上不可能出现。2.3 分层的本质把不确定性关进笼子LLM 最大的特点是不确定性——同样的输入可能得到不同的输出。这是它的能力来源也是工程化的最大敌人。分层交付的核心思路是把不确定性收敛到尽可能小的范围里。模型层是唯一允许存在不确定性的地方。能力层、编排层、状态层、接口层全部要做成确定性的、可测试的、可预测的。这样当系统出问题时你能快速判断是模型层的不确定性导致的那就调提示词、换模型、加约束还是其他层的确定性逻辑写错了那就正常 debug。这个思路和传统软件工程里的隔离变化原则一脉相承。把易变的部分模型行为和稳定的部分业务流程、数据结构分开让变化的影响范围可控。3. 五层架构逐层拆解每层到底放什么3.1 模型层唯一的不确定性来源模型层是整个系统里唯一不保证确定性的部分所以它的职责要尽可能纯粹接收结构化的输入返回结构化的输出。除此之外什么都不干。具体来说模型层要封装这几件事模型选型与路由不同任务用不同模型、提示词模板管理、输出格式约束强制 JSON Schema、重试与降级策略、Token 计量与成本控制。注意这里说的是封装不是实现业务逻辑。模型层不应该知道退款流程是什么它只知道给我一段文本和一个 schema我还你一段符合 schema 的 JSON。我在实际项目里会给模型层定义一个统一接口类似这样class ModelLayer: def invoke(self, prompt_template: str, variables: dict, output_schema: dict, model_hint: str default) - dict: # 1. 渲染提示词 # 2. 根据 model_hint 路由到具体模型 # 3. 调用模型强制输出符合 output_schema # 4. 校验输出失败则重试最多 N 次 # 5. 记录 token 消耗和延迟 # 6. 返回结构化结果 pass这个接口的关键在于输出 schema 强制校验。很多人调模型就是response model.chat(prompt)然后拿字符串去解析解析失败就崩。正确做法是让模型层负责保证输出结构正确上层拿到的永远是校验过的结构化数据。重试逻辑也放在这一层因为模型输出格式不对是模型层的问题不该让上层处理。提示模型层的重试要有上限并且要区分格式错误重试和内容错误重试。格式错误可以自动重试内容错误比如模型说我无法回答重试通常没用应该直接向上抛由编排层决定降级策略。3.2 能力层工具与技能的标准化封装能力层是 Agent 的手脚也就是工具Tool和技能Skill的集合。这一层的核心任务是把每一个外部能力封装成模型能理解、系统能调用的标准单元。一个标准的工具定义包含四部分名称、自然语言描述给模型看的、参数 schema结构化、执行函数。很多人只写执行函数描述随便糊一句结果模型根本不知道该在什么时候调用这个工具。工具描述的质量直接决定 Agent 的工具选择准确率这一点怎么强调都不过分。我总结的工具描述写法说清楚这个工具做什么、什么时候该用、什么时候不该用、参数的含义和格式。举个例子一个查询订单的工具描述不该只写查询订单而应该写根据订单号查询订单的详细状态包括物流、支付、退款进度。当用户询问具体订单的状态时使用。不要用于查询用户的历史订单列表那应该用 list_orders 工具。能力层还要处理工具执行的容错。外部 API 会超时、会返回错误、会限流。这些异常不该直接抛给模型而应该在能力层被捕获并转换成模型能理解的错误信息比如订单查询服务暂时不可用请稍后重试。这样模型可以据此决定是重试、换工具还是告知用户。工具封装要素常见错误正确做法工具描述一句话带过说明用途、使用时机、禁用场景参数 schema用自然语言描述参数用 JSON Schema 严格定义类型和必填项错误处理异常直接抛出捕获后转成模型可读的错误信息幂等性不区分读写写操作要支持幂等键防止重复执行超时控制用默认超时按工具特性设置独立超时3.3 编排层Agent 的大脑回路编排层是决定下一步做什么的地方也是 Agent 区别于普通 LLM 调用的核心。它负责意图识别、任务规划、工具选择、多步执行、结果整合。但注意编排层本身应该是确定性的代码逻辑而不是又一层模型调用。这里有个常见的误区很多人把编排也交给模型让模型输出下一步该调用哪个工具。这在简单场景下可行但在复杂业务里会失控——模型可能陷入循环、可能跳过必要步骤、可能做出业务上不允许的操作。我的做法是混合编排用代码定义主流程骨架确定性的状态机在关键决策点让模型做选择受约束的不确定性。比如一个退款 Agent 的主流程是确定的验证身份 → 查询订单 → 判断是否符合退款条件 → 执行退款 → 通知用户。这个骨架用代码写死。但判断是否符合退款条件这一步可以让模型结合订单信息和退款政策做判断。这样既保证了流程可控又利用了模型的语义理解能力。编排层还要负责循环控制。Agent 的多步执行必须有明确的终止条件达到最大步数、任务完成、或者遇到无法处理的错误。没有终止条件的 Agent 循环是生产事故的温床。3.4 状态与记忆层别让上下文变成垃圾场状态与记忆层是最容易被忽视、也最容易出问题的一层。它要回答三个问题当前对话的状态是什么、历史信息怎么存、什么时候读什么时候写。我把记忆分成三类物理隔离存储会话状态当前这一轮对话的临时数据比如用户刚说的订单号、刚调用的工具结果。生命周期是单次会话会话结束即销毁。短期记忆最近 N 轮对话的摘要用于维持对话连贯性。有容量上限超出后做摘要压缩。长期记忆用户的偏好、历史行为、关键事实。需要显式的写入策略不能什么都往里塞。前面那个翻车案例的根因就是把临时工具结果错误地写进了长期记忆。正确做法是工具返回结果默认只进会话状态只有经过明确的记忆提取步骤判断这条信息是否值得长期记住才写入长期记忆。注意长期记忆的写入一定要有准入判断。我见过太多项目把用户说的每句话都存进向量库结果检索时全是噪音。记忆不是越多越好是越准越好。3.5 交付接口层对外的稳定契约交付接口层是 Agent 对外的门面负责协议适配、鉴权、限流、日志埋点、以及最重要的——对外契约的稳定性。这一层的设计原则是内部怎么改都行对外接口不能变。业务方调用你的 Agent不应该关心你用的是哪个模型、工具怎么封装、记忆怎么存。他们只关心输入什么、输出什么、错误码是什么。接口层还要做全链路追踪。每个请求分配一个 trace_id贯穿模型层、能力层、编排层、状态层。这样线上出问题时你能通过一个 trace_id 还原整个执行链路看到每一步的输入输出、耗时、token 消耗。没有这个排查问题就是大海捞针。4. 层与层之间怎么通信契约先行的实操方法4.1 用数据结构定义层间契约分层之后层与层之间的通信就成了关键。我的经验是先定义数据结构再写实现。每一层的输入输出都用明确的 schema 定义任何跨层传递的数据都必须符合 schema。比如编排层调用能力层的契约# 编排层 - 能力层 { tool_name: query_order, arguments: {order_id: 12345}, trace_id: abc-123, timeout_ms: 3000 } # 能力层 - 编排层 { status: success, # success | error | timeout data: {...}, # 成功时的结构化数据 error: None, # 失败时的错误信息 latency_ms: 245 }这种契约先行的好处是任何一层都可以被 mock 掉单独测试。测试编排层时能力层返回预设的 mock 数据测试能力层时不需要启动模型。可测试性是分层交付最大的红利。4.2 依赖方向单向依赖禁止反向调用分层架构有一条铁律依赖只能单向上层依赖下层下层绝不反向调用上层。模型层不知道能力层的存在能力层不知道编排层的存在。违反这条规则的典型症状是工具函数里直接调用了编排逻辑或者模型层里硬编码了业务判断。一旦出现反向依赖分层就名存实亡了。我判断一个 Agent 项目分层是否合格有个简单方法看能不能把某一层单独抽出来复用。如果模型层能被另一个完全不同的 Agent 项目直接拿去用说明分层是干净的如果抽出来发现到处是业务耦合说明还是糊在一起的。4.3 异常传播每层只处理自己该处理的异常异常处理是分层里最容易乱的地方。原则是每层只处理自己能处理的异常处理不了的向上抛但抛之前要转换成上层能理解的格式。模型层的异常格式错误、超时在模型层重试重试失败后转成模型调用失败向上抛。能力层的异常API 错误、限流在能力层转成模型可读的错误信息。编排层收到异常后决定降级策略换工具、告知用户、终止流程。接口层负责把最终结果转成对外错误码。这样每一层的异常处理逻辑都很清晰不会出现底层异常直接冒到顶层用户看到一个看不懂的堆栈的情况。5. 落地时的真实坑分层不是画架构图5.1 过度分层的陷阱分层虽好但容易走极端。我见过一个项目把 Agent 拆成了十二层每层之间还要经过消息队列异步通信。结果一个简单的问答请求链路走下来要几百毫秒的额外开销调试时要在十几个服务之间跳来跳去。分层的粒度要匹配团队规模和业务复杂度。小团队、单一业务场景五层足够了甚至可以把状态层和编排层合并。大团队、多业务线才需要更细的拆分。分层的目的是降低认知负担和变更风险如果分层本身成了负担那就是过度设计。我的建议是先按五层起步遇到具体的痛点再拆。比如发现记忆逻辑太复杂再把它从编排层独立出来。不要一开始就追求完美的架构。5.2 提示词该放哪一层这是个高频争议点。我的答案是提示词模板放模型层提示词内容按用途分散。系统级的提示词定义模型角色和输出格式放模型层业务级的提示词定义具体任务放编排层作为参数传给模型层。这样做的理由是系统提示词是跨业务复用的属于模型层的基础设施业务提示词是随业务变化的属于编排层的业务逻辑。混在一起会导致改业务提示词时误伤系统提示词。5.3 状态管理的一致性难题多步执行的 Agent 里状态一致性是个硬骨头。比如 Agent 执行到第三步时失败了前两步的副作用比如已经调用了写接口要不要回滚我的做法是把有副作用的操作尽量后置并且设计成幂等。读操作可以随便重试写操作要么放在流程最后要么带幂等键。同时状态层要记录每一步的执行状态支持从失败点恢复而不是从头重来。5.4 观测埋点的最小集合分层之后埋点要覆盖每一层的边界。我总结的最小埋点集合是每次模型调用的输入输出和 token 消耗、每次工具调用的参数和结果、编排层的每一步决策、状态层的读写操作、接口层的请求响应和总耗时。这些数据通过 trace_id 串起来就是完整的执行链路。没有埋点的分层等于没有分层的黑盒。埋点是分层交付能真正发挥价值的前提。6. 从分层到交付一套可复用的检查清单6.1 上线前的分层自检在把 Agent 交付上线前我会过一遍这份清单模型层是否所有模型调用都经过统一接口输出是否强制 schema 校验重试策略是否明确能力层每个工具是否有清晰的描述和参数 schema异常是否被正确转换写操作是否幂等编排层主流程是否确定性可控是否有明确的终止条件降级策略是否定义状态层三类记忆是否物理隔离长期记忆是否有准入判断状态是否可恢复接口层对外契约是否稳定是否有全链路 trace_id错误码是否规范这份清单过一遍能挡掉大部分上线后才会暴露的问题。6.2 迭代时的分层影响分析分层最大的价值在迭代时体现。当业务方提一个新需求你能快速判断它影响哪几层换个模型只动模型层加个工具只动能力层改个流程只动编排层。影响范围可控是分层交付给团队带来的最实在的收益。我在实际项目里有个习惯每次需求评审时先做一次分层影响分析明确这次改动涉及哪几层、每层改什么、层间契约要不要变。这个习惯让我们的 Agent 项目在半年迭代里几乎没有出现过改 A 崩 B的情况。6.3 给团队的分层开发规范如果要把分层交付推广到团队我建议定几条硬规矩跨层调用必须走契约、禁止反向依赖、每层必须有独立的单元测试、埋点必须覆盖层边界、提示词按用途分层存放。这几条规矩不需要多复杂但能保证团队里每个人写的 Agent 都能拼到一起。回到最开始那句话AI Agent 工程化的核心不是让模型更聪明而是让系统可交付。分层交付就是实现这个目标最朴素也最有效的方法。别把智能糊进一锅把它拆开每一层管好自己的事剩下的交给契约和测试。这套方法我在几个项目里反复验证过越复杂的业务分层的收益越明显。