lingshu
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Warn
- network request — Outbound network request in plugins/image-gen/helpers.mjs
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
本机运行的微信 AI 助手平台:中文控制台 + 插件系统 + 带艾宾浩斯遗忘曲线的记忆 + 联网搜索 + AI 绘图。零依赖,纯 Node.js。
灵枢 AI 中枢(LingShu Hub)
一个跑在你自己电脑上的微信 AI 助手平台。
自带中文控制台、插件系统、会像人一样遗忘的记忆、上下文自动压缩、联网搜索与 AI 绘图。
纯 Node.js,零第三方依赖,git clone完就能跑。
目录
- 一、这是什么
- 二、能做什么
- 三、特色功能详解
- 四、5 分钟跑起来
- 五、把部署交给 AI
- 六、接入微信
- 七、模型配置
- 八、控制台导览
- 九、插件系统
- 十、记忆系统
- 十一、常见问题
- 十二、技术栈与目录结构
- 十三、安全与隐私
- 十四、更新记录
- 十五、路线图
一、这是什么
灵枢是一个本地优先的 AI 中枢:它把「模型」「记忆」「工具」三样东西接到一个你能完全掌控的地方,
再通过一层很薄的适配,把这些能力接到微信上。
它不是一个"关键词回复机器人",而是:
- 有记忆的助手:记得你叫什么、养了几只猫、对什么过敏;也记得群里谁爱打羽毛球、谁在考研
- 会遗忘的助手:不重要的琐事几天就淡出,重要的事能记几个月——像真人,而不是一个只增不减的数据库
- 能上网的助手:需要最新信息时自己搜、自己读网页,并把来源链接给你
- 能干活的助手:画图、看图、搜资料、记事情,都能通过插件扩展
- 你能改的助手:零依赖、单文件前端、几百行的核心模块,任何地方看不顺眼都能直接改
一句话:你自己的 AI 员工,住在你自己的电脑里。
二、能做什么
💬 微信
- 自动接收私聊 / 群聊消息,按规则决定回不回
- 文本、图片、表情包、文件都能收;能看图说话
- 生成的图片自动发出去(不用模型再调一次发送工具)
- 群聊默认要
@机器人或带唤醒词才回,避免刷屏 - 每个聊天可以单独设置人设、语气、模型、插件、触发方式
🧠 记忆
- 每轮对话后自动提取「值得记住的事」,打标签、评重要度
- 三层记忆:会话记忆 / 群成员专属记忆 / 人物画像
- 艾宾浩斯遗忘曲线:琐碎 3 天淡忘、重要 1 个月、非常重要基本永久
- 被想起来就算"复习",越常聊越难忘
- 忘掉的进归档,随时能捞回来;也能手动"钉住"某条永不遗忘
- 后台可视化:强度进度条、最后回忆时间、手动增删改查
🎭 人格
- 内置「大肥鱼」——DeepSeek 那条蓝色鲸鱼娘:爱吃白饭(token 就是白饭)、爱摸鱼、傲娇但心软、自称"本鱼"
- 另有默认助手 / 毒舌老友 / 温柔陪伴
- 控制台一点即换,可全局也可单聊
- 配合记忆,能记住对方的名字、宠物、忌口,还会自己提起来
- 想加自己的?放一个
.mjs到personas/就行(见 docs/PERSONAS.md)
📉 上下文
- 按 512K 上下文设计,到 48K 自动滚动压缩
- 旧消息压成摘要(人物、事实、约定、未完成的事都保住)
- 压缩失败不会丢消息,原样保留
🌐 联网
- 搜索:Bing / 360 / 百度 三源自动降级
- 读取:任意网页正文提取(自动识别编码、剥导航广告)
- 抓不到就如实说抓不到,不编造
🤖 模型
- 任意 OpenAI 兼容端点:DeepSeek、OpenAI、Gemini 中转、各类代理、本地 vLLM / Ollama(OpenAI 兼容模式)
- 一键接入 DeepSeek:粘一个 API Key,自动写地址 → 拉模型 → 选 DeepSeek-V4.1-Flash 当对话模型
- 识图走同一个模型:V4.1-Flash 支持图片输入,收到的图 / 表情包都归它认;聊天模型不支持看图时会自动转成文字描述再喂进去
- 可配多个,主模型限流/报错时自动降级到备用
- 一键拉取模型列表,不用手抄模型名
- 图片生成模型单独配置,与对话模型互不干扰
🔌 插件
- 一个目录 + 两个文件就是一个插件
- 网页里新建、在线改代码、热重载
- 按聊天粒度决定用哪些插件
- 内置:绘图、识图、记忆、联网搜索
🎛 控制台
- 中文单页应用,无构建、无框架、无 CDN 依赖
- 概览 / 聊天 / 记忆 / AI 配置 / 微信设置 / 插件 / 日志 七个页面
- 实时日志流、「发送自检」一键跑通全链路
- SSE 事件计数、读取器状态、收发统计都能看到
三、特色功能详解
1. 会遗忘的记忆(核心)
传统机器人要么"没有记忆",要么"什么都记"——后者用不了多久,记忆库就会被寒暄和废话淹没,
检索被噪声带偏,提示词被塞爆。
灵枢的做法是把"该不该记"和"该不该忘"分成两件事:
| 谁决定 | 信号 | 作用 |
|---|---|---|
| 模型打标签 | 重要度 0~1 + 分类标签 | 决定"这条信息有多重要" |
| 遗忘曲线 | 时间 + 回忆次数 | 决定"现在还记得多清楚" |
留存率 R = e^(-Δt / S)
稳定性 S = 26h × e^(重要度 × 4.6) × (1 + ln(1+回忆次数) × 0.55)
| 重要度 | 三天后 | 一周后 | 一月后 | 结果 |
|---|---|---|---|---|
| 0.10 琐碎 | 17% | 1% | 0% | 约 1.5 天淡忘 |
| 0.50 一般 | 76% | 53% | 6% | 约 2 周淡忘 |
| 0.75 重要 | 91% | 80% | 40% | 约 1 个月淡忘 |
| 0.90 非常重要 | 96% | 90% | 64% | 3 个月还剩 27%,且永不自动遗忘 |
关键设计:每次记忆被检索命中,就算一次"复习"——计时器归零、稳定性提升、重要度微涨。
于是"天天聊到的事"越来越牢,"只提过一次的琐事"自然淡出。这就是间隔重复效应。
细节见 docs/MEMORY.md。
2. 群成员专属记忆
群聊里,每个发言的人都有自己的那份记忆:
scopes/[email protected]
├── chat[] 群里发生的事(约了周六爬山)
└── members/
├── wxid_A { memories: [程序员, 爱打羽毛球, 说话直], profile: "..." }
└── wxid_B { memories: [考研中, 压力大, 喜欢猫和奶茶], profile: "..." }
检索时会给"当前说话人"的记忆额外加权(+0.12),所以 A 问问题时优先想起 A 的事。
记忆攒够 10 条自动生成人物画像(性格 / 兴趣 / 相处方式)。
3. 上下文压缩
每轮开始前估算 token
→ 超过 compressAtTokens(48000) 就把「最近 14 条之外」的旧消息交出去
→ 模型合并「已有摘要 + 新增对话」得到新摘要
→ 摘要成功后才删旧消息(失败则原样保留)
→ 摘要作为 system 消息常驻
摘要特别保留「尚未完成的事」,所以"上次没答的问题"不会被忘掉。
4. 多提供商自动降级
主提供商 → 429/402/403/5xx/网络错误 → 自动换下一个
→ 记住"上次成功的那个",之后优先走它
→ 一条消息内多轮工具调用复用同一条链路
→ 全失败才回一句人话("额度限流了,过几分钟再试")
用免费额度/中转的朋友会特别喜欢这个:以前是一条消息报错,现在是"悄悄换条路继续答"。
5. 工具轮次的兜底
带工具的小模型容易陷入"再查一下"的循环。灵枢做了三层保险:
- 工具描述里限定「一轮最多搜 2 次、最多读 2 页」
- 轮次用尽(默认 4 轮)→ 关掉工具强制模型作答
- 还是没输出 → 用工具结果兜底(列前三条标题+链接)
宁可给一份带链接的原始结果,也不让你收到空消息。
四、5 分钟跑起来
⚠️ 先搞清楚:这是两部分,别装混了
很多人(和 AI Agent)第一步就搞错了,这里说死:
┌─ 灵枢 LingShu ──────────── 这个仓库 ─────────────┐
│ 记忆 · 人格 · 模型 · 插件 · 控制台 │
│ 它不知道微信长什么样,只会「说话」和「记事」 │
└──────────────┬───────────────────────────────────┘
│ 本机 HTTP 127.0.0.1:5031 / 30001
┌──────────────┴─── 第三方组件,不在本仓库 ─────────┐
│ WeChatAgent:读消息 · 发消息 · 登录微信 │
└──────────────────────────────────────────────────┘
所以:
- 只装灵枢:控制台、记忆、人格、插件、模型全部能用,也能自检、调工具,
但连不上微信 —— 因为没人帮它读消息、发消息。 - 要接微信:必须再装底层读写组件(见 六、接入微信),
装好、登录微信、把会话加进白名单,顶栏三个灯变绿才算通。
这不是缺陷,是设计。注入那部分是逆向的、锁微信版本的、法律上灰色的,
跟你的产品代码解耦,你只需维护干净的那半边。
环境
- Node.js ≥ 20(推荐 22,
node -v检查) - Windows / macOS / Linux 都行
- 不需要
npm install(零依赖)
三步启动
# 1. 取代码
git clone https://github.com/123456qwerty-666/lingshu.git
cd lingshu
# 2. 初始化(建目录、生成配置、体检)
node scripts/bootstrap.mjs
# 3. 启动
node server/index.mjs
Windows 也可以直接双击 start.cmd(会自动跑初始化);停止双击 stop.cmd。
到这一步你能打开 http://127.0.0.1:17890 用控制台,
但微信那三个灯还是红的 —— 因为还没装底层读写组件。接微信看下一节。
macOS / Linux:
./start.sh # 启动
./stop.sh # 停止
启动后终端会打印:
╔═══════════════════════════════════════════════╗
║ 灵枢 AI 中枢 LingShu Hub v0.4 ║
║ 控制台: http://127.0.0.1:17890 ║
║ 微信: ❌ 未连接 ║
╚═══════════════════════════════════════════════╝
浏览器打开 http://127.0.0.1:17890 就是控制台。
没接微信也能用:控制台、记忆、插件、联网搜索都正常,只是收不到真实微信消息。
五、把部署交给 AI
这一节是给"让 AI 帮你装"准备的。你可以把下面这段整段复制给任意 AI 助手(Claude / GPT / Cursor / CodeBuddy 等),
它按步骤就能装好。仓库里还有一份更完整的 AGENTS.md 供 AI 直接读取。
复制给 AI 的提示词
帮我在这台电脑上部署「灵枢 AI 中枢」(LingShu Hub)。
仓库:https://github.com/123456qwerty-666/lingshu
要求:
1. 检查 Node.js 版本是否 ≥ 20,不够就告诉我怎么装。
2. clone 仓库后执行 node scripts/bootstrap.mjs 初始化。
3. 启动 node server/index.mjs,确认 curl http://127.0.0.1:17890/api/health 返回 ok:true。
4. 用 /api/config 接口帮我配置 AI 提供商(Base URL + API Key 我会给你),
然后用 /api/ai/models/refresh 拉模型列表,再用 /api/ai/test 验证连通。
5. 完成后把控制台地址、当前默认模型、以及还缺什么告诉我。
注意:
- 不要 npm install(这个项目零依赖)
- 不要把 API Key 写进任何会被提交的文件
- data/ 目录是运行时数据,不要提交到 git
AI 需要知道的关键事实
| 项目 | 值 |
|---|---|
| 启动命令 | node server/index.mjs |
| 初始化 | node scripts/bootstrap.mjs(幂等) |
| 端口 | 127.0.0.1:17890 |
| 健康检查 | GET /api/health |
| 配置接口 | POST /api/config(局部深度合并) |
| 冒烟测试 | POST /api/debug/send |
| 数据目录 | data/(不提交) |
| 依赖 | 无 |
| 验证命令 | npm run check(语法检查) |
AI 部署的典型流程
1. 体检 node -v;端口 17890 是否占用
2. 取代码 git clone … && cd lingshu
3. 初始化 node scripts/bootstrap.mjs
4. 起服务 node server/index.mjs(后台/前台皆可)
5. 配模型 POST /api/config → POST /api/ai/models/refresh → POST /api/ai/test
6. 建聊天 POST /api/chats/add(没有微信时用占位 talker)
7. 冒烟 POST /api/debug/send → 看 /api/logs
8. 交付 控制台地址 + 默认模型 + 待办(接微信 / 补 Key)
常见坑(AI 容易踩)
- 不要
npm install:没有依赖,装了反而多一个 node_modules - 不要手改
data/config.json里的密钥后提交 git - 不要把
app.bind改成0.0.0.0:会把聊天记录和密钥暴露到局域网 - 不要用「文件传输助手」测收消息:你发给自己的消息在数据库里是"已发送",读取器会丢弃
- 端口被占用:先
stop.cmd/./stop.sh,或改app.port
更细的部署手册见 docs/DEPLOY-AI.md。
六、接入微信
不想手动一步步来? 完整安装流程(含底层组件下载、微信版本核对、白名单、
失败排查)写在 docs/AGENT-GUIDE.md 第 6.0 节,
照着做就行,也可以直接把那一节丢给你的 AI 让它执行。
灵枢不注入微信进程、不修改客户端。它对接两个本机 HTTP 服务:
微信客户端 ←→ Reader(5031) 读会话 / 读消息 / 取图片 / SSE 实时推送
←→ Hook(30001) 发文本 / 发图片 / 发文件
↕
灵枢 server
步骤
- 先装底层读写组件。 灵枢自己不会读微信、不会发微信。
这两个服务属于第三方项目(不在本仓库),需要先在本机跑起来、
并把要接的会话加进它自己的白名单。
灵枢只跟它俩的 HTTP 接口说话,不关心它是怎么实现的。 - 控制台 →「微信设置」→ 填地址
- Reader 地址:
http://127.0.0.1:5031 - Hook 地址:
http://127.0.0.1:30001 - 账号标识:形如
wxid_xxx_1234(留空自动读)
- Reader 地址:
- 点「重新连接」,顶栏三个灯变绿:微信 / 推送 / 发送
- 「聊天」页搜索好友或群 → 添加 → 就能开始对话
关于白名单
读取器通常只轮询它自己授权的会话。你在灵枢里加了聊天,不代表读取器会推送。
添加聊天时灵枢会尝试同步(server/agent-bridge.mjs),但它只认特定项目的配置格式;
用别的读取器时需要你在读取器那边也授权这个会话。
判断方法:看日志里有没有 收到 [sse] xxx: ...,或看 /api/health 里 reader.pushed 是否在涨。
触发规则
| 模式 | 行为 |
|---|---|
smart(默认) |
私聊全回;群聊需 @机器人名 或含唤醒词 |
mention |
只有 @ / 唤醒词才回 |
prefix |
消息必须以唤醒词开头 |
all |
全部消息都回(群里慎用) |
off |
不自动回,只保留手动发送与自检 |
单个聊天可以在「聊天」页右侧覆盖这个设置。
三个必踩的坑
| 坑 | 现象 | 解法 |
|---|---|---|
| 只推白名单会话 | 日志一条 收到 [sse] 都没有,pushed 恒为 0 |
在读取器那边授权该会话 |
| 发文件有暂存区沙箱 | 发图返回 400 {"ret":1} |
文件必须落在 hook 模块目录旁的 state/files/outgoing/<64位hex>/,且 md5/size 完全匹配(灵枢已自动处理) |
| 文件传输助手收不到 | 发给自己没反应 | 自发消息会被读取器丢弃,改用联系人/群测试 |
完整契约与排查见 docs/WECHAT.md。
七、模型配置
灵枢只要求提供商是 OpenAI 兼容协议(/v1/chat/completions、/v1/models、/v1/images/generations)。
所以几乎所有服务都能接。
7.1 添加一个对话模型(控制台)
AI 配置 → + 添加提供商
| 字段 | 说明 | 例子 |
|---|---|---|
| ID | 英文标识,你自己定 | deepseek |
| 显示名称 | 好看的名字 | DeepSeek |
| Base URL | 兼容端点根地址,带不带 /v1 都行 |
https://api.deepseek.com |
| API Key | 你的密钥(保存后回显为 sk-xxx***) |
sk-... |
保存后点该卡片的 「刷新模型」,灵枢会请求 GET /v1/models 把模型列表写进配置——
不用手动抄模型名。然后「测试」验证连通,最后在上方选默认提供商 + 默认模型。
7.2 添加一个对话模型(命令行)
# 1) 写入提供商
curl -X POST http://127.0.0.1:17890/api/config -H 'Content-Type: application/json' -d '{
"ai": {
"providers": {
"my-gpt": {
"name": "我的中转",
"baseUrl": "https://api.example.com/v1",
"apiKey": "sk-你的key",
"models": []
}
}
}
}'
# 2) 拉模型列表
curl -X POST http://127.0.0.1:17890/api/ai/models/refresh \
-H 'Content-Type: application/json' -d '{"providerId":"my-gpt"}'
# 3) 设为默认(model 从上一步结果里挑)
curl -X POST http://127.0.0.1:17890/api/config -H 'Content-Type: application/json' \
-d '{"ai":{"defaultProvider":"my-gpt","defaultModel":"gpt-4o-mini"}}'
# 4) 验证
curl -X POST http://127.0.0.1:17890/api/ai/test -H 'Content-Type: application/json' \
-d '{"providerId":"my-gpt","model":"gpt-4o-mini","prompt":"只回答两个字:正常"}'
7.3 接入图片生成模型
绘图走的是 /v1/images/generations,和对话模型分开配置,可以是不同的提供商。
控制台:「AI 配置 → 添加提供商」,填好 Base URL 和 Key 后点「刷新模型」,
列表里带 🎨 标记的就是被识别为绘图模型的;如果自动识别不准,可以直接写进配置:
curl -X POST http://127.0.0.1:17890/api/config -H 'Content-Type: application/json' -d '{
"ai": {
"providers": {
"my-image": {
"name": "绘图服务",
"baseUrl": "https://api.example.com/v1",
"apiKey": "sk-你的key",
"models": [
{ "id": "flux-1.1-pro", "name": "FLUX 1.1 Pro", "imageGen": true },
{ "id": "gpt-image-1", "name": "GPT Image 1", "imageGen": true }
]
}
}
}
}'
要点:
imageGen: true是给灵枢看的标记,用于自动挑选绘图提供商(/v1/models里带image字样的也会被识别)- 灵枢会自动选择第一个带绘图模型的提供商,不需要额外设置
- 绘图接口常见限制:
n只能是 1、返回 URL 而不是 base64、耗时 10~20 秒——灵枢都处理了 - 免费额度常 429,灵枢会自动等 4s / 8s 重试 3 次
配置好之后,在微信里说「帮我画一只戴墨镜的柴犬」,模型会调用 generate_image,
生成的图自动发到当前聊天,你什么都不用做。
7.4 多提供商降级(强烈建议配)
curl -X POST http://127.0.0.1:17890/api/config -H 'Content-Type: application/json' \
-d '{"ai":{"defaultProvider":"deepseek","fallbackProviders":["gemini-proxy"]}}'
行为:主提供商返回 429 / 402 / 403 / 5xx / 网络错误 → 自动换下一个;
并记住"上次成功的那个",后续优先走它,避免每条消息都先撞一次限流。
日志里会写 已自动切换到 xxx。
7.5 常用参数
| 参数 | 位置 | 说明 |
|---|---|---|
defaultProvider |
ai |
默认提供商 id |
defaultModel |
ai |
默认模型 id |
fallbackProviders |
ai |
降级顺序(留空则自动尝试其它所有) |
providers.<id>.baseUrl |
ai |
兼容端点(带不带 /v1 都行) |
providers.<id>.apiKey |
ai |
密钥(也可用 apiKeyEnv 指向环境变量) |
providers.<id>.models[] |
ai |
{id, name, multimodal, imageGen} |
| 单聊模型 | chats.<talker>.model |
覆盖全局,{providerId, modelId} |
| 温度 / 长度 | 代码内 | server/index.mjs 的 temperature / maxTokens |
密钥安全:也可以
POST /api/config/secret用 Windows DPAPI 加密后存到data/secrets/,
配置文件里就不出现明文。
八、控制台导览
| 页面 | 能干什么 |
|---|---|
| 概览 | 连接状态、收发统计、插件数、聊天数、最近日志、发送自检 |
| 聊天 | 搜索/添加聊天、看历史、手动发消息、右侧单聊设置(模型/插件/人设/语气/触发/记忆/压缩) |
| 记忆 | 会话记忆 / 群成员记忆 / 归档三个 tab,强度进度条、编辑、钉住、搜索、预演遗忘、压缩、重建画像 |
| AI 配置 | 默认模型、提供商增删改、刷新模型、连通测试 |
| 微信设置 | 地址、账号、触发规则、唤醒词、回复策略、人设、读取器白名单 |
| 插件 | 启停、在线改代码、热重载、新建脚手架、查看工具清单 |
| 日志 | 历史日志 + SSE 实时流 |
深链接:#chats #memory #ai #logs,记忆页支持 ?talker=xxx&tab=members&member=yyy。
九、插件系统
一个插件就是一个目录:
plugins/my-plugin/
├── plugin.json # 元信息
└── index.mjs # export function setup(ctx) { return { tools: [...] } }
export function setup(ctx) {
return {
tools: [{
name: 'weather',
description: '查天气。参数:city',
parameters: {
type: 'object',
properties: { city: { type: 'string' } },
required: ['city'],
},
async run(args, runtime) {
// runtime 里有当前聊天上下文
return { city: args.city, temp: 26 };
},
}],
};
}
runtime里有talker/kind/senderWxid/senderName- 返回
{ path: 'xxx.png' }会被自动发到当前聊天 - 返回
{ success: false, error, hint },hint会指导模型怎么跟用户解释 - 写完点「重载插件」立即生效,不用重启
内置插件:
| 插件 | 工具 | 说明 |
|---|---|---|
image-gen |
generate_image |
AI 绘图,出图自动发送 |
vision |
describe_image |
来信图片解析 |
memory |
remember / recall / list_memories / forget |
记忆读写 |
web-search |
web_search / fetch_url |
联网搜索 + 读网页正文 |
详见 docs/PLUGINS.md。
十、记忆系统
完整设计见 docs/MEMORY.md。这里只列要点。
一条记忆
{
"kind": "preference",
"text": "对芒果过敏,需避免含芒果的食物",
"tags": ["健康", "过敏"],
"importance": 0.9,
"label": "非常重要",
"lastAccessAt": 1793530000000,
"accessCount": 2,
"pinned": false
}
自动打标签
每轮回复后异步调用一次小模型:
{
"importance": 0.9,
"label": "非常重要",
"tags": ["健康", "过敏"],
"items": [{ "kind": "preference", "text": "对芒果过敏", "importance": 0.9 }]
}
- 只记用户说的,不记 AI 自己说的
- 关于"这个人"的 → 成员记忆;关于"这里发生的事" → 会话记忆
- 同桶相似度 > 0.82 合并,跨桶也查一遍,不会存两份
检索打分
score = 关键词命中×0.45 + 留存率×0.25 + 重要度×0.20 + 新近度×0.10 + 同人加成×0.12
中文用字符二元组匹配,不需要向量数据库。命中即"复习"。
后台管理
- 每条记忆都有:标签、重要度、记忆强度进度条、存在时长、上次回忆时间
- 可钉住(永不遗忘)、编辑、忘掉(进归档)、从归档捞回
- 可「预演遗忘」看会忘哪些,再决定是否执行
- 可按关键词检索,看模型此刻会想起什么
十一、常见问题
Q:一定要有微信吗?
不。没接微信也能用控制台、自检、插件、记忆、搜索,只是收不到真实消息。
Q:AI 回复结尾会自带一串时间,怎么去掉?
已经修了(v0.4.2)。原因是给历史消息里 AI 自己的回复也加了时间尾注,
模型看到"我以前的输出都带时间"就学会了在结尾也附一个 —— 自我模仿。
现在的处理:只给对方的消息加时间 + 系统提示词里说明那是元信息、不要复述
- 发出前兜底清理。如果你自己改动后复发,检查
router.buildMessages()里
是不是又给role === 'assistant'的消息加了messageStamp。
Q:仓库里是不是只有个前端配置页面?能不能真的接微信?
不是,仓库里有 4500+ 行服务端代码(记忆引擎、人格、模型降级、插件、上下文压缩、
微信对接层),控制台只是其中一个文件。它能真的接微信 —— 但要分两步:
- 灵枢(本仓库)= 大脑,负责记忆/人格/模型/插件
- 读写组件(第三方,不在本仓库)= 手脚,负责真正读微信、发微信
只装灵枢能跑控制台和记忆,但连不上微信;装上底层组件并对接好才能收发消息。
详见 四、5 分钟跑起来 开头的说明。
Q:是模拟键鼠吗?会不会抢我的鼠标?
不是,而且完全不碰键鼠。 分两层看:
- 灵枢自己:就是一个本地 HTTP 服务,把要发的内容 POST 给本机接口(
127.0.0.1:30001)。
不注入微信、不改客户端、不碰键盘鼠标、不动剪贴板。 - 底层发送组件:是注入到微信进程里的 DLL,直接调用微信自己的内部函数发消息
—— 相当于在程序内部按了下按钮,而不是在屏幕上模拟点击。
所以:
- 不抢鼠标、不抢键盘、不抢输入焦点
- 不会冒出一个窗口自己在那儿动
- 微信可以最小化、可以在后台,你该打字打字、该用鼠标用鼠标,互不干扰
一句话:它是「程序内部直接调用」,不是「屏幕上的机器人手」。
需要说清楚的另一面:注入这种方式技术上比键鼠模拟更底层,
风险主要来自第三方组件(灵枢自身不注入)。见上一个问题。
Q:会不会封号?
本项目不注入微信进程、不改客户端。风险来自第三方组件和使用频率,请自行评估、小号试水。
Q:数据传到哪去了?
你的电脑。配置、上下文、记忆全在 data/ 里;只有模型调用和搜索请求会出网。
Q:为什么每轮多一次模型调用?
记忆打标签需要。不想付这个成本就设 memory.autoTag = false,只保留模型主动 remember。
Q:能跑本地模型吗?
能。任何 OpenAI 兼容服务都行(如 vLLM / Ollama 的 OpenAI 兼容模式),Base URL 填本地地址即可。
Q:能同时接多个微信号吗?
当前是单账号设计。多账号需要改造 wechat.mjs 的账号头与路由。
Q:记忆会不会越存越多?
会,但有上限与压缩:超过 maxChatMemories 就把低重要度的合并成摘要,遗忘曲线也会持续清理。
Q:为什么群聊里它不理我?
默认 smart 模式,群里需要 @机器人名 或包含唤醒词(默认 AI / 灵枢 / bot)。
可以在「微信设置」里改唤醒词,或给这个群单独设成「全部消息」。
Q:限定微信版本吗?换最新版的电脑微信能用吗?
分两层看:
- 灵枢本身不挑版本。 它不碰微信进程,只跟本机两个 HTTP 服务说话(读取消息
5031、发消息30001)。 - 卡版本的是底层的注入组件(WeChatAgent)。 它靠微信内部的内存偏移和函数表工作
(比如文件消息的工厂地址0x1C4CE70),微信一升级这些地址就变了,所以版本必须严格对上。
当前这版匹配 Windows x64 微信 4.1.10.27。
所以:
- 换成别的微信版本 → 注入对不上,消息读不到也发不出;
- 用安装包自带的那份匹配微信即可,装完记得关掉微信自动更新,否则哪天自动升级就失效;
- 等上游注入组件适配了新版微信,跟着升就行;
- 目前只支持 Windows x64,macOS 不行。
一句话:限定的不是灵枢,是它下面那层注入组件;微信版本跟着那个组件走。
Q:那我让我自己的 AI Agent 改一下,适配我的微信版本行不行?
分两半:
- 灵枢这一层随便改 —— 全是 Node.js 源码,对接地址、token、推送字段解析都是配置化的,
AI Agent 接一套新的读取/发送组件没问题。 - 卡住的是 Hook DLL 的内存偏移 —— 偏移硬编码在 C++ 源码里(如
g_hWeixinDll + 0xDE4C33),
且xwechat_offsets.h目前是空的,没有多版本偏移表。微信升级后这些地址就失效。
难点不是改代码,是拿到新版本的偏移,那需要逆向(x64dbg / IDA),不是读文本能得出的。
源码可以重编译(MSBuild),但前提是你已经逆向出偏移。
兜底方案:直接装配套版本的微信
如果 AI Agent 实在适配不了你电脑上现有的微信,别硬改,直接装这个版本:
| 项目 | 值 |
|---|---|
| 文件 | WeChatWin_4.1.10.27.exe |
| 大小 | 239,441,904 字节(228.3 MB) |
| SHA256 | 54203FC2B41983FA106B0AF0D67F86BEFC56CCD3DC1005D4BAB6DE8EA36B4F74 |
这是腾讯官方公开的微信电脑版安装包,仅为配套方便而镜像,版权归腾讯所有。
⚠️ 装完一定要关掉微信自动更新。 不关的话,微信哪天后台静默升级,整套链路会毫无预兆地失效。
- 微信左下角「三」→ 设置 → 通用,关掉自动更新相关选项
- 更稳妥:把微信安装目录设为只读,或直接掐掉
Weixin.exe的更新通道
(这条是本项目的头号"事后翻车"原因:不是装的时候坏了,是过几天微信自己升级了。)
现实路径:① 用上面的安装包装配套微信 / 等上游适配(最省事)→
② 社区有对应版本的 version.dll 就直接换,改一下 expectedVersion,一行代码都不用动 →
③ 自己逆向出偏移再重编译。详见 docs/WECHAT.md 第"零之二"节。
Q:前端能改吗?
能,就一个 public/index.html,原生 JS,没有构建步骤,改完刷新即可。
十二、技术栈与目录结构
技术栈:Node.js(ESM)+ 原生 HTTP + 原生 Fetch + 原生 DOM。没有框架、没有构建、没有依赖。
lingshu/
├── server/
│ ├── index.mjs # HTTP 服务 + API + 消息处理主流程
│ ├── config.mjs # 配置(原子写、BOM 容错、DPAPI 密钥)
│ ├── wechat.mjs # 读取器/发送器适配、SSE 长连接、文件暂存
│ ├── router.mjs # 事件解析、触发判断、上下文与摘要注入
│ ├── ai.mjs # OpenAI 兼容客户端(多提供商降级、工具循环)
│ ├── memory.mjs # 记忆引擎(遗忘曲线、打标签、压缩、画像)
│ ├── compressor.mjs # 上下文滚动压缩
│ ├── personas.mjs # 预设人格加载
│ ├── plugins.mjs # 插件主机(加载/调用/热重载/脚手架)
│ └── agent-bridge.mjs # 与读取器的会话白名单同步(可选)
├── personas/ # 预设人格(大肥鱼 / 默认 / 毒舌 / 温柔)
├── plugins/ # 内置插件
│ ├── image-gen/ # AI 绘图
│ ├── vision/ # 图片理解
│ ├── memory/ # 记忆工具
│ └── web-search/ # 联网搜索 + 网页读取
├── public/index.html # 控制台(单文件)
├── scripts/bootstrap.mjs# 初始化
├── docs/ # 详细文档
├── data/ # 运行时数据(gitignore)
└── config.example.json # 配置样例
模块规模:核心后端约 4000 行,前端单文件约 1400 行。
文档索引:
| 文档 | 内容 |
|---|---|
| docs/AGENT-GUIDE.md | AI Agent 完整执行手册:环境检测 → 部署 → 接模型 → 接微信 → 插件 → 交付,逐条命令 |
| docs/DEPLOY-AI.md | 可以直接复制给 AI 的部署提示词 |
| docs/TROUBLESHOOTING.md | 错误大全:现象 → 根因 → 验证命令 → 修复 |
| docs/PLUGINS.md | 插件安装(4 种方式)/ 开发接口 / 3 个实战 / 调试 / 分享 |
| docs/PERSONAS.md | 预设人格:大肥鱼怎么写的、怎么加自己的人格 |
| docs/ARCHITECTURE.md | 架构、消息流水线、设计取舍 |
| docs/MEMORY.md | 记忆系统完整设计(公式、参数、调参) |
| docs/API.md | HTTP API 全量清单 |
| docs/WECHAT.md | 微信接入契约与排障 |
| AGENTS.md | 供 AI 代理直接读取的速查 + 导航 |
| docs/PROMO-DOUYIN.md | 中文社区推广文案(视频脚本 / 标题 / 简介) |
十三、安全与隐私
- 服务默认只监听
127.0.0.1,局域网/公网访问不到 data/已在.gitignore,密钥、聊天记录、记忆不会被提交- 配置接口返回的 Key 一律打码(
sk-xxx***),回传打码值不会覆盖真实 Key - 支持用 Windows DPAPI 把密钥加密存到
data/secrets/ - 网页读取会拒绝内网地址(
localhost/10./192.168./172.16-31.) - 记忆、上下文、日志全部本地存储,没有云端同步
建议:
- 不要改
app.bind为0.0.0.0 - 不要把
data/config.json发给别人 - 公开仓库前跑一遍
git status确认没有data/
十四、更新记录
v0.4.2(本次新增:时间感知)
AI 现在知道"什么时候"了。 之前模型是"无时间感"的:它分不清「昨天说的」和「三个月前说的」,
听到「明天」「下周三」也只能含糊带过。现在补上了:
对话时间
- 系统提示词里常驻一行「【当前时间】2026-11-02 11:47:42 周一」
- 每条上下文消息后面都带上它真实的发送时间:
(发送时间:2026-11-02 11:47:42 周一) - 存上下文时同时记下
ts,所以翻旧账也能对上时间
实测:问它「现在几点了?今天星期几」→ 准确回答「2026 年 11 月 2 日 11 点 47 分,星期一」。
记忆时间
- 每条记忆新增
occurredAt(这件事发生在什么时候),和createdAt(什么时候存进来的)分开 - 注入给模型的记忆会带上时间:
- 名字叫阿海(2026-11-02 11:41 周一 · 3天前) - 打标签时把「当前时间」也喂给模型,并要求它把相对时间换算成具体日期再存:
对方说「明天要体检」,存下来的是「11月3日(周二)要去体检」,而不是过几天就没法看的「明天」 - 后台记忆卡片显示「🕒 2026-11-02 11:41 周一 · 3天前」,归档条目也显示发生时间
新增模块 server/time.mjs(formatTime / relativeTime / timeLabel / nowBlock)。
顺带修掉「回复结尾自带时间」
加完上面这版后发现 AI 有时会在回复末尾附上时间。原因查清楚了:
一开始我给历史消息里 AI 自己的回复也加了时间尾注,模型看到"我以前的输出都带时间",
就学会了在结尾也附一个 —— 典型的自我模仿。
三处一起修:
- 只给对方的消息加时间,不给 AI 自己的历史回复加(去掉模仿来源)
- 系统提示词里明确说明「(发送时间:…)是系统附加的元信息,不是对方说的话,回复时不要复述」
- 发出前兜底清理(
stripTimeEcho)—— 只删明确是时间戳的东西,
不动"下午 3:30 开会""11月3日(周二)"这类正常内容。
v0.4.1(优化)
修掉的 bug
- 控制台「自动压缩上下文」开关默认读的是聊天自己的覆盖值,没设过时显示成「关」,一保存就把阈值写成
0,
等于悄悄关掉了自动压缩。现在用「生效值」显示,并已把被写成0的聊天修正回 48000。 - 日志实时流每来一条就把整个列表替换掉,只能看到最后一条。改成追加缓冲 + 关键字/级别过滤。
willCompress在阈值0(已关闭)时误报true。- 记忆「捞回来」靠昵称匹配成员,容易串桶。归档时现在记下归属,捞回必定回原桶。
- 模型下拉在切换提供商后丢失已选模型;配置里已保存但不在列表里的模型会被下拉框清掉。
- 记忆检索在「一个关键词都没命中」时仍按低门槛硬塞一屏记忆。
- 后台展示的记忆强度用的是全局衰减参数,和实际遗忘行为对不上,改用该聊天自己的参数。
- 内置插件的代码弹窗仍给「保存」按钮,点了必失败 —— 现在标成「内置只读」并禁用保存。
体验与能力
- 控制台整体重新设计:状态胶囊、统计大数字卡片、进度条、滚动条、弹窗与 toast 全部重做。
- 新增「整理重复记忆」:同一件事的不同说法(「16 岁,读初三」/「今年16岁,正在读初三」)会被合并成一条。
- 新增「清空会话记忆」(先进归档,可捞回)。
- 上下文摘要可以直接在后台编辑并保存。
- 记忆列表钉住的排前面,标签显示来源(手动 / 压缩摘要)。
- 插件卡片显示「降级」标记;日志页支持级别与关键字过滤。
- 记忆重复判定阈值 0.82 → 0.7,避免同一事实被反复存成多条。
- 默认每轮召回量 8+6 → 6+4,不再一开口就注入十几条记忆。
十五、路线图
- 语音消息转写(读取器已有语音接口)
- 群聊真 @ 发送者(需要原生 mention 能力)
- 插件市场:从 URL 一键安装插件
- 记忆的向量检索层(可选,接口已预留)
- 多账号支持
- 开机自启 / 守护进程
免责声明
- 本项目仅供个人学习与研究,请遵守微信用户协议及当地法律法规。
- 请勿用于批量营销、骚扰、诈骗等用途。
- 使用第三方微信工具产生的风险由使用者自行承担。
- 仓库内不含任何账号、密钥或聊天数据。
License
灵枢 · 取其"中枢"之意 —— 把散落的模型、记忆与工具,接到一个自己完全掌控的地方。
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found