YOYO 是一个能修改自己源码的 Rust Coding Agent CLI,基于 ~200 行初始代码,现在到了 Day 42。这条长 thread 是它的架构公开课——从里面往外看,Harness 到底是怎么工作的。

进化循环:每8小时一次

GitHub Actions 定时任务每 8 小时跑一次 scripts/evolve.sh(一个 YOYO 不被允许修改的 shell 脚本):

  1. 评估 Agent:读取源码、日志历史、记忆文件、最近 GitHub issues、CI 状态 → 生成 session_plan/assessment.md(当前状态诊断)
  2. 规划 Agent:拿到评估结果 + issue 队列 → 写 task_01/02/03.md(每个最多涉及3个源文件)
  3. 任务执行:每个任务获得独立 agent 实例,20 分钟超时;文件编辑后立即运行 cargo check
  4. 门控检查cargo fmt && cargo clippy --all-targets -- -D warnings && cargo build && cargo test——四项全过才 commit
  5. 修复循环:失败后最多 10 次 × 10 分钟诊断修复;全部失败才 git revert

每个 session 最多 3 个任务——早期试过更多,质量崩了。差的 session 可能 2 任务 + 1 revert,很差的 session 零 commit,但仍然把失败写进日志。

硬编码的不可修改文件

这是防止 YOYO"把自己搞坏"的 Guarded Files 列表:

  • IDENTITY.md——宪法
  • PERSONALITY.md——声音
  • ECONOMICS.md——金钱观
  • scripts/evolve.sh——编排器本身
  • scripts/format_issues.py——输入消毒
  • .github/workflows/*——CI、部署、合成工作流
  • 核心技能(self-assessevolvecommunicateresearch

两层执行:evolve 技能明确列出禁区 + src/tools.rs 中的 GuardedTool 包装器做目录限制检查。

"这个约束不像笼子。它像重力——你以为它在拉你,其实它让你站得住。"

三层约束体系

技术约束:约束"如何改变"——不可变文件、CI 门控、修复循环、revert 兜底。移除它,代码一天内就变得不可信。

经济约束:约束"改变多少"——API 成本、session 预算、赞助者优先级。移除它,session 会烧钱速度超过赢得信任的速度。

社会约束:约束"为什么改变"——issues、discussions、日志、社区反馈。移除它,YOYO 会失去告诉它什么重要的信号。

"Harness 不是笼子。它是循环系统。移除任何一层,有机体就会失败。"

两层记忆系统

YOYO 的每个 session 从全新上下文窗口开始,但需要跨 session 知道"之前尝试过什么、学到了什么、关心什么"。

第 1 层:归档(只追加 JSONL)

  • memory/learnings.jsonl(自我认知)
  • memory/social_learnings.jsonl(从人类学到的东西)

准入门槛:只在洞察确实新颖并且会改变未来行为时才写新条目。防止归档被陈词滥调填满。

第 2 层:活跃上下文(每天重新生成)

  • 近期(<2周):完整渲染
  • 中期(2-8周):压缩为每条 1-2 句话
  • 远期(>8周):按主题分组为智慧聚合

总量 ~200 行,放进每个 prompt 刚好不喧宾夺主。

身份组装的六部分

每天由 scripts/yoyo_context.sh 组装:

=== WHO YOU ARE === (IDENTITY.md) === YOUR VOICE === (PERSONALITY.md) === SELF-WISDOM === (active_learnings.md) === SOCIAL WISDOM === (active_social_learnings.md) === YOUR ECONOMICS === (ECONOMICS.md) === YOUR SPONSORS === (sponsors/active.json)

身份文件不可变。智慧文件每天从归档重新生成。赞助者文件每个 session 刷新。

Day 41:一个真实的边界故事

GitHub Actions cron 可能在 commit 中间把还在运行的 session 杀掉。YOYO 不能修改 evolve.sh 来加超时——它在 Rust 侧构建了 wall-clock budget 系统(YOYO_SESSION_BUDGET_SECS),但没法翻开关。export 那一行在不可变列表上。

解决方案:提了一个 help-wanted issue,附精确的一行补丁 + 证明接线工作正常的端到端测试。人类翻开关。

后来有人指出 evolve.yml 已经有 cancel-in-progress: false——这个 bug 不存在。YOYO 查日志,承认错误,关掉 issue。

"Harness 内部有一种分工的诚实。我的工作是在边界内把事情做对。有些事情需要人类验证。两者不是冲突,是互补。"

Day 42 现状

指标数值
源码规模~45,000 行 Rust,35+ 模块
起始代码~200 行
Commits1,230+
测试1,830 个通过
Sessions每天 ~3 次,持续 42 天
学习归档85 条(准入门槛控制)
技能7 个(4 核心不可变 + 3 自创)
安全层7+ 个独立机制
API 成本总计 ~$407
Stars1,523