【AI】把“大杂烩抽取”拆成多步推理:一个从单提示到多阶段管线的实践案例

很多做 LLM 应用的同学,都会遇到一个经典场景:
一条长文本,要求模型一次性抽一堆字段,还要严格 JSON 输出。

规则写得越来越长,few-shot 越堆越多,但效果总是"差点意思"。

这篇文章讲一个常见的场景:电商客服聊天记录抽取,聊聊如何把"单步抽取"重构为"多步推理管线",以及中间踩过的坑和优化经验。


一、场景设定:从客服对话中抽订单与问题信息

需求:对电商客服对话做结构化抽取,目标字段大致如下:

  • 订单号
  • 商品名称
  • 数量
  • 退款/退货意向
  • 问题类型(物流/质量/错发/售后等)
  • 情绪/满意度(可选)

原始对话可能是这样:

客:上个月我在你们家买的那台黑色扫地机器人(订单号 2024-09-123456),用了不到一周就开始卡死不动了。

客:昨天快递终于送到了,但包装都烂了,感觉像旧的。

客:我想退货或者换新。

客:上次问你们的客服,说给我登记了,结果一直没人联系。

目标是抽出若干"事件",比如:

  • 一个是"商品质量问题+退货意向"
  • 一个是"物流包装问题"
  • 等等。

如果让模型一次性输出一个大 JSON 数组,同时填所有字段,很快会遇到:

  • 长对话、上下文复杂,模型要同时做:
    • 事件检测 + 订单识别 + 商品归因 + 问题分类 + 情绪判断
  • 规则一多,样例一堆,LLM 会"选择性失明":
    • 有时候字段全填,有时候只填一半
    • 有时候乱编订单号/商品名
    • 一句对话里有多个事件(质量 + 物流 + 客服体验),拆分经常乱

这是典型的"任务过载"。


二、为什么要改成多步?------先找"事件",再填细节

核心思路很简单:

把"从对话 → 结构化记录"拆成两步:
Step1:事件检测 & 粗标注
Step2:单事件细粒度抽取

Step1:事件检测(Conversation Event Detection)

只解决一个问题:这段对话里有哪些"服务事件"?

例如,针对一整段对话,输出:

json 复制代码
[
  {
    "事件原文": "上个月我买的那台黑色扫地机器人,用了一周就卡死不动了。",
    "粗略订单标识": ["2024-09-123456"],
    "粗略问题类型": ["商品质量问题"],
    "是否退款意向": false
  },
  {
    "事件原文": "昨天快递终于送到了,但包装烂了,感觉像旧的。",
    "粗略订单标识": ["2024-09-123456"],
    "粗略问题类型": ["物流/包装问题"],
    "是否退款意向": false
  },
  {
    "事件原文": "我想退货或者换新。",
    "粗略订单标识": ["2024-09-123456"],
    "粗略问题类型": ["售后/退换货"],
    "是否退款意向": true
  }
]

特点:

  • 不要求模型在这里就把"订单号格式""问题子类别""满意度评分"弄得很精确;
  • 只要求事件切得对 ,并且给出粗粒度标签
    • 这条话是关于哪一个订单;
    • 粗略属于哪个问题大类;
    • 有没有直白的退货/退款意向。

Step2:单事件细粒度抽取(Event-Level Structuring)

对 Step1 检出的每个事件,再单独跑一遍模型,抽出完整字段:

json 复制代码
[
  {
    "订单号": ["2024-09-123456"],
    "商品名称": ["黑色扫地机器人"],
    "数量": ["1"],
    "问题类型": ["商品质量问题"],
    "退款意向": ["退货或换新"],
    "情绪": ["不满"],
    "时间信息": ["上个月", "不到一周后"],
    "客服处理评价": ["上次说登记了,但一直没人联系"]
  }
]

每次 Step2 的上下文只是一小段"事件原文" + Step1 的粗略信息 →

模型任务简单得多,也更容易通过规则+示例牢牢控住字段。


三、Step1 提示词设计:只做"事件级别"的事

给 LLM 的系统提示大致是:

  • 你是客服对话分析助手;
  • 只做一件事:识别对话中的服务事件并粗标注
  • 输出一个 JSON 数组,每个元素代表一个事件。

字段设计(Step1)

  • 事件原文:对话中与该事件直接相关的那几句(可以跨两三句)
  • 粗略订单标识:能明显标识订单的片段(完整订单号或"上次买的黑色扫地机器人"等)
  • 粗略问题类型:粗粒度标签,如:商品质量物流/包装售后/退换货客服体验
  • 是否退款意向true/false

关键规则示例

  • 拆分规则
    • "商品有问题,而且快递也很慢" → 至少两个事件:质量问题 + 物流问题
    • "我想退货或者换新" → 单独一个"售后/退换货"事件
  • 时间上下文保留
    • 如果一句话里既有时间又有问题描述,要把时间一起截进 事件原文,方便 Step2 做时间归因;
    • 但像"半年前买的,现在才发现问题",就要在 Step2 再区分"购买时间 vs 问题发现时间"。

few-shot 重点

  • 主要教模型三件事:
    1. 一句多事要拆开;
    2. 事件原文要带上与该事件强相关的时间/订单/商品线索;
    3. 否定场景要识别(比如"本来以为要退货,后来发现自己搞错了",是否退款意向= false)。

四、Step2 提示词设计:像做"字段标注",而不是"阅读理解"

