lingshu

agent
Guvenlik Denetimi
Uyari
Health Uyari
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Uyari
  • network request — Outbound network request in plugins/image-gen/helpers.mjs
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

本机运行的微信 AI 助手平台:中文控制台 + 插件系统 + 带艾宾浩斯遗忘曲线的记忆 + 联网搜索 + AI 绘图。零依赖,纯 Node.js。

README.md

灵枢 AI 中枢(LingShu Hub)

一个跑在你自己电脑上的微信 AI 助手平台。
自带中文控制台、插件系统、会像人一样遗忘的记忆、上下文自动压缩、联网搜索与 AI 绘图。
纯 Node.js,零第三方依赖,git clone 完就能跑。

node deps license platform 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. 工具轮次的兜底

带工具的小模型容易陷入"再查一下"的循环。灵枢做了三层保险:

  1. 工具描述里限定「一轮最多搜 2 次、最多读 2 页」
  2. 轮次用尽(默认 4 轮)→ 关掉工具强制模型作答
  3. 还是没输出 → 用工具结果兜底(列前三条标题+链接)

宁可给一份带链接的原始结果,也不让你收到空消息。


四、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

步骤

  1. 先装底层读写组件。 灵枢自己不会读微信、不会发微信。
    这两个服务属于第三方项目(不在本仓库),需要先在本机跑起来、
    并把要接的会话加进它自己的白名单。
    灵枢只跟它俩的 HTTP 接口说话,不关心它是怎么实现的。
  2. 控制台 →「微信设置」→ 填地址
    • Reader 地址:http://127.0.0.1:5031
    • Hook 地址:http://127.0.0.1:30001
    • 账号标识:形如 wxid_xxx_1234(留空自动读)
  3. 点「重新连接」,顶栏三个灯变绿:微信 / 推送 / 发送
  4. 「聊天」页搜索好友或群 → 添加 → 就能开始对话

关于白名单

读取器通常只轮询它自己授权的会话。你在灵枢里加了聊天,不代表读取器会推送。
添加聊天时灵枢会尝试同步(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 实在适配不了你电脑上现有的微信,别硬改,直接装这个版本:

👉 https://github.com/123456qwerty-666/lingshu/releases/download/wechat-4.1.10.27/WeChatWin_4.1.10.27.exe

项目 值
文件 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.)
  • 记忆、上下文、日志全部本地存储,没有云端同步

建议:

  1. 不要改 app.bind 为 0.0.0.0
  2. 不要把 data/config.json 发给别人
  3. 公开仓库前跑一遍 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 自己的回复也加了时间尾注,模型看到"我以前的输出都带时间",
就学会了在结尾也附一个 —— 典型的自我模仿。

三处一起修:

  1. 只给对方的消息加时间,不给 AI 自己的历史回复加(去掉模仿来源)
  2. 系统提示词里明确说明「(发送时间:…)是系统附加的元信息,不是对方说的话,回复时不要复述」
  3. 发出前兜底清理(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

MIT


灵枢 · 取其"中枢"之意 —— 把散落的模型、记忆与工具,接到一个自己完全掌控的地方。

Yorumlar (0)

Sonuc bulunamadi