本文复盘一个客服数据分析场景下的 Agent 实践。
客服日常使用的是采购的第三方客服系统。要做阶段性复盘时,需要先把用户反馈和客服回复导出成 Excel。但原始文件一行只有一条消息,同一次咨询往往散在多行,无法直接用来分析用户完整的问题。
我们最终交付的不是一份模型生成的本地报告,而是直接进入客服工作流程的三项钉钉产物:
- 一份用户原声洞察周报。
- 一张问题聚类明细表。
- 一张原声样本池。
周报集中呈现数据概览、核心结论、高频问题 Top10、上升明显的问题、不满意集中问题、用户侧与主播侧问题分布,并给出典型原声摘要、建议跟进部门和后续动作。两张表格分别用于查看问题分布和核对经过脱敏的具体会话。
整条链路可以概括为:
text
Excel/CSV 输入
-> 字段映射与必填校验
-> 数据清洗与规则脱敏
-> 按会话标识聚合完整会话
-> 大模型会话级结构化分析
-> 问题聚类与样本抽取
-> 写入 1 份钉钉文档 + 2 张钉钉表格
这套 Agent 已经完成交付并进入实际业务使用。下面重点拆解这条链路中几个容易被低估的工程问题。
1. 整体架构:大模型只负责语义判断
整套 Agent 分为四个部分。
1.1 数据接入
数据接入负责读取客服导出的 Excel/CSV,识别不同文件中的字段名称,并检查会话标识与消息内容能否正确映射。
1.2 确定性预处理
预处理程序负责过滤无效记录、识别发送方角色、替换规则能够识别的敏感内容,再按时间和会话标识把多行消息还原成完整会话。
1.3 模型分析
大模型接收的是预处理后的完整会话。它负责判断用户核心诉求、问题主题、情绪和优先级,并以固定结构返回结果。
1.4 业务交付
业务交付部分把结构化结果转换成钉钉表格需要的二维数组,写入两张表格,然后生成周报并关联表格链接。

这个分工的重点是,大模型只承担不确定的语义判断。输入能不能用、字段是否缺失、消息怎样排序、结果能否写入表格,都由可以重复执行和检查的程序完成。
2. 关键实现一:先把逐行消息还原成完整会话
客服导出的原始文件中,一行代表一条消息。如果直接逐行分析,模型只能看到用户某一句话,无法判断客服是否已经回复、用户是否继续追问,也无法完整还原问题语境。
我们把会话标识和消息内容定义为必要字段。任何一个无法映射,流程都会停止并报告原因,不会拿残缺数据继续生成报告。
可以把这段预处理理解为以下流程:
python
rows = read_excel_or_csv(input_file)
mapped_rows = map_field_aliases(rows)
require_fields(mapped_rows, ["conversation_id", "message_text"])
clean_rows = filter_invalid_messages(mapped_rows)
redacted_rows = redact_by_rules(clean_rows)
sorted_rows = sort_by_conversation_and_time(redacted_rows)
conversations = group_by_conversation_id(sorted_rows)
实际执行时还需要处理几个细节:
- 不同文件的同一个含义可能使用不同字段名,需要先做别名映射。
- 空消息、系统消息和缺少会话标识的记录不应进入分析。
- 发送方角色缺失时,需要通过已有字段或文本前缀识别用户与客服消息。
- 同一会话内的消息需要先按时间排序,再组装成会话文本。
会话聚合完成以后,模型看到的才是一次完整咨询,而不是被拆散的单句消息。
3. 关键实现二:在模型前完成必要的隐私处理
客服对输入有一项硬性约束:未脱敏的原始对话不得直接进入大模型。
因此,预处理脚本不会把整份 Excel 原样交给模型。它会先提取分析所需的字段,再使用关键词和正则规则替换手机号等可以稳定识别的敏感信息。完成字段筛选、清洗和规则脱敏后,脚本才会按会话标识聚合消息,并把处理后的会话交给模型。
这个顺序很关键:
text
原始 Excel
-> 必要字段筛选
-> 确定性规则脱敏
-> 会话聚合
-> 模型分析
隐私处理是模型输入前的工程步骤,不依赖模型在分析时自己决定哪些内容不该看。
4. 关键实现三:让模型输出可以被程序验收
模型如果只返回一段自然语言总结,后续很难稳定完成统计、聚类和表格写入。因此,每个完整会话都需要生成一条固定结构的分析结果。
一条结果可以抽象为:
json
{
"conversation_id": "123456",
"problem_topic": "某类业务问题",
"core_user_need": "用户希望确认原因和后续处理时间",
"emotion": "negative",
"priority": "high",
"manual_category_mismatch": false,
"suggested_department": "建议跟进部门",
"suggested_action": "建议的后续动作",
"need_follow_up": true,
"confidence": 0.86
}
字段名称和枚举值必须稳定,业务侧才能继续进行以下处理:
- 校验必填字段是否完整。
- 把内部枚举映射为业务人员可以直接阅读的中文。
- 对相近问题做归并和统计。
- 将结果组装成钉钉表格需要的二维数组。
如果模型返回的结构不合要求,程序会阻止错误内容进入最终产物。
在会话级分析完成后,Agent 再把相近问题合并成业务可读的主题。重复出现、不满意较集中,以及人工分类和对话内容明显不一致的问题会被优先整理。每个主题同时抽取经过脱敏的原声样本,方便业务人员核对模型判断。
5. 业务交付:不是生成文件,而是写入真正使用的工具
这个项目有第二项硬性约束:最终结果只能写入钉钉文档和钉钉表格,不能降级为 .md、.csv、.xlsx 或可下载附件。
模型分析完成后,Agent 会把两张表格的内容组装成真实二维数组。第一行是固定中文表头,后面的每一行才是业务数据。
写入完成后,Agent 还会检查表格首个单元格:
- 问题聚类明细表的 A1 应当是"问题主题"。
- 原声样本池的 A1 应当是"会话 ID"。
- 如果 A1 出现本地路径或文件名,说明写入失败,需要清空后重新写入真实数据。
两张表格通过检查以后,Agent 再生成用户原声洞察周报,并把两张表格的链接写入对应章节。

