Day 16 / 共 20 天 · 第 4 周 Agent/Workflow/生态

Workflow 引擎(超越 RAG)

前三周把 RAG 全链路拆透了。第 4 周超越 RAG——LlamaIndex 用 Workflow(事件驱动引擎)作为 Agent 的底座。今天用图讲透"事件驱动编排"这个新范式:步骤发事件、事件触发步骤。

📍 你在整条链的位置(RAG 全链路已完成 ✅,进入智能体)
RAG 全链路 ✅ Workflow 编排引擎 Agent D17 记忆/观测
L01

超越固定 RAG 流程

🤔 RAG 是"检索→生成"的固定流程,但有些任务不固定 比如 Agent:"先想想用什么工具 → 调工具 → 看结果 → 再决定下一步 → 直到解决"。这是动态的、有分支、可能循环的——不是写死的流程。用固定的函数调用链没法优雅表达。
💡 Workflow = 表达"复杂控制流"的事件驱动引擎 LlamaIndex 用 Workflow 表达分支、循环、并发。Agent(D17)、复杂 RAG(多步查询)都建在 Workflow 上。(注意:Workflow 核心已抽成独立包 workflows,core 的 workflow/ 主要 re-export + LlamaIndex 特定事件。)
L02

事件驱动:步骤发事件、事件触发步骤

StartEvent step_one收Start发Middle step_two收Middle StopEvent 结束 Start Middle Stop step_two 也能发回 step_one 能收的事件 → 循环(Agent 的"想-做-看"就靠它)
事件驱动像多米诺骨牌:step 发出事件 → 接收该事件的 step 被触发 → 直到发出 StopEvent。发回环事件即可循环。
比"写死的调用链"灵活 能分支(发不同事件走不同步骤)、能循环(发回环事件)、能并发。目录:workflow/(workflow.py/decorators.py/events.py/context.py/handler.py)。
L03

@step:用类型注解声明事件流

workflow/decorators.py:7step(委托上游 workflows 包)。用法:

from workflows import Workflow, step
from workflows.events import StartEvent, StopEvent, Event

class MyFlow(Workflow):
    @step
    async def step_one(self, ev: StartEvent) -> MiddleEvent:   # 收 Start,发 Middle
        return MiddleEvent(data="...")
    @step
    async def step_two(self, ev: MiddleEvent) -> StopEvent:    # 收 Middle,发 Stop
        return StopEvent(result="done")
💡 参数类型=收什么事件,返回类型=发什么事件 引擎读这些类型注解,自动把步骤连成事件流——你不用手写"谁调谁"。只写步骤 + 声明输入输出事件,引擎自动编排。比手写调用链优雅(回想 wasm-go 的类型驱动、langgraph 的图)。
L04

Event:既是信号也是数据

💡 自定义 Event 继承 Event(Pydantic),装数据 步骤间通过 Event 传数据(MiddleEvent(data="...") 把 data 传给接收它的步骤)。分支:步骤按情况返回 EventAEventB,走不同后续。循环:步骤返回一个又会触发自己的事件。
Event 类型 = 控制流的"路标" Agent 的"想-做-看"循环就靠它:处理步骤发出"要调工具"事件 → 工具步骤执行 → 发出"有结果了"事件 → 回到处理步骤 → 直到发 StopEvent。(Day 17 会看到具体的 Agent 循环)
L05

Start / Stop Event

📝 跑一个 Workflow
flow = MyFlow()
result = await flow.run(input="...")   # 发 StartEvent 启动 → ... → StopEvent → 返回 result
读法:run 发出 StartEvent 启动,引擎按事件流跑各步骤,直到某步骤返回 StopEvent 结束、返回其 result。接收 StartEvent 的是"入口",返回 StopEvent 的是"出口",中间任意分支/循环。
L06

Context:跨步骤共享状态

workflow/context.pyContext:步骤可 await ctx.store.set/get 存取全局状态、ctx.write_event_to_stream 发流式进度、ctx.collect_events 等多个事件(并发汇合)。

Context = "共享内存 + 流式通道" 除了用 Event 传数据,还能用 Context 存整个流程共享的状态(累积的中间结果)。collect_events 支持"扇入"(等几个并发步骤都完成再继续)。write_event_to_stream 让流程"边跑边报进度"(前端实时看到 Agent 在干嘛)。回想 langgraph 的 State、wasm-go 的 Context——都是"跨步骤共享状态"的机制。
L07

和 langgraph 对比

两种编排范式 你学过的 langgraph 用"图"(节点+边+状态通道,Pregel 超步);LlamaIndex Workflow 用"事件驱动"(步骤+事件)。本质都是表达复杂控制流(分支/循环/并发),风格不同:langgraph 显式画图;Workflow 用类型注解隐式连接(收什么事件、发什么事件)。Workflow 的事件模型对"动态、涌现式"流程更自然(不用预先画全图)。两者都是 Agent 时代的编排基础设施。
L08

今日小结 + 动手

🧠 今天你应该能回答

  • 为什么复杂任务需要 Workflow 而非固定 RAG 流程?
  • "事件驱动"怎么工作(步骤收发事件、像多米诺)?
  • @step 怎么用类型注解声明事件流?Event 怎么做分支/循环?
  • Context 的作用?和 langgraph 的异同?

✋ 动手

cd /Users/bitmart/work/codes/github/llama_index/llama-index-core/llama_index/core
ls workflow/
cat workflow/decorators.py
grep -rn "upstream_step\|from workflows" workflow/*.py | head
明天预告 · Day 17:建在 Workflow 上的 Agent——让 LLM 自主决定用哪个工具、多步解决问题。FunctionAgent(原生工具调用)和 ReActAgent(推理-行动循环)。RAG 会成为 Agent 的一个工具。
← Day 15 Day 17 · Agent →