跳转至

企微 v2 助手 Agent:消息 → 接地回复 / 问答

把企微机器人从 v1 的 dummy 恒回 "1" 升级为 v2 真 agent:群里收到消息 → 跑治理+知识管线 → 要么确认/澄清待办,要么基于团队知识接地回答提问 → 合成 一句简洁、低摩擦的回复。本页讲它由哪几块组成、为什么不会乱编、怎么在 live 上线插上。

一句话

run_wecom_agent_turn(message) = 治理+知识管线(准入 → Connector Callback Ledger → Evidence → schedule/todo + 知识卡) 按结果路由:

  • 抽出了 ready 待办compose_reply 确认(Claude 把确定性事实措辞成一句)。
  • 否则(提问 / 歧义 / 闲聊)→ 试 严格 RAG compose_answer(只基于检索证据作答、 附 cited_paths,无据则婉拒);婉拒后回退 compose_reply(问澄清或低摩擦静默)。

返回 AgentTurn(run, reply, cited_paths)。channel 拿 reply 发回群即可。

组成(都在 main、synthetic 单测、opt-in)

模块 作用
framework/llm/reply_composer.py 回复脑:给定消息 + 管线确定性结果,Claude 合成低摩擦待办回复(compose_reply
framework/llm/answer_composer.py 问答脑:严格 RAG,只基于检索证据回答、附引用、无据婉拒(compose_answer
framework/workflows/wecom_message_pipeline.py 入站管线 opt-in extractor 钩子,可把关键词抽取换成 framework/llm/work_item_extractor.py 的 Claude 抽取
framework/workflows/wecom_agent.py 端到端接缝 run_wecom_agent_turn(event) -> AgentTurn(run, reply, cited_paths),按 ready 待办与否在回复脑 / 问答脑之间路由

为什么不会乱编(反幻觉姿态)

work_item_extractor 一致:事实由确定性代码给,Claude 只做措辞。

  • 交给模型的「系统已确定的处理结果」不含原始 userid、不含真实身份猜测—— 负责人识别是确定性代码按花名册做的,模型无法把模糊指代编成具体某个人。
  • prompt 明令:只复述系统结果,绝不编造负责人/时间/内容;需要澄清就直接问。
  • 闲聊/无可处理内容 → 模型 should_reply=false静默不打扰
  • LLM 调用失败 → 降级为空回复(不崩、不发未接地内容)。
  • 被准入层拒绝的消息 → 直接静默,根本不为它合成回复
  • 问答侧同样严格接地:只用检索到的片段回答、cited_paths 与传入片段取交集(编造引用漏不出去)、无检索结果根本不调 LLM、片段不足则婉拒并改走 Ask Router。

真 Claude 实测(Haiku,验证 prompt 设计)

原消息 Bot 回复
请 @发哥 今天18点前整理企微接口文档并发我 已给发哥登记这个任务,今天18点前整理企微接口文档。
让小李整理一下("小李"有多位) 小李有好几位,能说一下是哪个小李吗?
今天天气不错,大家午饭吃了吗 (静默,不打扰群)
记一下:下周要把回归测试补一下 补回归测试这个任务,谁负责?什么时候完成?

低摩擦、口语、该问就问、该静默就静默——符合「降低沟通摩擦」目标。

问答侧(严格 RAG,端到端真 Claude 实测):

原消息 Bot 回复
请问企微回调地址和端口是多少? 企微回调地址是 https://bf.comtom.cn/wecom/callback ,本地回调服务监听 18099 端口。(附依据来源 path)
公司今年的年终奖怎么发?(知识库无此资料) (婉拒,改去问负责人,不乱编)

接地、带引用、无据不编——符合产品「接地上下文」命题。

live 上线怎么插(配置而非改码)

整套全 opt-in / 注入,所以 live cutover 是配置:

  1. channel(Bot WS / 自建应用回调)收到消息 → 归一为 WeComMessageEvent
  2. run_wecom_agent_turn(event, admission_policy=…, dedup_registry=…, now=…, extractor=<Claude 抽取器>, reply_client=<Claude client>, answer_client=<Claude client>, search=<知识检索后端>, card_output_dir=<可选 /tmp>)
  3. 把返回的 turn.reply(非空时)发回群;turn.run 里是已落盘的可审阅知识卡等。

真凭证(Bot 通道凭证、Claude ~/.claude/.credentials.jsonANTHROPIC_API_KEY) 只在运行时读,不入库;framework/llm/claude_client.py 已封装鉴权。

相关