- 移除 GovAI, nomifun-tauri, 算力盒子 的 submodule 引用 - 添加所有子项目的完整源代码 - 保留原始 .git 为 .git.bak 备份
11 KiB
伙伴(Companions)
NomiFun 的数字伙伴从「单个 nomi」升级为多伙伴家庭:你可以创建多个伙伴并同时使用、分别培养、自定义名称/形象/人格,每个伙伴可以使用自己的聊天模型、绑定自己的专属知识库(演进出金融/文学/coding/情感等专业伙伴);而所有伙伴共享同一个记忆中枢——采集与学习是一条全局链路,任何一个伙伴学到的东西全家都记得。记忆、伙伴、知识库都可以打包成 .zip 导出/导入,换机平滑迁移。
入口是侧边栏的 桌面伙伴 页(即
/nomi路由);任意桌面伙伴窗口右键菜单的「打开聊天」也会深链到这里。
页面结构:伙伴切换条 + 双域 Tab
「桌面伙伴」页顶部是伙伴切换条:每个伙伴一张卡片(形象缩略图 + 名字 + 等级),加一个「新建伙伴」按钮。当前选中的伙伴驱动下面的伙伴域 Tab;与伙伴无关的全局数据归共享域 Tab:
| 域 | Tab | 内容 |
|---|---|---|
| 伙伴域(随切换条变化) | 总览 | 桌面伙伴开关 + 该伙伴的等级 / XP / mood + 共享统计 |
| 聊天 | 该伙伴自己的陪伴会话线程 | |
| 模型&知识 | 聊天模型选择 / 知识库绑定 | |
| 远程连接 | 该伙伴的 IM 机器人(按伙伴绑定,详见渠道指南) | |
| 设置 | 名称 / 形象 / 人格 / 勿扰 / 删除伙伴 | |
| 共享域(全局唯一) | 记忆 · 数据采集 · 学习 · 建议 | 共享记忆中枢(所有伙伴同一份) |
| 迁移 | 导出 / 导入迁移包(见下文) |
创建与管理多伙伴
- 点伙伴条上的新建伙伴,起个名字、挑一个形象(mochi / ink / roux / pixel / bolt / boo 六款)即可。
- 第一个伙伴自动成为默认伙伴(卡片带「默认」徽标)。默认伙伴是渠道未显式绑定时的回退对象(见下文渠道一节)。
- 在该伙伴的设置 Tab 里可以随时改名(即时生效)、换形象、调人格(预设或自定义)、为这个伙伴单独选聊天模型、开关桌面伙伴窗口与勿扰时段。
- 删除伙伴会级联清理:它的陪伴会话、运行时状态(XP 等)、
('companion', companionId)知识库绑定一并移除;若删的是默认伙伴,默认资格自动顺延给下一个。删除允许删到零个(共享记忆中枢独立于伙伴存在,采集/学习照常运行)。
每个伙伴在磁盘上是一个目录:{data_dir}/companion/companions/{companion_id}/config.json,目录即真相——这也是伙伴包导出/导入的单位。
多个桌面伙伴同屏
每个开启了桌面伙伴开关的伙伴拥有自己的桌面窗口(透明、置顶、可拖动,窗口 label 为 companion-{companionId})。多个可以同屏共处;建议同屏不超过 5 个(每个窗口是独立的 WebView 实例,开太多影响性能,UI 会提示但不硬限)。右键任意桌面伙伴窗口可直达它的聊天页。
共享记忆中枢
所有伙伴共用 {data_dir}/companion/shared/ 下的同一套记忆设施:
- 采集:单条链路订阅全局事件总线,按开关采集你的工作数据,写入
shared/events/YYYYMMDD.jsonl。 - 学习:单个学习器按设定间隔增量蒸馏事件为长期记忆,存入
shared/memory.db。学习链路使用共享配置里的学习模型(与每个伙伴的聊天模型相互独立,单链路单预算)。 - 任何一个伙伴聊天时保存的记忆、学习产出的记忆,对全体伙伴可见——换一个伙伴继续聊,它记得之前发生的一切。
XP 与 mood 的归属规则
| 来源 | 归属 |
|---|---|
| 学习 run 产出(按处理事件数 + 新记忆数计分) | 所有伙伴(家庭共同成长) |
| 建议被采纳(+20) | 所有伙伴 |
| 陪伴聊天轮次(+2) | 仅参与对话的那个伙伴 |
| 聊天中保存记忆(+5) | 仅该伙伴 |
mood 是全局的:由学习 run 产出、存共享状态,所有伙伴同一 mood(按伙伴分化的人格化 mood 留待后续版本)。
给伙伴绑定知识库
在伙伴的模型&知识 Tab → 知识库区域,用绑定控件为这个伙伴挂载一个或多个知识库(绑定关系为 ('companion', companionId))。生效范围:
- 该伙伴的陪伴聊天与它接待的渠道会话(会话上带
extra.companionId)都会挂载这个伙伴绑定的知识库——对话时可检索;不带 companionId 的普通会话维持原有的会话级绑定,二者不合并。 - agent 看到什么:库挂载到
{workspace}/.nomi/knowledge/,注入的上下文按库携带 描述 + AI 梗概 +「何时查阅」提示 + 按预算的目录(每库 20 条 / 全局 60 条,超出按目录聚合),外加一份显式检索协议——要求 agent 先查再答,而不是凭记忆作答。 - **回写(回血)**两种模式,简述如下:
- staged(暂存)——对话中产生的知识回写先落入知识库的
_inbox/(按会话隔离),由你在知识库页面审阅后入库; - direct(直写)——跳过暂存直接写入知识库正文。
- staged(暂存)——对话中产生的知识回写先落入知识库的
- AI 自动生成:知识库页面的「AI 生成」按钮(列表编辑 Modal 与详情页都有)调
POST /api/knowledge/bases/{id}/autogen,生成库的描述与README.md;.zip导入会自动补全空描述。需要已配置 AI Provider(否则返回409)。 - URL 知识源:创建知识库时可给出最多 16 条 URL。snapshot 模式在创建时抓取并把每页转为 markdown 落入库的
snapshots/(超过 32 KB 的页面由 AI 压缩),并自动生成梗概——详情页可刷新快照;live 模式留给 agent 运行期实时抓取(无网络工具的引擎可调网关工具nomi_knowledge_fetch_url)。仅接受公网http/httpsURL(SSRF 防护)。 - 伙伴也能自己养库:Desktop Gateway 提供 7 个知识工具(列表 / 绑定 / 建库 / 写文件 / AI 生成 / 抓取 URL),且伙伴系统提示里内置了「知识沉淀技巧」——陪伴或渠道聊天中它可以不经吩咐就建库并把心得沉淀进去。注意
nomi_knowledge_create_base带urls建库时,URL 抓取在后台异步执行——工具立即返回,agent 勿因快照尚未出现而重复建库;库描述(description)生成出来即代表抓取与梗概流水线已完成。
给不同的伙伴绑不同的库,就得到了「金融伙伴」「文学伙伴」「coding 伙伴」——人格、模型、知识三件套都按伙伴独立,记忆共享。
渠道绑定伙伴
每个 IM 平台(Telegram / Lark / 钉钉 / 微信)可以各绑一个伙伴来接待远程消息:打开该伙伴的 Remote tab(/nomi?companion=<id>&tab=remote),在那里连接或改绑 bot。未绑定渠道行时仍会读取旧的平台级偏好 assistant.{platform}.companionId 作为兼容回退。未绑定时回退默认伙伴;切换绑定会重置该渠道的活跃会话(下一条消息由新伙伴接待);被绑定的伙伴若被删除,自动回退默认伙伴并同样重置会话。详见 Channels 指南的「主 Agent 模式」一节。
companionId 不授予任何权限(记忆本就共享):它只决定 persona / 模型 / 知识库挂载,与授予网关工具的
desktopGateway标记性质不同。
导出 / 导入:换机迁移
共享域的迁移 Tab 提供三种 .zip 迁移包(仅桌面版提供迁移 UI;路径用系统对话框选取):
| 包 | 内容 | 导入语义 |
|---|---|---|
| 记忆包 | 全部长期记忆 + 学习历史 + mood;可选勾选包含原始事件数据 | 与本机记忆合并去重(保留原时间戳与来源) |
| 伙伴包 | 单个伙伴的人格 / 形象 / 设置 / XP + 它绑定的知识库名称清单(knowledge_refs) |
以新 id 创建新伙伴,名称冲突自动缀 "(2)";知识库引用按名称匹配本机已有库自动重建绑定,匹配不到的列出来提示你先导入对应知识库包再手动绑定 |
| 知识库包 | 知识库元数据 + md 文件树原样 | 新建知识库落地,名称冲突缀 "(2)" |
换机迁移步骤:
- 旧机:导出记忆包(按需勾选事件数据)→ 逐个导出伙伴包 → 逐库导出知识库包。
- 新机:先导入知识库包(让伙伴包的绑定重建能按名匹配上)→ 导入伙伴包 → 导入记忆包。
- 检查每个伙伴的模型设置:模型配置原样随包带走,但若新机没有配置对应 provider,会显示未配置,需在设置里重选。
隐私边界
events/*.jsonl是原始采集数据,包含你的工作内容原文——默认不导出,只有显式勾选「包含原始事件数据」才会进记忆包。- 聊天历史不随伙伴包迁移:陪伴会话记录存在主数据库里,伙伴包只带人格与设置。聊天记录留在原机。
旧版数据自动迁移
从单伙伴版本升级后,首次启动会自动检测旧布局 {data_dir}/companion/nomi/:若存在且尚无 companion/shared/,自动迁移为共享记忆中枢 + 第一个伙伴(默认名 "Nomi",继承原有 XP / 人格 / 形象 / 模型 / 桌面伙伴位置 / 陪伴会话线程)。迁移幂等可重入,完成后在旧目录写入 .migrated 标记并保留原目录(一个版本周期后清理)。无需任何手工操作。
手工走查清单
验证一套多伙伴部署是否健康,按序走一遍:
- 建两个伙伴:新建 A、B 两个伙伴,分别改名、换形象;确认第一个带「默认」徽标。
- 各绑一库:给 A 绑知识库 X、给 B 绑知识库 Y(伙伴模型&知识 Tab → 知识库)。
- 各自检索:分别在 A、B 的聊天里提问只在 X / Y 中存在的内容,确认 A 只命中 X、B 只命中 Y。
- 共享记忆互通:在 A 的聊天里让它记住一件事(保存记忆),切到 B 的聊天提问,确认 B 知道。
- 导出导入 roundtrip:导出记忆包 + A 的伙伴包 + 知识库 X 的包;(换机或清空后)按「知识库 → 伙伴 → 记忆」顺序导入,确认 A 重建后绑定自动恢复、记忆合并无重复。
- 渠道切换伙伴:在某个渠道平台把接待伙伴从 A 切到 B,确认活跃会话被重置、下一条远程消息由 B 的人格接待并挂 B 的知识库。
路由与 API
| 用途 | 位置 |
|---|---|
| 伙伴列表 / 创建 | GET/POST /api/companion/companions |
| 伙伴详情 / 修改 / 删除 | GET/PATCH/DELETE /api/companion/companions/{companionId} |
| 共享配置(采集 / 学习 / 默认伙伴) | GET/PATCH /api/companion/config |
| 每个伙伴的陪伴线程 | GET /api/companion/companions/{companionId}/companion/threads、…/companion/active |
| 导出记忆包 | POST /api/companion/export/memory({dest_path, include_events}) |
| 导出伙伴包 | POST /api/companion/export/companions/{companionId} |
| 导入记忆包 / 伙伴包 | POST /api/companion/import(按 manifest.kind 分发) |
| 导出 / 导入知识库包 | POST /api/knowledge/bases/{id}/export、POST /api/knowledge/bases/import |
| 渠道绑定伙伴 | POST /api/channel/settings/companion |