这一步看似只是输出形式的区别,实际上决定了项目是否真正交付。如果业务人员日常在钉钉里查看和追踪问题,Agent 就需要把可验收的结果交到钉钉,而不是给业务再增加一套下载、转换和上传流程。
6. 失败条件:宁可停止,也不生成不可验收的结果
遇到以下情况时,流程会停止并报告原因:
- 没有可用的上传文件。
- 文件无法解析。
- 会话标识或消息内容无法映射。
- 清洗后的有效会话数为零。
- 模型返回的结构无法通过校验。
- 钉钉授权、目标位置或写入工具不可用。
停止以后,Agent 只报告阻断原因和需要补充的信息,不会临时改成本地文件交付。
7. 业务如何使用这三项产物
客服可以先从周报查看高频问题和不满意集中点,再到聚类明细表确认问题分布和优先级,需要核对具体表达时,再进入原声样本池查看脱敏会话。
Agent 在这里完成的是发现、整理和定位问题,并提供后续处理线索。是否调整产品策略、运营规则、客服回复或业务流程,仍由对应团队结合实际情况判断和推进。
这个边界很重要。Agent 可以把分散在大量消息里的问题整理成可以阅读、筛选和继续追查的业务材料,但不代替业务做最终决策。
8. 可复用的 Agent 交付检查清单
这次实践最值得复用的,不是某个 Prompt,而是从原始数据到业务产物的完整交付链路。
如果你也在把客服记录、工单或用户反馈交给 Agent 分析,可以按以下顺序检查:
- 是否明确了必要字段,并在缺失时停止流程?
- 原始消息是否已经按会话标识聚合,而不是逐行分析?
- 是否只向模型提供分析必需且经过处理的字段?
- 模型输出是否使用固定结构、必填字段和枚举值?
- 程序是否会拒绝结构不合格的模型结果?
- 聚类结果是否能够回到经过脱敏的具体会话?
- 最终产物是否直接进入业务日常使用的工具?
- 写入完成后是否有可以稳定执行的验收规则?
- 输入、模型输出或业务工具异常时,是否有明确的停止条件?
总结
客服数据分析 Agent 的难点不只在模型选型和 Prompt。
它还需要解决原始数据怎样进入、多行消息怎样还原成完整会话、敏感内容怎样在模型前处理、模型输出怎样被程序校验,以及结果怎样交到业务真正使用的工具里。
花椒技术交流群
还在孤军研究 AI 工程化、AI 编程、Agent 落地 ,没人同行交流、没人拆解实战?
这里汇聚一线技术从业者,专注代码评审、企业内部 AI 助手 真实实战落地。想紧跟 AI 前沿动态、交流工程 落地经验、少走踩坑弯路,欢迎直接加入**「花椒技术交流群」**。群内专属福利拉满:每日精选 AI 行业日报 、文章独家延伸资料、文中未展开的技术细节,全部同步共享。
当这些环节都能够稳定运行和验收时,一个 Agent 才算从演示走到了交付。