章节 14 / 37 · 课程总览 · 起始 1:45:41

章节主旨

系统讲解 DOE 框架(Directive / Orchestration / Execution,指令-编排-执行)这一贯穿全课的三层软件架构:把一个概率性 AI agent 包在三层结构里,用「关注点分离」把它从「到处乱跑」约束成标准、一致、可预期的确定性系统。

核心论点

  1. DOE 是包在 AI agent 外的三层架构,本质只是「文件夹结构 + 系统提示」——目的是收窄输出的随机范围,不神秘。(→ 详解1)
  2. Directive 层(指令)= 自然语言写的 SOP,纯 markdown、零代码,人人可读——这是可解释性与降低协作门槛的关键。(→ 详解2)
  3. Orchestration 层(编排)= 像项目经理,运行时动态做路由决策——取代 no-code 时代「搭流程时一次性写死」的连线。(→ 详解3)
  4. Execution 层(执行)= 确定性的原子脚本,一脚本一事、可复用可版本管理——同输入必得同输出,不幻觉。(→ 详解4)
  5. DOE 有效是因为它扬长避短:用预建工具替代「每次现造」——如同给菜谱而非每次让厨师即兴发明新菜。(→ 详解5)
  6. 两个配置文件收口整个系统:agents.md(系统提示)+ .env(密钥凭证)——把 DOE 结构本身讲给 orchestrator 听。(→ 详解6)

知识点详解

1. DOE 三层架构总览:给 agent 装护栏 1:45:55

DOE 是包在一个 AI agent 外面的三层软件架构,由上到下是 Directive(指令)、Orchestration(编排)、Execution(执行)。它要解决的问题是:LLM 本身是概率(stochastic)系统,输出到处乱跑;三层结构通过「关注点分离」把它约束成标准、一致、确定的东西。

不要被「三层架构」吓到。Nick 反复强调它比想象中简单:DOE 说白了就是一个文件夹结构加一个系统提示。当下几乎所有 agentic 框架做的都是同一件事——建 directives、execution 两个文件夹,加一个 agents.md / claude.md 之类的提示文件,再放上 API keys(.env)。之所以「三层架构」这个框架值得先立起来,只是为了让后面的课程能对上号。

它为什么有用,落在「随机性」这个词上。DOE 所做的就是把可能输出的范围收窄:原本 agent 的输出散布在一个很宽的可能性区间,DOE 通过关注点分离把区间收紧,让系统只在一个很窄的边界内运作,因此更可靠。

Nick 的保龄球类比:新手容易把球滚进边沟(gutter)就废了;让球道升起护栏(guardrails),球撞墙弹回来还能打到瓶。DOE 对 agent 就是这套护栏——不保证完美,但显著提高「做到你想要的事」的概率。他称在一家做牙科诊所营销、年营收约 200 万美元的公司里,用这套把很多业务功能的错误率压到 2–3%。

2. Directive 层(指令):自然语言 SOP,零代码,人人可读 1:51:45

Directive 是用自然语言写成的 SOP(标准操作流程),以 markdown 文件存放,后缀 .md。用 markdown 而非纯文本或 HTML 是有意的:# 标题、* 列表这类标记给文本加上结构,能在更少 token 里塞进更多信息,比 HTML 标签 token 效率高得多。指令用来定义目标、输入、工具、预期输出、边界情况等。

写法上,Nick 说要「像给一个能干的员工下指令那样写」:讲清「做什么」和高层的「怎么做」,但不微观管理(micromanage),其余交给 agent 自己补齐——而且这些指令本身多半也是让 AI 来写。

结构上讲究模块化:每个 directive 是一个 markdown 文件,只覆盖一个工作流或一种能力。要有 scrape_leads.md,而不要 run_business.md——后者要求太大,模型会打转、抓不住边界。多个原子 directive 之后可以用「伞状指令」(如 run_onboarding_flow)编组,但不要伞到「经营整个公司」那种粒度。文件名务必描述性、不用缩写,因为模型主要靠名字判断该调哪个工作流。

一条硬规矩:directive 里绝对不含任何代码。指令全是自然语言,顶多放个 URL,绝不放可执行代码。原因是要让公司里所有人都能读懂——哪怕不懂技术、只要有系统思维的低层员工,也能看着指令说「客户有时会要 X,这里该加点逻辑」。这把系统变成可解释的白盒,消除组织瓶颈;如果指令技术到没人读得懂,就搞砸了。

3. Orchestration 层(编排):运行时做路由决策的项目经理 1:57:59

Orchestration 回答「谁来做」(the who),角色相当于一个称职的项目经理。好的项目经理很少亲自动手,而是当一个「枢纽」(nexus):吸入信息、思考、再把活派给下面的人。orchestrator 就是这样——接入各种输入,做协调与任务管理,最后调用工具。

它相对 no-code 的根本升级在于决策时机。老式 no-code(如 n8n)里,「这个节点连到那个节点」的编排是你在搭流程时一次性写死的。orchestrator 则是先把所有工具汇编好,在运行时才决定「先做这个、再跳那个、循环三次、最后收尾」。因为是运行时决策,它能随情境灵活适应。

灵活性的额外好处是容错:某一步坏了,它能诊断问题而不是直接崩掉、抛 404。若配合后面章节讲的 sub-agents,还能让 agent 端到端走一遍流程、发现问题就诊断,并把改动、易犯的逻辑错误等记录下来,供 agent 的未来实例参考。当然编排不是放任——「给一堆工具让它自己看着办」不行,方向约束正是靠上层的 directive 提供。

4. Execution 层(执行):确定性原子脚本 2:00:16

