你有没有过这样的经历:每天早上打开 Codex CLI,敲下第一行指令,它就像第一次见到你一样,对你的项目结构、编码习惯、偏好设置一无所知。你不得不重复描述上下文,重新解释需求,花掉宝贵的 Token 和时间,只是为了让它"想起来"昨天你们一起写到哪里了。

这不是你的问题,也不是 Codex 的 bug。这是当前所有 AI 编程 Agent 的结构性缺陷:它们是无状态的。每次会话结束,记忆清零。下一轮对话,从零开始。

最近 Hacker News 上一个叫 Wienerdog 的开源项目引起了我的注意。它用一个极简的思路解决了这个问题:不改变 AI 模型本身,而是在它周围安装正确的文件。 9 分投票,2 条讨论,不算爆款,但它背后的架构哲学值得每个重度 AI 编程用户琢磨。

核心洞察:装对文件,AI 自己就变聪明了#

Wienerdog 的 GitHub README 第一句话就点明了产品假设:

You already pay for a great AI model. Wienerdog makes it feel dramatically smarter, not by changing the model, but by installing the right files around it.

翻译过来:你已经为顶级 AI 模型付了钱。Wienerdog 让它感觉上聪明得多,不是靠改模型,而是靠安装对的「周边文件」。

什么样的文件?一个真实的个人档案、一份持续更新的 Markdown 记忆库、一组针对你重复性任务的技能文件,再加上一个每天晚上自动运行的「做梦」流程,它会回顾当天的对话,提炼重要信息,更新长期记忆。

设计哲学是纯文件的:没有守护进程,没有服务器,没有遥测。没有任何东西在监听,没有任何数据传回远程。wienerdog uninstall 会删除它写过的每一个文件。这个设计原则贯穿始终。

架构揭秘:不是应用,是「编译器 + 提示词」#

Wienerdog 对自己的定位很有意思:「一个编译器加上一组提示词,不是一个应用。」目标代码量控制在 ~4000 行纯 Node.js,除了 Google API 库之外零运行时依赖。

整个系统分三层:

