跳转至

24h打工人

Ch04.009 24h打工人

📊 Level ⭐ | 7.1KB | entities/24h-worker-agent.md

核心架构

文件 + 轮询调度

class AgentScheduler:
    def __init__(self):
        self.queue = FileQueue("storage/feedbacks/")
        self.tools = ToolProber(["codex", "gemini-cli", "claude"])
        self.state = JsonStateManager("storage/state/")
    def run(self):
        while True:
            task = self.queue.poll()
            if not task:
                time.sleep(10)
                continue
            tool = self.tools.get_available()
            try:
                result = tool.execute(task.prompt, task.workspace)
                self.state.update(task.id, status="done", output=result)
            except QuotaExhausted:
                self.tools.cooldown(tool, duration=300)
                self.queue.requeue(task)
            except Exception as e:
                self.state.update(task.id, status="failed", error=str(e))

SDD 目录结构

每个需求处理完会留下一组文档:

storage/feedbacks/2026-01-15/20260115-143021-a1b2c3/
├── sdd/
│   ├── spec.md      # 规格说明:目标、验收标准
│   ├── plan.md      # 技术方案:涉及文件、实现步骤
│   └── tasks.md     # 任务清单:每个任务的描述和状态
├── tasks.json       # 任务执行状态(供程序读取)
└── debug/
    ├── prompts/     # 每一步的 prompt
    └── agent.log    # 执行日志

调度层职责

  1. 接收任务:用户反馈进来,写入文件队列
  2. 分发执行:轮询队列,调用 CLI 执行
  3. 状态管理:记录每一步的输入输出,持久化到文件
  4. 失败切换:某个 CLI 配额用完,自动换下一个

并发策略

策略 具体做法 理由
组间并发 前端任务和后端任务同时跑 代码在不同目录,不会冲突
组内串行 同一个前端项目的任务排队执行 可能修改同一文件,避免冲突
失败隔离 单个任务失败不影响其他组 故障不扩散

工具失败自动切换

正常流程:task → codex(可用)→ 执行成功 → 完成
失败切换:task → codex(配额耗尽)→ gemini-cli → 执行成功 → 完成
全部不可用:task → 等待 → 5 分钟后自动探活 → 恢复后继续

自举能力

系统曾自己修复了自己的 bug:发现需求澄清页面无法选择选项,直接通过反馈系统提交 bug,SDD 流程自动触发,最终自动修复完成。 自举前提: 1. 清晰的设计文档——AI 知道每个模块该做什么、不该做什么 2. SDD 流程——spec → plan → tasks 的标准路径 3. constitution.md——架构约束文件,定义代码组织规范、命名规则、模块边界 → 原文存档

相关实体

深度分析

24h 打工人的架构选择折射出 Agent 系统落地的核心矛盾:如何在"让 AI 自由发挥"和"让系统可控可维护"之间找到平衡点。

文件队列优先于消息队列

作者选择文件系统作为任务队列而非数据库或消息中间件,这一选择在 Agent 系统的实验阶段有充分理由:调试成本低、AI 可直接读取、与 Git 版本控制天然兼容。但这个选择在规模化后会遇到瓶颈——文件系统的原子性、一致性远弱于专业队列系统,适合"原型验证 + 快速迭代"阶段,不适合"高并发 + 低延迟"的生产场景。

SDD 本质是结构化记忆

SDD(Spec-Driven Development)不只是文档规范,更是一套结构化记忆机制。传统的 Agent 运行时丢失上下文,导致每次交互都是"从零开始"。SDD 通过 spec → plan → tasks 的分层,将模糊的需求转化成可追溯的决策链条。spec.md 记录"为什么做",plan.md 记录"打算怎么做",tasks.md 记录"做了什么"。这套机制解决了 Agent 系统的核心问题:无法自我纠错——因为每次迭代都有据可查。

自举能力的有条件性

系统能自己修复自己的 bug,这一能力被作者描述为"自举",但更准确的理解是:系统具备在边界内自我修复的能力。自举的前提是 constitution.md 定义了清晰的模块边界和代码组织规范,AI 在这个边界内工作,而不是自由发挥。这说明 Agent 自举不是无条件的,需要三个充分条件:清晰的设计文档、标准化的执行路径(SDD)、以及约束性的架构文件。没有这三样,"自举"只是碰运气。

工具切换的工程价值

Tool Prober + 冷却机制解决了 AI CLI 工具的配额不可控问题。这个设计的巧妙之处在于:它不依赖任何单一工具的成功,而是把失败当作常态来设计系统。当 codex 配额耗尽,系统自动切换到 gemini-cli,这个切换对用户透明,且不会丢失任务状态。这种"容错降级"思路是 Agent 系统工程化的关键——不是追求每个工具都完美,而是让系统在任何工具失败时都能继续运行。

实践启示

  1. 原型阶段用文件系统,正式生产换队列系统:24h 打工人的文件队列设计适合快速验证,但规模化后需要升级到 Redis/RabbitMQ 等专业队列,以获得原子操作、持久化、重试等企业级能力。
  2. 先补 spec 再动手,避免 Vibe Coding 陷阱:Vibe Coding 在前 3 天有明显的效率优势,但第 7 天开始债台高筑。第三天是补 spec 的最佳时间点——此时对问题有足够理解,修改成本尚低。
  3. constitution.md 是 Agent 自举的前提:架构约束文件不需要写得多复杂,但至少覆盖三件事:目录结构约定、模块边界、命名规则。让 AI 在"框架内工作"而非"自由发挥"。
  4. 脚手架投资回报率高于模型升级:作者估算脚手架升级(成本 +50%,效果 +200%)远优于模型升级(成本 +300%,效果 +20%)。对于个人开发者和小团队,优先投资 SDD 流程、调度层、失败切换等工程化能力,而非追逐最新最贵的模型。
  5. 留痕是为了进化,不是为了 debug:SDD 的每一步文档不只是为了出错时追溯,更重要的是积累系统行为的模式。当某个 Skill 的成功率可以被量化评估,系统才能真正"学会下一次做得更好"。