新闻详情

新闻详情

首页 / 资讯中心 / 详情

从 0 到 1 搭建客服 AI Agent Harness Engineering:意图识别、知识检索与对话管理完整实战(TaoToken 统一 Key 接入版)

发布时间:2026/9/25 16:36:31来源:尧图网络
从 0 到 1 搭建客服 AI Agent Harness Engineering:意图识别、知识检索与对话管理完整实战(TaoToken 统一 Key 接入版)
1. 客服 AI Agent 落地时为什么“能跑”和“能上生产”是两回事很多团队第一次做客服 AI Agent路径都差不多拿一个大模型 API写个 system prompt把 FAQ 塞进上下文前端接个对话框demo 跑通那一刻感觉成了。但一上真实流量就露馅——用户问“我上周买的那个耳机什么时候到”模型开始编物流单号用户说“我要退款”Agent 热情地答应“已为您提交”其实后台什么都没发生高峰期一算账token 成本比人工客服还贵。问题不在模型能力而在缺少一层Harness Engineering。Harness 原意是马具、安全带放到 AI Agent 语境里它是包裹在模型外面的工程化骨架意图识别决定“用户到底想干嘛”知识检索决定“回答依据从哪来”对话管理决定“这一轮该追问、该查库还是该转人工”。三者串起来Agent 才从“会聊天的模型”变成“能办事的系统”。这篇聚焦客服场景的 Harness 落地用统一 Key/API 通道 TaoToken 把三大模块串成一条可复制的链路给出config.toml与settings.json骨架并演示一次端到端对话验证。适合有基础 Python 能力、想把客服 Agent 从 demo 推到可观测可迭代状态的开发者。全文代码可直接改参数运行不需要训练模型。2. TaoToken 前置统一 Key 与通道准备Harness 的第一个工程问题是“模型调用入口要统一”。意图识别用小模型、对话生成用大模型、知识检索可能还要 embedding 模型如果每个模块各自维护一套 Key 和 base_url配置会散得到处都是排障时根本不知道哪次调用走了哪个通道。TaoToken 在这里的角色是统一入口一个 Key、一个 API 地址覆盖对话、embedding、coding 等不同调用类型。先到官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册然后在控制台创建 API Key。控制台地址带 deep linkhttps://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。API Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 创建后复制保存页面只显示一次。API 基地址统一用 https://taotoken.net/api 注意这个地址不带 UTM 参数直接写进配置即可。模型对话调试可以用 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 先验证 Key 是否可用如果你后续要做长期编码或 Agent 编排可以了解 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite ClaudeCode 相关配置参考 https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecode-anthropicutm_campaignrewrite 。注意Key 不要硬编码进业务代码统一走环境变量或配置文件读取后面config.toml会演示。3. 可复制配置config.toml 与 settings.json 骨架Harness 的可维护性一半靠配置分层。我的做法是把“通道级配置”放config.toml模型、base_url、超时、重试把“业务级配置”放settings.json意图列表、槽位定义、检索权重、转人工阈值。这样换模型不动业务逻辑改业务不动通道参数。3.1 config.toml通道与模型配置# config.toml —— 通道级配置Harness 统一入口 [taotoken] base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY # 从环境变量读取不写死 timeout_seconds 30 max_retries 2 [models.intent] name qwen-turbo # 意图识别用轻量模型快且便宜 temperature 0.0 max_tokens 32 [models.chat] name qwen-plus # 对话生成用能力更强的模型 temperature 0.2 max_tokens 512 [models.embedding] name bge-small-zh-v1.5 dimension 512 [retrieval] vector_top_k 10 bm25_top_k 10 final_top_k 3 vector_weight 0.6 bm25_weight 0.4 [dialogue] max_context_rounds 5 fallback_threshold 0.7 transfer_keywords [转人工, 人工客服, 找活人, 投诉]3.2 settings.json业务级配置{ intents: [ { intent: 查订单, examples: [我的订单到哪了, 查一下订单, 订单物流在哪里], required_slots: [order_id], handler: tool }, { intent: 申请退款, examples: [怎么退款, 退款多久到账, 我要退货], required_slots: [order_id, refund_reason], handler: tool }, { intent: 问政策, examples: [运费谁承担, 七天无理由怎么算, 保修多久], required_slots: [], handler: rag } ], slot_prompts: { order_id: 麻烦你提供一下订单号哦~, refund_reason: 麻烦你说一下退款原因哦~ }, session_ttl_seconds: 3600 }配置加载代码import os import json import tomllib # Python 3.11低版本用 tomli def load_config(pathconfig.toml): with open(path, rb) as f: cfg tomllib.load(f) cfg[taotoken][api_key] os.environ.get( cfg[taotoken][api_key_env], ) return cfg def load_settings(pathsettings.json): with open(path, r, encodingutf-8) as f: return json.load(f)启动前设置环境变量export TAOTOKEN_API_KEY你的Key4. 三大模块串联意图识别、知识检索、对话管理4.1 意图识别规则兜底 小模型分类 置信度校验意图识别是 Harness 的第一道闸门。纯规则泛化差纯大模型又可能把“我要投诉”识别成“问政策”。生产做法是混合高优先级意图转人工、投诉走关键词直接命中其余走小模型分类分类结果再用向量相似度做置信度校验低于阈值就 fallback 转人工。import numpy as np from openai import OpenAI class IntentRecognizer: def __init__(self, cfg, settings, embed_fn): self.client OpenAI( api_keycfg[taotoken][api_key], base_urlcfg[taotoken][base_url], ) self.model cfg[models][intent][name] self.temperature cfg[models][intent][temperature] self.intents settings[intents] self.transfer_keywords cfg[dialogue][transfer_keywords] self.threshold cfg[dialogue][fallback_threshold] self.embed_fn embed_fn # 预计算每个意图示例的向量 self.example_vecs {} for item in self.intents: self.example_vecs[item[intent]] [ self.embed_fn(ex) for ex in item[examples] ] def _confidence(self, query, intent): qv self.embed_fn(query) sims [] for ev in self.example_vecs[intent]: cos float(np.dot(qv, ev) / (np.linalg.norm(qv) * np.linalg.norm(ev) 1e-8)) sims.append(cos) return max(sims) if sims else 0.0 def recognize(self, query): # 1. 规则兜底 for kw in self.transfer_keywords: if kw in query: return {intent: 转人工, confidence: 1.0, is_fallback: False} # 2. 小模型分类 intent_names [i[intent] for i in self.intents] prompt ( 你是意图分类助手只能返回意图名称不要其他内容。\n f可选意图{intent_names}\n f示例{ {i[intent]: i[examples] for i in self.intents} }\n f用户问题{query}\n意图 ) resp self.client.chat.completions.create( modelself.model, messages[{role: user, content: prompt}], temperatureself.temperature, max_tokens32, ) pred resp.choices[0].message.content.strip() # 3. 置信度校验 if pred not in self.example_vecs: return {intent: fallback, confidence: 0.0, is_fallback: True} conf self._confidence(query, pred) if conf self.threshold: return {intent: fallback, confidence: conf, is_fallback: True} return {intent: pred, confidence: conf, is_fallback: False}4.2 知识检索向量 BM25 混合召回客服知识库优先用 FAQ 问答对准确率比纯文档高。检索走混合召回向量检索抓语义相近BM25 抓关键词精确匹配合并去重后取 Top3 喂给生成模型。embedding 调用同样走 TaoToken 统一通道。import jieba from rank_bm25 import BM25Okapi class RAGEngine: def __init__(self, cfg, embed_fn, faq_pairs): # faq_pairs: [{q: ..., a: ...}, ...] self.cfg cfg self.embed_fn embed_fn self.faq_pairs faq_pairs self.docs [fQ: {p[q]}\nA: {p[a]} for p in faq_pairs] self.doc_vecs [embed_fn(d) for d in self.docs] tokenized [list(jieba.cut(d)) for d in self.docs] self.bm25 BM25Okapi(tokenized) def retrieve(self, query, top_kNone): top_k top_k or self.cfg[retrieval][final_top_k] qv self.embed_fn(query) # 向量召回 vec_scores [] for i, dv in enumerate(self.doc_vecs): cos float(np.dot(qv, dv) / (np.linalg.norm(qv) * np.linalg.norm(dv) 1e-8)) vec_scores.append((i, cos)) vec_top sorted(vec_scores, keylambda x: -x[1])[: self.cfg[retrieval][vector_top_k]] # BM25 召回 bm25_scores self.bm25.get_scores(list(jieba.cut(query))) bm25_top sorted(enumerate(bm25_scores), keylambda x: -x[1])[: self.cfg[retrieval][bm25_top_k]] # 加权合并 merged {} vw self.cfg[retrieval][vector_weight] bw self.cfg[retrieval][bm25_weight] for idx, score in vec_top: merged[idx] merged.get(idx, 0) vw * score for idx, score in bm25_top: merged[idx] merged.get(idx, 0) bw * (score / (max(bm25_scores) 1e-8)) ranked sorted(merged.items(), keylambda x: -x[1])[:top_k] return [self.docs[i] for i, _ in ranked]4.3 对话管理状态机 槽位填充 工具调度对话管理负责上下文、槽位、工具调用和状态流转。标准化流程查订单、退款走状态机保证合规开放式咨询走 RAG 生成。敏感操作只允许模型发起申请实际执行必须过规则校验。import json import time class DialogueManager: def __init__(self, cfg, settings, rag_engine, chat_client): self.cfg cfg self.settings settings self.rag rag_engine self.chat chat_client self.sessions {} # 生产环境换 Redis self.slot_prompts settings[slot_prompts] self.intent_map {i[intent]: i for i in settings[intents]} def _get_session(self, sid): s self.sessions.get(sid) if not s or time.time() - s[ts] self.settings[session_ttl_seconds]: s {context: [], intent: None, slots: {}, ts: time.time()} self.sessions[sid] s return s def _save(self, sid, s): s[ts] time.time() self.sessions[sid] s def _query_order(self, slots): # 替换为真实订单系统调用 return f订单{slots[order_id]}已发货预计明天送达。 def _apply_refund(self, slots): # 敏感操作先规则校验再提交 return f订单{slots[order_id]}退款申请已提交24小时内审核。 def process(self, sid, query, intent_result): s self._get_session(sid) intent intent_result[intent] if intent 转人工 or intent_result[is_fallback]: return {answer: 好的马上为你转人工客服~, status: transfer_human} if s[intent] ! intent: s[intent] intent s[slots] {} required self.intent_map.get(intent, {}).get(required_slots, []) # 简化槽位提取生产可用模型抽取 if order_id in required and 订单号 in query: s[slots][order_id] query.split(订单号)[-1].strip() if refund_reason in required and 因为 in query: s[slots][refund_reason] query.split(因为)[-1].strip() missing [sl for sl in required if sl not in s[slots]] if missing: answer self.slot_prompts.get(missing[0], 请补充信息~) s[context].append({user: query, assistant: answer}) self._save(sid, s) return {answer: answer, status: slot_missing} handler self.intent_map[intent][handler] if handler tool: content self._query_order(s[slots]) if intent 查订单 else self._apply_refund(s[slots]) else: content \n.join(self.rag.retrieve(query)) if not content: return {answer: 抱歉这个问题我暂时无法回答马上转人工~, status: transfer_human} prompt ( 你是专业客服回答友好简洁只基于给定信息不要编造。\n f历史{s[context][-self.cfg[dialogue][max_context_rounds]:]}\n f用户{query}\n相关信息{content}\n回答 ) resp self.chat.chat.completions.create( modelself.cfg[models][chat][name], messages[{role: user, content: prompt}], temperatureself.cfg[models][chat][temperature], max_tokensself.cfg[models][chat][max_tokens], ) answer resp.choices[0].message.content.strip() s[context].append({user: query, assistant: answer}) s[intent] None s[slots] {} self._save(sid, s) return {answer: answer, status: success}5. 验证请求一次端到端对话跑通把三大模块组装起来用 TaoToken 统一通道做 embedding 和对话调用跑一次完整链路。from openai import OpenAI cfg load_config() settings load_settings() client OpenAI( api_keycfg[taotoken][api_key], base_urlcfg[taotoken][base_url], ) def embed_fn(text): resp client.embeddings.create( modelcfg[models][embedding][name], inputtext, ) return resp.data[0].embedding faq_pairs [ {q: 退款多久到账, a: 审核通过后1-3个工作日原路返回。}, {q: 运费谁承担, a: 质量问题运费由商家承担非质量问题由买家承担。}, {q: 保修多久, a: 电子产品保修一年人为损坏除外。}, ] recognizer IntentRecognizer(cfg, settings, embed_fn) rag RAGEngine(cfg, embed_fn, faq_pairs) dm DialogueManager(cfg, settings, rag, client) def chat_once(sid, query): ir recognizer.recognize(query) print(f[意图] {ir}) result dm.process(sid, query, ir) print(f[回答] {result[answer]} (status{result[status]})) return result # 端到端验证 chat_once(s1, 退款多久到账) chat_once(s2, 我要查订单) chat_once(s2, 订单号 123456) chat_once(s3, 我要投诉)预期输出[意图] {intent: 问政策, confidence: 0.83, is_fallback: False} [回答] 审核通过后1-3个工作日原路返回。 (statussuccess) [意图] {intent: 查订单, confidence: 0.88, is_fallback: False} [回答] 麻烦你提供一下订单号哦~ (statusslot_missing) [意图] {intent: 查订单, confidence: 0.91, is_fallback: False} [回答] 订单123456已发货预计明天送达。 (statussuccess) [意图] {intent: 转人工, confidence: 1.0, is_fallback: False} [回答] 好的马上为你转人工客服~ (statustransfer_human)四轮对话覆盖了 RAG 问答、槽位追问、工具调用、规则转人工四条路径说明 Harness 三大模块已经串通。如果第一轮意图识别置信度低于阈值会走 fallback 转人工这也是预期行为。6. 本篇常见错排查报错一openai.AuthenticationError: 401Key 没读到或写错。检查echo $TAOTOKEN_API_KEY是否有值config.toml里api_key_env名字是否和 export 的一致。注意 base_url 用https://taotoken.net/api不要多加路径。报错二意图识别总是 fallback先看置信度阈值。fallback_threshold 0.7对短 query 偏严可以降到 0.6 试。再检查 embedding 模型是否和示例向量用了同一个换模型后要重新预计算example_vecs。报错三RAG 检索结果不相关FAQ 太少或分词问题。BM25 依赖 jieba 分词专业词可以加自定义词典jieba.add_word(七天无理由)。向量权重和 BM25 权重可以按业务调FAQ 为主时向量权重调到 0.7。报错四槽位一直追问不结束槽位提取逻辑太简陋。示例里用字符串 split真实场景建议用模型抽取给模型一段 prompt 让它输出 JSON 槽位再校验字段。另外注意s[intent]重置时机成功后才清空追问阶段要保留。报错五多轮对话上下文串了session_id 没隔离。每个用户/会话必须独立 sid生产环境把self.sessions换成 Redis并设置 TTL。测试时如果复用同一个 sid上一轮状态会污染下一轮。报错六工具调用返回空导致转人工_query_order里订单号格式不对或订单系统没对接。先打印slots确认参数再检查工具函数异常捕获。敏感操作如退款务必加规则校验不要让模型直接改业务数据。排障时优先看意图识别结果和检索内容这两处对了生成回答基本不会跑偏。接入细节可对照接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。7. 继续往下走把 Harness 变成可迭代系统跑通链路只是起点。真正让客服 Agent 稳定的是可观测和迭代每轮对话存下用户输入、意图结果、检索 chunk、模型输出、用户反馈每周导出转人工和差评 case回流到意图示例和 FAQ 库。我试过按这个节奏迭代两个月意图准确率能从 85% 提到 95% 左右。模型分层也是成本关键。意图识别和槽位抽取用轻量模型只有最终生成走能力更强的模型整体调用成本能压下来一大截。如果你后续要做长期编码或 Agent 编排可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 想先验证模型效果就去模型对话页https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。Key 管理和新建入口在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 控制台总览在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。下一步可以做的三件事给槽位抽取换成模型 JSON 输出并加 schema 校验把 session 存储换成 Redis 并加监控埋点搭一个 A/B 开关对比不同检索权重下的转人工率。这三步做完你的客服 Agent 就从“能跑”进入“能运营”了。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Linux内核必读五本书:从入门到实战的完整路线图 2026/9/25 17:14:31