Step2 的系统提示可以写得很"工程化":

  • 你已经拿到一个具体的服务事件片段 + 一些粗略信息;
  • 不需要再关心整段对话的其他内容
  • 只围绕这个片段填下面这些字段:

字段示例:

  • 订单号:严格匹配对话中出现的订单号格式,不编造
  • 商品名称:原文出现的商品名,如果模糊就用片段中最接近商品描述的短语
  • 数量:明确提到"买了两台"、"一共三件"等才填
  • 问题类型:在已有大类上再做一下细化(如"质量问题-机器卡死")
  • 退款意向:归一化为 无 / 退货 / 换新 / 退款
  • 时间信息:按你业务需要,可能拆成"购买时间/问题发生时间/联系客服时间"等
  • 情绪:粗分"满意/一般/不满/愤怒"等

关键约束

  • 不编造 :没有就 []"无";不要根据"常识"乱补订单号、下单时间;
  • 时间归属
    • "上个月买的" → 购买时间
    • "用了不到一周就坏了" → 问题发生时间
    • "昨天又来找你们" → 本次联系客服时间
  • 多值拆分
    • 一个事件中如果既有购买时间又有问题发生时间,可以分别放到对应字段,必要时拆成多个记录。

Step2 few-shot 重点

  • 用几个精心设计的示例覆盖难点:
    • 购买时间 vs 问题时间;
    • 一句话里多个时间点;
    • 含模糊订单标识("上次的那单")但没有明确订单号的情况;
    • 情绪"转折":例如"虽然问题解决了,但过程太糟糕"。

五、效果对比:多步 vs 单步

在一个小规模测试集上(几十条真实或合成客服对话),常见的结果是:

  • 单步抽取
    • 简单样本 OK,复杂样本一旦时间/问题/情绪混在一起,很容易:
      • 只提一个时间,忽略另外两个;
      • 把"购买时间"误当成"问题发生时间";
      • 情绪字段经常"我行我素",要么全空,要么各种主观补充。
  • 多步抽取
    • Step1 只做"哪儿有事 + 大概什么事",容错空间大得多;
    • Step2 围绕一个短片段做字段填空,更像传统 IE 任务,规则能落地,few-shot 更好使;
    • 整体召回率(尤其是复杂样本中的问题事件召回)显著提升;
    • 错误更容易定位:
      • 事件没检出 → 调 Step1;
      • 字段乱填 → 调 Step2。

六、对提示词工程师和 AI 开发者的几点建议

  1. 能拆就拆,别让一个 prompt 做所有事

    • 大模型强在"复杂推理能力",但不是"全活一口气干完"的意思。
    • 把任务拆成"事件检测 → 单事件结构化 → 聚合/后处理",往往整体质量和可控性都更好。
  2. 提示词不是越长越好,关键在"分角色"

    • Step1 的角色:事件侦探(在哪儿发生了什么事)
    • Step2 的角色:数据标注员(为这个事件填表)
    • 各自的规则和 few-shot 都要紧贴这个角色的职责,而不是全贴在一个 prompt 里。
  3. few-shot 要为"最常见的错误模式"服务

    • 时间归属错,就设计专门的"边界示例";
    • 拆分错,就设计"一个句子多个事件"的重点示例;
    • 方案/情绪乱填,就来一两个"错误 vs 正确"的对照示例。
  4. 多步 ≠ 多开销,而是换取"可维护性"

    • 是的,多步意味着更多 API 调用;
    • 但如果单步方案需要各种后处理脚本、人工规则修补,整体成本经常更高。
    • 尤其在高要求场景(金融、医疗、客服质检)中,"可解释 + 可迭代"往往比"省几次 API 调用"更重要。

如果你现在手上也有一个"超级长提示词 + 一堆规则 + 一堆样例"的抽取任务,不妨试着问自己三个问题:

  1. 我能不能先只做"事件检测",晚一点再管字段?
  2. 哪些错误其实是"事件没切好"导致的,而不是模型不会填字段?
  3. 如果把最常错的 20% 场景拆出来做一个 Step2,会不会简单很多?

这三个问题,基本就是从单步到多步重构的起点。

相关推荐
PPIO派欧云1 小时前
PPIO上线GLM-OCR:0.9B参数SOTA性能,支持一键部署
人工智能·ai·大模型·ocr·智谱
雨大王5121 小时前
怎么打造一个能自我进化的制造数字基座?
人工智能·汽车·制造
fengfuyao9852 小时前
基于MATLAB的表面织构油润滑轴承故障频率提取(改进VMD算法)
人工智能·算法·matlab
爱吃泡芙的小白白2 小时前
深入解析CNN中的Dropout层:从基础原理到最新变体实战
人工智能·神经网络·cnn·dropout·防止过拟合
Eloudy2 小时前
全文 -- TileLang: A Composable Tiled Programming Model for AISystems
人工智能·量子计算·arch
金融RPA机器人丨实在智能2 小时前
2026动态规划新风向:实在智能Agent如何以自适应逻辑重构企业效率?
算法·ai·重构·动态规划
才盛智能科技2 小时前
K链通×才盛云:自助KTV品牌从0到1孵化超简单
大数据·人工智能·物联网·自助ktv系统·才盛云
哥布林学者2 小时前
吴恩达深度学习课程:深度学习入门笔记全集目录
深度学习·ai
广州赛远2 小时前
IRB2600-201.65特殊机器人防护服清洗工具详解与避坑指南
大数据·人工智能