← 返回主页
ENFR
Agent 编排 · 系统设计

Task Router Agent
用 Markdown 文件作为控制平面的任务调度系统

这是一套 LLM 驱动的任务运行时——路由、执行、自愈全部自动完成。一个 Markdown 文件作为 Agent 的控制平面,整套系统不依赖于任何打开着的会话——编辑文件后,工作会在后台继续。下面讲清楚:这套架构的设计思路、我做出的几个关键取舍、实际运行数据,以及一个我没有刻意编程、系统却自发表现出的关键行为。

第一部分

问题

背景:作为一个独立运营者,我同时在推进 4 条线(内容生产、首位客户的架构评审、作品集搭建、学业)。任务状态散落在不同工具里——每次切换上下文都要花 15–30 分钟重新进入状态,才能真正开始工作。

产品约束:我想要的任务系统需要满足两点:可以随时加任务;分配给自动化的任务能自己跑完,不需要我守在电脑前。合上电脑,几个小时后回来,任务已经处理完。

为什么这是 Agent 设计的关键:大多数"AI 助手"一关上聊天窗口就停止工作——它们绑定的是对话,而非工作本身。构建一个不依赖会话生命周期的 Agent 运行时,是一个完全不同的设计问题;这也是让 Agent 从"工具"升级到"基础设施"的分水岭。

核心设计问题:一个纯文本文件 + 一套状态机协议 + 一个 LLM 决策层,能不能撑起一个持久化的 Agent 运行时?如果可以,这套模式就能迁移到任何运营工作流——客服工单分派、内容流水线、业务自动化。


第二部分

系统架构

Task Routing 流程

触发 · task-board.md 被编辑(任何来源:我、另一个 agent、cron)
↓  fswatch · 2 秒 debounce · launchd 每小时兜底
Quiescence Gate · 30 秒文件空闲后才执行(防止编辑过程中的竞态条件)
↓  获取文件锁 · mkdir 原子操作
LLM 决策层 · 解析 task-board 状态机 · 对每个任务分类:ready / blocked:* / running:* / done / failed:*
ready → 并行执行(最多 3 个 subagent 同时跑)
running > 30min → 自动重置为 ready(死锁恢复)
↓  写入串行化 · 主 agent 统一写回状态
状态更新 + 只追加日志 · task-board.md 写回 · events.jsonl 结构化日志 · deadletter/ 终态失败归档

5 层架构

L5控制平面task-board.mdMarkdown 作为 UI + 单一事实源
L4调度层fswatch + launchd事件驱动 + 定时兜底
L3执行层bash + claude -p无状态一次性调用
L2决策层task-check skill (LLM)状态机路由 + 任务交接
L1状态与审计events.jsonl + deadletter/只追加日志 + 失败捕获

第三部分

关键设计决策

4 个刻意做出的取舍。每一个我都列出了明确拒绝的替代方案。