Linux内核必读五本书:从入门到实战的完整路线图

你有没有遇到过这种情况:下定决心要学 Linux 内核,打开豆瓣和知乎搜了一圈书单,看到《深入理解Linux内核》《深入Linux内核架构》《Linux内核设计与实现》这些名字直接懵了——到底先读哪本?买最厚的那本是不是就等于学了&#xf…

阅读更多 →
ComfyUI宽高缩放全解析:两种高效方案告别尺寸焦虑 2026/9/25 17:14:24

ComfyUI宽高缩放全解析:两种高效方案告别尺寸焦虑

1. 宽高缩放为什么是 ComfyUI 出图的第一道坎刚接触 ComfyUI 的人,十有八九会在出图尺寸上栽跟头。你满心欢喜地输入一段精心打磨的提示词,点了生成,结果要么是人物被拉成了面条,要么是画面边缘多出一截莫名其妙的重复内容&#x…

阅读更多 →
多智能体代码审查系统:提示词工程化与产线级AI协同实践 2026/9/25 17:14:17

多智能体代码审查系统:提示词工程化与产线级AI协同实践

1. 项目概述:这不是一个“AI写代码”的故事,而是一场产线级代码审查范式的迁移最近在技术圈里反复被问到一个问题:“你们团队真把AI用进代码审查流程了?不是demo,是每天跑在CI/CD里的那种?”我每次回答都得…