Execution 回答「怎么做」(the how),是确定性(deterministic)、模块化的一层,脚本存在 execution 文件夹里,Nick 通常用 Python(语言其实无所谓,Python 随时能转成 Rust / Node / Java)。核心原则:每个脚本只干一件事。比如 scrape_leads 这个工作流底下可能有 scrape_apify.pyupload_to_gsheet.pypresent_to_user.py,各自把一件事做到极好。

确定性的意义是:同样的输入喂给同样的脚本,永远得到同样的输出。参数被显式传入(如 --location=Texas --amount=200),不存在歧义,agent 总知道该期待什么。这与「不给工具、直接甩 prompt 让 agent 现场发挥」形成对比——后者跑 10 次会有 10 条不同路径。

执行脚本大部分不是 AI,所以不幻觉:要么正确运行,要么抛出清晰错误。因此可以做单元测试(unit testing,把函数隔离到只剩输入输出来测)、可版本管理、可独立优化——甚至靠后面讲的 self-annealing(自退火)逐步把串行流程改成并行,持续增量改进。

一个常见疑问:脚本里能不能用 AI?能。比如 process_leads_with_claude.py 读取 Google Sheet 的每一行、逐行发给 Claude 打标签、再写回。它仍在调 Claude,但因为被框在单一工作流内(prompt 固定、temperature 调到很低、尽量确定),比给 orchestrator 全权自由要可预期得多。要点始终是:让执行脚本尽量原子、尽量确定。

5. 为什么 DOE 有效:预建工具替代「每次现造」 2:06:45

DOE 之所以奏效,是因为它扬长避短、发挥各方所长。不约束 LLM 输出时它极不可预测:可能 80% 时候能成,但那 20% 会「失败得很壮观」(把楼炸了那种)。而用预建工具替代临场造工具,让 LLM 不必每次从零搭工具,直接减少了到达目标所需的步骤总数。

Nick 的菜谱类比:给人一份菜谱,和每次让他即兴发明一道新菜,结果的确定性天差地别。让它「照那份西班牙海鲜饭菜谱做」,拿到想要味道的概率,远高于每次让它凭当下的偏好和随机性现场发挥、端出一个「海鲜饭 3.0」。DOE 就是把这份「菜谱」(预建的确定性脚本 + 自然语言指令)交到 agent 手里。

6. 两个配置文件:agents.md(系统提示)与 .env(密钥) 2:07:17

除了 directives 与 execution,还有两个关键配置文件收口整个系统。第一个是 agents.md(系统提示):在每次与 orchestrator 对话开始时自动注入,充当持久上下文,免得你重复交代。它按 IDE 环境命名——可以是 agents.mdclaude.mdgemini.mdcursor.md;Nick 建议全都放着,这样换任何 IDE / 模型都能立刻读懂(甚至可以三家模型开三个标签并行跑,分摊各自的 rate limit)。

agents.md 的作用有三:把 DOE 框架结构本身讲给 orchestrator 听(「everything I’m telling you, we’re just going to tell the agent」,很 meta);定义错误处理行为,让 agent 遇错不「打转失控」;而且它可以越写越好——Nick 说自己每周都会发现没覆盖到的边界情况,加一行,模型下次就不再犯。self-annealing(自退火)概念正是这样冒出来的:他发现模型有时自己解决问题、有时来找他,于是干脆写明「你自己把问题解决掉」。

第二个是 .env:存放所有 API keys 与凭证(如 ANTHROPIC_API_KEY=...OPENAI_API_KEY=...)。执行脚本不硬编码密钥,而是去 .env 里取。.env 只是程序员早年定下的约定,直观、易懂,对新手友好;对企业也好用——SOP 可以直接复制粘贴进来转成指令。

术语

  • DOE(Directive Orchestration Execution)——指令-编排-执行,包在 AI agent 外的三层软件架构,用于约束输出、降低随机性。
  • SOP(Standard Operating Procedure)——标准操作流程;DOE 里的 directive 就是自然语言写的 SOP。
  • stochasticity(随机性)——LLM 输出的不确定/随机特性;DOE 的目标就是收窄其可能范围。
  • deterministic(确定性)——同输入必得同输出;execution 脚本的核心属性。
  • orchestrator(编排器)——运行时动态做路由决策的 agent,角色类比项目经理。
  • self-annealing(自退火)——让 agent 自行解决问题并把经验沉淀回 agents.md,持续增量改进(本章预告,后续详讲)。
  • agents.md——每次会话开头自动注入的系统提示,承载持久上下文与错误处理规则。
  • unit testing(单元测试)——把脚本隔离到只剩输入输出来验证其正确性。

自检问题

  1. DOE 三个字母各代表哪一层,分别回答「什么/谁/怎么」中的哪个问题? 答案:Directive 指令层=「做什么」(自然语言 SOP);Orchestration 编排层=「谁来做」(运行时路由的项目经理式 agent);Execution 执行层=「怎么做」(确定性原子脚本)。见 2:00:16
  2. 为什么 directive 里坚决不放任何代码? 答案:为了让公司里所有人(包括不懂技术、只要有系统思维的员工)都能读懂并改进,把系统做成可解释的白盒、消除组织瓶颈。见 1:56:42
  3. execution 脚本为什么能做单元测试和版本管理,而 orchestrator 不能同样确定? 答案:因为执行脚本大多不是 AI、不幻觉,同输入必得同输出,要么正确要么抛清晰错误,故可隔离测试、版本控制、独立优化;orchestrator 是概率性的运行时决策。见 2:00:16
  4. Nick 用什么类比说明「预建工具」为何优于「每次现造」? 答案:菜谱类比——照菜谱做拿到想要结果的概率,远高于每次让厨师即兴发明新菜;DOE 就是把确定性脚本这份「菜谱」交给 agent。见 2:06:45