跳转到内容

Learn Journal 设计哲学

高级

内容验证于 2026-06-24

本教程属于学习路径: · 浏览全部路径
前置要求:

前面两篇讲了 Learn Journal 是什么、怎么用。这篇讲的是为什么这样设计——每个设计决策背后的 trade-off,包括这些决策的代价和尚未解决的问题。

如果你只是想用 Learn Journal,不需要读这篇。但如果你想理解“怎么设计一个 AI 驱动的工具”,或者你想做类似的项目,或者你想评估这套方案的可行性,这篇会有帮助。

第二轮重构的最大变更是引入双层架构——概率层和确定性层的明确分离。

早期设计是纯协议驱动:所有行为都写在 markdown 规则里,由 AI 执行。问题是:

  • AI 可能忘记规则(上下文窗口竞争)
  • AI 可能理解偏(同一段协议,不同模型执行不同)
  • AI 的行为不可复现(同样的输入,不同 session 可能不同输出)
  • 用户无法验证“AI 是否真的在遵循协议”

这意味着:系统的核心价值(结构化记录)建立在一个不可靠的基础上。

概率层(AI 协议) — 负责“体验好”的部分:引导对话、判断时机、追问 why、六步讲解、工件路由。这些事情 AI 做得比脚本好,但不保证每次都做对。

确定性层(shell 脚本) — 负责“可靠”的部分:格式验证(lint-notes.sh)、数据统计(stats.sh)、健康检查(health-check.sh)、导出(export.sh)。这些事情脚本做得比 AI 好——输出确定、可复现、不依赖模型。

设计目标:即使概率层完全失效(AI 不遵循协议、换了不兼容的模型、上下文窗口不够),用户仍然可以:

  • 手动复制模板填写笔记
  • 运行 lint-notes.sh 检查格式
  • 运行 stats.sh 查看客观指标
  • 运行 health-check.sh 确认系统状态

概率层是锦上添花,确定性层是底线保障。这个设计决策的代价是:需要维护两套逻辑(协议 + 脚本),且两者可能不一致。

Learn Journal 的 AI 行为不是写在代码里的 if-else,而是写在 markdown 文件里的自然语言规则。

类比:法律条文 vs 程序代码。法律用自然语言写,任何人都能读懂、修改、质疑。Learn Journal 的协议文件就像“AI 的法律”——你打开 protocols/core.md,能直接看到 AI 遵循的规则,觉得不对可以直接改。

优势

  • 可修改:用户不需要会编程就能调整 AI 的行为
  • 可审计:AI 做了奇怪的事,你可以对照协议文件检查
  • 可分发:一个 markdown 文件比一个 npm 包容易分发得多
  • AI 原生理解:大语言模型天生擅长理解自然语言指令

代价

  • 没有类型检查,AI 可能“理解偏了”——同一段协议,不同模型的执行一致性不保证
  • 协议越长,AI 遵循的可靠性越低(上下文窗口竞争)
  • 用户修改协议后可能破坏系统行为,没有编译器帮你检查
  • 版本管理困难:协议文件更新后,AI 的行为变化不可预测

应对方式:确定性层兜底。协议驱动本质上是用“灵活性”换“确定性”,双层架构让你两者都有——只是分布在不同层。

更多关于协议驱动设计的思考,见 CLAUDE.md 编写哲学

Learn Journal 不维护外部数据库或 JSON 状态文件。所有状态都存在文件本身里:

  • 笔记内容 - 每篇 markdown 文件
  • 来源和元数据 - front-matter 字段
  • 知识关联 - markdown 内部链接
  • 学习进度 - 文件数量和目录结构本身
  • AI 贡献标注 - <!-- AI-assisted --> 注释

优势

  • 任何 AI 工具都能读:不需要数据库驱动或 API 集成
  • 零依赖:不需要安装 SQLite、不需要跑后台服务
  • 人类可读:打开文件就能看到所有状态
  • Git 友好:每次状态变化都是一个 diff
  • 确定性层可直接操作:shell 脚本用 grep/awk 就能统计