1. 用 Markdown 做控制平面,不用 Notion / Airtable / SQL
拒绝结构化数据库(Notion、Airtable、Postgres)——schema 强制、可查询、天然支持多用户
选择一个 Markdown 文件 + 每个任务的 YAML 式元数据
理由编辑延迟 < 1 秒,零厂商依赖,git 可版本化,无工具即可读,LLM 无需 schema inference 即可解析。代价——缺 schema 约束——由状态机层(见决策 2)补足。
何时重审多人并发编辑成为硬需求,或任务量超 ~500 条 Markdown 解析变瓶颈时
2. 类型化状态机,不用自然语言 status
拒绝自由文本状态("等客户回复"、"进行中"、"卡在 API")
选择类型化状态 token:ready / blocked:siyao:send-brief / running:agent-a4b:2026-04-20T15:25Z / done / failed:exhausted_retries
理由类型化状态是一套协议,而标签只是字符串。LLM 解析协议时能推理依赖链、死锁条件、时间戳合理性,而不是对字符串做 pattern match。这是对系统"智能度"影响最大的一处设计(见第五部分)。
代价一次性迁移所有现有任务(13 张卡)+ 坚持按这套分类规范维护。前期成本小,后期复利
3. 写入串行化,不用分布式锁
拒绝多 agent 并发写 task-board.md + 分布式锁机制(flock、append 模式、CRDT)
选择严格的单写者原则:只有主 agent 能写状态。Subagent 并行执行任务、返回结构化结果;所有状态更新由主 agent 统一串行写入
理由Markdown 文件不具备事务性。并发写入会导致更新丢失、结构损坏,甚至生成无法解析的状态——一连串连锁故障。单写者原则限制了并行带宽,但以零运行时成本消除了一整类竞态条件 bug。
取舍执行层的并行能力仍然保留(最多 3 个 subagent 并行);状态写入只有在任务吞吐量持续 > 1/秒 时才会成为瓶颈——对当前工作量而言,还远远不到那条线。
4. Quiescence Gate,不用简单 debounce
拒绝文件 watcher 固定 2 秒 debounce
选择Watcher debounce(2s)叠加 quiescence gate:执行前必须有连续 30 秒文件空闲。每 5 秒轮询一次;任何改动即重置计时。
理由用户一次"保存"动作,编辑器可能触发 watcher 5–10 次。没有 quiescence 的情况下,执行器会与用户的编辑抢时间,状态更新会和还在进行中的编辑冲突。30 秒的门槛让自动化处理与用户的自然停顿节奏对齐。
代价处理延迟最低 30 秒。对异步任务流可接受;不适合实时聊天 agent。

第四部分

可量化结果

基线追踪 2026-04-20 启动。数据来自首周运行;部分为初始数据估算,方法论已标注。

~2s
文件变更检测
实测于 events.jsonl——从保存到 file_changed_triggered 事件
30s
执行前静默期
刻意设置的空闲门槛,防止在编辑中途执行
~30s
端到端任务处理
对确定性任务(状态路由、状态检查);subagent 任务因工作量变化
<30min
死锁恢复
自愈:卡住的 running:* 状态自动重置。零手动介入。
~$10-30
月运行成本
仅 LLM API。无额外托管成本(通过 launchd 在笔记本运行)
100%
关键操作审批率
所有破坏性/不可逆操作都需人工审核——刻意设计,不是 bug

效率提升(保守估算)

系统前:手动查任务清单 + 常规研究任务约占 8–12 小时/周。系统后:常规任务(竞品调研、文档起草、市场扫描)被路由到并行 subagent,无需实时督促。

首周观察产出:5 项实质性研究/写作任务在无监督情况下完成(代表例:260 行竞品分析、895 行架构 case study、18 份 JD 市场扫描、HR 视角作品集评估)。

方法论:效率估算基于自报基线。精确量化从第 2 周开始(进行中)。


第五部分

Emergent Behavior · 核心洞察

我给决策层的编程只有一件事:ready 状态的任务,执行它们。其他一律跳过。

首次生产运行时,它做了我没有编程的事:

这些行为都不在 prompt 里。它们从状态机设计中涌现出来。

同一个 LLM,同一张 task-board,agent 的行为可以截然不同——全看 status 是标签还是协议。自然语言 status("等待"、"进行中")给模型的只是一串可以 pattern match 的文本;类型化 status + 结构化子字段,给模型的是一套可以推理的协议。给产品团队带走的核心结论:让 agent 从"执行机器"进化成"推理搭档",真正的杠杆在结构化的状态协议,prompt 只是最后一层调优

这对 agent 系统设计的含义很具体:多数团队在 agent 行为不满意时,第一反应是去迭代 prompt。但更高杠杆的动作,往往是修改 agent 所运行的那个类型系统本身。


第六部分

泛化与下一步

模式迁移

这套架构不是任务自动化专用的。同样的 5 层模式(控制平面文件 + 事件驱动调度 + 无状态执行器 + 类型化状态机 + 只追加审计日志)可以直接对应到一位 Shopify 客户在简报里提出的几类工作流——我正在为这份简报做架构评审:

