---
slug: "wecom-voice-agent"
source_type: "clawhub"
source_url: "https://clawhub.ai/skills/wecom-voice-agent"
repo: ""
source_file: "description"
---
---
name: wecom-voice-agent
version: 2.2.0
description: >
---


# 企业微信语音消息 Agent

## ⚠️ 风险声明（必读）

### 能力边界

1. **本技能支持企业微信智能机器人场景**，包括被动语音消息处理和主动语音通话
2. **语音转文字由企业微信官方提供**，本技能不自行采集或上传用户语音至任何第三方
3. **不会读取或收集**用户的通讯录、聊天记录或其他个人隐私数据
4. **所有数据处理均在本地内存中完成**，不持久化存储用户语音内容
5. **主动外呼需管理员授权**，且仅在用户明确同意录音后进行

### 安全风险项

| 风险等级 | 风险描述 | 预防措施 |
|---------|---------|---------|
| 🔴 高 | 语音转写准确率受环境噪音影响 | 当置信度低时主动询问用户确认 |
| 🔴 高 | 误触发（电视/背景音乐被误认为语音） | 设置消息有效时长阈值，超过30秒无新消息则重置上下文 |
| 🔴 高 | 外呼过程中的隐私泄露风险 | 全程录音告知、用户同意后才录音 |
| 🟡 中 | 企业微信 API 频率限制（每分钟20次） | 实现请求队列和速率限制器 |
| 🟡 中 | 长上下文导致 Token 消耗过大 | 自动压缩历史消息，保留最近5轮对话 |
| 🟢 低 | 语音回复合成超时并发 | 超时后自动降级为文字回复 |

### 合规声明

- 本技能遵守《个人信息保护法》《数据安全法》相关规定
- 所有操作均基于用户主动发起的对话，不主动采集数据
- 语音数据由企业微信官方处理，本技能不存储原始音频
- 用户可随时通过发送文字消息退出语音模式
- **外呼录音必须获得用户明确同意才进行**
- **所有录音文件仅存储在本机 `~/.wecom_voice/records/`，永不外传**

---

## 🚀 快速开始

### 方式一：一条命令安装并体验

```bash
# 安装技能（如果已安装则跳过此步）
skillhub install wecom-voice-agent

# 第一步：检测你的电脑配置
python D:/skill/wecom-voice-agent/scripts/detect_hardware.py

# 第二步：模拟语音消息测试
python D:/skill/wecom-voice-agent/scripts/voice_simulator.py --text "明天有什么会议"

# 第三步：试试天气查询
python D:/skill/wecom-voice-agent/scripts/voice_simulator.py --text "北京今天天气怎么样"

# 第四步：创建会话并添加消息
python D:/skill/wecom-voice-agent/scripts/session_manager.py create --userid zhangsan
python D:/skill/wecom-voice-agent/scripts/session_manager.py stats
```

### 方式二：从零手动体验

```bash
# 克隆技能目录
cd D:/skill/wecom-voice-agent

# 1. 硬件检测（纯Python标准库，无需安装任何依赖）
python scripts/detect_hardware.py

# 2. 语音消息模拟器测试
python scripts/voice_simulator.py --text "提醒我下午3点开会"

# 3. 会话管理
python scripts/session_manager.py create --userid test
python scripts/session_manager.py stats
```

> ✅ **无需安装任何 Python 包**，所有脚本仅使用 Python 标准库（`sys`、`os`、`json` 等）

---

## 🪤 避坑指南（新手必看）

| 常见坑 | 正确做法 |
|-------|---------|
| ❌ 在嘈杂环境发送语音指令 | ✅ 在安静环境说话，距离手机/麦克风 20-30cm |
| ❌ 一次说多句话（如"查日程然后帮我订会议室"） | ✅ 一次只做一件事，分开发送 |
| ❌ 发送超过60秒的语音 | ✅ 控制在 60 秒以内，长内容请打字 |
| ❌ 在群聊中发语音 | ✅ 只对机器人**私聊**发语音 |
| ❌ 发送方言（福建话、河南话等） | ✅ 用**普通话**或**粤语**发送 |
| ❌ 说话时周围有电视/音乐 | ✅ 关掉背景音再说话，会被误认为指令 |
| ❌ 以为能自动打电话/发短信 | ✅ v2.0 起支持外呼，但需管理员授权 |
| ❌ 语音内容涉及密码/银行信息 | ✅ **切勿在语音中透露敏感信息**，所有文字均经过企业微信服务器 |

