# weida_1_6
**Repository Path**: oseas31/weida_1_6
## Basic Information
- **Project Name**: weida_1_6
- **Description**: youkeda夏令营
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-08-14
- **Last Updated**: 2026-10-09
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# weida_1_6 — 微信 AI 机器人
> 威达(Weida)实习项目 · Java 21 / Spring Boot 4.1 / Maven
>
> 一个跑在微信里的 AI 助手:扫码登录后即可对话、画图、识图、查天气、语音问答……支持多模型提供商路由与 Function Calling 工具调用。
---
## 1. 项目简介
本项目通过 `wechat-ilink-sdk` 接入微信 iLink 通道,实现一个可长时间稳定运行的微信机器人:
- **多模型统一路由**:DeepSeek(主对话 + 工具调用)、ModelScope Qwen(多模态 + 流式思考链)、ModelScope GLM-5.2(对话兜底)、智谱 GLM-4V / CogView(识图 / 文生图),支持 `auto` 容错切换
- **Function Calling**:模型自主决定调用天气、时间、POI、联网搜索、计算器、任务计划、技能加载等本地工具,结果回传后生成最终回答,防止编造实时信息
- **语音闭环**:微信语音条 → SILK 解码 → 阿里云实时 ASR 识别成文字;文字回复可按需/按模式 → TTS 合成 MP3 文件发回微信
- **Skill 技能系统**:`skills/` 目录按 `SKILL.md` 规范组织技能,模型经 `load_skill` 工具按需加载指令,新增能力只需新增一个技能目录
- **长程任务计划**:模型用 `update_plan` 工具维护「目标 → 步骤清单(含状态)」,编排循环每轮回注系统提示词,跨轮自我定位不迷路
- **开发规范强制**:checkstyle 绑定 `validate` 阶段,命名与风格违规直接构建失败(规则见 `checkstyle.xml` 与 `AGENTS.md`)
## 2. 功能特性
| 能力 | 说明 |
| --------- | -------------------------------------------------------------------- |
| 智能对话 | 两级记忆:热缓存(最近 60 条/人 + 摘要压缩)+ JSONL 冷归档(重启自动恢复),支持「清除记忆」重置 |
| 工具调用 | 天气 / 时间 / 计算 / 汇率 / POI / 联网搜索 / 电脑Agent / 邮件 / 任务计划 / Skill,共 11 个工具(见第 8 章) |
| 天气查询 | 高德权威数据优先,wttr.in 兜底,防 LLM 编造 |
| 文生图 | 智谱 CogView,生成后直接发图 |
| 图片识别 | 智谱 GLM-4V,支持后续追问「图里有什么」 |
| 语音消息 | 识别为文字后走统一意图路由,指令等价于打字 |
| 语音回复 | 单条朗读(「读出来:…」)或全局语音模式(「以后都用语音回复」) |
| 文件消息 | 文本文件(txt/md/java 等)由大模型总结并写入记忆,二进制文件回复文件名与大小 |
| 联网搜索 | 维基百科中文 API,免 Key,30 秒去重缓存 |
| 任务计划 | `update_plan` 维护长程任务「目标 → 步骤清单」,跨轮自我定位(长任务不迷路) |
| Skill 技能 | `load_skill` 按需加载 `skills/` 技能指令(群规速查 / POI / 邮件等) |
| 电脑Agent遥控 | 微信触发 `computer_agent`,本机 Node 桥接驱动 kimi 真机操作电脑(写代码/改文件/跑命令),后台异步回推结果 |
| 仓库功能 | Gitee 咨询/监控分支新提交、GitHub Star 排行,按用户订阅定时推送 |
| 邮件收发 | `send_mail` 发信(可含图片/附件)、`receive_mail` 读公用演示收件箱 |
| 控制台登录 | 不依赖 GUI,登录链接直接打印到控制台,浏览器扫码即可 |
## 3. 架构图
```mermaid
flowchart TD
subgraph 用户["用户侧"]
USER([微信用户])
end
subgraph 通道["微信通道(wechat-ilink-sdk 2.3.3)"]
SDK["ILinkClient
扫码登录 · 心跳保活 30s · 500ms 轮询"]
end
subgraph 应用["应用层(Spring Boot 4.1)"]
BOT["WechatBotService 消息中枢
有界队列(1024) + 单线程 worker,不阻塞接收"]
subgraph 输入["消息分流"]
ASR["语音 → SilkVoiceEncoder
→ 阿里云实时 ASR(WebSocket)"]
IMG["图片 → 智谱 GLM-4V 识图"]
FILE["文件 → FileHandler
文本总结 / 二进制提示"]
INTENT["文字 → IntentParser
规则识别 17 类意图"]
end
subgraph 会话["会话与状态"]
MEM["ConversationMemory
热缓存 60 条/用户 + 摘要压缩"]
ARK["SessionPersistenceService
JSONL 冷归档 · 重启恢复"]
VMS["VoiceModeStore
语音模式开关/用户"]
end
subgraph 路由["对话路由 ChatAdapterRouter"]
DS["DeepSeekChatAdapter
对话+工具 · 非流式"]
QW["QwenChatAdapter
多模态 · 流式+思考链 · 无工具"]
GLM["GlmChatAdapter
GLM-5.2 对话兜底 · 限流自动切 Qwen"]
end
subgraph 工具["Function Calling(默认 6 轮上限)"]
TE["ToolRunner 门面 + ToolRegistry
11 个插件工具"]
end
subgraph 输出["输出侧"]
DRAW["智谱 CogView 文生图 → 发图片"]
TTS["TTS 双协议
dashscope(阿里云) | openai(硅基流动)"]
end
REST["AiController /ai/*
REST 调试入口"]
end
subgraph 外部["外部服务"]
AMAP["高德:天气 weatherInfo
POI place/text"]
WTT["wttr.in(免 Key 兜底天气)"]
WIKI["维基百科中文(免 Key 搜索)"]
DASH["阿里云百炼:ASR/TTS"]
SIL["硅基流动:CosyVoice2 TTS"]
ZP["智谱:GLM-4V 识图 / CogView 画图"]
GIT["Gitee/GitHub API
仓库咨询/监控/排行"]
MAIL["SMTP / IMAP
邮件收发"]
BRIDGE["Node 桥接 → kimi
电脑Agent 遥控"]
end
USER -->|扫码/发消息| SDK
SDK -->|推消息| BOT
BOT -->|语音| ASR
BOT -->|图片| IMG
BOT -->|文字| INTENT
BOT -->|文件| FILE
ASR -->|识别文字| INTENT
INTENT -->|聊天/天气| 路由
BOT <--> MEM
MEM -->|落盘/恢复| ARK
BOT <--> VMS
路由 --> DS
路由 --> QW
路由 --> GLM
DS -->|tool_calls| TE
TE -->|get_weather| AMAP
TE -->|get_weather 兜底| WTT
TE -->|web_search| WIKI
TE -->|poi_search| AMAP
TE -->|computer_agent| BRIDGE
路由 -->|仓库功能| GIT
TE -->|send_mail/receive_mail| MAIL
TE -->|update_plan| PLAN["UserPlanStore 计划快照回注"]
TE -->|load_skill| SKILL["skills/ 技能指令"]
BRIDGE -->|kimi acp / kimi-p| KIMI["本机 kimi"]
路由 -->|画图| DRAW
BOT -->|语音回复| TTS
TTS --> DASH
TTS --> SIL
应用 -.REST 调试.-> REST
classDef ext fill:#eef4ff,stroke:#4a7bd6,color:#1f3a6e;
classDef core fill:#fdf6e3,stroke:#c9a227,color:#6b5400;
class AMAP,WTT,WIKI,DASH,SIL,ZP,GIT,MAIL,BRIDGE,KIMI ext;
class BOT,INTENT,FILE,路由,TE,PLAN,SKILL core;
```
> 提示:Markdown 渲染器不支持 Mermaid 时,可在 [mermaid.live](https://mermaid.live) 粘贴上述代码查看。
## 4. 技术栈
| 类别 | 选型 |
| ----------- | ---------------------------------------------------- |
| 语言 / 框架 | Java 21 · Spring Boot 4.1(webmvc) |
| 构建 / 质量 | Maven · maven-checkstyle-plugin 3.6.0(validate 阶段强制) |
| 微信接入 | `wechat-ilink-sdk` 2.3.3(心跳 30s 保活必需) |
| 音频 | `silk-codec` 0.0.5(WAV ⇄ SILK)+ 自研重采样/位深转换 |
| HTTP / JSON | OkHttp 4.12.0 · Gson 2.11.0 |
| 二维码 | zxing core 3.5.3(仅依赖,登录已改为控制台链接) |
| 数据库 | JDBC(JdbcTemplate)+ MySQL(RepositoryStore 订阅存储);对话记忆走 JSONL 冷归档,无需数据库 |
## 5. 包结构
```
com.weida
├─ ai # 模型客户端/适配器路由/记忆/语音模式/工具执行
│ └─ skill # Skill 技能系统(SkillLoader / SkillParser / SkillTool)
├─ agent # 电脑 Agent 通道(HttpAgentChannel / AgentBridgeProperties / AgentChannelException)
├─ git # Gitee/GitHub 仓库咨询/监控/排行
├─ mail # 邮件收发工具(MailSendService / MailReceiveService)
├─ amap # 高德天气与 POI
├─ weather # 天气兜底服务(wttr.in / 高德 adcode)
├─ intent # 意图枚举与规则解析
├─ search # 联网搜索(维基百科)
├─ config # iLink 心跳等配置 Bean
├─ controller # REST 调试入口
├─ wechat # iLink 封装、消息路由、SILK 编码、文件处理
└─ Weida16Application.java
```
## 6. 快速开始
### 6.1 环境要求
- JDK 21+、Maven 3.9+
- MySQL 可选:仅仓库监控/排行订阅(`RepositoryStore`,JdbcTemplate)使用;不装也可启动,仅该功能不可用
- 至少一个 LLM 提供商 API Key(推荐 DeepSeek)
### 6.2 配置密钥
密钥不写入 Git。创建本地配置(已 gitignore):
```properties
# local/application-local.properties(示例)
DEEPSEEK_API_KEY=sk-...
ZHIPU_API_KEY=...
MODELSCOPE_API_KEY=...
DASHSCOPE_API_KEY=...
WEATHER_API_KEY=... # 高德天气与 POI 共用
SILICONFLOW_TTS_API_KEY=... # 仅使用硅基流动 TTS 时需要
```
也可用同名环境变量;`application.properties` 中 `${KEY:}` 占位,缺省不报错。
### 6.3 启动与登录
```bash
mvn spring-boot:run
```
控制台会打印登录链接,浏览器打开后用微信扫码,登录成功即开始监听消息。
### 6.4 常用指令(微信里发送)
| 指令示例 | 效果 |
| ------------------- | -------------- |
| `你好` | 智能对话 |
| `北京天气` | 查天气(工具调用) |
| `现在几点了` | 真实时间(工具调用,防编造) |
| `帮我画一只猫` | 文生图发图 |
| 发一张图片 | 图片识别 |
| `读出来:今天天气不错` | 单条语音回复 |
| `以后都用语音回复` / `切回文字` | 全局语音模式开关 |
| `清除记忆` | 重置会话上下文 |
| `帮助` / `help` | 查看完整帮助 |
## 7. 模型提供商矩阵
| 提供商 | 能力 | 说明 |
| -------------------------------------------------- | --------------------- | ----------------------------------------------------- |
| DeepSeek `deepseek-v4-flash` | 对话 · Function Calling | 默认主模型,非流式;工具调用**始终由其承担** |
| ModelScope Qwen `Qwen3.8-27B` | 多模态 · 对话 | 流式 + `reasoning_content` 思考链;**不支持工具**(自动降级 DeepSeek) |
| ModelScope GLM `GLM-5.2` | 对话 | OpenAI 兼容;流式思考链;**不支持工具/识图**,限流(429)自动切 Qwen |
| 智谱 `glm-4.6v-flash` / `cogview-3-flash` | 识图 / 文生图 | 图片问答与画图 |
| 阿里云百炼 `qwen3-tts-flash` / `paraformer-realtime-v2` | TTS / ASR | `ai.tts.provider=dashscope`(默认) |
| 硅基流动 `CosyVoice2-0.5B` | TTS(OpenAI 兼容) | `ai.tts.provider=openai`;响应体即音频字节 |
对话路由 `ai.chat.provider`:`deepseek`(默认)| `qwen` | `glm` | `auto`(主模型失败自动切备选;qwen/glm 的工具调用降级 DeepSeek,GLM 限流自动切 Qwen)。
## 8. ToolRunner 工具清单
| 工具 | 数据源 | 说明 |
| ------------------- | ------------------------------ | ------------------------------------- |
| `get_weather` | 高德天气 → wttr.in 降级 | 实时 + 未来 3 天预报;城市候选正则验证 |
| `get_current_time` | 本地时钟 | 当前日期/时间,系统提示强制调用防编造 |
| `calculator` | 本地计算 | 四则运算,除零友好提示 |
| `currency_exchange` | 内置固定汇率表 | CNY/USD/EUR/JPY 兑换 |
| `poi_search` | 高德 place/text | 餐厅/加油站等周边真实地点,要求模型不编造 |
| `web_search` | 维基百科中文 API | 前 3 条摘要,剥标签 + 截断,30s 去重缓存 |
| `update_plan` | `UserPlanStore`(内存快照) | 维护长程任务「目标 → 步骤清单(pending/in_progress/done)」,每轮提交全量最新列表;编排循环回注系统提示词 |
| `load_skill` | `skills/` 目录 SKILL.md | 按需加载技能指令(read / list),技能只提供指令不执行业务 |
| `computer_agent` | 本机 Node 桥接 → kimi | 微信遥控电脑执行真实任务(写代码/改文件/跑命令),后台异步执行并回推结果 |
| `send_mail` | SMTP(spring-boot-starter-mail) | 发送邮件,支持纯文本/HTML、内嵌图片、附件(URL),收件人上限 5 |
| `receive_mail` | IMAP | 读取项目公用演示邮箱收件箱最近 N 封邮件(默认 5,最大 20) |
工具调用循环上限默认 6 轮(`agent.max-tool-rounds`,保护上限 30),防止死循环。
### 8.1 电脑 Agent 桥接(`computer_agent`)
- **链路**:`ToolRunner` 识别 `computer_agent` → 提交 `AgentTaskHandler`(单线程池异步,不阻塞消息 worker)→ `HttpAgentChannel` POST 到本机桥接服务
- **桥接服务**:`scripts/agent-bridge/index.mjs`(Node),监听 `127.0.0.1:8765`,两种模式:
- **ACP 长驻(优先)**:基于官方 `@agentclientprotocol/sdk`,kimi 长驻,适合 OAuth 登录用户
- **kimi -p 一次性(回退)**:每次任务 `spawn` 一次 `kimi -p`,兼容第三方 API key;ACP 认证失败或 `AGENT_FORCE_KIMI_P=1` 时自动回退
- **健康检查**:`GET /agent/status` 返回 `kimiAlive/mode/sessionId/pid`,脚本/Java 复用前先探测
- **会话目录**:固定 `~/.weida/agent-sessions`,桥接层 `#safePath`/`ensureSessionDir` 严格校验只允许读写该目录内
- **一键验证**:`scripts/verify-bridge.ps1` / `.cmd`(含健康检查、`kimi -p` 强制模式)
- **安全注意**:仅限本机可信环境使用;未绑 `127.0.0.1` 或暴露到多用户时需自行增加鉴权
### 8.2 工具插件化架构(AgentTool + ToolRegistry)
每个工具是独立的 `@Component`(实现 `AgentTool`,自带 `name/schema/execute/isValidResult`),由 `ToolRegistry` 自动收集为工具清单;`ToolRunner` 只保留并行执行 / 独立超时 / 重试 / 结果校验这些横向能力。
- **新增工具**:新建一个 `@Component` 的 `AgentTool` 实现类即可,公共文件零改动(开闭原则)
- **归属**:schema、执行逻辑、专项结果校验全部收敛到工具自身,工具之间互不耦合
### 8.3 分层架构与扩展点
按职责分层,各层通过接口/注册表解耦,新增能力无需改既有层:
| 层 | 组件 | 职责 | 新增能力方式 |
| ----- | --------------------------------------------------- | ------------------------------ | -------------------------- |
| 接入/路由 | `MessageHandler`(WechatBotService 收集) | 按意图分发到各能力 Handler | 新增一个 `MessageHandler` 认领意图 |
| 编排 | `AgentOrchestrator`(从 AiApiClient 抽离) | 模型 ↔ 工具 循环状态机、反思重试、上限总结 | 编排调整只改 AgentOrchestrator |
| 传输 | `AiHttpTransport`(AiApiClient/AgentOrchestrator 共用) | HTTP 拼装、解析、统一错误分类(AUTH/QUOTA…) | 错误分类只改一处 |
| 工具 | `AgentTool` + `ToolRegistry` | 每个工具自带 schema/执行/校验 | 新增一个 `AgentTool` 自动收集 |
```mermaid
flowchart LR
U[用户消息] --> W[WechatBotService]
W -->|按意图| H[MessageHandler 链]
H --> AL[AgentOrchestrator 编排循环]
AL --> HS[AiHttpTransport 传输]
AL --> R[ToolRegistry]
R --> T[AgentTool ×11]
style AL fill:#f3e5f5,color:#7b1fa2
style R fill:#fff3e0,color:#e65100
style HS fill:#e8f5e9,color:#1b5e20
```
## 9. 关键配置说明
| 配置项 | 默认值 | 说明 |
| ------------------------------- | ---------------------------------------------------- | -------------------------------------------------- |
| `ai.chat.provider` | `deepseek` | 对话路由:deepseek / qwen / glm / auto |
| `ai.tts.provider` | `dashscope` | TTS 提供商:dashscope / openai |
| `ai.openai-tts.*` | 硅基流动 URL | openai TTS 的 url / model / voice / response-format |
| `amap.weather.default-city` | `深圳` | 高德天气无候选时兜底城市 |
| `weather.default-city` | `上海` | 兜底天气服务默认城市 |
| `amap.weather.enabled` | `true` | 高德天气注入开关 |
| `spring.config.import` | `optional:file:./local/application-local.properties` | 本地密钥文件(gitignore) |
| `agent.bridge.enabled` | `true` | 电脑 Agent 桥接开关 |
| `agent.bridge.url` | `http://127.0.0.1:8765/agent/chat` | 桥接 HTTP 地址(与 Node 侧端口一致) |
| `agent.bridge.session-root` | `${user.home}/.weida/agent-sessions` | 会话根目录(Java / Node / 验证脚本三方一致) |
| `agent.bridge.timeout-seconds` | `600` | 单次任务超时(秒) |
| `git.gitee.token` | `${GITEE_API_TOKEN:}` | Gitee Token(环境变量,建议配合监控使用) |
| `git.github.token` | `${GITHUB_API_TOKEN:}` | GitHub Token(环境变量,可提升搜索限流) |
| `git.gitee.monitor-interval-ms` | `300000` | Gitee 监控轮询间隔(毫秒) |
| `git.github.ranking-cron` | `0 0 21 * * *` | 每天 21:00 推送 GitHub Star 排行 |
| `spring.mail.*` | `${MAIL_HOST:smtp.qq.com}` 等 | 邮件发送 SMTP(账号/授权码用环境变量占位,禁止提交真实凭证) |
| `mail.imap.*` | `${MAIL_IMAP_HOST:imap.qq.com}` 等 | 邮件接收 IMAP(仅读公用演示收件箱) |
| `ai.glm.*` | ModelScope GLM-5.2 端点 / 模型 | GLM 对话兜底(key 复用 `MODELSCOPE_API_KEY`) |
| `agent.max-tool-rounds` | `6` | 工具编排循环轮数上限(保护上限 30) |
| `skills.dir` | `skills` | Skill 技能目录(相对工作目录或绝对路径) |
| `context.ttl-minutes` | `60` | 会话热缓存惰性过期时间(分钟) |
| `context.history-window` | `10` | 送入模型的最近对话轮数(轮 = user + assistant 两条) |
| `context.persistence.path` | `${user.home}/.weida/sessions` | JSONL 冷归档目录(每用户一个文件,重启恢复) |
| `wechat.bot.enabled` | `true` | 微信机器人总开关(false 跳过 iLink 登录,测试/CI 隔离) |
| `amap.poi.enabled` | `true` | 高德 POI 周边搜索开关 |
完整配置见 `src/main/resources/application.properties`。
## 10. 测试与研发规范
```bash
mvn test # 单测 + checkstyle(validate 阶段强制)
```
- 核心覆盖:`ConversationMemoryTest` / `SessionPersistenceServiceTest`(记忆两级)、`ToolRunnerTest` / `UnifiedAdapterLayerTest` / `AiApiConfigTest`(工具与路由)、`UpdatePlanToolTest` / `UserPlanStoreTest`(计划)、`SkillLoaderTest` / `SkillParserTest` / `SkillToolTest`(技能)、`IntentParserTest`、`WechatBotServiceTest`、`RepositoryCommandParserTest` / `RepositoryStoreTest`
- `AmapWeatherServiceTest` 8/8;`AmapPoiServiceTest`(需 `WEATHER_API_KEY` 实调高德 4/4)
- 真机测试(`AgentOrchestratorLiveTest` 等)默认跳过,需 `-Dloop.live=true` 显式开启(烧真实 token)
- checkstyle 违规即构建失败;命名规则见 `AGENTS.md` 与 `checkstyle.xml`
- Git 流程:个人分支 `dev_<拼音>` → PR → `dev`(受保护)→ 测试 → PR → `main`(受保护)
## 11. 已知限制与 FAQ
- **记忆为「热缓存 + JSONL 冷归档」两级**:对话内容写入 `~/.weida/sessions`(每用户一个 JSONL,重启自动恢复);语音模式、任务计划快照、搜索缓存仍为纯内存,重启清空
- **Qwen / GLM 不支持 Function Calling**:`provider=qwen|glm` 时工具调用由路由自动降级到 DeepSeek;GLM 对话限流(429)自动切 Qwen
- **RAG 知识库规划中**:设计文档与任务拆分见 `docs/design/rag-design.md`,MySqlKnowledgeStore 规划复用 JDBC 数据源
- **机器人以文件形式发 MP3 语音**:iLink 平台不支持发原生语音条,微信中点开播放
- **微信消息可靠接收依赖心跳**:`ILinkClientConfig`(心跳 30s / 超时 35s / 重试 3 次)**禁止删除**;登录后不得调用预热 `getUpdates()`(会吞消息)
- **编码红线**:Windows PowerShell 5.1 的 `Get-Content/Set-Content -Encoding UTF8` 会写 BOM 并误读中文,禁止用于改写 Java 文件(PowerShell 7+ 原生 UTF-8 可用)
---
[AGENTS.md](AGENTS.md) — 开发规范(命名/包结构/Git 工作流/关键约束)