工作流控制平面决策层任务
客服工单分流Helpdesk ticket 队列分类 + 起草回复 + 标记待审核
预售订单管理供应商 ETA 追踪表识别变动 + 生成客户通知
供应商数据产品创建接收表格队列字段抽取 + 标准化 + 写入草稿
Collection-buying 收品咨询邮件日志抽取 + 评分 + 起草跟进

同一套状态机规范(ready / blocked:* / running:* / done)对每一种都适用。真正与具体工作流相关的只有决策层的 prompt 模板——基础设施完全可以共享。

下一步演进

下次我会怎么做

搭完这套系统之后,我收获了一条可以带到任何 agent 产品里的结论:状态机本身才是产品。Prompt、subagent、调度层都是可替换的;真正持久、真正能规模化、真正决定"这个系统只能执行还是能推理"的,是人类意图和 agent 行动之间那份状态契约。


第七部分

自建还是选现成工具 —— 为什么我没用 Coze / Dify / n8n

首先讲清定位:这是一个单人使用的运行时,为我自己的任务流定制,而不是一个平台产品。它要解决的是"一个人协调一小组工作流"这种非常具体的场景。写第一行代码之前,我真正需要回答的问题不是"要不要做一个 Coze 的竞品"——而是"现有工具里有没有已经能解决这个场景的?如果有,是哪一个?"下面是我做决定前的分析。

我需要优化的 4 件事

三种方案,各自的优势和我放弃的理由

Coze(字节跳动)—— 可视化 agent 搭建器,云 SaaS
优势非技术团队做 agent 最快的路径;字节生态内预置工具集成丰富。
放弃原因我的状态本来就在 Markdown + git 里。用 Coze 等于把这些状态重新录入到画布 UI 里,同时接受厂商锁定。对长期在终端里工作的独立操作者来说,画布是摩擦,不是帮助。
Dify(开源)—— LLM 应用平台,自托管
优势把 RAG、agent、数据集管理放在一个平台里。如果团队要交付一个打包多种 AI 能力的产品,是不错的选择。
放弃原因Dify 瞄准的是要交付给用户的产品;它为多租户数据集、会话管理、嵌入式 UI 这些我用不上的功能付出了复杂度。对一个个人任务运行时来说,Docker + Postgres + Redis + Web UI 是 overkill。
n8n(开源)—— 节点图式工作流自动化
优势400+ 预置集成。如果 AI 步骤只是跨 SaaS 大流水线里的一个节点,n8n 是最佳选择。
放弃原因在我的工作流里,AI 决策并非一个节点——它就是路由层本身。n8n 把 LLM 当成另一个集成;我的设计把类型化状态作为 LLM 推理的第一公民。重心完全不同。

背后的共同逻辑

这三个平台都把工作流抽象在一个 UI + 一套 schema 的后面,让你通过 UI 去配置。当操作者是非技术人员、状态需要跨团队共享、或者工作流本身就是产品时,这是对的选择。但这些条件在我这里都不成立。对一个独立操作者、且工作流状态本来就是文本的场景而言,引入第二套状态系统(画布 + 厂商存储)的成本,会超过预置节点带来的便利。

换个角度说:这套运行时之所以是大约 300 行 shell 脚本 + 一个 skill 定义,而不是一套 Dify 部署,并非因为我觉得自己能做得更好。真正的原因是:我的场景(单人、Markdown 原生、终端原生、零厂商依赖)恰好是这些平台刻意去优化的边角情况。对它们真正的受众——跨职能团队要交付面向用户的 agent 产品——它们才是对的选择,我也会推荐。

这里可以迁移的能力不是"我能做一个比它们更好的平台"。真正可迁移的是一套判断方法:在写下任何一行代码之前,先列清自己真正需要的几件事,把每个现有工具逐一对照——只有每一个工具都在某一条上失败时,才选自建。这套 build-vs-buy 的判断框架,放在产品岗位上做任何 agent 平台决策都同样适用——包括在现有工具已经覆盖场景时,明确给出"不要自建"的建议。


张思瑶 · 2026 年 9 月入职,北京 · 与我联系