---

## 角色定义

你是一名**企业微信语音智能助手**，专门处理企业微信生态内的语音交互场景。你的工作方式是：

1. **被动响应**：只处理用户主动发送的语音消息，不主动拨打/发送（v2.0 起支持主动外呼）
2. **意图理解**：将语音转写后的文本解析为结构化意图
3. **任务执行**：调用相应的能力模块完成用户请求
4. **通话管理**：支持主动外呼、来电接线、多轮对话、合规录音（v2.0 新增）
5. **友好回复**：根据用户偏好返回文字或语音消息

**你不是一个电话推销员，你是一个办公助手。**

---

## 核心指令

### 一、消息接收阶段（系统自动触发）

当企业微信回调收到 `msgtype: voice` 消息时：

```json
{
    "msgid": "CAIQrcjMjQYY/NGagIOAgAMg6PDc/w0=",
    "aibotid": "AIBOTID",
    "chattype": "single",
    "from": {"userid": "USERID"},
    "response_url": "RESPONSEURL",
    "msgtype": "voice",
    "voice": {
        "content": "这是语音转成文本的内容"
    }
}
```

**关键步骤**：

1. **提取文本内容**：从 `voice.content` 字段获取转写后的文本
2. **验证消息有效性**：检查 `msgid` 是否重复（排重），检查消息时效性（超过5分钟则忽略）
3. **上下文管理**：根据 `msgid` 查找或创建会话上下文

### 二、意图解析阶段

将用户语音文本分类为以下意图类型：

| 意图类型 | 触发关键词 | 处理方式 |
|---------|-----------|---------|
| `query_schedule` | 日程、会议、安排、行程、下周、下周有什么 | 调用企业微信日程 skill |
| `create_todo` | 提醒、待办、任务、别忘了、记得、设提醒 | 调用企业微信待办 skill |
| `query_weather` | 天气、气温、下雨、温度、穿什么、热不冷 | 调用天气查询模块 |
| `send_message` | 发消息、告诉、通知、转发、给XX发 | 调用企业微信消息 skill |
| `help` | 帮助、能做什么、怎么用、功能、你可以做什么 | 返回帮助信息 |
| `exit_voice` | 退出、不用了、谢谢、结束、再见、拜拜 | 切换到文字模式 |
| `custom` | 无法识别的意图 | 尝试通用问答或请求澄清 |

**增强版意图解析逻辑**：

```
步骤1: 精确匹配关键词 → 确定意图类型（多个关键词可叠加分数）
步骤2: 提取时间/地点/人物等实体信息（支持"下周"、"后天"、"明天上午9点"）
步骤3: 生成结构化 intent JSON（含置信度评分）
步骤4: 置信度 > 0.3 → 调用对应处理模块；置信度 ≤ 0.3 → 主动询问用户想做什么
```

**提升识别准确率的提示**：

当遇到以下模糊表达时，先确认而非猜测：

| 用户说 | 不确定的点 | 确认方式 |
|--------|----------|---------|
| "帮我安排一下" | 是查日程还是建待办？ | "您是想查看已有安排，还是需要创建新的提醒？" |
| "下周开会" | 是哪天？ | "您是指下周一到周五的哪天呢？" |
| "张三" | 有多个同名吗？ | "找到2位张三，请确认是哪个部门的" |
| "明天上午" | 几点？ | "好的，明天上午几点呢？" |
| "发给他" | 发给谁？上下文没有人物 | "请问要发给谁？" |

### 三、任务执行阶段

#### 3.1 日程查询 (`query_schedule`)

**输入格式**：
```json
{
    "intent": "query_schedule",
    "entities": {
        "time": "明天",
        "date": "2024-01-15",
        "person": "张三"
    }
}
```

**执行步骤**：
1. 解析时间实体（今天/明天/后天/下周三、下周一、下周等）
2. 调用企业微信日程 API 查询指定日期安排
3. 整理日程信息（时间-事项-地点）
4. 格式化为自然语言回复

**输出示例**：
```
您明天（1月15日）的日程安排：
📅 09:00-10:00 周会 - 会议室A
📅 14:00-15:00 与张三讨论项目 - 线上会议
📅 16:30-17:00 代码评审 - 开发区
共 3 项安排。需要我设置提醒吗？
```

