把客服会话拆成原子任务:LLM、Tool、Rule、Human 该怎么分
一条会话丢给大模型,拆对了是资产,拆错了是事故。
[读者] {做企业级 Agent 的 FDE 与后端工程师} [痛点] {整段会话塞给大模型,出错后查不清是谁的错} [现在读] {多客户多语言同时上线,一次越权退款就够停服} [读完] {能把会话拆成原子任务,并给每一段标上执行者}[旧方案] {单 Agent 吃整段会话,自主决定查什么、说什么、做什么} | v [新需求] {多语言、多客户、多政策,每个动作都要留痕可审计} | v [冲突] {模型的语言能力和企业系统的确定性要求,根本不是一回事} | v [后果] {编造状态、算错金额、重复退款、责任无法归因}我是老李,带一支 FDE 团队,做面向海外电商的全球智能客服平台。会话入口有 WhatsApp、邮件、网页聊天和电话转写,背后连着 CRM、订单、支付、物流、工单、知识库六套系统。任务是,让一条跨语言、跨渠道的客户会话,被系统稳定接住、办完、留下证据。
上一版方案很朴素:一个「万能客服 Agent」,把整段会话、系统提示词和工具清单一起塞进上下文,让模型自己决定查什么、说什么、做什么。前三周看着很聪明,客户还夸回复有人味。
问题是客户从 1 家变成 4 家,语言从英语扩到西语和阿拉伯语,退款政策从 1 套变成 4 套。同一句「我要退款」,在 A 客户是签收后 7 天无理由,在 B 客户是发货前 48 小时可撤单。大 Agent 的错误,从「偶尔说错话」变成了「说不清是谁错的」。
一条客服会话丢进模型,到底该拆成几段才算够?
每一段凭什么判给 LLM、Tool、Rule 还是人?
拆完之后,怎么证明它比一个「大 Agent」更可靠?
01、故事
周三凌晨两点,WhatsApp 进来一条西语会话:
Pedí esto la semana pasada, no llega. Pedido 55127733. Quiero el reembolso y cambiar la dirección.大意是:上周下的单还没到,订单号 55127733,我要退款,还要改收货地址。
有经验的客服专家看到这句话,脑子里会自动跑一遍流程:先确认订单号和商品,再查物流节点,再判断是否触发丢件政策,再算可退金额(含运费和税),再看地址能不能改(发货前可改、发货后要走承运商),最后才决定是安抚、退款、改地址还是升级工单。这是一个多步骤、多执行者协作的过程。
大 Agent 只做了一件事:回了一句很温柔的西语道歉,然后调了退款工具。金额它自己算的,政策它自己记的,地址它压根没管。
第二天客户又来问货呢,工单里挂着两条退款记录,物流那边地址没改。客服主管来问我:这单到底哪个环节错了?
我说不出来。因为整段会话是一次模型调用,中间没有可检查的中间产物,失败不可归因。
一条西语单
三天没人接
大模一声允
退款退两次
02、问题
旧方案失效的地方,不是模型不够聪明,而是它把八件性质完全不同的事压在了一次推理里。
业务影响有三层。客服团队要给客户解释两笔退款;财务对账多出一笔;合规要审计每一次资金操作,而这次审计拿不到任何可指认的中间证据。
技术表现也很具体:
- 同一句话在不同客户下得到不同政策解释,因为政策靠模型从长提示词里「回忆」。
- 金额由模型心算,货币、税、运费都没走订单系统。
- 地址变更诉求根本没被识别,因为它藏在西语句子里,而关键词表只覆盖英文。
- 一次调用里同时发生了「判断」和「行动」,判断错了,行动已经落地。
本篇要达成的可验证标准有五条:
- 一条会话必须被拆成若干原子任务,每个任务有类型、执行者、目标、验证方式。
- 执行者必须来自白名单,越权即判失败。
- 每个任务可独立单测,失败能定位到具体 task_id。
- 涉及金额或系统状态的任务,证据必须来自工具返回值,而不是模型生成。
- 高风险行动必须带幂等键,重复投递不产生第二次副作用。
拆不清任务
就说不清责任
标不准执行
就守不住底线
03、原理
先给一个判断:客服任务不是同一种东西。把它们混在一起,模型的能力边界就自动变成了系统的风险边界。
本篇采用八类原子任务:
| 类型 | 语义 | 天然执行者 | 为什么 |
|---|---|---|---|
| extract | 非结构化文本转结构化槽位(订单号、商品、时间、诉求) | LLM | 语言理解是它的主场 |
| classify | 意图、情绪、优先级、风险等级 | LLM + Rule | 语义靠模型,阈值靠规则 |
| summarize | 长会话压缩、跨渠道上下文合并 | LLM | 生成式压缩难用规则替代 |
| generate | 多语言回复、语气、澄清追问 | LLM | 唯一合理选择 |
| retrieve | 政策文档、知识库、订单与物流状态 | Tool | 要的是事实,不是措辞 |
| compute | 退款金额、税费、运费、SLA 剩余时长 | Tool | 可复算、可对账 |
| judge | 政策是否适用、是否升级 | Rule(边界案件 HUMAN) | 判定必须指向条款 |
| act | 退款、改地址、建工单、发通知 | Tool(高风险加 HUMAN 审批) | 有副作用,必须可审计 |
第一个反直觉判断:模型越擅长语言,越不该让它做数字和状态查询。语言能力会制造一种「它什么都能答」的错觉,而企业系统需要的是「它只在有证据时才能答」。
第二个反直觉判断:把任务拆细,主要收益不是准确率提升,而是可归因。拆细以后,错误会挂在某个 task_id 上,而不是挂在一个大 Agent 身上。
ReAct(arXiv:2210.03629)给了一个有用的形状:推理与行动交替进行,思考之后是显式的动作,拿到观察结果再继续推理。它的价值在于把「行动」变成一个有明确接口、有返回值的显式步骤,而不是藏在自然语言里。本篇做的事情,是给这个形状补一条约束:不是所有动作都该由模型发起,也不是所有思考都该由模型完成。
Anthropic 工程博客把常见做法区分成 workflow(预定义路径)与 agent(模型自主决策),并单独列出 routing、orchestrator-workers 这类模式;本篇的「执行者路由」就是 routing 的一个落地形态。Microsoft Agent Framework 则把 agent 与 workflow 放在同一个框架里,同时提供 checkpoint、human-in-the-loop 这类工程能力。这两份资料的 API、版本与模式命名,需按当前官方文档核验;本篇只取它们的工程直觉:能定路径的地方别让模型自由发挥,需要自由发挥的地方要留可检查的接口。
语言归模型
数字归代码
政策归规则
风险归人
04、架构
[输入] 多渠道原始会话(文本 / 语音转写 / 邮件) | v [模块] Task Decomposer 任务分解器(类型 + 执行者 + 验证方式) | v [数据/状态] TaskPlan {task_id, type, executor, goal, inputs, verify, risk, idempotency_key} | v [处理] Executor Router → LLM / Rule / Tool / Human,各自返回带证据的结果 | v [输出] 结构化办理结果 + 证据链 + 审计记录(下游 CRM / 订单 / 工单 / 支付)这个架构的边界很清楚:它不负责让模型变聪明,只负责让「哪件事该谁做」变成显式数据。TaskPlan 是纯数据结构,可以落库、可以回放、可以 diff。
收益有三点。第一,任意一个原子任务可以单独写单测,不用起整个 Agent。第二,执行者可以按客户策略替换,A 客户的政策判断用规则引擎,B 客户的政策判断先走人工,TaskPlan 的形状不变。第三,失败可归因到 task_id,审计能回答「依据哪条政策、用了哪个工具、返回什么」。
代价同样明确。多了一层编排,端到端延迟增加;TaskPlan 本身需要定义和版本管理;执行者路由表一旦写死,业务变化时要有人维护。
适用条件:任务类型相对稳定、下游系统有可调用的接口、错误代价高于编排成本。如果只是给内部员工做一个问答助手,这套东西就是过度设计。
输入先分解
任务带标签
路由分四路
证据留全程
05、实战一次
环境:Python 3.11 及以上,无需第三方依赖。
依赖:仅标准库 dataclasses、enum、re、json。
配置:新建目录 fde,文件 fde/task_split.py。
核心实现:V1 只做一件事——把一条会话按关键词规则拆成带执行者标签的任务,先把骨架跑通。
# fde/task_split.pyfrom__future__importannotationsfromdataclassesimportdataclassfromenumimportEnumimportjsonimportreclassTaskType(str,Enum):EXTRACT='extract'CLASSIFY='classify'SUMMARIZE='summarize'GENERATE='generate'RETRIEVE='retrieve'COMPUTE='compute'JUDGE='judge'ACT='act'classExecutor(str,Enum):LLM='llm'TOOL='tool'RULE='rule'HUMAN='human'@dataclassclassTask:task_id:strtype:TaskType executor:Executor goal:strverify:str=''risk:str='low'idempotency_key:str=''defto_dict(self)->dict:return{'task_id':self.task_id,'type':self.type.value,'executor':self.executor.value,'goal':self.goal,'verify':self.verify,'risk':self.risk,'idempotency_key':self.idempotency_key,}RULES=[('classify',TaskType.CLASSIFY,Executor.LLM,'识别意图与情绪',r'refund|reembolso'),('extract',TaskType.EXTRACT,Executor.LLM,'抽取订单号与商品槽位',r'\b\d{8,12}\b'),('retrieve',TaskType.RETRIEVE,Executor.TOOL,'查询订单与物流状态',r'no llega|where|delivery'),('act',TaskType.ACT,Executor.TOOL,'变更收货地址',r'change address|address change'),('summarize',TaskType.SUMMARIZE,Executor.LLM,'压缩会话上下文',r'.'),]defdecompose_v1(text:str)->list[Task]:plan:list[Task]=[]fori,(name,ttype,executor,goal,pattern)inenumerate(RULES,start=1):ifre.search(pattern,text,re.IGNORECASE):plan.append(Task(f't{i}_{name}',ttype,executor,goal))returnplandefmain()->None:session=('Pedí esto la semana pasada, no llega. ''Pedido 55127733. Quiero el reembolso y cambiar la dirección.')plan=decompose_v1(session)print(json.dumps([t.to_dict()fortinplan],ensure_ascii=False,indent=2))if__name__=='__main__':main()启动:
python-mfde.task_split请求:就是那条西语会话,没有额外参数。
验证:程序应输出一批带 type 与 executor 的任务对象。
未在当前环境实测,以下为预期结果(示例输出):
[{'task_id':'t1_classify','type':'classify','executor':'llm','goal':'识别意图与情绪'},{'task_id':'t2_extract','type':'extract','executor':'llm','goal':'抽取订单号与商品槽位'},{'task_id':'t3_retrieve','type':'retrieve','executor':'tool','goal':'查询订单与物流状态'},{'task_id':'t5_summarize','type':'summarize','executor':'llm','goal':'压缩会话上下文'}]V1 跑通了,会话确实被拆成了带执行者的任务。但缺口就摆在输出里:地址变更(act)没有任务,退款金额(compute)没有任务,政策判断(judge)没有任务,回复生成(generate)也没有任务。
V1 只是把「能匹配到关键词的东西」变成了任务,而不是把「业务真正需要的东西」变成任务。这个差别,就是下一章的入口。
先跑通骨架
再谈准确率
规则能过线
缺口才显形
06、排查
诊断一:西语诉求整段丢失
现象:英文会话里出现 change address 会生成 act 任务,同一诉求换成西语 cambiar la dirección 就没有任何 act 任务。
怀疑:规则表是不是只覆盖了英文的表面形式。
检查:把 RULES 的每条 pattern 打日志,观察哪条命中、哪条落空。
证据:r'change address|address change'在西语文本上零命中,而 t1、t2、t3 三个任务正常生成。
根因:任务拆解的入口绑定了语言的表面形式,把「识别诉求」这件语义工作交给了字符串匹配。
修复:抽取与意图识别交给 LLM,输出必须符合固定 schema;规则只负责校验 schema 和补齐必填槽位。语言扩展不再依赖新增关键词,而是换 prompt 与 schema 字段。
诊断二:退款金额在整个计划里没有来源
现象:回放历史工单时发现,TaskPlan 里没有任何 compute 任务,但最终回复里出现了具体金额。
怀疑:金额是从订单系统取的,只是没被记成任务。
检查:查该轮调用的 trace,看任务列表和工具返回值。
证据:整轮只有一个 retrieve 任务,其返回体里只有物流节点,没有任何金额字段。
根因:任务类型学里没有把「算」识别成独立任务,模型在生成回复时顺手把数字说了出来。
修复:出现金额类诉求时强制生成 compute 任务,且 verify 字段必须以 tool: 前缀指向具体工具方法,例如 tool:order.get_refundable_amount;没有证据的金额一律不允许进入回复。
诊断三:判断和行动被揉进了一步
现象:退款有时落在错误的客户政策上,但审计看不出依据。
怀疑:是不是政策库检索不准。
检查:看任务列表里是否存在独立的 judge 任务。
证据:policy: 前缀的验证依据在整个计划里一次都没出现。
根因:政策判断被模型写在自然语言推理里,而不是落成 checkable 的任务。
错误尝试:我们曾经把「判断该不该退款 + 调用退款接口」合并成一个 Agent 任务,理由是省一次调用、少一层延迟。这个做法是错的。判断和执行揉在一起后,判断错了执行已经发生,回滚要动资金链路;审计只能看到「Agent 调用了退款」,看不到依据哪条条款;工具权限也无法按角色最小化,因为同一个执行者既在读政策又在写资金。
现象先复现
怀疑要落点
证据能指认
根因才收口
07、优化
三个根因指向同一件事:V1 把「拆得对不对」交给了人眼,而不是交给可执行的规则。V2 就做这个——把执行者边界写成白名单,把任务完整性写成断言。
修改一:为每类任务定义允许的执行者集合。
修改二:为需要外部证据的任务定义 verify 前缀,没有前缀就不合法。
修改三:为会话内容定义触发条件,出现某类诉求但没有对应任务时,直接判计划不合法。
# fde/plan_guard.pyfromfde.task_splitimportTask,TaskType,Executorimportre EXECUTOR_MATRIX={TaskType.EXTRACT:{Executor.LLM},TaskType.CLASSIFY:{Executor.LLM,Executor.RULE},TaskType.SUMMARIZE:{Executor.LLM},TaskType.GENERATE:{Executor.LLM},TaskType.RETRIEVE:{Executor.TOOL},TaskType.COMPUTE:{Executor.TOOL},TaskType.JUDGE:{Executor.RULE,Executor.HUMAN},TaskType.ACT:{Executor.TOOL,Executor.HUMAN},}VERIFY_PREFIX={TaskType.EXTRACT:'schema:',TaskType.RETRIEVE:'tool:',TaskType.COMPUTE:'tool:',TaskType.JUDGE:'policy:',TaskType.ACT:'tool:',}REQUIRED_WHEN=[(r'cambiar la direcci[oó]n|change address|地址',TaskType.ACT,'出现地址变更诉求时必须生成行动任务'),(r'reembolso|refund|退款',TaskType.JUDGE,'出现退款诉求时必须生成政策判断任务'),(r'reembolso|refund|退款',TaskType.COMPUTE,'出现退款诉求时必须生成金额计算任务'),]defvalidate_plan(text:str,plan:list[Task])->list[str]:errors:list[str]=[]seen={t.typefortinplan}fortinplan:ift.executornotinEXECUTOR_MATRIX[t.type]:errors.append(f'{t.task_id}:{t.type.value}不允许由{t.executor.value}执行')prefix=VERIFY_PREFIX.get(t.type)ifprefixandnott.verify.startswith(prefix):errors.append(f'{t.task_id}: 缺少{prefix}前缀的验证依据')ift.typeisTaskType.ACTandt.risk=='high'andnott.idempotency_key:errors.append(f'{t.task_id}: 高风险行动缺少幂等键')forpattern,need,messageinREQUIRED_WHEN:ifre.search(pattern,text,re.IGNORECASE)andneednotinseen:errors.append(f'plan: 缺少{need.value}任务({message})')returnerrors新行为:把 V1 生成的那份计划直接喂进 validate_plan,会立刻得到三条错误,而不是等到客户投诉才发现。
示例输出:
['plan: 缺少 act 任务(出现地址变更诉求时必须生成行动任务)','plan: 缺少 judge 任务(出现退款诉求时必须生成政策判断任务)','plan: 缺少 compute 任务(出现退款诉求时必须生成金额计算任务)']补齐后的一份合法计划长这样(示例输出):
[{'task_id':'t1_classify','type':'classify','executor':'llm','verify':'schema:IntentV1'},{'task_id':'t2_extract','type':'extract','executor':'llm','verify':'schema:SlotsV1'},{'task_id':'t3_retrieve','type':'retrieve','executor':'tool','verify':'tool:order.get_status'},{'task_id':'t4_retrieve','type':'retrieve','executor':'tool','verify':'tool:kb.search_policy'},{'task_id':'t5_compute','type':'compute','executor':'tool','verify':'tool:order.get_refundable_amount'},{'task_id':'t6_judge','type':'judge','executor':'rule','verify':'policy:refund_window_v3'},{'task_id':'t7_act','type':'act','executor':'tool','verify':'tool:address.change','risk':'high'},{'task_id':'t8_generate','type':'generate','executor':'llm','verify':'schema:ReplyV1'}]验证方式:把 validate_plan 挂到 CI 上,用一批历史会话做回放,断言「零越权」与「零缺任务」。注意这验证的是计划合法性,不是回复质量,两者要分开度量。
这里有两处必须留给人。一是政策判断的边界案件,规则引擎给出 indeterminate 时升级到 human executor,这是 TaskPlan 里一种正常状态,不是异常。二是高风险 act,t7 的幂等键由分解器在生成计划时一次写死,重试不会产生第二次副作用。
白名单收紧
断言补缺口
幂等防重放
审批卡高危
08、演进
[同一输入] | +--[V1] {整段会话一次推理 / 失败不可归因,风险随模型能力浮动} | +--[V2] {原子任务 + 执行者路由 / 多一层编排,需维护路由表与校验规则} | [Trade-off] {得到 可归因、可替换、可测试、可审计;失去 一次调用搞定的简洁与低延迟;适用边界 任务类型稳定、下游有可调用接口、错误代价高于编排成本}正确性上,V1 依赖模型状态,同一句话在不同客户下可能给出不同结论;V2 把政策判断收到 rule executor,结论只随政策和数据变,不随措辞变。
稳定性上,V1 是单次长调用,任何一环漂移都影响整体;V2 每段可重试、可降级,retrieve 失败可以重试,judge 拿不到明确结论可以升级人工。
复杂度上,V1 明显更低,一个 prompt 加几个工具就能跑;V2 多了 TaskPlan 定义、执行者路由表和 validate_plan 这套校验,需要有人维护。
成本上,V1 的 token 消耗集中在一轮,V2 拆成多轮调用,语言类任务的 token 总量通常更高;但 compute、retrieve、judge 走到工具和规则,反而更便宜也更稳。
适用范围上,V2 适合多客户多政策、有资金动作、需要审计的场景;单客户单政策、只做问答不做动作的场景,V1 足够。
遗留问题有三个:TaskPlan 的版本治理还没有方案;并发执行时的依赖顺序(compute 必须在 retrieve 之后)目前靠人工排列;上游抽取 schema 变更时,下游任务的 verify 前缀需要联动升级。
简化有代价
拆分有成本
取舍看场景
演进看证据
09、洞见
9.1 拆分的粒度由「验证方式」决定
不要按业务动作拆,要按验证方式拆。能被断言验证的,归 Rule 或 Tool;需要人读一遍才能判断的,才归 LLM。退款金额可以断言等值,所以它是 compute;回复是否得体无法断言,所以它是 generate。粒度标准定了,任务数量自然收敛,也不会出现「一个任务里既查数据又写资金」的混装。
9.2 语言能力越强,越要给它划禁区
反直觉判断:模型在语言上越强,越容易让人忘记它在数字和状态上的不可靠。它能流畅地说出「已为您计算退款金额 12.34 美元」,听起来比工具返回值更像人话,但这恰恰是最危险的地方——人话的确定性来自表达,系统的确定性来自证据。
9.3 执行者不是身份,是权限
反直觉判断:LLM、Tool、Rule、Human 这四个标签,本质不是「谁来干活」,而是「谁被允许做什么」。把标签理解成身份,就会纠结「这个 Agent 算不算 Tool」;理解成权限,问题立刻清晰:谁有权读资金、谁有权写资金、谁有权在证据不足时拍板。权限模型一旦成立,审计和降级都是顺带的。
9.4 拆解的第一收益是可归因
拆解常被当成提准确率的手段,其实第一收益是可归因。错误挂到 task_id 上,团队才能讨论「是抽取错了、检索错了还是政策错了」。可归因之后,替换执行者才成为一次局部改动,而不是重写整个 Agent。
语言归语言
数字归数字
拆开是责任
留下是证据
10、系统落地
原来有什么:一个吃整段会话的大 Agent,加上六套下游系统的工具接口。会话进来是一次长调用,出去是一句回复和若干副作用,中间没有持久化的结构。
本篇新增什么:一层任务分解与执行者路由。会话进来先变成 TaskPlan,八类原子任务各自带 type、executor、verify 和幂等键;validate_plan 在计划进入执行前做一次合法性断言。这套东西不改变下游系统,只是在模型和系统之间插入一层可检查的中间态。
现在能做什么:一条跨语言会话可以被拆成可单独测试的任务;越权执行者会在计划阶段被拦下;金额和状态类结论只能来自工具返回值;高风险行动带幂等键;失败能定位到具体 task_id,审计能回答依据哪条政策、用了哪个工具。
还缺什么:TaskPlan 目前是线性列表,没有表达任务之间的依赖和可并发关系;多客户场景下执行者路由表还是全局一份,没有按客户做策略覆盖;政策判断的 indeterminate 状态还没有稳定的人工接管通道和排队策略;跨渠道上下文合并后的槽位冲突(两个渠道给了不同订单号)还没有仲裁规则。
下一步如何演进:把 TaskPlan 从列表升级成带依赖的图,让 compute 显式依赖 retrieve、act 显式依赖 judge;把执行者矩阵做成按客户可覆盖的策略对象;把 human executor 接成一个有超时和兜底的话务队列。这些都会用到同一个 TaskPlan 契约,所以现在这份结构值得先冻结下来。
原有一张网
现加一层格
能办三类事
还缺调度环
11、小结
Q1 → {拆到八类原子任务,粒度标准是「能否被单独验证」} Q2 → {语言理解给 LLM,状态与计算给 Tool,政策判定给 Rule,高风险与边界案件给 Human} Q3 → {靠执行者白名单 + verify 前缀 + 完整性断言,把不可归因的整段推理拆成可检查的计划} 状态 → {客服会话原子任务分解器 V1 可运行,执行者矩阵与计划校验器 V2 可断言}三问有回应
一问一落点
能力已落地
边界已写清
12、作业
12.1 理解题:为什么金额计算不能交给 LLM?
参考答案:不是因为模型算不对,而是因为它算得不可验证和不可对账。金额需要能复算、能追溯到订单与政策条款、能在审计时复现。工具返回值天然具备这些属性,自然语言输出的数字不具备。判断标准是「这件事能否被断言验证」,能则归 Tool。
12.2 实战题:给一条英文会话补一份合法 TaskPlan
会话内容:My order 8830012 arrived broken. I want a refund and I need it delivered to a new address.
参考答案:至少包含 classify(llm)、extract(llm,抽订单号与破损诉求)、retrieve(tool,查订单与物流)、retrieve(tool,查退换政策)、compute(tool,算可退金额)、judge(rule,判断破损件是否走退货流程)、act(tool,改地址,高风险带幂等键)、act(tool,发起退款或换货,带幂等键)、generate(llm,生成多语言回复)。用 validate_plan 校验时应返回空错误列表。
12.3 排障题:validate_plan 返回「缺少 compute 任务」,但计划里金额确实算对了,怎么判断问题在哪?
参考答案:先确认金额来源。查该轮 trace,如果金额出现在 generate 任务的输出里且没有对应的工具调用记录,说明它来自模型生成,属于侥幸正确,必须补 compute 任务并让证据以 tool: 前缀落库。如果金额确实来自工具调用,只是没有被记成独立任务,那是分解器的问题,要把调用提升为显式任务,否则重试、审计和降级都无处挂载。
12.4 架构判断题:把所有任务都改成「LLM 出方案 + Tool 校验」,能替代执行者矩阵吗?
参考答案:不能。执行者矩阵管的是权限,不是正确性。让 LLM 先出方案再校验,等于让模型先做一次资金或状态相关的决策,校验只是事后拦截;一旦校验缺位或规则漏配,副作用已经落地。矩阵的价值在于把「谁被允许做」前置成计划约束,校验是第二道防线,两者不能互相替代。
题在纸上练
功在线上成
答完回头看
抓手在手里
13、思考
回到本篇冲突:模型的语言能力和系统的确定性要求不是一回事,而我们过去用一个 Agent 把它们焊在了一起。
拆成原子任务,不是为了让系统看起来更工程化,而是为了让每一段都能被单独验证、单独替换、单独负责。八类任务的价值不在于分类本身好看,而在于它逼着我们回答一个问题:这件事到底能不能被断言。能断言的,交给代码和规则;不能断言的,才交给模型,并且要把它的输出落到固定结构里。
这套判断可以迁移到任何企业级 Agent 场景:先问副作用在哪里,再问证据从哪来,最后才问模型该说什么话。顺序反过来,就会得到一个会说人话、但说不清责任的系统。
拆到能验证
标到能归因
判到能取舍
才叫真落地