Blog·Studio
文章系列日历归档关于搜索
Blog·Studio

一个记录思考、笔记与作品的技术博客。

Connect

© 2026 · Blog Studio

鄂ICP备19019526号

crafted with care

stay curious ✦

  1. 文章
  2. ›客服 AI 应用工程 2026:意图路由、澄清与转人工

Index

  • 一、为什么客服是 Agent 落地最难的象限
  • 二、先把"客服"翻译成状态机
  • 三、意图路由:把分类当成一等公民
  • 四、澄清与追问:把"缺信息"显式化
  • 五、拒答与转人工:交接契约
  • 六、结果计费与评估:把"成功"写成可执行断言
  • 七、语音通道:客服的第二形态
  • 八、工具、会话与护栏:生产底座
  • 九、落地路线与八个常见陷阱
  • 十、小结
  • 参考文献

客服 AI 应用工程 2026:意图路由、澄清与转人工

把大模型接进客服系统,难点不在模型,而在于把一段自然语言对话翻译成可路由、可补全、可交接、可计费的工单状态机。本文给出一套从意图分层到 outcome 结算的完整落地方法。

2026年10月26日·约 54 分钟阅读·16,029 字·1 次阅读·博主
#智能体与 AI 应用开发
客服 AI 应用工程 2026:意图路由、澄清与转人工

Index

  • 一、为什么客服是 Agent 落地最难的象限
  • 二、先把"客服"翻译成状态机
  • 三、意图路由:把分类当成一等公民
  • 四、澄清与追问:把"缺信息"显式化
  • 五、拒答与转人工:交接契约
  • 六、结果计费与评估:把"成功"写成可执行断言
  • 七、语音通道:客服的第二形态
  • 八、工具、会话与护栏:生产底座
  • 九、落地路线与八个常见陷阱
  • 十、小结
  • 参考文献

客服 AI 应用工程 2026:意图路由、澄清与转人工

导语:把大模型接进客服系统,难点不在模型,而在于把一段自然语言对话翻译成可路由、可补全、可交接、可计费的工单状态机——本文给出一套从意图分层到 outcome 结算的完整落地方法。

客服是 Agent 落地中最被低估、也最难被做好的一类应用。它不像代码助手那样有自动测试可以当反馈信号,也不像搜索问答那样有"答得对不对"的二元判据;它的输入是千奇百怪的自然语言,输出是一连串可能改钱、改库存、改用户权益的动作,而最终的成功判据——"客户的问题被解决了"——本身必须由业务方先定义清楚,再由工程系统去测量和结算。

本文不谈 Agent 内核原理,也不重复"框架怎么选"这类话题。聚焦的是一个具体问题:如何把客服 Agent 从"演示能聊"推到"生产能算账"。全文围绕五个可工程化的对象展开——意图路由、槽位与澄清、拒答与转人工、结果计费、语音通道——并给出会话状态机设计、工具契约、评估口径与上线路线。


一、为什么客服是 Agent 落地最难的象限

Anthropic 在其工程博客《Building effective agents》(2024 年 12 月 19 日发布,文首已加注"自 2024 年 12 月以来相关工具生态已有变化")的附录一里,把客服列为两个最具前景的 Agent 落地领域之一,并给出了四条理由:客服交互天然遵循对话流,同时需要访问外部信息与执行动作;工具可以把客户数据、订单历史和知识库文章拉进来;退单、更新工单这类动作可以被程序化处理;而成功可以用用户定义的 "resolution" 清晰度量。

这四条理由恰好定义了客服 Agent 的骨架,也解释了为什么它比看起来难:

其一,输入侧的方差极大。 同一句"我的订单还没到",可能是物流延迟、可能是地址填错、可能是想改地址、也可能是根本没付款只是在下单页看到"处理中"。意图识别错一次,后面全部动作都错。

其二,状态是隐式的。 客服对话的真实状态不在上下文里,而在一张工单上:客户是谁、订单是哪一单、已经尝试过什么、哪一步需要人批、哪一步可以回滚。把这些藏在 prompt 里会导致状态无法持久化、无法交接、无法审计。

其三,"成功"必须先定义。 这不是技术问题而是业务契约问题。Intercom 在 2026 年 9 月 23 日更新的《Fin AI Agent outcomes》文档里,把这个契约写得非常具体:一次会话最多只计一次 outcome,类型包括 Resolution(最后一次 AI 答复之后客户不再请求帮助,0.99 美元)、Procedure handoff(Fin 成功执行一个被配置为最终交接给人或工作流的 Procedure,0.99 美元)、Disqualification(判定潜客不符合资格并据此淘汰,0.99 美元)、Qualification(把潜客匹配到资格条件并据此路由,9.99 美元)、以及 Self-serve routing(自助式路由,按 0.99 美元的较低费率计)。这意味着工程实现必须把"结果"变成可写事件、可判定条件,而不是靠人看对话录像。