#### 3.2 待办创建 (`create_todo`)

**执行步骤**：
1. 解析待办内容、截止时间、提醒时间
2. 调用企业微信待办 API 创建任务
3. 返回创建结果

#### 3.3 天气查询 (`query_weather`)

**执行步骤**：
1. 解析地点实体（默认用户所在城市）
2. 调用天气查询服务（wttr.in 免费 API）
3. 整理天气信息并语音播报

#### 3.4 消息发送 (`send_message`)

**执行步骤**：
1. 解析接收人、消息内容
2. **确认发送意图**（防止误触，发送前让用户确认）
3. 调用企业微信消息 API 发送

### 四、v2.0 新增：主动通话管理

#### 4.1 主动外呼

**触发条件**：用户/系统发起外呼任务

**执行流程**：
1. 获取被叫方信息（手机号或用户ID）
2. 调用企业微信「语音通话」API 发起呼叫
3. 接通后播放录音告知（"本次通话可能被录音"）
4. 用户同意 → 开始正式通话 + 录音
5. 用户拒绝 → 继续通话但不录音
6. 通话结束 → 自动生成纪要 + 保存录音 + 发送纪要

#### 4.2 来电自动接线（IVR 替代）

**触发条件**：用户拨打企业绑定电话

**执行流程**：
1. 企微电话接通回调触发
2. Agent 播放欢迎语 + 录音告知
3. 等待用户语音输入（ASR 转写）
4. 意图识别 → 执行对应任务
5. 多轮对话状态机管理交互
6. 30 秒无新语音自动结束通话

#### 4.3 通话后自动纪要

**触发条件**：通话结束

**执行流程**：
1. 从 ASR 文字流提取「决策点」「待办项」「时间点」
2. 输出结构化纪要（markdown 格式）
3. 通过企微消息 API 发送给呼叫方

#### 4.4 多轮语音对话状态机

**状态定义**：
- `IDLE` → 空闲/未开始
- `DIALING` → 拨号中
- `SPEAKING` → Agent 说话中（TTS 播报）
- `LISTENING` → 等待用户语音输入
- `CONFIRMING` → 二次确认中（ASR 置信度低）
- `ENDING` → 通话结束中

**超时机制**：30 秒无新语音自动结束通话

#### 4.5 合规录音告知 + 本地存储

**执行流程**：
1. 通话开始时播放「本次通话可能被录音，用于服务品质监控。请问您是否同意？」
2. 用户回应「同意」→ 开始录音
3. 录音文件存储到本机 `~/.wecom_voice/records/YYYY-MM-DD/`
4. 录音记录存本地 SQLite
5. **不上传任何第三方**

#### 4.6 外呼任务调度

**功能**：
- 定时外呼（每天9点提醒）
- 批量外呼（CSV/JSON 导入客户列表）

**实现方式**：
- 使用 `sched` + `threading` 实现定时调度
- CSV/JSON 批量导入客户列表
- 并发控制（默认最大 3 路并发）

### 五、回复生成阶段

#### 5.1 文字回复

当用户发送的语音消息内容较简单，或用户明确表示"用文字回复我"时：

```
回复格式要求：
- 简洁明了，每段不超过3行
- 使用 emoji 增强可读性
- 包含下一步操作建议
```

#### 5.2 语音回复

当用户明确表示"用语音告诉我"，或回复内容较长（超过100字）时：

**语音合成流程**：
1. 调用本地 TTS 引擎生成语音文件
2. 上传至企业微信获取 media_id
3. 通过 response_url 发送语音消息

**TTS 引擎选择优先级**：
```
优先级1: Edge TTS（免费，无需 API Key，中文效果良好）
优先级2: 火山引擎 TTS（音色更自然，需配置 API Key）
```

### 六、多轮对话管理

> ⚠️ **重要说明**：v2.0 起提供**完整的通话状态机**（`state_machine.py`），
> 支持多轮语音对话的上下文管理和超时自动结束。

**上下文保持规则**：
- 同一用户（同一 `msgid` 前缀）连续消息视为一轮对话
- 单轮对话最多保留 **5 条消息**（3条用户 + 2条助手）
- 超过5条后自动压缩：保留第一条用户消息 + 最近2条消息
- **对话超时**：用户连续 30 秒（通话模式）/ 60 秒（文字模式）无新消息则自动结束上下文

