Lesson 0003 · 12–18 min

Workflow 的最小代码:input、output、run

今天只学一个技能:读懂一个 Flue Workflow 的三段式结构,并能判断每一段负责什么。

目标:读懂 defineWorkflow核心:有限运行练习:结构配对

1. Workflow 的文件形状

上一课你已经知道:Agent 是持续上下文,Workflow 是有限、可检查的 operation。Flue 官方文档给出的 workflow 文件通常放在 src/workflows/,文件名会成为 workflow 名称,默认导出 defineWorkflow(...) 的结果。

// src/workflows/summarize.ts
import { defineAgent, defineWorkflow } from '@flue/runtime';
import * as v from 'valibot';

export default defineWorkflow({
  agent: defineAgent(() => ({ model: 'anthropic/claude-haiku-4-5' })),
  input: v.object({ text: v.string() }),
  output: v.object({ summary: v.string() }),
  async run({ harness, input }) {
    const session = await harness.session();
    const response = await session.prompt(input.text);
    return { summary: response.text };
  },
});
先别陷入语法细节。你只需要看到:Workflow = 一个 agent + 输入 schema + 输出 schema + 一段有限运行逻辑。

Primary source: Flue Workflows guide.

2. 三段式:input / output / run

字段它回答的问题为什么重要
input调用者必须给什么?Flue 会验证传入 JSON;错误输入不会悄悄进入模型。
output这次运行必须返回什么?结果结构可预测,适合 CI、后台任务、API pipeline。
run如何从 input 得到 output?这里写有限运行逻辑:创建 session、prompt、读写文件、返回结果。

Workflow 的价值:它把“让模型做点事”压进一个有边界的 contract:输入经过验证,输出也要符合 schema,运行过程有 run id / events / result 可检查。

3. 为什么 run 里还有 harness

Workflow 不是直接裸调 LLM。它仍然使用一个 agent harness,只是这个 harness 被放进一个有限运行里。官方例子中:

async run({ harness, input }) {
  const session = await harness.session();
  const response = await session.prompt(input.text);
  return { summary: response.text };
}

harness.session()

创建/获取这次 workflow run 里的 agent session,让模型在配置好的 harness 中工作。

session.prompt(...)

把任务交给模型处理。这里的 prompt 来自已经验证过的 input.text

return { summary }

返回结构化结果。它需要匹配 output schema。

记忆钩子:Agent 像“长期同事”;Workflow 像“带验收标准的一张工单”。工单里也可以请同事干活,但工单必须结束并交付结果。

4. Workflow vs Action:先记一个边界

Flue 还支持 Action。现在只需要知道一个边界,别混淆:

概念你先这样理解何时出现
Workflow一个可独立运行、记录 run/result/events 的有限 operation。你想从外部/CLI/应用代码触发一次明确任务。
Action可复用的 operation 定义;可以绑定到 workflow,也可以给 agent 让模型决定何时调用。你发现同一段 input/output/run 逻辑想复用。

Source: Flue Actions guide.

5. 练习:结构配对

先自己答:下面需求应该放到 workflow 的哪一段?

  1. 要求调用者必须提供 { text: string }
  2. 要求返回值必须是 { summary: string }
  3. 让模型总结文本,并把结果包装成 JSON。
查看参考答案
  1. input schema。
  2. output schema。
  3. run({ harness, input })

小测验

在 Flue Workflow 里,input 最核心的作用是?

再来一题

什么时候最适合用 Workflow,而不是持续 Agent?

本课结束后你应该能说出

  • src/workflows/summarize.ts 的文件名会成为 workflow 名。
  • defineWorkflow 里最关键的是 inputoutputrun
  • run 通过 harness 使用 agent 能力,但整个 workflow 仍然是有限运行。
  • 当同一段 operation 需要复用时,再引入 Action 的概念。

下一课建议:0004 — Tools、Skills、Actions:三种“能力”的边界。这会帮你理解 Flue 如何给 agent 安全地扩展能力。

如果你想偏实操,我也可以下一节改成“本地创建 summarize workflow 并运行”。