“407智能体”这个名字,听起来像个内部项目代号,实际上它确实就是一个编号。我接到的需求单恰好是407号,需求方在“功能描述”那一栏写了一大段话,概括下来就一句:能不能做一个智能体,把那些重复、琐碎、还需要一点脑子的活接过去。
这样的需求在当下不少见。很多人一提“智能体”就联想到全能助理,但实际上,一个能落地的智能体,往往是从一件非常具体的事开始的。这篇文章要讲的,是我把一个编号为407的需求,做成一个真正能跑起来的智能体的过程。包括它最初怎么立项、架构怎么选、工具怎么接、坑怎么踩,以及上线前后我在成本和边界上做的取舍。
如果你也在做类似的事——不管你是产品经理、后端开发,还是一个人负责一个小项目的全栈,这篇文章里的思路和经验,应该能帮你少走不少弯路。
1. 407智能体的由来:一份写着“做个智能体”的需求单
1.1 需求单上写的是“智能体”,但真实需求是三件具体事
拿到需求单的第一天,我就约了需求方开了一个半小时的会。需求方是某业务组,他们每天要处理大量外部咨询、资料整理、内部答疑,听起来事情很多,但真正落实到系统里,其实就是三类重复劳动:
第一,自动回答常见咨询,并且能区分“该回的”和“该转人工的”。比如“发票怎么开”这种问题可以自动回复,但“我们公司的合同为什么还没审批”这种涉及具体业务状态的问题,得转人工。
第二,自动把零散记录整理成固定格式的档案。业务组每天会收到各种邮件、语音转文字、群聊里的备注,这些内容需要按客户、按项目归入档案。
第三,自动汇总多个来源的信息,生成日报和周报的草稿。以前这件事是组里一个同事每天花一个半小时手动拼的,效率很低。
这三件事分别对应了问答、抽取、生成三种能力。一旦把“智能体”拆成这三件事,技术方案就很清晰了——问答走知识库检索加生成,抽取走结构化信息提取,生成走模板加模型润色。需求单上的“智能体”只是个含糊的愿望,真正落地的是这三件事。
1.2 为什么一定要用智能体,而不是普通脚本
需求方一开始也问过我:这些活能不能写脚本,一个定时任务不就把日报生成了吗?
我当时的回答是:能,但只解决了三分之一。脚本最怕的是输入不固定、步骤不固定、要求不固定。比如,抓取数据这种活,脚本确实可以干,但业务组的邮件里经常会多一句“只取本周的,剔除测试数据”,脚本下一分钟就懵了,因为它不知道“本周”和“测试数据”在业务里是什么意思。
而大模型驱动的智能体能理解这句话,并且能在不改代码的情况下调整执行方式。它可以把“取数据”这件事拆成“理解时间范围”和“识别测试数据特征”两个小步骤,再去调对应的接口。这种能力是传统脚本完全不具备的。
所以需求组的判断是:这个项目要做的不是一堆自动化任务,而是一个能理解人在说什么、能自己安排步骤的数字员工——这就是“407智能体”最早的定义。
1.3 团队和周期的现实约束
当时我们组只有两个开发,还得兼顾其他项目,时间窗口大约是四周上线内测版。
这个约束直接影响了方案选择。我们没有一开始就去搭一套复杂的智能体平台,而是采取了“边攒边用”的策略:先调用现成的模型API,加上少量代码,跑通一个最小闭环。先让业务组用起来,再在每个月的迭代中逐步把工具链、知识库、权限管理补上。
这四周里,前两周是在搭骨架,后两周几乎每天都在填坑。后面我讲到的翻车记录,基本都是这两周里发生的。
2. 407智能体的骨架:模块总线式架构与模型选择
2.1 没有选择“一个大Prompt搞定一切”的原因
不少初次做智能体的人,第一步就是写一个超级Prompt,把所有规则、背景、例子都塞进去,然后希望模型什么都能干。我见过很多这样的Demo,看起来很惊艳,实际一上生产就崩。
为什么崩?三个原因:第一,不好调试。你根本不知道模型到底是根据哪句话做的决定,出了问题只能整段Prompt反复改,越改越乱。第二,上下文迅速膨胀。每轮对话都要把那一大段规则重新算一遍,时间长、成本高。第三,权限不好控制。一个Prompt里什么都允许,模型就什么都敢做,包括它不该做的。
所以我在设计407智能体时,明确了一个原则:把大脑和手脚分开。大脑负责判断,手脚负责执行,大脑不能直接碰系统,手脚不能代替大脑做决定。
2.2 架构上的四个模块
407智能体从逻辑上分成四层:
入口层负责接收消息。不管消息来自IM、邮件还是网页表单,先做格式清洗,再做一次意图初判——这个请求到底是咨询、录入、查询还是汇总。
决策层是核心,由大模型加一个任务规划器组成。模型的任务不是直接输出最终答案,而是拆解问题、选择工具、检查工具返回的结果,必要的时候再决定是否需要向用户追问。
执行层是一组被注册好的工具。工具是智能体的“手脚”,包括查知识库、写档案、发提醒、调内部业务API等等。
记忆层承担两类存储:短期记忆负责当前对话的上下文,长期记忆负责业务偏好和项目约定。
用表格来看会更清楚:
| 模块 | 核心职责 | 失败处理 |
|---|---|---|
| 入口层 | 清洗消息、意图初判 | 无法判断时进入人工接待 |
| 决策层 | 任务拆解、选择工具、校验结果 | 计划冲突时向用户确认 |
| 执行层 | 调用知识库、业务API等实际工具 | 工具报错时走重试或降级 |
| 记忆层 | 短期上下文、长期业务知识 | 检索不到时明说不知道 |
这种“模块总线”式的设计,最大好处是可替换。后来我们把其中一个轻量模型换成了新版本,只改了路由配置,其他模块完全没动。
2.3 模型选型:大而全不是唯一答案
很多人以为做智能体一定要用最强的模型,其实不是。关键是分级:让该便宜的便宜,该贵的贵。
在407智能体里,简单的意图识别和FAQ问答走的是轻量模型,速度快、成本低。需要多步推理、工具组合的复杂任务才走强模型。结构化抽取任务则用强约束的模型能力,指定输出JSON格式,解析不了就重试。
举个例子:用户问“发票多久能开出来”,入口层识别这是FAQ类问题,直接走轻量模型加知识库召回,整个链路耗时不到两秒。但如果用户问“把上周发的所有邮件里关于发票的段落整理出来,并按项目归档”,入口层识别这是多步骤任务,会交给强模型去做拆解和规划。
这个分级策略,后来看是407智能体控制成本的关键之一。
3. 407智能体的手脚:工具注册、函数调用与任务编排
3.1 工具的定义与注册机制
智能体能不能“干活”,首先取决于工具描述写得好不好。模型的优势在于理解自然语言,但工具本身是结构化的。两者之间需要一个桥梁,就是工具描述。
我给407智能体定义工具时,严格要求描述里包含四个信息:什么时候用、参数怎么填、返回什么、以及可能的失败情况。比如一个查客户信息工具的描述,类似这样:
TOOL_DESCRIPTION = { "name": "query_customer_info", "description": "根据客户名称或客户编号查询客户档案信息。当用户询问客户联系人、地址、合作状态时使用。", "parameters": { "customer_id": {"type": "string", "description": "客户编号,格式如CUS-2024-001"}, "include_contacts": {"type": "boolean", "description": "是否返回联系人列表,默认false"} }, "returns": "返回客户基础信息、合作状态、最近跟进记录。如果查不到客户,返回空列表。" }工具描述里面有个细节特别容易踩坑:失败情况的说明一定要明确。早期我们没有在描述里写“查不到客户返回空列表”,结果模型拿到空列表后以为“这个客户没有信息”,直接生成了一句“该客户暂无档案”。这其实是幻觉的变种,根子在于工具描述不够清晰。
3.2 任务编排:从自由发挥到半受控流程
智能体跑一个复杂任务的时候,完全让模型自由发挥是很危险的。比如整理归档这种流程性强的环节,你让模型自己决定顺序,它可能先写档案再去拉数据,也可能把“归档”理解成“发送邮件”。
我的做法是:给流程搭一个轻量状态机。把任务分成几个阶段:收集输入、查证信息、生成草稿、确认执行。模型可以决定每个阶段怎么完成,比如在收集输入阶段选择调用哪个接口,但阶段的顺序和跳转条件由状态机控制。
这样做的好处是:既保留了大模型处理不确定性的能力,又让整个执行过程有迹可循——出了任何问题,我们能从日志里看到它卡在哪个环节。
3.3 工具调用出错的四级兜底
工具调用不可能一帆风顺。我遇到过日期解析错误、业务接口超时、知识库检索无结果、权限校验失败等情况。
针对这些异常,我设计了四级兜底逻辑:
第一级,重试。针对单次超时或偶发网络错误,自动重试一次。
第二级,换工具。比如主知识库查不到,自动换到备用的文档引擎再查一次。
第三级,澄清询问。如果换工具后仍然拿不到数据,模型会向用户输出一句“我暂时没查到相关信息,你确认一下关键词对不对?”而不是自己猜一个答案。
第四级,转人工。如果整个流程出现超过两次异常,直接把会话转入人工处理,并附带完整的执行日志。
这个兜底逻辑后来成为407智能体“可信赖感”的重要来源。业务组反馈说,它至少不会乱给答案了——说不知道,然后让人来接手,这是可以接受的;胡说八道才是不能接受的。
4. 407智能体实测翻车录:幻觉、上下文漂移与参数格式灾难
4.1 三个最典型的翻车现场
内测那两周,我们记录了大量翻车案例,顺手整理成了一张表:
| 问题 | 现场表现 | 根因 | 修复办法 |
|---|---|---|---|
| 幻觉 | 明明没有数据,模型编造了一个统计数 | 模型没有区分“查到”和“猜的” | 工具返回加状态字段,空结果必须明说 |
| 上下文漂移 | 对话第七轮时,模型忘了最开始说的客户范围 | 多轮上下文被压缩后丢失关键信息 | 关键约束单独存进记忆层,每轮调用时重新注入 |
| 参数格式灾难 | 模型把“项目状态”传成了“已完成”,但系统里没有这个枚举值 | 工具描述里的枚举没写全,模型自由发挥 | 参数描述里明确枚举,模型输出前做预校验 |
这三个问题,做智能体的人大概率都会遇到。难的不是解决某个单点,而是建立一套让它们不再发生的机制。
4.2 一次完整排查:“它说完成了,但数据库里没有记录”
有一次业务组反馈说,407智能体回复“档案已归档”,但在档案系统里查不到。这是比较严重的信任事故,我按日志逐层排查。
第一步,查执行日志,发现工具的确被调用了。第二步,看工具入参,发现传入的档案ID列表是空的。第三步,追上游,发现是从邮件主题里提取ID时,提取逻辑把“RE: 合同编号CUS-2024-015”里的编号提取错了,导致查无结果。第四步,原来模型拿到空ID列表后,没有意识到“数据源为空”是一种异常,反而认为“用户要求归档的档案不存在,所以自动跳过”,于是直接输出了“已完成”。
这个案例的关键教训是:模型把“无数据可做”理解成了“任务完成”。修复方法是在工具返回结构里加一个显式的状态位,只有状态位是success且写入条数大于0时,模型才允许输出“已完成”。
4.3 让“状态”成为工具调用的硬约束
经过那几次翻车之后,我定了一条规矩:407智能体里所有工具返回值必须包含status字段,取值只能是success、empty、error三者之一。模型只有在success时才能继续执行下一步;empty时要向用户反馈“没有找到数据”;error时直接走兜底逻辑。
规矩定下之后,很多以前模糊的判断都有了标准。模型不需要猜“这算不算成功”,只需要读状态位。这也是我从那段时间的实践中得到的最重要的经验:不确定的东西交给模型去处理,但确定性的判断,要交给程序去锁定。
5. 407智能体上线前的关键配置:知识库、记忆与权限边界
5.1 知识库搭建:从“扔一堆文档进去”到“认真切块”
不少朋友搭知识库,第一反应是把所有文档直接丢进向量库,然后让模型检索。这样做的效果通常很一般,因为检索到的片段可能是一大段无关内容,或者把多个主题混在一起。
我给407智能体搭知识库时,做法是先做文档清洗和切块。每个文档按标题层级拆成独立的小块,每块控制在几百字以内,并且保留元数据,比如来源文档、所属类目、更新日期。检索的时候,先按类目过滤,再走向量召回,最后加一层相关性重排,只取最相关的一小块给模型。
切块这件事听起来简单,实际很考验耐心。文档里的表格、嵌套列表、多级标题,都需要单独处理。我们花了整整两天清洗文档,但上线之后知识库回答质量的提升,让这两天非常值。
5.2 短期记忆与长期记忆的分工
对话式智能体绕不开记忆问题。如果只靠上下文窗口把历史消息全塞进去,一是很快会超出长度限制,二是模型容易抓不住重点,上下文漂移会越来越严重。
我采用了“短期记忆加长期记忆”的双层记忆设计。短期记忆里存最近几轮对话的摘要,每轮对话结束后自动压缩一次;长期记忆只存结构化信息,比如用户所在的项目、最近关注的主题、沟通偏好。这些信息不会存原文,而是转成字段,方便后面调用。
关键约束单独放进长期记忆。比如前面提到的上下文漂移问题,客户范围这种关键信息,从一开始就被放进长期记忆,每轮回答前主动注入,就不会因为对话太长被模型忘掉了。
5.3 权限边界:智能体不能什么都干
智能体的能力边界必须在设计阶段就划好,不能让模型自己判断什么事能做。我根据“变更影响程度”把权限分成三档:
可自动执行:查知识库、整理草稿、生成摘要、解析文档。这些操作只读不写,或者写入后可以撤回。
需人工确认:发外部消息、修改项目状态、创建档案记录。这些操作会影响真实业务,智能体只能生成待确认卡片,人工点一下确认按钮才能执行。
禁止自动执行:删除数据、批量导出客户信息、涉及资金或合同状态的变更。这些动作在权限层直接拦截,智能体连申请的入口都没有。
这套分级规则看起来很简单,但非常实用。业务组用了一段时间后甚至说,407智能体最让人放心的地方不是它能干多少,而是它知道自己哪些不能干。
6. 407智能体落地之后的现实问题:成本、评估与人工兜底
6.1 成本控制:别让智能体“烧钱”
智能体项目的成本,大头几乎都在模型API的token消耗上。刚开始跑内测的时候,我们每天的token消耗高得吓人,后来通过三级优化才压下来。
第一级是缓存。用户问过的FAQ问题,答案直接缓存,不再重复调用模型。第二级是路由分流。前面说的轻量模型和强模型分级,简单问题根本不需要强模型出场,成本直接降一大截。第三级是工具返回压缩。工具返回长文本时,模型不能全量读取,先在工具层做一次摘要,再送给模型。
我大概算过一个数:通过这三项优化,407智能体的日均token消耗降到了原来的三分之一,而业务组没有感觉到回答质量有任何下降。
6.2 怎么评估它“好不好用”
智能体的效果评估比传统软件难得多。不是“功能实现了”就完了,要看用户在真实场景里愿不愿意用。
我建了一个评估集,从历史工单里挑了五十条真实记录,每条都标注了“期望行为”。每周用这个评估集跑一遍回归,统计五个指标:正确回答率、召回率、转人工率、平均对话轮数、用户撤销率。转人工率和用户撤销率尤其重要,因为它们反映了智能体在真实业务里的“兜底效率”。
后来我们给业务组也开放了“点踩”按钮,用户对回答不满意的时候可以直接标记,这些标记会进入下一轮优化清单。
6.3 人工兜底不是妥协,而是设计的一部分
最后想认真强调一点:不要把“必须转人工”看成是智能体没做好。恰恰相反,成功的智能体几乎都有清晰的人工兜底路径。
407智能体里的转人工方式是:当置信度低于阈值、或者连续两次执行异常、或者用户主动要求,会话会直接转给人工客服,同时把前面所有的上下文和操作日志打包好。人工客服不需要让用户重新讲一遍,拿起就能续上。业务组反馈说,这套“无缝转接”比智能体本身还受好评。
我个人的体会是:智能体的价值不是替代人,而是把人从重复劳动里抽出来,让人只处理真正需要判断力的部分。
最后再分享一个小经验。做407智能体这段时间,我最大的感受是:不要试图让智能体做所有事。它现在能自动处理的也只是起初被拆得足够细的那几件事,但恰恰是这几件,每天帮团队省下了不少时间。如果下次再有人拿一份写着“做个智能体”的需求单过来,我会先跟他聊半小时,把“智能体”翻译成一件件具体的事,而不是先打开IDE。