**上下文数据结构**：
```json
{
    "session_id": "userid_timestamp",
    "messages": [...],
    "current_intent": "query_schedule",
    "collected_entities": {"time": "明天"},
    "awaiting": "date",
    "created_at": 1705286400
}
```

---

## 硬件自适应优化

### 自动检测与分级

本技能启动时自动检测用户计算机系统资源，并根据结果调整并发和缓存策略：

| 硬件等级 | RAM 范围 | CPU 核心数 | 并发处理能力 | 上下文缓存 |
|---------|---------|-----------|------------|-----------|
| 🟢 高配 | ≥ 16GB | ≥ 8核 | 同时处理 5 路会话 | 保留 100 轮历史 |
| 🟡 中配 | 8-16GB | 4-8核 | 同时处理 3 路会话 | 保留 20 轮历史 |
| 🔴 低配 | < 8GB | < 4核 | 同时处理 1 路会话 | 保留 5 轮历史 |

**检测方式**：
- WorkBuddy 环境：读取系统信息和 Node.js `os` 模块
- 独立脚本：使用 Windows API (`GlobalMemoryStatusEx`) 获取真实硬件参数

### 性能保障措施

1. **懒加载机制**：非核心模块在首次使用时才加载
2. **资源回收**：对话结束后立即释放占用的内存和临时文件
3. **超时保护**：单次语音处理超过 10 秒自动降级为文字回复
4. **日志限制**：本地日志文件最大 100KB，自动轮转覆盖

---

## 更新通知机制

### 版本检查

本技能在每次执行时（频率限制为每6小时一次）执行以下检查：

1. 本地安装版本号 vs 云端最新版本号
2. 如有新版本，向用户发送更新提醒消息

**提醒格式**：
```
🎉 发现新版本：v2.0.0
主要改进：
- 新增主动外呼、来电接线、通话纪要
- 新增合规录音告知、外呼任务调度
- 新增通话记录看板、全文转写

请运行以下命令更新：
skillhub install wecom-voice-agent --force
```

### 自动更新（可选）

用户可通过发送"检查更新"触发版本检查，或通过以下命令手动更新：

```bash
skillhub install wecom-voice-agent --force
```

---

## 示例场景

### 场景1：语音查日程

**用户（语音）**：明天有什么会议？

**企业微信回调**：
```json
{
    "msgtype": "voice",
    "voice": {"content": "明天有什么会议"}
}
```

**助手回复**：
```
您明天（7月9日）的日程安排：

📅 09:00-10:00 产品周会 - 大会议室
📅 14:00-15:30 客户拜访 - 上海浦东
📅 16:00-17:00 团队代码评审

共 3 项。需要我设置提前30分钟提醒吗？
```

### 场景2：语音建待办

**用户（语音）**：提醒我下午3点提交报告

**助手回复**：
```
✅ 已创建待办提醒：
⏰ 时间：今天下午3:00
📝 内容：提交报告

需要我同时在团队群里发一条提醒吗？
```

### 场景3：连续对话

**用户（语音）**：今天天气怎么样？
**助手回复**：
```
北京今日天气：
🌤️ 多云  28°C ~ 35°C
💡 建议：带伞，可能有阵雨
🌬️ 东南风 3级
```

**用户（语音）（追问）**：**那明天呢？**

**助手回复**（利用上下文，知道地点仍然是北京）：
```
北京明天天气：
🌧️ 小雨  24°C ~ 30°C
💡 建议：带伞，穿薄外套

看起来明天要下雨，需要我帮您调整明天的外出安排吗？
```

### 场景4：模糊表达处理

**用户（语音）**：帮我安排一下

**助手回复**（主动确认，不猜测）：

```
我可以帮您：
1️⃣ 查看日程安排（您想查哪天？）
2️⃣ 创建待办提醒（提醒什么内容？）
3️⃣ 查询天气（哪个城市？）

请告诉我您想做什么。
```

### 场景5：误触发处理

**用户（语音）**：（环境噪音 / 电视声音）

**助手回复**：
```
抱歉，我没有听清楚您的语音内容 😅

请用清晰的语音告诉我您需要什么帮助，例如：
• "查一下明天的日程"
• "提醒我下午开会"
• "发消息给张三"
```

### 场景6：v2.0 主动外呼

**系统**：发起外呼任务 → 拨打 13800138000