其四,错误代价不对称。 答错一句可以道歉,多退一笔钱要人工去追。所以客服 Agent 的护栏密度天然高于其他类型。


二、先把"客服"翻译成状态机

在写任何 prompt 之前,先定义数据模型。客服 Agent 的最小完整状态至少包含六个对象:

对象含义常见取值举例谁来决定
intent 意图客户要解决哪一类事物流查询 / 退款 / 改地址 / 咨询路由器
slot 槽位完成该意图所需的具体参数order_id / 新地址 / 退款原因对话填充
action 动作对外部系统产生的写入发起退款 / 更新地址 / 建工单Agent + 工具
policy 策略该动作的前置条件与审批要求金额上限、是否需要人批业务配置
handoff 交接把会话移交给人或工作流携带结构化上下文Agent 显式调用
outcome 结算本次会话最终计什么resolution / handoff / disqualification业务规则 + 事件

一次客服会话因此可以显式地分成六个阶段:识别 → 补全 → 执行 → 交接 → 收尾 → 结算。把这六个阶段固定下来之后,几乎所有的工程问题就都有地方可以挂载:意图错了看识别阶段,槽位卡住看补全阶段,误操作看执行阶段与策略配置,"AI 明明解决了但没计费"看结算阶段。

这里最容易被跳过的是"收尾"和"结算"两阶段的分离。用户在界面上看到"问题已解决"和系统在账上记一笔 outcome,是两件不同的事。前者可以由模型判断,后者必须由确定性代码根据事件日志判断——因为计费是要跟客户对账的,不能让模型说了算。


三、意图路由:把分类当成一等公民

Anthropic 定义的 routing 工作流是:"路由对输入进行分类,并把它导向专门的后续任务。这一工作流允许关注点分离,并构建更专门的 prompt。如果没有这一工作流,针对一类输入做的优化往往会损害其他输入的表现。"它给出的客服示例非常直白:把不同类型的客服提问(一般性咨询、退款申请、技术支持)导向各自不同的下游流程、prompt 和工具。

这条原则值得逐字咀嚼。"针对一类输入做的优化会损害其他输入"——这是把 30 类意图塞进一个 prompt、挂 40 个工具的写法必然会踩到的坑:意图一多,工具描述彼此干扰、上下文被稀释、每类意图的专属规则互相污染,最后表现为"简单问题答得还行,复杂问题一上手就乱"。路由的本质不是分类,是上下文隔离。

推荐的实现是三层:

第一层,传统分类器或小模型。 高频、边界清晰的意图(订单状态查询、物流催问)用轻量模型或规则先分流。这一层的价值是延迟和成本:客服是高频链路,绝大多数轮次根本不需要旗舰模型。Anthropic 在同一篇文章里给的成本路由建议是——把简单/常见问题路由到 Haiku 4.5 这类更小更省成本的模型,把困难/不寻常的问题路由到 Sonnet 4.5 这类更强模型。

第二层,LLM 分类。 边界模糊、需要理解上下文的意图("上次那个问题还没解决"实际指向哪个工单)交给大模型做带解释的分类,并且要求输出置信度。

第三层,兜底。 分类置信度低于阈值时,不猜测,而是走澄清或直接转人工。"我不知道"必须是一个合法的路由结果,而且要是一个被显式建模、可以被评估的分支,而不是让模型在低置信度时自由发挥。

路由的工程化产物应该是一张表,而不是一段 prompt:

route(intent_confidence):
    if confidence >= HIGH:
        bind_intent_tools(intent)      # 工具白名单
        bind_prompt(intent)             # 专属 prompt
        bind_budget(intent)             # token / 调用次数 / 金额上限
        enter(slot_filling)
    elif confidence >= MEDIUM:
        ask_clarification(max_questions=1)
    else:
        handoff(reason="intent_unclear")

注意这里每个意图绑定了三样东西:工具白名单、专属 prompt、预算上限。缺任何一样,路由就退化成"换个说法问模型"。工具白名单保证意图与能力边界一致(退款意图里不应该出现"查询物流"工具);专属 prompt 保证优化不会互相污染;预算上限让高成本意图(退款、换货)有天然的收敛点。


四、澄清与追问:把"缺信息"显式化

澄清是客服 Agent 里最被低估的机制,它的工程含义远比"再问一句"复杂。

先看一个直接来自计费文档的细节。Intercom 的文档明确写着:如果 Fin 提出了澄清问题而客户没有回应,会话会在不活跃超时后自动关闭;由于 Fin 的最后一条消息是问题而不是答案,因此不会记录 resolution 状态,也不构成可计费 outcome。换句话说,一次澄清提问在收入语义上等于把这次会话押在了"客户会回答"上。这解释了为什么澄清不能随便问——每问一次,都在消耗这次会话的期望价值。

在工程上,澄清应该被设计成一次有成本的状态转移,而不是一次随口的提问。几条实操规则:

