1. 当所有人都在聊模型时,真正的工程战场已经转移了
过去一年,我参加过的技术交流里,十场有八场在讨论模型参数、推理成本、上下文窗口。但真正让我睡不着觉的,是另一件事:一个能跑通Demo的智能体,和一个能扛住真实业务流量的智能体,中间隔着的距离,比大多数人想象的要远得多。
这个距离,就是Agent Infra——智能体基础设施。
说得直白一点,Agent Infra是让智能体从“玩具”变成“工具”的那层工程底座。它管的是:任务怎么拆解和调度、工具怎么注册和调用、记忆怎么存储和检索、多个智能体之间怎么协作、执行链路怎么观测和回滚、权限怎么隔离、成本怎么控制。这些东西听起来不如模型本身性感,但任何一个真正把智能体推进到生产环境的团队都会告诉你:模型能力决定了下限,基础设施决定了上限。
这篇文章适合三类人看。第一类是做应用开发的工程师,你已经在调API做智能体,但发现越做越乱,想搞清楚系统化的工程方法。第二类是技术负责人,你在评估智能体到底能不能进业务流程,需要知道工程上要准备什么。第三类是对这个方向感兴趣但还没动手的人,你想知道这个领域的全貌和切入点在哪里。
我会从实际工程的角度,把Agent Infra拆开来讲。不堆概念,不画大饼,讲清楚每个模块解决什么问题、为什么这样设计、实际落地时容易踩什么坑。读完之后,你应该能判断自己当前的项目处于哪个阶段,下一步该补哪块能力。
2. 拆解Agent Infra:它到底由哪些东西构成
2.1 从一次真实的失败说起
先讲一个我亲身经历的场景。早期我做过一个智能体,功能是帮用户整理会议纪要并自动生成待办事项。Demo阶段非常顺利,输入一段会议记录,它能提取关键信息、识别行动项、分配给对应的人。但上线第一周就出了问题:有用户输入了一份两万字的会议记录,智能体在处理到一半时上下文超限,直接报错;另一个用户连续提交了五份纪要,系统把不同会议的待办事项混在了一起;还有一个场景是智能体调用日历工具创建事件时,因为权限配置问题,把事件创建到了错误的日历上。
这三个问题,没有一个跟模型能力有关。它们全部是基础设施层面的缺失:上下文管理、会话隔离、权限控制。这就是为什么我说Agent Infra是真正的战场——模型能力已经足够强了,但工程底座没跟上,智能体就永远只能停留在演示阶段。
2.2 Agent Infra的六个核心模块
把Agent Infra拆开来看,我认为它包含六个相互关联的模块。每个模块解决一类特定的工程问题,缺了任何一个,系统都会在某个场景下出问题。
任务编排与调度是整个系统的中枢。它负责接收用户请求,决定用哪个智能体来处理,把复杂任务拆解成子任务,按依赖关系排序,然后依次或并行执行。这里的关键设计决策是:用静态的流程图来编排,还是让模型动态决定下一步?静态编排可控性强但灵活性差,动态编排灵活但难以预测和调试。实际工程中,大多数团队采用的是混合方案——主干流程静态定义,分支决策交给模型。
工具注册与调用是智能体与外部世界交互的通道。每个工具需要定义清晰的输入输出schema、错误处理逻辑、超时策略和重试机制。我见过太多项目把工具调用写成一堆散落的函数,没有统一的注册中心,结果就是新增一个工具要改五个地方,排查一个调用失败要翻三四个日志文件。
记忆与状态管理解决的是智能体的“记性”问题。短期记忆对应当前会话的上下文,长期记忆对应跨会话的知识积累。这里最容易被忽视的是状态的一致性——当智能体在多个步骤之间传递信息时,如何保证状态不会丢失、不会串扰、不会因为某个步骤失败而整体崩溃。
多智能体协作是当单个智能体搞不定时引入的横向扩展能力。一个智能体负责规划,一个负责执行,一个负责审核,它们之间怎么通信、怎么解决冲突、怎么保证整体目标一致,这些都是需要基础设施来支撑的。
可观测性与调试是生产环境的生命线。你需要知道每一次智能体调用的完整链路:输入是什么、模型返回了什么、调用了哪些工具、每个工具耗时多久、最终输出是什么、中间哪一步出了问题。没有这套东西,线上出问题你只能靠猜。
安全与权限是最后但绝不是最不重要的模块。智能体可以调用工具、访问数据、执行操作,这意味着它需要一套完整的权限体系。哪些工具可以被哪些智能体调用、哪些数据可以被哪些用户访问、敏感操作是否需要二次确认,这些都必须在前端基础设施层面解决,而不是指望模型自己判断。
2.3 为什么现在必须关注Agent Infra
一个很现实的判断:模型能力正在快速商品化。今天某个模型在某个基准上领先几个百分点,下个月可能就被追平了。但基础设施能力不一样,它需要时间积累、需要踩坑、需要跟具体业务场景磨合。一个团队在Agent Infra上投入的工程能力,会成为它真正的护城河。
另一个原因是,智能体的应用场景正在从“单点任务”走向“复杂工作流”。早期的智能体就是问答、翻译、摘要这些单步任务,对基础设施的要求很低。但现在越来越多的场景要求智能体连续执行十几个步骤、调用七八个工具、在多个系统之间传递数据。这种复杂度下,没有基础设施支撑就是在裸奔。
3. 任务编排:从“能跑”到“跑得稳”的关键一跃
3.1 静态编排与动态编排的取舍
任务编排是Agent Infra里最核心也最难做好的部分。我把它比作乐高积木的底板——所有其他模块都插在这块底板上。
静态编排的思路是:开发者预先定义好一个流程图,每个节点是一个步骤,节点之间的连线是执行顺序。智能体按照这个图一步步走,遇到条件分支就根据预设规则选择路径。这种方式的优点是可控、可预测、容易调试。缺点是灵活性差,遇到流程图没覆盖的情况就卡住了。
动态编排的思路是:给智能体一个目标,让它自己决定怎么拆解、怎么执行。这种方式灵活,能处理开放性问题。但缺点是难以预测行为、难以保证一致性、调试成本高。
我的经验是:主干流程用静态编排,分支决策用动态编排。比如一个客服智能体,主干流程是“识别意图→查询知识库→生成回复→判断是否需要转人工”,这是固定的。但在“查询知识库”这一步,用哪个检索策略、检索几个结果、要不要追问用户,这些可以交给模型动态决定。
3.2 任务拆解中的粒度控制
任务拆解的粒度是一个容易被忽视但影响巨大的问题。拆得太粗,单个步骤太复杂,模型容易出错;拆得太细,步骤数量爆炸,调度开销和上下文传递成本都会上升。
我的一般原则是:每个步骤应该是一个“原子操作”——要么是一次模型调用,要么是一次工具调用,要么是一次数据转换。如果一个步骤里包含多次模型调用或工具调用,就应该考虑继续拆。
但这里有个例外:如果多个操作之间有强依赖关系,且中间结果不需要暴露给外部,可以合并成一个步骤。比如“读取文件→解析内容→提取关键字段”这三个操作,如果它们总是连续出现且中间结果不需要单独记录,就可以合并。
3.3 错误处理与重试策略
生产环境里,任务失败是常态而不是异常。工具调用超时、模型返回格式错误、外部API限流,这些都会导致步骤失败。基础设施需要提供统一的错误处理和重试机制。
我的做法是给每个步骤定义三个属性:最大重试次数、重试间隔策略、失败后的降级方案。最大重试次数一般设为2到3次,因为大多数临时性故障在重试后能恢复。重试间隔用指数退避,第一次等1秒,第二次等2秒,第三次等4秒。降级方案则取决于业务场景——可以返回缓存结果、可以跳过该步骤继续执行、可以终止整个任务并通知用户。
注意:重试不是万能的。如果失败原因是参数错误或权限不足,重试多少次都没用。所以错误分类很重要——可重试错误和不可重试错误要分开处理。
3.4 并行执行与依赖管理
当任务拆解出多个子任务后,如果它们之间没有依赖关系,就应该并行执行。这能显著缩短整体响应时间。但并行执行引入了一个新问题:如何管理并发和资源竞争。
我的做法是用一个有向无环图来管理任务依赖。每个节点是一个子任务,边表示依赖关系。调度器按照拓扑排序依次执行,没有依赖关系的节点可以并行。同时给每个节点设置资源配额,防止某个节点占用过多资源影响其他节点。
这里有个实际踩过的坑:并行执行时,多个子任务可能同时写入同一个状态存储,导致数据覆盖。解决方案是给每个子任务分配独立的状态空间,最后再合并。或者用乐观锁机制,写入时检查版本号。
4. 工具调用与记忆系统:智能体的手脚和大脑
4.1 工具注册中心的必要性
工具调用是智能体与外部世界交互的唯一通道。我见过很多项目把工具调用写成散落的函数,每个函数有自己的参数格式、错误处理方式、日志记录方式。这种做法的后果是:新增工具成本高、排查问题困难、权限控制无从下手。
正确的做法是建一个工具注册中心。每个工具在注册时提供以下信息:工具名称和描述、输入参数的JSON Schema、输出结果的JSON Schema、超时时间、重试策略、权限要求、调用示例。注册中心负责统一管理这些工具,提供发现、调用、监控的能力。
这样做的好处是:智能体只需要知道工具的名称和描述,就能通过注册中心调用;新增工具只需要注册一次,所有智能体都能用;权限控制可以在注册中心统一实施;调用日志和指标可以统一采集。
4.2 工具描述的写法直接影响调用准确率
这是一个容易被低估的细节。工具描述是模型决定是否调用该工具、以及如何填写参数的主要依据。描述写得不好,模型就会调用错误的工具或者填错参数。
我总结了几条工具描述的写法原则。第一,描述要说明“什么时候用这个工具”,而不仅仅是“这个工具做什么”。比如“查询天气”不如“当用户询问某个城市的天气情况时,用这个工具查询实时天气”。第二,参数描述要给出格式示例。比如日期参数,要明确写“格式为YYYY-MM-DD,例如2024-01-15”。第三,要说明工具的局限性。比如“这个工具只支持查询中国城市的天气,不支持国外城市”。
4.3 记忆系统的分层设计
记忆系统是智能体保持上下文连贯性的基础。我把它分为三层:会话记忆、用户记忆、知识记忆。
会话记忆是当前对话的上下文,通常直接放在模型的上下文窗口里。关键问题是窗口满了怎么办。我的策略是:保留最近N轮对话的完整内容,更早的对话做摘要压缩。摘要的粒度可以是每5轮压缩一次,保留关键信息如用户意图、已确认的事实、未解决的问题。
用户记忆是跨会话的长期记忆,存储用户的偏好、历史行为、常用信息。这部分不能直接放在上下文里,而是通过检索按需注入。比如用户之前提到过“我习惯用邮件沟通”,这个信息在后续会话中应该被检索出来并注入上下文。
知识记忆是领域知识的存储和检索,通常用向量数据库实现。关键设计决策是:检索策略用相似度检索还是混合检索?返回几个结果?检索结果怎么注入上下文?我的经验是,混合检索(向量相似度+关键词匹配)效果更好,返回结果控制在3到5个,注入时加上来源标注。
4.4 记忆检索的触发时机
记忆检索不是越多越好。每次模型调用都注入大量记忆,不仅浪费上下文窗口,还可能引入无关信息干扰模型判断。
我的做法是设置触发条件:当用户提到历史信息时触发用户记忆检索;当问题涉及领域知识时触发知识记忆检索;当对话轮次超过阈值时触发会话摘要。这样既能保证记忆的可用性,又不会过度消耗上下文。
5. 多智能体协作与可观测性:从单兵作战到团队配合
5.1 什么时候需要多智能体
不是所有场景都需要多智能体。单个智能体加多个工具,能解决大部分问题。多智能体的引入应该是因为单智能体在某个维度上遇到了瓶颈。
常见的瓶颈有三种。第一种是上下文超限:任务需要处理的信息量太大,单个智能体的上下文窗口装不下。第二种是能力冲突:任务需要同时具备多种差异很大的能力,比如既要严谨审核又要创意生成,单个智能体很难同时做好。第三种是并行需求:任务可以拆分成多个独立子任务,需要同时执行以提高效率。
5.2 多智能体的通信模式
多智能体之间的通信模式主要有三种。消息传递是最常见的,一个智能体完成任务后把结果发给下一个智能体。共享状态是多个智能体读写同一个状态存储,适合需要频繁交换信息的场景。黑板模式是有一个中心化的数据结构,所有智能体都可以读写,适合需要协商和冲突解决的场景。
我实际用得最多的是消息传递模式,因为它简单、可控、容易调试。共享状态模式在需要频繁交换信息的场景下效率更高,但状态一致性管理更复杂。黑板模式我很少用,因为中心化结构容易成为瓶颈。
5.3 可观测性的三个层次
可观测性是生产环境的生命线。我把它分为三个层次:日志、指标、链路追踪。
日志记录每一次智能体调用的详细信息:输入、输出、调用的工具、耗时、错误信息。关键是日志要结构化,方便后续查询和分析。我一般用JSON格式,每个字段都有明确的含义。
指标是聚合后的统计数据:调用次数、成功率、平均耗时、P95耗时、工具调用分布、错误类型分布。这些指标用来监控系统健康度和发现异常。
链路追踪是把一次完整请求的所有步骤串联起来,形成一个调用链。当用户反馈“这次回答不对”时,你可以通过链路追踪看到每一步的输入输出,快速定位问题出在哪。
5.4 调试智能体的特殊挑战
调试智能体比调试传统程序难得多。传统程序的bug可以复现,因为输入相同输出就相同。但智能体的输出有随机性,同样的输入可能得到不同的输出。而且智能体的决策过程是黑盒,你很难知道它为什么选择了某个工具或某条路径。
我的应对策略是:记录完整的决策上下文。每次模型调用时,把完整的prompt、模型返回的原始内容、解析后的结构化结果都记录下来。这样当出现问题时,你可以回放整个决策过程,看到模型当时看到了什么、输出了什么。
另一个策略是设置断点和人工审核。在关键步骤上设置断点,当智能体做出某个决策时暂停执行,等待人工确认后再继续。这在调试阶段非常有用,能帮你快速定位问题。
6. 安全权限与成本控制:生产环境的必修课
6.1 权限体系的三个维度
智能体的权限控制比传统应用复杂,因为它涉及三个维度:用户维度、智能体维度、工具维度。
用户维度决定哪些用户可以触发哪些智能体。智能体维度决定每个智能体可以调用哪些工具。工具维度决定每个工具可以访问哪些数据。这三个维度交叉,形成完整的权限矩阵。
我的做法是用基于角色的访问控制来管理。每个用户有角色,每个角色有权限集。智能体也有角色,工具也有访问级别。调用时检查用户角色是否有权限触发该智能体,智能体角色是否有权限调用该工具,工具访问级别是否允许访问目标数据。
6.2 敏感操作的二次确认
有些操作是不可逆的或者影响重大的,比如删除数据、发送邮件、创建订单。这些操作不能完全交给智能体自主决定,需要引入二次确认机制。
我的做法是:在工具注册时标记该工具是否为敏感操作。如果是敏感操作,智能体调用时不会直接执行,而是生成一个待确认的请求,推送给用户确认后再执行。确认请求里包含操作详情、影响范围、预期结果,让用户能做出知情决策。
6.3 成本控制的四个抓手
智能体的成本主要来自模型调用和工具调用。控制成本有四个抓手:减少调用次数、降低单次成本、缓存复用结果、设置预算上限。
减少调用次数的关键是优化任务拆解粒度,避免不必要的步骤。降低单次成本的方法包括:用更小的模型处理简单任务、压缩上下文长度、减少工具返回的数据量。缓存复用是把频繁调用的结果缓存起来,下次直接返回。设置预算上限是给每个用户或每个任务设置最大成本,超过后终止执行并通知。
6.4 一个实际的成本优化案例
我之前做过一个智能体,功能是帮用户分析数据报表。最初的设计是每次分析都调用模型重新理解报表结构,成本很高。后来我做了两个优化:第一,把报表结构的解析结果缓存起来,同一份报表第二次分析时直接复用;第二,把简单的数据查询和计算交给代码执行,只有需要理解和推理的部分才调用模型。这两个优化把成本降低了大约六成。
7. 工程师的入场券:从哪个模块开始下手
7.1 不同阶段的团队该补什么
如果你刚开始做智能体,还在Demo阶段,我的建议是先不要碰基础设施。用最简单的方案快速验证想法,确认场景可行后再考虑工程化。
如果你已经有一个能跑的智能体,但经常出问题,我的建议是先补可观测性。把日志、指标、链路追踪做起来,你才能知道问题出在哪。没有可观测性,其他优化都是盲人摸象。
如果你已经在生产环境跑了一段时间,想提升稳定性和效率,我的建议是按顺序补:任务编排、工具注册中心、记忆系统、权限控制。这个顺序的原因是,任务编排是骨架,工具注册是手脚,记忆是大脑,权限是保险。
7.2 技术选型的几个原则
Agent Infra的技术选型没有标准答案,但有几个原则可以参考。
优先用成熟组件,不要重复造轮子。向量数据库用现成的,任务队列用现成的,日志系统用现成的。你的精力应该花在智能体特有的逻辑上,而不是通用基础设施上。
接口标准化比实现优化更重要。工具注册的schema、任务编排的接口、记忆检索的API,这些接口一旦定下来,后续替换实现就很容易。反之,如果接口混乱,换一个组件就要改一堆代码。
从简单方案开始,按需演进。不要一开始就设计一个支持多智能体、多租户、多区域的复杂架构。从单智能体、单租户开始,遇到瓶颈再扩展。过度设计是早期项目最大的浪费。
7.3 我踩过的三个坑
第一个坑是过早引入多智能体。早期我觉得多智能体很酷,把一个简单的任务拆成三个智能体协作。结果调试成本翻了三倍,性能反而下降。后来退回单智能体加多工具,问题迎刃而解。
第二个坑是忽视上下文管理。早期我把所有历史对话都塞进上下文,结果很快超限。后来做了摘要压缩和按需检索,才解决了这个问题。
第三个坑是没有做工具调用的幂等性。有一次智能体调用支付工具时超时,重试后导致重复支付。后来给所有写操作工具加了幂等键,才避免了这个问题。
7.4 这个方向值得投入吗
我的判断是:值得。原因很简单——智能体的应用场景在快速扩展,但工程能力的供给远远跟不上。能调API做Demo的人很多,能把智能体稳定跑在生产环境的人很少。这个差距就是机会。
而且Agent Infra的能力是可迁移的。你今天在客服场景积累的任务编排经验,明天可以用在数据分析场景。你今天在电商场景积累的权限控制经验,明天可以用在金融场景。这些工程能力不会因为模型迭代而贬值,反而会随着智能体应用范围的扩大而增值。
如果你正在做智能体相关的项目,我的建议是:不要只盯着模型能力,花点时间把基础设施搭起来。短期看可能见效慢,长期看这是唯一能让你从“能做Demo”走到“能做产品”的路径。