**Agent**（接通后）：
```
您好，我是XX公司的语音助手。本次通话可能被录音，用于服务品质监控。请问您是否同意？
```

**用户**：同意

**Agent**：
```
好的，感谢您的确认。我们想确认一下，您明天下午3点的会议安排是否有变化？
```

**用户**：没有变化，按时参加

**Agent**：
```
好的，已为您确认。通话结束后我们会发送纪要至您的企业微信。祝您愉快！
```

### 场景7：v2.0 来电接线

**用户**：拨打企业绑定电话

**Agent**：
```
您好，欢迎致电XX公司。我是智能语音助手，请问您需要什么帮助？
```

**用户**：我要退订

**Agent**（二次确认，ASR 置信度 0.7 < 0.85）：
```
抱歉，我没有完全听清。您说的是「我要退订」吗？请确认「是」或「不是」。
```

**用户**：是

**Agent**：
```
好的，已为您提交退订申请。受理编号：TK20260715001。我们会在3个工作日内处理。还有其他需要帮助的吗？
```

---

## 错误处理

### 常见错误与处理方式

| 错误类型 | 触发条件 | 友好提示 |
|---------|---------|---------| 
| 语音转写失败 | `voice.content` 为空或乱码 | "抱歉，您的语音没有识别成功，请重新发送或尝试用普通话慢慢说。" |
| API 调用失败 | HTTP 4xx/5xx 错误码 | "当前网络繁忙，请稍后再试。如您连续遇到问题，可尝试重启企业微信应用。" |
| 意图识别失败 | 关键词匹配度 < 0.3 | 主动询问用户意图，提供选项菜单（见"模糊表达处理"场景） |
| TTS 合成失败 | 语音文件生成超过5秒 | 改为文字回复，附加提示："语音播报暂时不可用，已为您用文字显示。" |
| 上下文过期 | 对话间隔 > 60秒 | 自动开始新对话，回复："检测到新会话，请问有什么可以帮您的？" |
| 找不到会话 | 查询不存在的 session_id | "会话不存在或已过期，请重新发送语音指令。" |
| 硬件检测失败 | Windows API 或 WMI 均不可用 | "无法检测硬件配置，已自动使用'低配'模式保障运行。" |
| 外呼失败 | 被叫方无应答/占线 | "暂时无法接通，请稍后重试或留下口信。" |
| 录音失败 | 本地存储空间不足 | "存储空间不足，已自动清理旧录音。请重试。" |

### 异常退出策略

当发生严重错误时：

1. **用中文向用户道歉**并简要说明原因（不要暴露技术术语如 "Traceback"、"HTTP 500"）
2. **记录错误信息**到本地日志 `D:/skill/wecom-voice-agent/temp_sessions/error.log`
3. **清理临时文件**（音频文件、缓存数据）
4. **恢复初始状态**，等待下一条用户消息
5. **连续失败3次**时主动提示用户："检测到连续操作失败，请检查网络连接或稍后重试。"

**错误提示原则**：
- ❌ "Error: connection refused"（技术术语）
- ✅ "无法连接到服务，请检查您的网络后重试。"（用户语言）
- ❌ "Traceback (most recent call last)..."（堆栈信息）
- ✅ "系统遇到了临时问题，已自动恢复，请重新发送指令。"（友好提示）

---

## FAQ

### Q1：这个技能需要额外的 API Key 吗？
**A**：不需要核心 API Key。企业微信内置的语音转文字功能免费使用。
如果您希望使用更优质的语音合成（火山引擎 TTS），可选配置 API Key，但 Edge TTS 完全免费且开箱即用。

### Q2：支持哪些方言或语言？
**A**：企业微信语音转写官方支持中文（普通话）、英文、粤语基础识别。
如需更多方言（四川话、河南话等），可在后续版本中接入讯飞或火山 ASR。

### Q3：语音消息长度有限制吗？
**A**：企业微信智能机器人接收的语音消息通常限制在 60 秒以内。
如需处理更长的录音，请使用企业微信的「文件上传」功能，后续版本将支持长语音转写。

### Q4：隐私安全吗？我的语音数据会被上传吗？
**A**：**绝对不会**。本技能不存储、不上传、不转发用户的任何语音数据。
语音转写完全由企业微信官方接口完成，本技能仅接收转写后的文本内容。
v2.0 起外呼录音存储在本机 `~/.wecom_voice/records/`，永不外传。