第一,必填槽位要区分类型。 有些槽位是绝对必填(退款必须知道订单号),有些是条件必填(只有"换地址"才需要新地址),有些是可选(备注)。把三者混为一谈会导致过度提问。

第二,禁止默认值。 客服场景里"猜"一个参数的代价远高于多问一句——猜错订单号就是给错误的人退款。

第三,每轮最多问一个问题。 一次抛三个问题,客户大概率只回答第一个,剩下的答案与问题错位,槽位状态直接污染。

第四,同一槽位最多追问一次。 客户没给或者给不了,就走替代路径(转人工、用订单列表让客户点选),而不是陷入追问循环。

第五,沉默必须有定义。 客户不回答不是"还在想",而是一个明确的终止信号。这条在计费口径上已经被 Intercom 写死了,工程上要照做:澄清超时应当关闭会话,且不计 outcome。

槽位填充的状态可以很简单:

slots = {order_id: None, refund_reason: None, confirmed: False}
# 每轮:从用户输入抽取候选槽位 → 校验 → 若缺必填则生成一条澄清问题并 return
#       若全部就绪则 confirmed = True,进入执行阶段

关键设计取舍是:槽位校验必须是确定性代码,不能交给模型判断"信息够不够"。模型可以负责抽取槽位,但不能负责声明抽取正确。把"够不够"写成 schema 上的必填字段加一段 Python 校验,是可测试的;让模型自己判断则不可测试。


五、拒答与转人工:交接契约

客服会话的出口有且只有三种:完成(resolution)、交接(handoff)、拒答(disqualification)。三者的工程实现完全不同。

交接的实现有成熟的参考实现。 OpenAI Agents SDK 的 handoffs 文档写得很清楚:handoff 允许一个 agent 把任务委派给另一个 agent,"这对不同 agent 各自专精不同领域的场景特别有用——例如一个客服应用里,可能有分别专门处理订单状态、退款、FAQ 等任务的 agent"。关键实现细节是:handoff 在 LLM 看来就是一个 tool。如果有一个名叫 Refund Agent 的 agent 需要被交接,对应的 tool 名字就是 transfer_to_refund_agent。

handoff() 函数可以覆盖的字段包括:tool_name_override(默认由 Handoff.default_tool_name() 解析为 transfer_to_<agent_name>)、tool_description_override、on_handoff(回调,接收 agent context,可选接收 LLM 生成的输入,输入由 input_type 决定)、input_type(handoff tool-call 参数的 schema)、is_enabled(布尔或返回布尔的函数,允许运行时动态启停某个交接),以及 nest_handoff_history。文档还明确了一条设计原则:handoff() 总是把控制权交给你指定的那个 agent;如果有多个可能目的地,就为每个目的地注册一个 handoff,让模型自己选;只有当你自己写的交接代码必须在调用时决定返回哪个 agent 时,才使用自定义 Handoff。

这套 API 背后的工程直觉,对客服系统是可以直接迁移的:

  • 交接工具名要语义化。 transfer_to_refund_agent 比 route_intent_2 好得多——工具名本身就是给模型的路由提示。
  • 用 on_handoff 在交接瞬间拉数据。 文档说这个回调"在你知道交接被调用时启动一些数据拉取正合适"。客服场景里这正是人类坐席最想做的事:不要让客户再把订单号、已尝试动作、报错信息重复一遍。交接时一次性把工单摘要、历史尝试、客户等级、风险标记塞进上下文,人类接手时看到的是一个完整案件,而不是一句"转人工了"。
  • 用 input_type 定义交接契约。 交接不是"喊一声",而是一份结构化的移交单:发生了什么、已收集到哪些槽位、为什么升级、下一步建议。Anthropic 在同一篇文章里强调 agent 执行中必须从环境获得 "ground truth"(工具调用结果、代码执行结果)来评估进展,并可以设置停止条件——移交单本质就是把这些 ground truth 固化成交接契约。

人工审批门与交接是两件事。 OpenAI Agents SDK 另有一套 human-in-the-loop 机制,用于在敏感工具调用前暂停等待人批准或拒绝:工具通过 needs_approval=True 声明总是需要审批,或提供一个异步函数按每次调用决定是否需要审批。该回调接收 run context、已解析的工具参数和 tool call ID。文档给出了一条极重要的失败安全规则:当 SDK 无法安全检查参数时,可调用式审批规则一律 fail closed——参数缺失、为空、只含空白、是畸形 JSON、是合法 JSON 但不是对象(例如 null 或数组)、或包含 NaN / Infinity / -Infinity 这类非标准常量时,回调不会被调用,该次调用转为需要人工审批。Runner 与 Realtime 的工具调用行为一致。

