Files
qiweimanager-master/plan.md

25 KiB
Raw Blame History

企业微信自动客服改造方案

1. 目标概述

当前项目已经具备企业微信消息管理能力,后端 helper.exe 通过 DLL 注入、Socket 回调、本地 HTTP 服务和 requestdata / eventdata 模板,能够接收企业微信事件并发送企业微信消息。

本次需求是在现有能力上增加“自动客服”模块:

  • 前端提供一键开启入口。
  • 后端自动监听企业微信消息。
  • 私聊客户消息自动处理。
  • 群聊消息仅在用户 @ 当前机器人时处理。
  • 根据本地知识库检索内容。
  • 调用 AI 根据知识库内容生成回复。
  • 能回答则自动回复客户。
  • 不能回答、AI 失败或知识库低匹配时,自动私信指定同事转人工处理。

2. 当前项目基础

2.1 技术结构

项目当前是:

  • 桌面端Wails
  • 后端主程序Goqiweimanager.exe
  • 辅助进程Gohelper.exe
  • 前端Vue 3 + Vite + Element Plus
  • 本地 HTTP 服务:默认 http://localhost:10001
  • 企业微信底层通信:Helper_4.1.33.6009.dllLoader_4.1.33.6009.dll
  • 发送消息模板:requestdata/*.json
  • 接收事件模板:eventdata/*.json

2.2 已有关键能力

现有项目已经支持:

  • 启动/注入企业微信:type=10000
  • 发送文本消息:requestdata/sendVWorkTextMessage.json
  • 群 @ 消息:requestdata/sendVWorkGroupAtMessage.json
  • 获取群列表:requestdata/getVWorkGroupList.json
  • 获取内部好友列表:requestdata/getVWorkInternalFriendList.json
  • 获取外部联系人列表:requestdata/getVWorkExternalFriendList.json
  • 接收企业微信消息回调:helper.go 中的 MyRecvCallback
  • 事件转换:TransformData 使用 eventdata/<type>.json
  • 本地 HTTP 管理页面:http://localhost:10001/
  • 操作日志和前端配置管理

2.3 最适合接入的位置

自动客服的核心入口建议放在:

helper/helper.go
MyRecvCallback(...)

原因:

  • 这里能拿到所有企业微信入站事件。
  • 当前已经在这里做了消息解析、时间过滤、ResponseChannel 判断、回调转发。
  • 自动客服需要的是“被动监听消息”,不是主动请求响应,所以这里最自然。
  • 可保持现有 /api/send-wxwork-data/api/third-party-request 和 callback 功能不被破坏。

3. 总体架构设计

3.1 新增模块

建议新增以下模块:

config/
  types.go                       # 增加 AutoReplyConfig 配置结构

helper/
  auto_reply.go                  # 自动客服主流程
  auto_reply_ai.go               # AI 调用适配
  auto_reply_knowledge.go        # 本地知识库解析、索引、检索
  auto_reply_handoff.go          # 转人工通知
  auto_reply_status.go           # 状态统计、运行记录
  auto_reply_http.go             # helper 侧自动客服 HTTP 接口

frontend/src/
  components/AutoReply.vue       # 自动客服配置和状态页面

如果希望少建文件,也可以把 helper 侧先合并为 2 到 3 个文件,但不建议全部塞进 helper.go,否则后续维护会变得很吃力。

3.2 消息处理链路

整体链路如下:

企业微信收到消息
  ↓
DLL Socket 回调
  ↓
helper.go / MyRecvCallback
  ↓
解析原始 JSON
  ↓
判断是否是主动请求响应
  ↓
如果是响应:继续走现有 ResponseChannel
  ↓
如果是独立入站消息:进入自动客服判断
  ↓
转换 eventdata 结构
  ↓
判断是否需要处理
  ↓
知识库检索
  ↓
AI 生成回复
  ↓
发送企业微信文本消息
  ↓
失败或无法回答时私信指定同事

3.3 不破坏现有功能的原则

自动客服必须做到:

  • 不影响当前前端“启动企微”。
  • 不影响现有 requestdata 模板调用。
  • 不影响第三方 callback。
  • 不影响本地 dashboard。
  • 不影响主动请求等待回调的逻辑。
  • 自动客服出错不能导致 helper.exe 崩溃。
  • 自动客服处理必须异步,不阻塞 MyRecvCallback

4. 配置设计

4.1 在 config 中新增 autoReplyConfig

建议在 config/types.go 中新增:

type AutoReplyConfig struct {
    Enabled bool `json:"enabled"`

    Listen ListenConfig `json:"listen"`
    Knowledge KnowledgeConfig `json:"knowledge"`
    AI AIConfig `json:"ai"`
    Handoff HandoffConfig `json:"handoff"`
    ReplyPolicy ReplyPolicyConfig `json:"replyPolicy"`
}

type ListenConfig struct {
    EnablePrivateChat bool `json:"enablePrivateChat"`
    EnableGroupChat bool `json:"enableGroupChat"`
    GroupTriggerMode string `json:"groupTriggerMode"`
    IgnoreSelfMessage bool `json:"ignoreSelfMessage"`
    DeduplicateSeconds int `json:"deduplicateSeconds"`
}

type KnowledgeConfig struct {
    Directory string `json:"directory"`
    IndexPath string `json:"indexPath"`
    SupportedExtensions []string `json:"supportedExtensions"`
    TopK int `json:"topK"`
    MinScore float64 `json:"minScore"`
    AutoRebuildOnStart bool `json:"autoRebuildOnStart"`
}

type AIConfig struct {
    Provider string `json:"provider"`
    BaseURL string `json:"baseUrl"`
    APIKey string `json:"apiKey"`
    Model string `json:"model"`
    TimeoutSeconds int `json:"timeoutSeconds"`
    Temperature float64 `json:"temperature"`
    MaxTokens int `json:"maxTokens"`
}

type HandoffConfig struct {
    HumanUserID string `json:"humanUserId"`
    HumanConversationID string `json:"humanConversationId"`
    MessageTemplate string `json:"messageTemplate"`
    IncludeKnowledgeHits bool `json:"includeKnowledgeHits"`
}

type ReplyPolicyConfig struct {
    UnknownAnswerToken string `json:"unknownAnswerToken"`
    MaxQuestionLength int `json:"maxQuestionLength"`
    CooldownSeconds int `json:"cooldownSeconds"`
}

并把它挂到现有配置:

type Config struct {
    CallbackConfig CallbackConfig `json:"callbackConfig"`
    AutoReplyConfig AutoReplyConfig `json:"autoReplyConfig"`
    LastUpdated int64 `json:"lastUpdated"`
}

4.2 默认配置

默认值建议:

{
  "autoReplyConfig": {
    "enabled": false,
    "listen": {
      "enablePrivateChat": true,
      "enableGroupChat": true,
      "groupTriggerMode": "mention_only",
      "ignoreSelfMessage": true,
      "deduplicateSeconds": 300
    },
    "knowledge": {
      "directory": "config/knowledge",
      "indexPath": "config/knowledge/index.json",
      "supportedExtensions": [".md", ".txt", ".csv", ".xlsx", ".docx", ".pdf"],
      "topK": 5,
      "minScore": 0.35,
      "autoRebuildOnStart": false
    },
    "ai": {
      "provider": "openai_compatible",
      "baseUrl": "",
      "apiKey": "",
      "model": "",
      "timeoutSeconds": 25,
      "temperature": 0.2,
      "maxTokens": 800
    },
    "handoff": {
      "humanUserId": "",
      "humanConversationId": "",
      "messageTemplate": "客户问题需要人工处理:\n客户{{customerName}}\n问题{{question}}\n来源{{source}}\n会话{{conversationId}}\n原因{{reason}}",
      "includeKnowledgeHits": true
    },
    "replyPolicy": {
      "unknownAnswerToken": "NO_ANSWER",
      "maxQuestionLength": 1000,
      "cooldownSeconds": 3
    }
  }
}

5. 前端改造方案

5.1 新增菜单

frontend/src/App.vue 左侧菜单新增:

自动客服

建议位置:

系统首页
企微账号
自动客服
操作记录
回调配置

5.2 新增 AutoReply.vue 页面

页面模块建议分为 6 块:

  1. 运行状态
  2. 一键开启/关闭
  3. AI 配置
  4. 知识库配置
  5. 人工接管配置
  6. 最近处理记录

5.3 运行状态区

显示:

  • 自动客服状态:未开启 / 运行中 / 错误
  • helper 连接状态
  • 当前活跃企微账号数
  • 知识库文件数
  • 知识库切片数
  • 今日处理消息数
  • 今日自动回复数
  • 今日转人工数
  • 今日 AI 失败数
  • 今日忽略消息数

5.4 一键开启按钮

按钮行为:

点击“一键开启自动客服”
  ↓
保存当前自动客服配置
  ↓
调用启动企微 type=10000
  ↓
通知 helper reload 配置
  ↓
如果知识库索引不存在,提示并重建索引
  ↓
自动客服状态变为运行中

对应 Wails 方法:

SetAutoReplyEnabled(true)

5.5 AI 配置区

字段:

  • AI 类型:
    • OpenAI 兼容接口
    • 本地模型接口
  • Base URL
  • API Key
  • Model
  • Timeout
  • Temperature
  • Max Tokens
  • 测试连接按钮

OpenAI 兼容接口示例:

https://api.openai.com/v1
https://api.deepseek.com/v1
http://localhost:1234/v1

本地模型接口示例:

http://localhost:11434

5.6 知识库配置区

字段:

  • 本地知识库目录
  • 支持格式展示md、txt、csv、xlsx、docx、pdf
  • TopK
  • 最低匹配分数
  • 重建知识库索引按钮
  • 上次索引时间
  • 索引结果

5.7 人工接管配置区

字段:

  • 指定同事 user_id
  • 指定同事 conversation_id
  • 转人工消息模板
  • 是否附带知识库命中片段
  • 测试发送按钮

说明:

  • 最稳妥方式是配置 humanConversationId
  • 如果只配置 humanUserId,后端按 S:<robotId>_<humanUserId> 推导 conversationId。
  • 页面必须提供“测试发送”,确认能私信到指定同事。

6. Wails 后端接口方案

app.go 中新增方法:

func (a *App) GetAutoReplyConfig() interface{}
func (a *App) SaveAutoReplyConfig(jsonData string) (bool, string)
func (a *App) SetAutoReplyEnabled(enabled bool) (bool, string)
func (a *App) GetAutoReplyStatus() interface{}
func (a *App) RebuildKnowledgeIndex() interface{}
func (a *App) TestAIConnection() interface{}
func (a *App) TestHumanHandoff() interface{}

这些方法主要负责:

  • 读写 config/config.json
  • 转发请求到 helper.exe
  • 返回统一格式给前端

统一返回格式建议:

{
  "success": true,
  "message": "ok",
  "data": {}
}

失败时:

{
  "success": false,
  "message": "错误原因",
  "data": null
}

7. helper HTTP 接口方案

在 helper 本地 HTTP 服务中新增:

GET  /api/auto-reply/status
POST /api/auto-reply/reload
POST /api/auto-reply/rebuild-knowledge
POST /api/auto-reply/test-ai
POST /api/auto-reply/test-handoff

7.1 GET /api/auto-reply/status

返回:

{
  "success": true,
  "data": {
    "enabled": true,
    "running": true,
    "lastError": "",
    "knowledgeFileCount": 10,
    "knowledgeChunkCount": 320,
    "todayReceived": 100,
    "todayReplied": 60,
    "todayHandoff": 12,
    "todayIgnored": 28,
    "lastMessages": []
  }
}

7.2 POST /api/auto-reply/reload

用途:

  • 重新加载 config/config.json
  • 重新初始化自动客服配置
  • 不重启 helper

7.3 POST /api/auto-reply/rebuild-knowledge

用途:

  • 扫描本地知识库目录
  • 解析文档
  • 构建索引
  • 写入 config/knowledge/index.json

7.4 POST /api/auto-reply/test-ai

用途:

  • 使用当前 AI 配置发起一次测试请求
  • 不进入企业微信消息流程

7.5 POST /api/auto-reply/test-handoff

用途:

  • 给指定同事发送一条测试私信
  • 验证 humanConversationIdhumanUserId 是否正确

8. 自动客服消息判断规则

8.1 只处理文本消息

当前文本消息模板主要是:

eventdata/11041.json
event = 20002

自动客服初版只处理:

{
  "event": "20002",
  "data": {
    "message": "...",
    "conversationId": "...",
    "fromWxId": "...",
    "toWxId": "...",
    "fromNickName": "...",
    "atWxIdList": []
  }
}

非文本消息处理策略:

  • 图片:转人工
  • 文件:转人工
  • 语音:转人工
  • 视频:转人工
  • 位置:转人工
  • 链接:转人工
  • 名片:转人工

8.2 私聊处理规则

私聊消息满足:

  • 不是群聊 conversationId
  • 不是机器人自己发出的消息
  • 文本内容不为空
  • 没有重复处理过

则自动处理。

8.3 群聊处理规则

群聊消息必须满足:

  • 是群聊 conversationId
  • 文本消息
  • 不是机器人自己发出的消息
  • atWxIdList 包含当前机器人 ID或文本内容包含 @ 当前机器人昵称
  • 未重复处理

未 @ 机器人时:

  • 不回复
  • 计入 ignored
  • dashboard 可记录原因:group message without mention

8.4 自己消息过滤

如果满足以下任一条件,忽略:

  • fromWxId == robotId
  • fromWxId == 当前登录企微 user_id
  • 原始消息标记为自己发送
  • sender == receiver 且能确认是本机消息

8.5 去重策略

使用以下字段生成去重 key

robotId + conversationId + serverId

如果没有 serverId

robotId + conversationId + localId + sendTime + fromWxId

默认 300 秒内重复消息不处理。

9. 知识库方案

9.1 本地目录

默认目录:

config/knowledge/

建议结构:

config/knowledge/
  faq.md
  product.md
  price.xlsx
  after-sales.docx
  policy.pdf
  index.json

9.2 支持格式

用户选择“全都支持”,因此初版支持:

  • .md
  • .txt
  • .csv
  • .xlsx
  • .docx
  • .pdf

9.3 解析策略

不同文件策略:

  • Markdown/TXT按标题和段落切分。
  • CSV按行切分每行拼接字段名和值。
  • Excel按 sheet + 行切分。
  • DOCX提取段落文本后切分。
  • PDF提取页面文本后切分。

每个 chunk 建议结构:

{
  "id": "hash",
  "source": "faq.md",
  "title": "售后政策",
  "content": "具体内容",
  "line": 12,
  "page": 0,
  "updatedAt": 1710000000,
  "hash": "..."
}

9.4 检索策略

初版不引入向量库,使用本地关键词 / BM25 风格检索:

  • 中文分词可先用 rune bigram + keyword 简化实现。
  • 英文按空格和标点切词。
  • 计算 query 和 chunk 的相关度。
  • 返回 topK。
  • 最高分低于 minScore 时认为知识库无法回答。

默认:

topK = 5
minScore = 0.35

9.5 后续增强方向

后续可以升级为:

  • 本地 embedding
  • OpenAI embedding
  • SQLite FTS5
  • 向量数据库
  • 混合检索

但初版不建议一开始引入复杂依赖,先把闭环跑通。

10. AI 调用方案

10.1 OpenAI 兼容接口

请求:

POST {baseUrl}/chat/completions
Authorization: Bearer {apiKey}

如果用户填写的 baseUrl 是:

https://api.openai.com/v1

则最终请求:

https://api.openai.com/v1/chat/completions

请求体:

{
  "model": "gpt-4.1-mini",
  "temperature": 0.2,
  "max_tokens": 800,
  "messages": [
    {
      "role": "system",
      "content": "你是企业微信客服助手,只能基于知识库回答。知识库没有答案时输出 NO_ANSWER。"
    },
    {
      "role": "user",
      "content": "客户问题 + 知识库片段"
    }
  ]
}

10.2 本地模型接口

默认适配 Ollama

POST {baseUrl}/api/chat

请求体:

{
  "model": "qwen2.5",
  "stream": false,
  "messages": [
    {
      "role": "system",
      "content": "你是企业微信客服助手,只能基于知识库回答。知识库没有答案时输出 NO_ANSWER。"
    },
    {
      "role": "user",
      "content": "客户问题 + 知识库片段"
    }
  ]
}

如果本地模型提供 OpenAI-compatible 接口,则用户直接选择 OpenAI 兼容模式即可。

10.3 Prompt 约束

系统提示词建议:

你是企业微信客服助手。
你只能根据提供的知识库片段回答客户问题。
如果知识库片段不能支持答案,必须只输出 NO_ANSWER。
不要编造政策、价格、承诺、库存、物流时效。
回答要简洁、礼貌、像真人客服。
如果客户要求人工、投诉、退款、合同、发票、价格特殊审批,也输出 NO_ANSWER。

用户消息格式:

客户昵称:{{fromNickName}}
客户问题:{{question}}

知识库片段:
[1] {{chunk1}}
[2] {{chunk2}}
[3] {{chunk3}}

请基于知识库回答。

10.4 AI 无法回答判定

以下情况触发转人工:

  • 知识库最高分低于阈值。
  • AI 返回 NO_ANSWER
  • AI 返回空字符串。
  • AI HTTP 调用失败。
  • AI 超时。
  • AI 返回结构无法解析。
  • 消息是非文本。
  • 客户明确要求人工客服。
  • 客户问题超过最大长度。
  • 命中敏感业务关键词,例如退款、投诉、合同、发票、赔偿等。

11. 自动回复发送方案

11.1 私聊回复

使用已有模板:

requestdata/sendVWorkTextMessage.json

转换后的底层 type

{
  "type": 11029,
  "data": {
    "conversation_id": "{{conversationId}}",
    "content": "{{answer}}"
  }
}

调用方式:

sendTextToConversation(clientId, conversationId, answer)

11.2 群聊回复

群聊 @ 机器人后,默认回复到原群:

conversationId = 原消息 conversationId

可选策略:

  • 默认不 @ 提问人,只回复文本。
  • 后续可以增加 replyWithAtSender 开关,使用 sendVWorkGroupAtMessage

初版建议默认不 @,避免 atList 字段兼容问题带来发送失败。

12. 转人工私信方案

12.1 私信对象配置

用户要求:

直接发私信给指定同事的企业微信

因此配置:

{
  "humanUserId": "指定同事user_id",
  "humanConversationId": "指定同事私聊conversation_id"
}

优先级:

  1. 如果配置了 humanConversationId,直接使用。
  2. 如果没有配置,则使用 S:<robotId>_<humanUserId> 推导。
  3. 如果推导失败或发送失败,记录错误并在前端状态展示。

12.2 转人工消息内容

默认模板:

客户问题需要人工处理

客户:{{customerName}}
客户ID{{fromWxId}}
来源:{{source}}
会话ID{{conversationId}}
问题:{{question}}
原因:{{reason}}
时间:{{time}}

请及时处理。

如果开启 includeKnowledgeHits,追加:

知识库候选:
1. {{source}} / score={{score}}
2. {{source}} / score={{score}}

12.3 转人工触发原因枚举

建议原因:

knowledge_low_score
ai_no_answer
ai_timeout
ai_http_error
ai_parse_error
non_text_message
manual_keyword
send_reply_failed
config_missing

前端展示时转成中文。

13. 状态统计和运行记录

新增内存状态对象:

type AutoReplyStatus struct {
    Enabled bool
    Running bool
    LastError string

    KnowledgeFileCount int
    KnowledgeChunkCount int
    KnowledgeLastIndexedAt int64

    TodayReceived int
    TodayReplied int
    TodayHandoff int
    TodayIgnored int
    TodayAIFailed int

    LastMessages []AutoReplyRecord
}

运行记录:

type AutoReplyRecord struct {
    ID int64
    Time string
    RobotID string
    ConversationID string
    Source string
    FromWxID string
    FromNickName string
    Question string
    Action string
    Reason string
    Answer string
}

Action 可选:

ignored
replied
handoff
failed

14. 错误处理策略

14.1 自动客服不能影响主流程

自动客服所有处理都必须:

  • recover panic
  • 写日志
  • 更新状态
  • 不向外抛出导致 MyRecvCallback 异常

14.2 AI 超时

默认:

25 秒

超时后:

  • 不继续等待。
  • 转人工。
  • 状态计入 TodayAIFailedTodayHandoff

14.3 发送失败

自动回复发送失败时:

  • 记录失败。
  • 转人工通知。
  • 如果转人工也失败,写入 LastError

14.4 知识库索引失败

单个文件失败:

  • 不影响其他文件。
  • 在前端显示失败文件。
  • 写入日志。

全部失败:

  • 自动客服仍可开启。
  • 所有问题都会因为知识库低分而转人工。

15. 实施步骤

阶段一:配置和接口骨架

  1. 扩展 config/types.go,加入自动客服配置结构。
  2. 修改默认配置生成逻辑。
  3. app.go 增加 Wails 方法:
    • GetAutoReplyConfig
    • SaveAutoReplyConfig
    • SetAutoReplyEnabled
    • GetAutoReplyStatus
  4. 在 helper HTTP server 增加自动客服路由。
  5. 确认现有编译不受影响。

阶段二:前端自动客服页面

  1. 新增 frontend/src/components/AutoReply.vue
  2. 修改 App.vue 侧边栏,增加“自动客服”菜单。
  3. 实现配置读取、保存、开关、状态刷新。
  4. 实现测试 AI、测试人工私信、重建知识库按钮。
  5. 保持当前 UI 风格,不做大规模视觉重构。

阶段三:知识库模块

  1. 创建 helper/auto_reply_knowledge.go
  2. 实现本地目录扫描。
  3. 实现 .md/.txt/.csv 解析。
  4. 实现 .xlsx/.docx/.pdf 解析。
  5. 实现 chunk 切分。
  6. 实现索引保存和加载。
  7. 实现关键词/BM25 风格检索。
  8. 将统计信息暴露给状态接口。

阶段四AI 模块

  1. 创建 helper/auto_reply_ai.go
  2. 实现 OpenAI-compatible 调用。
  3. 实现 Ollama 本地模型调用。
  4. 实现 prompt 构造。
  5. 实现 NO_ANSWER 判断。
  6. 实现 AI 测试接口。

阶段五:消息监听和自动回复

  1. 创建 helper/auto_reply.go
  2. MyRecvCallback 中接入自动客服入口。
  3. 确保 ResponseChannel 响应不触发自动客服。
  4. 实现文本消息过滤。
  5. 实现私聊自动处理。
  6. 实现群聊 @ 机器人处理。
  7. 实现去重。
  8. 实现调用知识库 + AI + 发送回复。

阶段六:转人工私信

  1. 创建 helper/auto_reply_handoff.go
  2. 实现转人工消息模板渲染。
  3. 实现指定同事私信发送。
  4. 实现测试发送。
  5. 自动回复失败时触发转人工。

阶段七:测试和验证

  1. 增加 Go 单元测试。
  2. 增加 mock AI server 测试。
  3. 前端执行 npm run build
  4. Go 执行 go test ./...
  5. 构建 helper。
  6. 构建 Wails。
  7. 实机验证私聊、群聊 @、群聊未 @、转人工。

16. 测试用例

16.1 私聊文本自动回复

输入:

{
  "event": "20002",
  "data": {
    "conversationId": "S:customer_robot",
    "fromWxId": "customer",
    "toWxId": "robot",
    "message": "你们营业时间是几点?"
  }
}

预期:

  • 检索知识库。
  • 调用 AI。
  • 发送回复到原 conversationId。
  • 状态 TodayReplied +1

16.2 群聊未 @ 不回复

输入:

{
  "event": "20002",
  "data": {
    "conversationId": "R:group",
    "fromWxId": "customer",
    "message": "你们营业时间是几点?",
    "atWxIdList": []
  }
}

预期:

  • 不调用 AI。
  • 不发送消息。
  • 状态 TodayIgnored +1

16.3 群聊 @ 机器人自动回复

输入:

{
  "event": "20002",
  "data": {
    "conversationId": "R:group",
    "fromWxId": "customer",
    "message": "@机器人 你们营业时间是几点?",
    "atWxIdList": ["robot"]
  }
}

预期:

  • 调用知识库。
  • 调用 AI。
  • 回复到原群。

16.4 知识库无答案转人工

输入:

你们能不能帮我办理完全无关的问题?

预期:

  • 检索低分。
  • 不调用或不采纳 AI。
  • 私信指定同事。
  • 状态 TodayHandoff +1

16.5 AI 返回 NO_ANSWER 转人工

AI 输出:

NO_ANSWER

预期:

  • 不回复客户。
  • 私信指定同事。
  • 状态 TodayAIFailed +1TodayHandoff +1

16.6 AI 超时转人工

预期:

  • 超过 timeout 后触发转人工。
  • 不阻塞后续消息处理。

16.7 重复消息不重复回复

同一个 serverId 连续进入两次。

预期:

  • 第一次处理。
  • 第二次忽略。

17. 验收标准

完成后应满足:

  • 前端有“自动客服”页面。
  • 能一键开启/关闭自动客服。
  • 能配置 AI 接口。
  • 能配置本地知识库目录。
  • 能重建知识库索引。
  • 能测试 AI 连接。
  • 能配置指定人工同事并测试私信。
  • 私聊客户文本消息能自动回复。
  • 群聊只有 @ 机器人时才自动回复。
  • 未 @ 的群消息不会回复。
  • AI 无法回答时能私信指定同事。
  • 自动客服处理失败不影响现有企业微信管理能力。
  • 原有 http://localhost:10001/ dashboard 和 requestdata 接口保持可用。

18. 风险点和注意事项

18.1 conversationId 推导风险

私信指定同事最好配置明确的 humanConversationId

如果只配置 humanUserId,按 S:<robotId>_<humanUserId> 推导可能因企业微信内部规则不同而失败,因此必须提供“测试发送”。

18.2 群聊 @ 判断风险

有些事件可能 atWxIdList 不完整,因此群聊触发判断应同时支持:

  • atWxIdList 包含机器人 ID
  • 文本内容包含 @机器人昵称

18.3 AI 胡答风险

必须强制 AI 只基于知识库回答。

如果知识库没有答案AI 必须输出 NO_ANSWER

18.4 文件解析依赖风险

.xlsx/.docx/.pdf 支持会引入新依赖或额外解析逻辑。

如果希望第一版更稳,可以先实现 .md/.txt/.csv,但本需求要求“全都支持”,因此计划里按全格式支持实现。

18.5 不阻塞 DLL 回调

AI 调用和知识库检索都不能直接阻塞 MyRecvCallback

应通过 goroutine + 队列处理。

19. 建议的默认上线策略

第一版建议:

  • 先只开启私聊自动回复。
  • 群聊只开 @ 机器人触发。
  • 最低知识库分数先设置偏高,例如 0.4
  • AI 无答案严格转人工。
  • 所有转人工消息都附带原始 conversationId 和客户 ID。
  • 开启详细日志,方便回放和排查。

20. 后续增强方向

后续可以继续增加:

  • 多机器人分别配置知识库。
  • 不同群使用不同知识库。
  • 客户画像和历史上下文。
  • 工单系统对接。
  • 向量检索。
  • 对话记忆。
  • 人工接管后暂停自动回复。
  • 黑名单/白名单群配置。
  • 敏感词和合规审核。
  • 前端消息实时流展示。