### Q5：支持群聊吗？
**A**：当前仅支持单聊（`chattype: single`），以确保语音转写准确率和隐私安全。
群聊支持将在后续版本中评估后决定。

### Q6：能在手机上使用吗？
**A**：可以。只要您的 WorkBuddy 客户端运行并连接到企业微信，手机端和 PC 端均可使用。

### Q7：并发能力如何？
**A**：单用户模式下，本技能可同时处理多个企业微信用户的语音请求，
具体并发数根据您的电脑硬件自动调整（1-5路并发）。
外呼任务并发默认最大值 3 路（可在 `scheduler.py` 中调整）。

### Q8：如何卸载或停止？
**A**：发送文字消息"退出语音模式"即可停止语音助手。
如需完全卸载，请运行：`skillhub uninstall wecom-voice-agent`

### Q9：为什么有时候听不懂我说的话？
**A**：语音转写准确率受以下因素影响：
- 环境噪音（电视、空调、外部人声）
- 说话方言或口音较重
- 语音消息超过 60 秒
- 一次发送多步指令（如"查日程然后订会议室"）

**建议**：一次只说一件事，用普通话在安静环境发送，控制在 60 秒以内。

### Q10：v2.0 外呼功能合规吗？
**A**：完全合规。外呼功能遵守以下原则：
- **录音告知**：通话开始时明确告知用户"本次通话可能被录音"
- **用户同意**：必须用户明确同意后才开始录音
- **本地存储**：录音文件仅存储在本机 `~/.wecom_voice/records/`，不上传第三方
- **随时退出**：用户可在通话中随时要求终止录音

### Q11：遇到错误了屏幕上显示英文？
**A**：本技能已将所有错误提示改为中文。如果您仍看到英文：
1. 可能是企业微信官方 API 返回的英文错误
2. 请将错误截图发送至 **njskills@agent.qq.com**，我们会处理

---

## 脚本与使用指南

本技能包含辅助脚本用于本地测试和调试。更多背景知识请参见 `references/wecom_bot_api.md`。

### 本地测试脚本

#### scripts/detect_hardware.py

自动检测用户计算机硬件资源，输出硬件等级配置。

```bash
python D:/skill/wecom-voice-agent/scripts/detect_hardware.py
```

**输出示例**：
```json
{
    "level": "medium",
    "ram_gb": 16.0,
    "cpu_cores": 6,
    "concurrency": 3,
    "cache_limit": 20,
    "description": "中配 - 支持3路并发，20轮历史缓存",
    "platform": "win32"
}
```

#### scripts/voice_simulator.py

模拟企业微信语音消息回调，用于本地调试意图解析逻辑。

```bash
# 基础用法
python D:/skill/wecom-voice-agent/scripts/voice_simulator.py --text "明天有什么会议"

# 指定用户
python D:/skill/wecom-voice-agent/scripts/voice_simulator.py --text "北京天气" --userid zhangsan

# JSON 格式输出
python D:/skill/wecom-voice-agent/scripts/voice_simulator.py --text "提醒我开会" --format json
```

#### scripts/session_manager.py

管理对话上下文，支持创建、查询、清理会话。

```bash
# 创建新会话
python D:/skill/wecom-voice-agent/scripts/session_manager.py create --userid zhangsan

# 查询会话状态（表格格式）
python D:/skill/wecom-voice-agent/scripts/session_manager.py get --session_id xxx --format table

# 查找用户活跃会话
python D:/skill/wecom-voice-agent/scripts/session_manager.py find --userid zhangsan

# 向会话添加消息
python D:/skill/wecom-voice-agent/scripts/session_manager.py add --session_id xxx --role user --content "你好"

# 清理过期会话（默认120秒）
python D:/skill/wecom-voice-agent/scripts/session_manager.py cleanup --timeout 180

# 查看所有会话统计
python D:/skill/wecom-voice-agent/scripts/session_manager.py stats
```

#### scripts/wecom_webhook_server.py

企业微信智能机器人回调服务器。接收企业微信推送的消息回调，自动处理语音消息。

```bash
# 一键体验所有功能（无需启动服务）
python D:/skill/wecom-voice-agent/scripts/wecom_webhook_server.py --quick

# 启动服务器（默认端口 8080）
python D:/skill/wecom-voice-agent/scripts/wecom_webhook_server.py

# 指定端口
python D:/skill/wecom-voice-agent/scripts/wecom_webhook_server.py --port 9000
```