第一层:规范核心(~/.wienerdog/

这是唯一的真实来源。配置文件 config.yaml、供应商中立的技能文件夹、提示词模板、状态数据(水位线、队列、摘要)、密钥(Google OAuth token),以及一个 install-manifest.json 记录每一个被修改过的文件。

第二层:适配器

wienerdog sync 命令将核心编译为每个 AI 工具本地能理解的格式:

  • 对 Claude Code:在 ~/.claude/CLAUDE.md 中插入托管区块(<!-- wienerdog:begin --> / <!-- wienerdog:end --> 之间的内容),在 ~/.claude/skills/ 下创建符号链接
  • 对 Codex CLI:在 ~/.codex/AGENTS.md 中插入同样的托管区块,在 config.toml[skills] 段注册技能路径
  • 会话钩子:SessionStart 注入预渲染的记忆摘要,SessionEnd 将会话路径加入处理队列

第三层:记忆金库(~/wienerdog/

采用 Obsidian 兼容的 PARA 结构:

~/wienerdog/
├── 00-Inbox/           # 待处理的捕捉内容
├── 01-Projects/        # 活跃项目
├── 02-Areas/           # 持续关注的领域
├── 03-Resources/       # 参考资料
├── 04-Archive/         # 归档
├── 05-Skills/          # 梦幻合成的技能文件(git 版本控制)
├── 06-Identity/        # 身份档案:profile、preferences、goals
├── 07-Daily/           # 每日日志
├── reports/dreams/     # 每晚做梦报告
└── .git/               # 纯本地 git 仓库

每一份自动生成的文件都必须包含来源元数据:idtypeorigin(interview / capture / dream / manual)、source_sessionsconfidence(置信度分数)、derived_from_untrusted。最后这个字段是安全体系的关键,后面会讲到。

关键设计决策:CLAUDE.mdAGENTS.md 的内容是构建产物,不是手写文件。 用户身份、偏好、目标、指令都存储在 06-Identity/ 下的独立笔记中,sync 命令动态渲染,幂等执行(第二次运行 diff 为零)。Wienerdog 从来不会拥有用户的整个配置文件,只拥有一个清晰标记的区块。卸载时删除的也只是这个区块。

「做梦」:夜间自动学习的工程实现#

这是 Wienerdog 最独特的功能。每天凌晨 3:30(可配置),wienerdog run-job dream 启动一个受控的夜间流程:

第一步:编排器(纯代码)

获取分布式锁,扫描自上次水位线以来所有更新的对话记录。注意,这里扫描的是原始转录文件~/.claude/projects/**/*.jsonl~/.codex/sessions/**/rollout-*.jsonl),不是钩子输出。即使你关闭了所有钩子,Codex 用户也能获得完整的记忆捕捉。然后对每段对话内容进行敏感信息脱敏(正则匹配 API key、token 等模式),写入规范化的工作区。

第二步:大脑(AI 驱动,工具受限)

运行 wienerdog-dream 技能,但被严格限制:只能读工作区和记忆金库,只能写记忆金库,没有 Bash、没有网络访问。分三个阶段执行:

  1. 摄取:从每段对话中提取候选信息,与现有金库去重
  2. 排序:按重要性、跨会话复现次数、新颖性、稳定性、可操作性、用户显式信号六个维度打分
  3. 整合:按门控等级写入

第三步:三级门控写入

Wienerdog 设计了三个信任等级的门控,默认模式「标准」:

等级目标条件写入位置
Tier 1每日日志分数 ≥ 0.5,单次会话即可07-Daily/
Tier 2原子笔记 / 项目 MOC分数 ≥ 0.75对应 PARA 目录
Tier 3身份档案、偏好、技能、注入摘要的内容分数 ≥ 0.85 复现 ≥ 3 次不同会话 derived_from_untrusted: false06-Identity/05-Skills/

Tier 3 的核心安全规则:来自不可信来源的内容永远无法晋升到 Tier 3。 如果候选信息的源头是工具结果(邮件正文、网页内容),即使它在多次对话中反复出现,也不会被写入会注入到下一轮会话摘要的区域。这从根本上防止了持久性提示注入。

第四步:技能合成

当一个多步骤操作流程在 ≥ 3 次不同会话中成功复现,梦想过程会生成一个 SKILL.md 草稿,状态标记为 incubating(孵化中)。后续的梦想流程观察该技能的实际使用效果,表现良好则提升为 activeWienerdog 自带的技能永远不会被原地编辑,改进建议只写入梦想报告。

第五步:验证与提交

代码层编排器对金库做最终 diff 验证。任何对 06-Identity/05-Skills/ 的修改,如果缺少 Tier 3 条件的前置元数据,都会被回滚并标记在报告中。然后完成一次 git commit,重新生成摘要,推进水位线,释放锁。整个过程有看门狗保护(默认 20 分钟超时),超时即告警。

双 Agent 共享记忆:一个金库,两种工具#

如果你同时使用 Claude Code 和 Codex CLI,Wienerdog 提供了一个独特价值:共享记忆。

CLAUDE.mdAGENTS.md 都是从同一个采访(/wienerdog-setup)和同一个金库渲染而来。你在 Codex 里教会它的东西,下次打开 Claude Code 时它也能用上。反过来也一样。切换工具不再意味着面对一个对你一无所知的 AI。

这个设计承认了一个现实:在高频 AI 编程用户群体中,工具切换是常态而非例外。有时 Codex 的沙箱安全性更适合做基础设施变更,有时 Claude Code 的交互体验更适合做架构讨论。共享记忆让工具选择回归到技术匹配,而不是被"哪一个更了解我的项目"所绑架。

安全设计:把信任放在代码层,不靠提示词#

Wienerdog 的安全架构有一条清晰的分界线:治理逻辑在 CLI 代码中强制执行,不在 AI 提示词中「请求」AI 遵守。

最典型的例子是 Google Workspace 集成中的发送授权:

  • 外发动词(Gmail 发送、日历邀请)只能在 config.yaml 中显式声明发送授权(send grant)后执行
  • 授权由用户在交互式终端中通过 wienerdog grant send ... 命令创建,包含类型化确认
  • 任何技能、钩子、无头任务都不能创建授权
  • 未经授权的发送操作退化为草稿加通知

这不是"请 AI 不要乱发邮件"的软约束,而是 CLI 层面的硬编码检查。Wienerdog 的威胁模型文档明确指出:「这是关于 Wienerdog 自身代理和 CLI 针对被劫持 AI 执行的保护声明,不是针对同用户下其他软件的绝对保证。」

为什么不是 OpenClaw 或 Hermes?#

Wienerdog 在 README 中主动对比了同类项目:

Projects like OpenClaw and Hermes are impressive — and they are applications: gateways, daemons, servers you must run, secure, and update. Wienerdog is different by design: just files.

这个区别不是修辞。OpenClaw 和 Hermes 是需要运维的应用:网关、守护进程、服务器。Wienerdog 走的是完全相反的路线:所有功能通过 AI 工具本身的指令执行,Wienerdog 只提供文件和配置。

从用户角度看,这意味着:

  • 不需要额外运行任何长期服务
  • 不需要开放端口
  • 不需要升级一个独立的应用栈
  • 始终在 Claude Code / Codex 的服务条款范围内运行

但也有代价:夜间梦想流程依赖 AI 模型完成核心智能工作,API 调用成本由用户承担。这不是一个免费方案,而是把计算资源的自主权完全交还给用户。

Wienerdog 给编程 Agent 设计的启示#

撇开具体实现,Wienerdog 提出的问题值得深思:AI 编程 Agent 的记忆应该放在哪里?

目前的主流方案是嵌入在模型的上下文窗口中:每次对话前把历史对话摘要、项目背景、编码规范一股脑塞进 System Prompt。这个方案的瓶颈显而易见:Token 消耗线性增长,上下文窗口再大也有上限,而且每次都要重新"喂"一遍。

Wienerdog 提供了一条替代路径:把记忆外化到文件系统中。AI 不需要在上下文中携带所有历史信息,它只需要在需要时读取对应的文件。这本质上是一种**检索增强生成(RAG)**的本地化实践:不是从向量数据库检索,而是直接读 Markdown 文件。

更值得关注的是「梦想」机制。它把 AI 作为一个主动学习的主体来设计:不是被动等待用户告诉它该记住什么,而是主动扫描对话历史,提取模式,更新知识。这个设计思路如果被更广泛地采用,可能会改变我们对编程 Agent 的认知,从「工具」转向「学徒」。

局限与风险#

当然,Wienerdog 还处于 0.x 阶段,文件格式在 1.0 之前可能变化。几个现实的局限:

  1. API 成本:每次梦想运行都在消耗 API Token。如果每天跟 Codex 对话很多,每月多花几美元到几十美元是可能的
  2. 记忆质量取决于模型:Tier 3 的门控逻辑依赖 AI 对重要性的判断。如果模型在某天状态不好,可能会漏掉有价值的信息或写入噪音
  3. 隐私边界:自动扫描对话记录意味着所有对话内容都会被分析。敏感项目需要谨慎评估
  4. 单机限制:记忆金库是纯本地的。如果你在多台机器上工作,需要自己解决同步问题(git remote 是文档推荐的方案)

总结#

Wienerdog 最吸引人的地方,不是它的某个具体功能,而是它的设计哲学:最好的 AI 工具不是给模型加更多参数,而是给模型更好的上下文。 文件系统是计算机科学中最古老、最稳定的抽象之一。把 AI 记忆建立在这个基础上,是一种深思熟虑后的「返璞归真」。

如果你每天花大量时间跟 Codex 或 Claude Code 对话,尝试给它们装一个文件级的外挂记忆系统,可能会是一个有趣的实验。至少,下次打开终端时,你的 AI 能认出你来。


参考来源:Wienerdog GitHub — README, Architecture, Threat Model 文档 · Hacker News 讨论