同页还说明了审批面的作用域:审批是 run 级别的,不限于当前顶层 agent——无论工具属于当前 agent、通过 handoff 到达的 agent,还是嵌套的 Agent.as_tool() 执行,嵌套场景下中断仍浮现在外层 run 上,由外层 RunState 批准或拒绝后恢复原始顶层 run。要让被暂停的运行跨越进程重启而恢复,靠的是 RunState 序列化。

LangChain 侧的 LangGraph interrupt() 提供了另一种实现,并给出了一组对客服场景同样适用的工程铁律。文档列出的规则是:不要用 try/except 包住 interrupt 调用;不要在一个节点内重排 interrupt 调用;不要在 interrupt 调用中返回复杂值;interrupt 之前触发的副作用必须是幂等的。 最后一条在客服系统里尤其致命——如果"已发起退款"这个副作用在 interrupt 之前执行,而审批在两分钟后被拒绝,那么重放时必须识别出退款已发起过并跳过,否则会退两次款。

文档还专门警告了一个陷阱:不要在单个节点里写 while True 加 interrupt() 的循环。因为节点在每次恢复时都会从头重跑,循环里多次调用 interrupt 会导致每次恢复重放此前所有迭代——第一次恢复重放 1 轮,第二次重放 2 轮,指数级重复执行循环体内的代码。正确模式是把待提问的问题存进 state(如 pending_question),在节点里恰好调用一次 interrupt(),如果答案不合法就返回更新后的 pending_question 让下次调用重新提问,并用 add_conditional_edges 路由回该节点直到收集到合法值。

审批与拒绝的写法是 Command(resume=True) 批准、Command(resume=False) 拒绝,interrupt() 的返回值即恢复时传入的载荷。

把这些机制对齐到客服场景,能推导出几条可执行的工程指标:交接上下文完整率(移交单中必填字段的填充比例)、人类重复询问率(人类接手后问了客户已经在对话里说过的问题的比例)、交接后一次解决率、以及审批误操作率。第一条直接决定人工成本,第二条是绝大多数 AI 客服系统"看起来聪明但实际上很烦"的技术根因。


六、结果计费与评估:把"成功"写成可执行断言

计费口径是一套现成的评估定义,这是客服场景相对于其他 Agent 应用的独特优势——业务方已经把"成功"写成了可判定的规则,我们要做的是把它翻译成工程断言。

先把 Intercom 的口径完整列出,因为它定义了 outcome 的边界条件:

  • Resolution(0.99 美元):定义为"在 Fin 最后一次答复之后,不再请求进一步帮助"。文档区分两种:confirmed resolution(客户给出肯定回应,如"好的谢谢""这有帮助")与 assumed resolution(客户退出对话且未再请求协助)。
  • Procedure handoff(0.99 美元):Fin 成功执行一个被配置为最终交接给人或工作流的 Procedure。文档强调,一次会话即使 Fin 解决了多个问题或运行了多个 Procedure,也只计费一次。
  • Disqualification(0.99 美元):仅在为 Sales 配置 Fin 时发生——它判定潜客不符合资格条件并据此淘汰。
  • Qualification(9.99 美元):仅在为 Sales 配置 Fin 时发生——把潜客匹配到你定义的资格条件并据此路由,例如"预约销售团队通话""开始试用""路由到自助式 onboarding"。会议预约与开始试用按 9.99 美元计,路由到自助式 outcome 按 0.99 美元计,需要在 playbook 里用 Outcome type 开关标记,且已有的 outcome 不会自动改价。
  • Self-serve routing(0.99 美元):把潜客匹配到被标记为自助式的路由结果。

文档里还有一条对工程实现极具约束力的规则:如果一次会话被视为已解决(无论 confirmed 还是 assumed),但客户之后回到同一会话继续寻求协助——即使跨越了计费周期——该 resolution 会被扣除且不计费。 这意味着 outcome 不是终态,而是可撤销的判定。工程上必须保留"客户在 T 时刻之后又回到本会话"的事件流,用于回滚计费。

另外两个操作性的细节:Fin 在所有套餐中可用,但不使用不计费,可以设置使用提醒和硬性上限;以及"resolution 只在 Fin 实际给出答案时才计数,如果只是回应一句问候,不算答案也不算 resolution"。

把这套口径翻译成工程断言,得到三个层次的评估体系:

任务层指标(单轮可判):意图路由准确率、槽位抽取精确率/召回率、澄清问题的必要率(在必填槽位已可从上下文推导时是否仍然发问)、动作选择正确率、护栏拦截的误报/漏报率。

会话层指标(跨轮可判):首次接触解决率、转人工率与转人工原因分布、澄清轮次分布、平均每会话 LLM 调用次数与 token 成本、重复求助率(同一个会话内客户重复问同一件事的比例)。

业务层指标(跨会话可判):每 outcome 成本、每坐席时(人工处理时长 × 人工单价与自动解决时长 × 成本的对标)、outcome 被回滚的比例。