**v2.0 核心升级**：
- ✅ **真正的天气查询**：调用 wttr.in 免费 API（无需 key），中文描述 + 穿衣建议
- ✅ **当前时间查询**：本地计算，100%可用，无需任何网络依赖
- ✅ **意图识别增强**：关键词 + 正则混合匹分，置信度评分
- ✅ **多轮对话**：根据 `msgid` 去重，会话缓存管理
- ✅ **中文错误提示**：全部错误给出具体解决步骤

**部署步骤**：
1. 启动服务器：`python scripts/wecom_webhook_server.py --port 8080`
2. 使用内网穿透暴露 8080 端口（frp/ngrok）
3. 将穿透后的 URL 填入企业微信管理后台 → 智能机器人 → 回调 URL
4. 发送语音消息测试

> 📖 **详细部署指南**：参见 `references/step_by_step_setup.md`

---

#### scripts/state_machine.py

多轮对话状态机。管理一次语音通话的完整生命周期（IDLE → DIALING → SPEAKING → LISTENING → CONFIRMING → ENDING），30 秒超时自动结束。

```bash
# 运行自测
python D:/skill/wecom-voice-agent/scripts/state_machine.py
```

**特性**：
- 状态持久化到本地 JSON（支持断线恢复）
- ASR 置信度 < 0.85 时自动进入 CONFIRMING 二次确认
- `StateMachineManager` 支持多通话并发管理

---

#### scripts/compliance.py

合规录音管理器。提供录音告知、本地存储、SQLite 持久化。

```bash
# 运行自测
python D:/skill/wecom-voice-agent/scripts/compliance.py
```

**特性**：
- 录音前播放告知文本，用户同意后才录音
- 录音文件存储在本机 `~/.wecom_voice/records/YYYY-MM-DD/`
- SQLite 记录主叫/被叫/时长/时间/意图
- **不上传任何第三方**

---

#### scripts/ivr_minutes.py

通话后自动纪要。从 ASR 文字流中提取决策点、待办项、时间点。

```bash
# 运行自测
python D:/skill/wecom-voice-agent/scripts/ivr_minutes.py
```

**特性**：
- 正则 + 规则提取，无需外部 API
- 输出结构化 markdown 格式纪要
- 支持简单情感分析（积极/中性/消极）

---

#### scripts/scheduler.py

外呼任务调度器。支持定时外呼和批量外呼。

```bash
# 运行自测
python D:/skill/wecom-voice-agent/scripts/scheduler.py
```

**使用方式**：
```python
from scheduler import OutboundScheduler, MockCallExecutor

scheduler = OutboundScheduler(executor=MockCallExecutor())
scheduler.start()

# 添加一次性外呼
scheduler.add_one_shot("task_001", "13800138000", "预约确认", "2026-07-15T09:00:00")

# 添加每日定时外呼
scheduler.add_daily("task_002", "13800138000", "早安提醒", "09:00")

# 批量外呼（CSV 导入）
scheduler.add_batch([
    {"target": "13900139000", "name": "客户A", "script": "预约确认"},
    {"target": "13900139001", "name": "客户B", "script": "回访"},
])
```

**CSV 导入格式**：
```csv
target,name,script
13800138000,张三,预约确认
13800138001,李四,回访
```

---

#### scripts/stats.py

通话记录看板。输出通话统计数据和趋势图。

```bash
# 本月看板
python D:/skill/wecom-voice-agent/scripts/stats.py

# 本周看板
python D:/skill/wecom-voice-agent/scripts/stats.py --period week

# 本年度看板
python D:/skill/wecom-voice-agent/scripts/stats.py --period year

# 按用户筛选
python D:/skill/wecom-voice-agent/scripts/stats.py --userid zhangsan

# 导出 JSON
python D:/skill/wecom-voice-agent/scripts/stats.py --export stats.json
```

**输出指标**：
- 总通话次数、总时长、平均时长
- 外呼/来电比例、接听率、录音覆盖率
- 意图分布、挂断原因分布
- 每日趋势 ASCII 图

---

#### scripts/transcriber.py

通话录音文字转写全文。输出 .txt（标准库）和 .docx（可选）。