代价

  • 查询效率低:想知道“哪些笔记被引用过”需要遍历所有文件。对几百篇笔记不是问题,但如果规模到几千篇会变慢。
  • 一致性风险:AI 改了 markdown 但 front-matter 没更新(或反之),没有数据库事务保证原子性。
  • 没有回滚机制(除非用 git):普通用户不用 git 的话,AI 误删或误改一个文件就是永久的。
  • 并发问题:如果两个 AI session 同时修改同一个文件,后写的覆盖先写的。

对于个人知识库的规模(几百篇笔记)和使用模式(单人单 session),这些代价是可接受的。

同一套协议文件,通过不同的“适配器”支持 4 个 AI 工具(Claude Code、Codex、CatDesk、Cursor)。

架构长这样:

protocols/ <- 核心规则(所有平台共享)
├── artifact-routing.md
├── daily-rhythm.md
├── explain-protocol.md
├── quality-gates.md
└── review-system.md
adapters/ <- 薄壳翻译层(每个平台一个)
├── claude-code/CLAUDE.md
├── codex/AGENTS.md
├── catdesk/CATDESK.md
└── cursor/.cursorrules
scripts/ <- 确定性层(平台无关)
├── lint-notes.sh
├── stats.sh
├── health-check.sh
└── export.sh

优势

  • 用户不被锁定:换工具只需要换一个适配文件
  • 方法论比工具活得久:AI 工具可能一年后换代,方法论不会过时
  • 确定性层完全平台无关:shell 脚本在哪都能跑

代价

  • 最低公约数问题:不同 AI 工具的能力不同,协议只能用所有工具都支持的能力
  • 适配器维护成本:每个新工具需要一个新适配器
  • 行为不一致:同一段协议,Claude Code 和 Cursor 的执行效果可能差异很大

方法论实验的最大风险不是“失败”,而是“不知道自己失败了”——持续投入时间但没有产出价值,靠主观感觉“好像有用”维持。

Kill switch 用客观指标替代主观判断:

指标计算方式阈值含义
active_days_ratio有记录的天数 / 总天数< 50% 连续 4 周用户已经不用了
reuse_rate被引用的笔记 / 总笔记数< 10%(3 个月后)知识库没有复用价值
ai_assist_ratioAI 标注段落 / 总段落> 70%变成了 AI 代写工具
decay_slope周产出线性回归斜率持续负值使用量在衰减

所有指标由 stats.sh 确定性计算,不依赖 AI 判断。

A. 实验成功 — 指标持续健康 + 有可迁移性证据。产出:方法论文章 + 开源 skill pack 继续存在。

B. 实验失败 — kill switch 触发。产出:诚实的失败报告(哪个假设错了、为什么)。失败报告本身有价值——告诉后来者“这条路走不通”。

C. 自然消亡 — 窗口期(约 2 年)内未完成验证,既没成功也没明确失败。产出:归档代码 + 简短说明。

明确终态的意义:避免“僵尸项目”——既不活跃也不关闭,占据心智资源。

知道自己在被观察时,行为会改变(霍桑效应)。stats.sh 的存在本身可能让用户“为了指标而记录”。应对措施:

  • 指标不公开展示(不做 dashboard)
  • 只在月末检查一次
  • 关注趋势而非绝对值

原始规划里有一个“Layer 3:独立桌面 App”作为终态。但经过反思,这个方向存在几个未解决的矛盾:

Skill 包可能已经够用 — 对已有 Claude Code / Cursor 的用户,80% 的价值在 skill 层已经交付。独立 App 多出来的是安装包、UI、通知、SQLite 索引——但用户已经为宿主工具付过费了,多装一个 App 的边际价值必须非常大才能跨过安装门槛。

商业模式矛盾 — 数据本地 + 用户拥有 + AI 推理走 API = 每个活跃用户都是持续的 API 成本,但又不锁数据、不锁格式。订阅制会和“本地优先、可完全脱离 App 用 markdown”冲突。

差异化脆弱 — “本地数据 + 对话式交互 + 学习方法论 + 主动引导”的四交集不是技术壁垒,是 prompt + 模板 + 工作流设计——极易复制。大厂加一个 Learning Mode system prompt 再绑日历提醒,就能覆盖大部分场景。

所以当前的决策是:停留在 skill 包形态,不做独立 App。如果未来有明确证据表明 skill 包不够(比如“被动触达”确实是致命缺陷),再重新评估。