开源评估工具的现状(2026-10-26 实时拉取 GitHub API):promptfoo 26451★(MIT,2026-10-26 有推送)、langfuse 36516★(NOASSERTION 许可证,TypeScript,2026-10-26 推送)、confident-ai/deepeval 19111★(Apache-2.0)、explodinggradients/ragas 16152★(MIT,最后推送 2026-02-24)、guardrails-ai/guardrails 7559★(Apache-2.0)。做 PII 脱敏可以用 microsoft/presidio(11515★,MIT,2026-10-26 推送)。

一个实践建议:断言优先于模型评判。 凡是能用确定性规则判定的(转人工率、重复求助率、outcome 回滚率、每次会话调用次数),一律用规则判定;只有"回答是否切题且有据"这种没有硬判据的维度才交给 LLM 评判。把两类指标混在一起用模型判,既贵又不可复现。ragas 16152★ 的最后推送时间是 2026-02-24,近八个月没有更新,用它做 RAG 场景评估时要注意维护节奏;而 deepeval 与 promptfoo 都是当日仍在推送的活跃项目。


七、语音通道:客服的第二形态

文字客服跑通之后,语音几乎是必答题,但语音不是"把 TTS 和 STT 接上"这么简单,它引入了文字渠道不存在的三个问题。

第一个问题是轮次判定(turn detection)。 LiveKit Agents 文档把这件事讲得最细:轮次检测就是判断用户何时开始和结束"轮次",从而让 agent 知道何时开始听、何时开始响应。大多数轮次检测依赖 VAD(voice activity detection)检测用户输入中的静音,agent 对 VAD 数据应用启发式规则做短语端点检测(phrase endpointing)来确定一句话或一个想法的结束。LiveKit 提供三种模式:Turn detector model(对多数 agent 推荐且是默认,从语音含义和声学属性两方面预测轮次结束,叠加在 VAD 之上)、VAD only(需要最低延迟或 turn detector model 未覆盖的语言时使用)、STT endpointing(已经在用自带轮次检测的 STT 时使用,例如 AssemblyAI 或 Deepgram Flux)。

第二个问题是打断(interruption)。 用户在 agent 说话过程中插话,agent 必须能及时让出控制权——但要区分"真打断"和"附和"(backchanneling,比如"嗯""对")。LiveKit 提供的 adaptive interruption handling 就是干这个的。此外还有 uninterruptible speech(不可打断段落,用于必须完整播报的关键信息,例如合规声明)、user turn limit(用户轮次上限,防止无限循环)以及 endpointing delay(可设 min_delay 与 max_delay,Python 侧还支持依据会话停顿统计做动态端点)。

第三个问题是多步流程中的回退。 LiveKit 的 Task 与 TaskGroup 模型是很好的参考:Task 是聚焦、可复用的单元,完成目标后返回类型化结果,接管会话直到目标达成;TaskGroup 执行有序的任务序列,同时允许用户回到之前的步骤做修正——组内所有任务共享会话上下文,组结束时把摘要结果交还给启动它的 agent。文档提到 task factory 在任务被重新访问时可以被重新初始化,task 的 id 与描述会作为标识符传给 LLM,让 LLM 在需要回到前一步时知道那个任务的目的和上下文。文档同时给出了用异常跳过剩余任务的模式(在回调里抛出自定义异常并在 await task group 处捕获),并强调 return_exceptions 默认为 false。

这套"允许回退到前一步"的能力,正是客服场景里最实用的特性之一:客户说"不对,我说的是另一个订单",agent 需要能退回槽位填充阶段重新填 order_id,而不是从头重来。

电话接入层面,Twilio 的 Conversation Relay 提供了一条相对直接的路径:通过 TwiML 的 <ConversationRelay> 名词建立会话,例如

const response = new VoiceResponse();
const connect = response.connect({ action: 'https://myhttpserver.com/connect_action' });
connect.conversationRelay({
  url: 'wss://mywebsocketserver.com/websocket',
  welcomeGreeting: 'Hi! Ask me anything!'
});

LiveKit 则提供了另一条路径,其 Agents 文档说明 agent 可以通过 LiveKit 的 SIP 集成呼出和接听电话,用户从电话接入而不必打开前端应用;其语音管线既支持由多个专用模型组成的 STT-LLM-TTS 管线,也支持具备直接语音到语音能力的 realtime 模型。

语音渠道还有一条容易被忽略的客服铁律:语音里不能发链接。 文字渠道常见的"请点击这个链接查看物流"在电话里是无效的,方案必须改写——要么口述关键信息,要么通过短信补发链接,要么改成"我帮您改到xx地址,您确认吗"这种确认式对话。这条约束会反过来影响工具设计:语音场景下的工具应当返回可直接朗读的短文本,而不是长 URL。


八、工具、会话与护栏:生产底座

