fish 假设的场景不是"一个 AI 的私人记忆库",而是很多 AI 共用的一个家:每个 AI 有自己的身份、自己的项目。
大模型没有记忆。市面上的"记忆工具"大多停在静态工具:模型想起来就调用,想不起来就等于不存在。
fish 的出发点相反——它假设 AI 不会想起来,所以把关键能力做成自动触发的机制:
部分能力:
【协作看板】 多个AI改一个项目时会自动“拉群”,系统自动推送其他AI的实时工作给AI参与方, 当写入冲突文件时,系统自动提醒AI规避风险;
【主动推送】 当有个项目的重要文件,项目内的其他AI经常读,但就某个AI不读,系统会自动推送给那个AI起到提醒作用; 如果提醒了还不看,这份文件对于它的权重就往下掉,直到系统不再推送,多 AI 权重独立计算;
【激活记忆】 保留AI可以通过查找获取到所需文件的能力,支持接入自己的知识库, 当你的AI在做某个风格的设计时,系统会自动从知识库中推送相关文档给对应来访AI,供他判断,不需要AI自己想起来才查找;
通过设备-宿主Agent-会话(hooks 发 token 给 MCP 服务识别)来判定为单个AI, 生活(我)、项目(工作)、知识库(素材库),三层独立构思, 记忆(权重管理)、推送(主动推送)、看板(AI协作),底层机制互相强化,
| 通道 | 能不能「强制」 | fish 的做法 |
|---|---|---|
| MCP tools | ❌ AI 不调就没有 | 常规查询(recall / inject / kb) |
| MCP resources | ⚠️ 宿主决定预加载 | 半强制(索引/状态) |
| 宿主 hooks | ✅ 事件驱动,必达 | 身份注入、动作采集、撞车提醒、提示词递记忆 |
一句话:MCP 是手,hook 是神经反射。fish 两条都长。
fish 不绑定单一宿主——主动能力走标准协议(MCP + 宿主 hooks),谁按协议接谁就有反射弧:
| Agent / 宿主 | 接入方式 | 状态 |
|---|---|---|
| DSH | hooks(Claude Code 方言)+ MCP | ✅ 已支持 |
| WorkBuddy / CodeBuddy | hooks(CodeBuddy 方言)+ MCP | ✅ 已支持 |
| Codex | hooks 适配层(patch_codex.py)+ MCP |
✅ 已支持 |
| ZCode | hooks(Claude Code 兼容方言)+ MCP | 🔬 已调研、待接入 |
| 未来的 agent | 实现 hooks 协议(7 事件子集)+ MCP client | 按协议接即可 |
为什么能做到:fish 把"主动"拆成协议而不是绑定某个产品——注入/采集/拦截只依赖事件与 JSON 字段,不依赖宿主的私有能力。接一个新宿主只需要一个方言适配层(事件映射 + matcher 契约 + 心跳验证),内核不用改。
📐 可交互架构图(缩放 / 拖拽 / 导出 / 深链):docs/diagrams/fish-architecture.html
flowchart TB
subgraph 接入层
H1[DSH / WorkBuddy / CodeBuddy hooks]
H2[MCP Server]
H3[CLI]
end
subgraph 服务层
S1[记忆:remember / recall / inject]
S2[身份:session / whoami / token]
S3[看板:checkin / 撞车 / 动态]
S4[知识库:vault / tree / read]
S5[推送:候选 / 时机 / 度量]
end
subgraph 认知层
C1[推送候选:规则 / 联想 / 态势 / 意外 / 提示词]
C2[收益 - 成本 决策]
C3[注入包:身份 / 坐标 / 规矩 / 注意 / 索引]
end
subgraph 数据层
D1[(events 不可变事件表)]
D2[(投影:code_index / FTS5 / links)]
D3[(组织:boards / presence / kb_vault)]
end
H1 --> 服务层
H2 --> 服务层
H3 --> 服务层
S1 --> D1 --> D2
S3 --> D3
S5 --> C1 --> C2 --> C3
D2 --> C3
一次工具调用的闭环(这是 fish 与"静态记忆工具"最大的差别):
sequenceDiagram participant U as 用户 participant H as 宿主 hooks participant F as fish participant D as SQLite U->>H: 提示词 H->>F: UserPromptSubmit(注入/递记忆) F-->>H: additionalContext(候选) H->>H: 模型决定写文件 H->>F: PreToolUse(撞车判定) F-->>H: ask / warn(同一占用面) H->>H: 工具执行 H->>F: PostToolUse(采集路径/动作) F->>D: tool_activity + 快照 H->>F: Stop / SessionStart(沉淀/入职) F-->>H: 注入包(我们是谁 + 最近 + 该注意)
| 能力 | 说明 |
|---|---|
| 事件溯源记忆 | 所有写入是 events 里不可变的事件;code_index / FTS5 / 关联边都是可重建投影。删投影不丢真相。 |
| 身份四维 | 设备 → 宿主 → 账号 → 会话公民;token 是唯一归属来源(machine / self-reported 分开标注)。 |
| 主动注入 | SessionStart 一次给全"我们是谁、我们在哪、这里的规矩、最近发生了什么、该注意什么"。 |
| 看板协作 | 数据库做真相 + Markdown 做渲染;「在场 / 在做什么 / 实际在动」三栏;撞车检测按会话身份键(同公民不同窗口也能区分)。 |
| 推送系统 | 候选池(规则/联想/态势/意外/看板/提示词)+「收益 − 成本」决策 + 度量回填。 |
| 知识库 | 已登记 vault 的只读树/读/检索;写入有备份、原子写、乐观锁、敏感面默认拒读。 |
| hooks 全景 | 动作采集(只记路径/摘要)、提示词递记忆、撞车三态(off/warn/ask)、身份锚(会话白名单)。 |
| 判据体系 | 每条判据先证明「改坏必红」(变异自证);三态分明(绿/跳/判不到)。 |
前置:Python 3.11+、SQLite(内置)。
git clone https://github.com/kinganyi/fish.git
cd fish
# 1) 初始化(建库 + 事件表 + 投影)
python p0/fish.py init
# 2) 签发会话凭证(绑定一个公民;token 就是你的身份)
python p0/fish.py session start --alias my-ai --project demo
# 3) 记一条
python p0/fish.py remember --project demo --title "今天想清楚的一件事" \
--body "..." --type fact --token <token>
# 4) 查
python p0/fish.py recall --query "想清楚" --token <token>
# 5) 生成注入包(L0 身份 + L1 状态 + 候选)
python p0/fish.py inject --budget 1800 --token <token>MCP 接入(AI 工具面):
{
"mcpServers": {
"fish": { "type": "stdio", "command": "python", "args": ["p0/mcp_server.py"] }
}
}hooks 接入(让 fish 获得"神经反射"):见 p0/hooks-运维说明.md(支持 DSH / WorkBuddy / CodeBuddy 方言;装完重启宿主,按说明复核心跳)。
p0/
├── fish.py # 主程序:事件/投影/身份/看板/推送/知识库/CLI(单文件,~18k 行)
├── mcp_server.py # MCP Server(18 个工具)
├── fish_activity.py # 动作采集/快照/撞车(hook 快路径,不 import fish)
├── fish_surface.py # 路径/占用面原语(唯一实现,fish 与 hook 共用)
├── fish_naming.py # 可读名(人类面永不含 ULID / 完整会话键)
├── fish_*hook.py # 宿主 hook 入口(SessionStart / UserPromptSubmit / PreToolUse / PostToolUse)
├── install_hooks.py # 两宿主 hooks 配置安装/校验/回滚(merge 语义)
├── kb_* / test_*.py # 知识库与 1149 条判据
└── hooks-运维说明.md # 事件表 / 重启 / 回滚 / 心跳 / 方言契约
测试:
cd p0 && python -m unittest discover -p "test_*.py"(1149 条)。 变异自证(判据有没有判别力):python mutation_session_rows.py等脚本,exit 0才算过。
- 事件不可变,投影可重建 —— 真相只在
events;任何派生结构坏了都能重建,删了也能长回来。 - 身份只有一处来源 —— token。
machine(宿主签发)与self-reported(AI 自报)分开标注,不混。 - 未登记 = 未发生 —— 看板/协作面只认登记与可观测事实;推断单独标注。
- 判据必须能失败 —— 每条关键判据配一个「把实现改坏」的变异体:基线绿 → 变异红 → 字节还原 → 复绿。
- 主动服务优先 —— 凡是「AI 想起来才做」的能力,都尽量补一条 hook 通道让它自动发生。
更多设计决策与取舍(含被否决的方案),见 docs/ARCHITECTURE.md。
- 判据:1149 条(
Ran 1149 tests — OK),覆盖记忆/身份/看板/推送/知识库/hooks。 - 变异自证:11 个变异体(会话维度修复)全部 CAUGHT;其余批次另有变异脚本。
- 数据:单机 SQLite(FTS5),无外部服务依赖。
- 活跃开发中;接口会随判据演进。
Apache-2.0(见 LICENSE),版权人:安逸(Copyright 2026 安逸)。
选它而不是 AGPL:我们要的是生态与商用友好(带专利授权);AGPL 会限制采用。
说明:本仓库从作者的生产工作区导出,代码与测试中保留了少量本机路径示例(如
I:\...),运行前请按你的环境调整;生产数据(记忆库/审计/备份)不在仓库内。