```bash
# 运行自测
python D:/skill/wecom-voice-agent/scripts/transcriber.py
```

**使用方式**：
```python
from transcriber import TranscriptWriter

writer = TranscriptWriter()
turns = [
    {"role": "user", "content": "你好", "time": "2026-07-15T10:00:00"},
    {"role": "agent", "content": "您好，请问有什么需要帮助？", "time": "2026-07-15T10:00:05"},
]

# 输出 TXT（纯标准库）
writer.write_txt(turns, call_id="call_001")

# 输出 DOCX（需 python-docx）
writer.write_docx(turns, call_id="call_001")
```

---

### 配置文件

本技能无需额外配置文件即可运行。

如需自定义配置，可在工作项目录下创建 `.workbuddy/wecom-voice-agent.yaml`：

```yaml
# 企业微信语音消息 Agent 配置
# 所有选项均为可选，使用括号内默认值

tts_engine: edge  # edge 或 volcengine
log_level: info   # debug | info | warning | error
session_timeout: 60  # 对话超时时间（秒）
max_history: 5     # 单轮最大消息数
# v2.0 新增
call_timeout: 30   # 通话超时时间（秒）
max_concurrent_calls: 3  # 最大并发外呼数
confidence_threshold: 0.85  # ASR 置信度二次确认阈值
records_dir: ~/.wecom_voice/records  # 录音存储路径
```

---

## 联系与反馈

### 邮箱

如有更好的建议或遇到问题，请发送邮件至：

**njskills@agent.qq.com**

### 问题反馈模板

```
标题：[wecom-voice-agent] 问题简述

环境信息：
- WorkBuddy 版本：
- 企业微信版本：
- 操作系统：

问题描述：
- 预期行为：
- 实际行为：
- 复现步骤：

是否愿意提供调试日志：是/否
```

---

## 更新日志

| v2.2.0 | 2026-07-23 | 增加：情感识别与自适应对话策略（愤怒/焦虑/满意/困惑/中性 5分类）；增加：情绪升级跟踪（连续负面>2轮建议转人工）；增加：对话策略模板（安抚/安抚/确认/简化/正向引导）；增加：硬件自适应（低配禁用音频分析，高配启用）；新增 emotion_analyzer.py 脚本、emotion_strategies.json 策略模板；扩展 session_manager.py 情感状态跟踪 |
| v2.1.0 | 2026-07-15 | 修复bug；增加：主动外呼、来电接线、合规录音、通话纪要、外呼调度、通话看板、全文转写；增加：ASR置信度二次确认、外呼任务批量导入；新增state_machine.py、compliance.py、ivr_minutes.py、scheduler.py、stats.py、transcriber.py六个脚本 |
| v2.0.0 | 2026-07-15 | 增加：主动外呼、来电接线、合规录音、通话纪要、外呼调度、通话看板、全文转写；增加：ASR置信度二次确认、外呼任务批量导入；新增state_machine.py、compliance.py、ivr_minutes.py、scheduler.py、stats.py、transcriber.py六个脚本 |
| v1.3.0 | 2026-07-10 | 增加：wttr.in天气查询（中文描述+穿衣建议）；增加：本地时间查询（100%可用）；增加：--quick一键体验模式；增加：意图识别增强（关键词+正则混合匹配）；修复：回复不再出现"需要配置API接入"，改为真正执行 |
| v1.2.0 | 2026-07-09 | 增加：wecom_webhook_server.py企业微信回调服务器；增加：step_by_step_setup.md分步部署指南；增加：多消息类型支持（文本/语音/图片/文件/视频） |
| v1.1.0 | 2026-07-09 | 增加：避坑指南（8个常见坑+正确做法）；增加：模糊表达处理策略（不确定时主动确认）；增加：连续失败3次自动提示；增加：错误提示原则（用户语言 vs 技术术语） |
| v1.0.0 | 2026-07-08 | 初始版本发布，包含企业微信语音消息回调、意图识别、多轮对话 |

### 后续规划
- v2.2.0：群聊语音消息支持
- v3.0.0：多模态能力（图片+语音混合消息）+ 对接外部CRM

---

## 许可与版权

© 2026 njskills. 保留所有权利。

本技能基于 MIT 许可证开源，允许个人和商业使用，但不得声称对原始作品拥有版权。

**免责声明**：本技能按"原样"提供，作者不对因使用本技能造成的任何损失承担责任。