工具契约就是业务边界。 Anthropic 在附录二专门讲了对工具做 prompt engineering:工具定义与规格应该得到和整体 prompt 同等的注意力;常见做法是给模型足够的 token 去"想清楚再写",保持格式贴近互联网文本中自然出现的形式,避免出现"保持对数千行代码的准确计数"或"对写出的代码做字符串转义"这类格式开销。它给出的例子极具体:写 diff 需要在写新代码之前就知道 chunk header 里有多少行会变;在 JSON 里写代码(相比 markdown)需要额外转义换行和引号。

它还记录了一条真实教训:SWE-bench 的 agent 工具优化花的时间比整体 prompt 更多。原因是模型在使用相对路径的工具时会犯错(agent 移出根目录之后),修法是把工具改成始终要求绝对路径,模型随后就再也没出过错。这就是 poka-yoke——通过改变参数设计让犯错变难。客服场景的对应物非常直接:查订单的工具如果接受自由文本订单号,模型就会自己编;改成只接受从候选列表中选择的枚举 id,编造就从"可能"变成"不可能"。

还有一条文档反复强调的准则:把工具描述当成给团队里初级开发者写一份优秀 docstring。这在工具数量多的时候尤其重要——相似的工具(查物流 vs 查订单状态)必须靠描述区分开。

会话与持久化。 OpenAI Agents SDK 的 sessions 文档给出了一个干净的默认行为:当启用会话记忆时,每次 run 之前 runner 会自动取出该会话的对话历史并前置到输入条目;每次 run 之后,本次产生的所有新条目(用户输入、助手回复、工具调用等)自动存入会话;后续使用同一会话的 run 会包含完整对话历史,从而免去了手动调用 .to_input_list() 和自行管理会话状态。文档同时提供了控制历史与新输入如何合并、限制取回历史长度,以及内置实现清单——OpenAI Conversations API sessions、OpenAI Responses compaction sessions、SQLite(及异步版)、Redis、SQLAlchemy、Dapr、MongoDB、Advanced SQLite、Encrypted sessions,以及 Session ID 命名规范。

客服场景里有两个特殊需求值得强调。其一是限制取回历史长度:长期会话如果全量塞进上下文,成本和延迟都会失控,"最近 N 轮 + 摘要 + 结构化槽位状态"的组合比"全历史"更稳。其二是纠错能力:文档提到内存操作中的 pop_item 用于 corrections——客户说"我刚才说的不对"时,能从会话里撤回那条错误陈述并重新填槽,这比让模型在长上下文里"自己记住别用那条"要可靠得多。

LangGraph 侧的对应物是 checkpointer 与 thread_id:文档把 thread_id 称为你的持久化游标,复用它会恢复同一个 checkpoint,换新值则开启一个空状态的新线程;interrupt() 触发时,LangGraph 通过持久化层保存图状态并无限期等待,直到你用 Command 重新调用图来恢复。

护栏。 OpenAI Agents SDK 提供三类护栏位置——输入护栏、输出护栏、工具护栏,外加 tripwires(当某个条件被触发时直接抛出异常终止运行)。客服场景的护栏清单至少包括:金额上限与动作白名单(哪些意图可以触发退款、退款金额上限)、PII 脱敏(presidio 11515★)、拒绝执行法律/医疗/投资建议、以及跨境数据合规。护栏的位置选择有讲究:输入护栏防提示注入与越权请求,工具护栏防的是"模型被诱导调用了不该调用的工具",输出护栏防的是"回答里出现了不该出现的信息(内部价格、其他客户数据)"。