Learn Journal 最初是一个人的实习日志系统(intern-journal)。把它变成别人也能用的东西,遇到了三类问题:

原始系统里到处是“只有我自己才懂”的假设:文件路径写死了、命名规范是我的习惯、工具链假设了 Claude Code + macOS + zsh。

解法:抽象为配置。把所有个人偏好提取到 config.yaml,协议文件引用配置值而不是硬编码。

原始系统假设用户有 mentor(所以有 feedback/ 目录)、用 Claude Code(所以只有 CLAUDE.md)、懂 git(所以有 pre-commit hook)。

解法:适配 + 降级。没有 mentor?去掉 feedback 目录。不用 Claude Code?提供 4 个适配器。不懂 git?lint 脚本是可选的(确定性层仍可手动运行)。

自己用的时候不会犯的错,别人会犯。适配文件放错位置、忘记创建 config.yaml、代码块里写“来源:”触发 lint 误报。

解法:防御性设计。lint 脚本用行级状态机避免代码块误判;适配器加 fallback 逻辑;初始化脚本幂等(重复运行不破坏已有数据)。

需要说明的是:上面三类问题的“解法”目前还在 spec 阶段,核心假设(copier 路径可行、skill 抽出后能独立运行、外部用户能装上)全部未验证。intern-journal 本身跑通了,但“别人也能用”这一步还没有走完。

研究了 6 个相关产品后提取的教训:

工具复杂度杀死用户 — Obsidian 需要 5-8 个插件才能拼出类似体验。Learn Journal 的应对:零配置开始用(Level 0 模板)。但 Obsidian 的优势是“打开就写”——输入效率上,Learn Journal 的对话模式可能反而更慢。

被动工具没有粘性 — Notion 模板搭完两周后就不想打开了。Learn Journal 的应对:AI 在你打开工具时主动引导。但这依赖用户先打开工具——如果用户不打开,Learn Journal 和 Notion 模板一样被动。

AI 做专精角色 — 通用 AI 什么都能做但什么都做不好。Learn Journal 只做一件事:帮你结构化学习。但这也意味着:如果用户的 AI 工具本身加了类似功能,Learn Journal 的独立价值会被侵蚀。

差异化的脆弱性 — Learn Journal 的差异化是“方法论打包”——prompt + 模板 + 工作流设计。这不是技术壁垒,极易复制。Learn Journal 的真正价值不在于“别人做不到”,而在于“别人还没做”+ “方法论经过了真实验证”。这是时间窗口优势(约 1-2 年),不是结构性壁垒。

生态位消亡条件:Cursor/Copilot 内置 learning mode、Claude Desktop Projects + Memory 覆盖核心功能、或 AI 编码工具市场整合导致宿主消失。任一发生,项目生态位消失——接受这个现实,价值在方法论验证不在工具存续。

以下是当前设计中明确没有好答案的问题:

1. 如何验证方法论的可迁移性? — N=1 的验证不够。需要 5-10 个不同背景的用户试用 2-4 周,但目前连 skill 包的独立分发都还没完成。鸡生蛋问题。

2. 反代写 vs 降摩擦的最优平衡点在哪? — 追问越多,记录摩擦越大;摩擦越大,用户越可能放弃。当前选择“宁可少记”,但这可能导致 active_days_ratio 过低触发 kill switch。

3. 概率层的一致性如何保证? — 同一段协议,不同模型、不同 context 长度、不同 session 的执行效果不同。确定性层兜底了“验证”,但没有兜底“引导体验”。

4. skill 包更新后用户怎么升级? — 协议文件更新了,用户怎么知道?怎么合并?如果用户改过协议文件,升级会覆盖他的修改吗?目前没有版本管理方案。

5. 天花板极低怎么办? — 约 4 万人理论上限,< 1000 人可触达。答案是:不办。这是方法论实验,不是商业项目。验证假设不需要大用户量。

6. 无法证明因果 — 即使所有指标正面,也可能是“多写笔记”本身有效,跟 AI 辅助无关。这个问题(Q6)在当前实验设计下无法回答——需要对照组,但单人实验没有对照组。诚实承认这个局限。

这些问题不是“以后会解决的”——它们是当前设计的结构性限制,可能需要根本性的方向调整才能解决。