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
事件驱动:步骤发事件、事件触发步骤
事件驱动像多米诺骨牌:step 发出事件 → 接收该事件的 step 被触发 → 直到发出 StopEvent。发回环事件即可循环。
比"写死的调用链"灵活
能分支(发不同事件走不同步骤)、能循环(发回环事件)、能并发。目录:
workflow/(workflow.py/decorators.py/events.py/context.py/handler.py)。L03
@step:用类型注解声明事件流
workflow/decorators.py:7 的 step(委托上游 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 传给接收它的步骤)。分支:步骤按情况返回 EventA 或 EventB,走不同后续。循环:步骤返回一个又会触发自己的事件。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.py 的 Context:步骤可 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 的一个工具。