开源底座的现状(均为 2026-10-26 实时拉取 GitHub API):工单与收件箱侧有 chatwoot/chatwoot(38330★,Ruby,2026-10-26 推送)与 zammad/zammad(6031★,AGPL-3.0,Ruby);LLM 应用层有 langgenius/dify(159589★,Python,2026-10-26 推送)、vercel/ai(27521★,TypeScript,2026-10-26 推送)、n8n-io/n8n(208635★,TypeScript,2026-10-26 推送)、microsoft/autogen(61572★,CC-BY-4.0)、openai/openai-agents-python(30296★,MIT,2026-10-22 推送)、google/adk-python(22012★,Apache-2.0)、langchain-ai/langchain(148486★,MIT,2026-10-26 推送)、langchain-ai/langgraph(43925★,MIT,2026-10-26 推送)、microsoft/semantic-kernel(28697★,MIT,C#)、BerriAI/litellm(62064★)、anthropics/anthropic-cookbook(53789★,MIT)、anthropics/anthropic-sdk-python(4008★,Apache-2.0)、openai/openai-python(31955★,MIT);工具与 Agent 运行时侧有 livekit/agents(14939★,Apache-2.0,2026-10-26 推送)、baptisteArno/typebot.io(10580★,TypeScript)、browser-use/browser-use(119181★,MIT)、Skyvern-AI/skyvern(23278★,AGPL-3.0)、ComposioHQ/composio(30759★,MIT,TypeScript)、microsoft/BotFramework(284★,已归档,2020-01-08 最后推送);检索与记忆侧有 infiniflow/ragflow(92895★,Apache-2.0,Go)、milvus-io/milvus(46486★,Go)、qdrant/qdrant(35258★,Rust)、chroma-core/chroma(29583★,Rust)、pgvector/pgvector(23483★,C)、weaviate/weaviate(16915★,Go)、lancedb/lancedb(11776★,Apache-2.0,Rust)、mem0ai/mem0(67837★,MIT)、letta-ai/letta(25260★)、topoteretes/cognee(32770★,Apache-2.0)、deepset-ai/haystack(26847★,Apache-2.0,2026-10-26 推送)。

方法论上有一个值得写进正文的重要提醒:star 数高不代表项目活跃,路径 200 也不代表它是权威仓库。 本次实测中,Chainlit/chainlit 有 12515★ 但仓库已被标记 archived(最后推送 2026-09-18);microsoft/BotFramework 仅 284★ 且已归档、2020 年后无推送;microsoft/copilot-studio-agents 只有 13★ 且 2024-12-26 后无推送——这三个都返回 HTTP 200,但都不该被当作"活跃的官方方案"引用。另有若干路径直接 404:Dify-ai/dify、typebot-io/typebot、dust-tt/dust、salesforce/Agentforce、weavel-ai/guardrails、unitaryai/dspy,其中 Dify 与 Typebot 的真实路径分别是 langgenius/dify(159589★)和 baptisteArno/typebot.io(10580★),用搜索 API 按仓库名 + 星标排序才能定位。凡是没有实时拉取到确认状态的仓库,本文一律不引用。


九、落地路线与八个常见陷阱

路线建议分三阶段,每阶段的验收标准不同。

第一阶段:只读知识问答。此时不接任何写动作,唯一目标是验证意图路由与检索的准确率,并同时把 outcome 定义写进代码——在还没有写权限的时候就把结算口径定下来,是最容易被跳过但最不该被跳过的一步。验收看意图路由准确率与幻觉率。

第二阶段:加入可逆的写动作。优先选择"可逆 + 低金额 + 高频"的写动作(下单备注修改、预约改期、催单工单创建),所有真正改变资金或权益的动作仍走人工审批。此阶段重点建立护栏与审批闭环,验收看护栏误报率、审批通过时延、审批拒绝后的回滚正确性(尤其要验证幂等性)。

第三阶段:加入转人工与按结果计费。上线 handoff 机制与 outcome 结算,验收看首次接触解决率、转人工率、每 outcome 成本、以及 outcome 回滚比例。

八个常见陷阱:

  1. 先做 Agent 再想定指标。 这是最贵的错误。指标口径如果晚于系统两周上线,你将永远无法回答"这个 Agent 到底有没有用",只能靠感觉继续投入。
  2. 路由只改了 prompt,没改工具集。 30 类意图共用 40 个工具,路由等于没做。
  3. 澄清变死循环。 客户不答、模型追问、再追问。必须在代码层设"同一槽位最多追问一次"与"每轮最多一个问题"。
  4. 把"缺信息"和"不确定"混为一谈。 缺槽位要澄清,不确定意图要转人工,用错工具会把简单问题复杂化。
  5. 交接只传一句话。 人类接手后重新问一遍客户,等于把成本转嫁给用户。
  6. 让模型自由生成政策数字。 退款上限、时效承诺、费用规则必须来自工具返回值,并对返回值做断言,而不是让模型复述。
  7. 忽略 outcome 可撤销。 客户回头追问导致的回滚必须能追溯,否则财务对不上账。
  8. 停止条件只写在文档里。 最大轮次、最大工具调用次数、最大金额、最大澄清次数,都必须是代码里的硬约束,不是 prompt 里的一句祈使句。

十、小结

客服 Agent 的工程难点,可以被压缩成一句话:让一段不确定的自然语言,稳定地落到一次可审计、可回滚、可计费的动作上。

本文给出的路径是:用意图路由做上下文隔离,每个意图绑定专属 prompt、工具白名单与预算上限;用槽位与澄清做缺失信息的状态化处理,把"问什么""问几次""沉默怎么办"全部写死;用拒答与转人工构建三条合法出口,交接必须携带结构化上下文,审批必须 fail closed 且幂等可重放;用 outcome 计费反向定义成功,把评估拆成任务层、会话层、业务层三档并让断言优先;用语音通道的轮次检测、打断区分与任务回退补上文字渠道缺失的交互能力。

Anthropic 在那篇工程博客结尾给出的三条原则,放在客服这个具体场景里依然成立且更加具体:保持 Agent 设计的简单性;优先保证透明度——显式展示 Agent 的规划步骤(对客服而言,这意味着把"我接下来要做什么"讲给客户听);以及认真打磨 Agent-Computer 接口,做充分的工具文档与测试。客服场景还会加上第四条:把业务契约前置——先定义什么叫解决、什么算交接、什么该计费,再开始写代码。


参考文献

  1. Anthropic Engineering. Building effective agents. https://www.anthropic.com/engineering/building-effective-agents (2024-12-19 发布,文首含 2026 年更新说明)
  2. Anthropic Docs. Tool use overview. https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview
  3. Intercom Help. Fin AI Agent outcomes. https://www.intercom.com/help/en/articles/8205718-fin-ai-agent-overview (Beth-Ann Sher,2026-09-23)
  4. OpenAI Agents SDK (Python). Handoffs. https://openai.github.io/openai-agents-python/handoffs/
  5. OpenAI Agents SDK (Python). Human-in-the-loop. https://openai.github.io/openai-agents-python/human_in_the_loop/
  6. OpenAI Agents SDK (Python). Sessions. https://openai.github.io/openai-agents-python/sessions/
  7. OpenAI Agents SDK (Python). Guardrails. https://openai.github.io/openai-agents-python/guardrails/
  8. OpenAI Agents SDK (Python). Tools. https://openai.github.io/openai-agents-python/tools/
  9. LangChain Docs. LangGraph overview. https://docs.langchain.com/oss/python/langgraph/overview
  10. LangChain Docs. Interrupts. https://docs.langchain.com/oss/python/langgraph/interrupts
  11. LiveKit Agents Docs. Turn detection & interruptions. https://docs.livekit.io/agents/build/turns/
  12. LiveKit Agents Docs. Tasks and task groups. https://docs.livekit.io/agents/build/tasks/
  13. LiveKit Agents Docs. Voice AI 与 Telephony/SIP. https://docs.livekit.io/agents/start/voice-ai/ 与 https://docs.livekit.io/sip/
  14. Twilio Docs. Conversation Relay(<ConversationRelay> TwiML 名词). https://www.twilio.com/docs/voice/conversationrelay
  15. Vercel AI SDK. Introduction(AI SDK Core 与 AI SDK UI 分层). https://ai-sdk.dev/docs/introduction
  16. GitHub REST API v3 — Repositories endpoint(仓库元数据、license、pushed_at 实时拉取). https://docs.github.com/en/rest/repos/repos
  17. GitHub REST API v3 — Search repositories(按仓库名定位真实路径). https://docs.github.com/en/rest/search/search#search-repositories
  18. 仓库实测(2026-10-26):chatwoot/chatwoot 38330★、zammad/zammad 6031★、RasaHQ/rasa 21359★、Chainlit/chainlit 12515★(已归档)、microsoft/BotFramework 284★(已归档)、microsoft/copilot-studio-agents 13★(2024 年后无推送)
  19. 仓库实测(2026-10-26):promptfoo/promptfoo 26451★、langfuse/langfuse 36516★、confident-ai/deepeval 19111★、explodinggradients/ragas 16152★(最后推送 2026-02-24)、guardrails-ai/guardrails 7559★、microsoft/presidio 11515★
  20. 仓库实测(2026-10-26):langgenius/dify 159589★、n8n-io/n8n 208635★、langchain-ai/langchain 148486★、langchain-ai/langgraph 43925★、openai/openai-agents-python 30296★、google/adk-python 22012★、microsoft/autogen 61572★、BerriAI/litellm 62064★、vercel/ai 27521★、livekit/agents 14939★、baptisteArno/typebot.io 10580★、browser-use/browser-use 119181★、ComposioHQ/composio 30759★、anthropics/anthropic-cookbook 53789★
  21. 仓库实测(2026-10-26):infiniflow/ragflow 92895★、milvus-io/milvus 46486★、qdrant/qdrant 35258★、chroma-core/chroma 29583★、pgvector/pgvector 23483★、weaviate/weaviate 16915★、lancedb/lancedb 11776★、mem0ai/mem0 67837★、letta-ai/letta 25260★、topoteretes/cognee 32770★、deepset-ai/haystack 26847★
  22. 仓库路径三态核验(2026-10-26):Dify-ai/dify 404 → langgenius/dify;typebot-io/typebot 404 → baptisteArno/typebot.io;dust-tt/dust、salesforce/Agentforce、weavel-ai/guardrails、unitaryai/dspy 均 404 且未入正文
  23. 全站标题词频扫描(2026-10-26,714 篇 published):客服 / 工单 / 坐席 / 转人工 / 意图路由 / 槽位 / 澄清 / 拒答 / CSAT / 人工接管 全站 0 命中
←返回文章列表

Related

可能也会喜欢

  • AI 应用交付物工程 2026:从工具结果到可验证产物10月31日
  • AI 应用的记忆写侧工程 2026:抽取、晋升与冲突消解10月30日
  • 向量数据库选型 2026:pgvector 与专用引擎的边界10月29日

Conversation

0 条

留下你的想法

加载评论中…

New comment