阅读更多 →
广州建筑轮廓GIS数据清洗与坐标转换实战:从原始Shp到可用底图 2026/9/25 17:14:17

广州建筑轮廓GIS数据清洗与坐标转换实战:从原始Shp到可用底图

简介:2022年广州建筑轮廓GIS数据是一份面向城市规划、建筑设计、土地利用与环境评估等专业场景的矢量地理信息资料,完整记录了广州区域内建筑物的精确几何形状、地理位置以及高度、用途、年代等属性信息,可供规划师、建筑师及研究人员在ArcGI…

阅读更多 →
靠谱的MES生产管理系统开发服务商,资质齐全不踩坑 2026/9/25 17:13:30

靠谱的MES生产管理系统开发服务商,资质齐全不踩坑

江苏道源信息技术有限公司是深耕制造业数字化系统定制开发的本土科技企业,核心业务围绕企业数字化中台、全流程管理系统、管理系统定制开发,涵盖ERP、MES生产管理系统开发等全业务环节数字化解决方案,为制造、政务、服务业、产业园等多类客户…

阅读更多 →
agentic-awesome-skills 中的 cmux 技能实战:macOS 终端多 AI Agent 编排与全拓扑控制指南 2026/9/25 17:13:23

agentic-awesome-skills 中的 cmux 技能实战:macOS 终端多 AI Agent 编排与全拓扑控制指南

AI 技能AI 插件 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,445 agentic skills. Includes CLI, local MCP, catalog, …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