Day 17 / 共 20 天 · 第 4 周 Agent/Workflow/生态
Agent 智能体(建在 Workflow 上)
建在 Workflow 上的 Agent——让 LLM 自主决定"用哪个工具、怎么多步解决问题"。今天看 FunctionAgent 和 ReActAgent,以及 RAG 怎么作为 Agent 的一个工具(本课两条主线在此汇合)。
📍 你在整条链的位置
Workflow D16→
Agent(用工具+多步)→
聊天记忆 D18→
观测 D19
L01
Agent 比普通 LLM 多什么
🤔 问"北京比上海气温高几度?",普通 LLM 能答吗?
答不准——它不知道实时天气。而且这需要"查北京 + 查上海 + 相减"三步。普通 LLM 只会一次性输出,不会"分步查、用工具"。
💡 Agent = 会用工具 + 能自主循环 的 LLM
① 工具:能调函数(查天气、算数、搜网、跑 RAG);② 自主循环:自己决定"该用哪个工具、用完看结果再决定下一步",直到解决。这超越了 RAG 的"一次检索一次生成"——是多步、动态、自主的。LlamaIndex 的 Agent 都建在 Day 16 的 Workflow 上(
agent/workflow/)。L02
tools:给 LLM 的"能力"
tools/:FunctionTool(把 Python 函数包成工具)、QueryEngineTool(把查询引擎包成工具)。
📝 把函数变成工具
from llama_index.core.tools import FunctionTool
def get_weather(city: str) -> str:
"""查询某城市当前气温""" # ← 这个 docstring 给 LLM 看,帮它判断何时用
return f"{city}: 15°C"
tool = FunctionTool.from_defaults(fn=get_weather)工具的"描述"是给 LLM 读的
工具的名字、docstring、参数类型会转成 LLM 能理解的"工具规格"。LLM 看着描述判断"该调哪个、传什么参数"(Day 15 的 function calling)。所以描述要写清楚。
QueryEngineTool 把 Day 12 的查询引擎包成工具——RAG 就成了 Agent 的一种能力(L06)。L03
FunctionAgent:用原生工具调用
agent/workflow/function_agent.py:19:class FunctionAgent(BaseWorkflowAgent)。
📝 一个能查天气+算数的 Agent
from llama_index.core.agent.workflow import FunctionAgent
agent = FunctionAgent(tools=[weather_tool, subtract_tool], llm=llm)
resp = await agent.run("北京比上海气温高几度?")
# → Agent 自主:查北京(15°) → 查上海(12°) → 相减 → "北京比上海高 3 度"依赖 LLM 的原生工具调用(最主流最稳)
现代 LLM(GPT-4/Claude)原生支持"函数调用"——给它工具列表,它直接返回"我要调 weather('北京')"这样的结构化决策。FunctionAgent 用这个:LLM 决定调哪个 → Agent 执行 → 结果喂回 LLM → 循环直到给出最终答案。比让模型"用文字描述要调什么"稳。
L04
Agent 循环:想-做-看
function_agent.py:33-48 的 take_step:把对话 + 工具喂 LLM,LLM 要么"决定调工具"要么"给最终答案"。这个 take_step 被包在 Workflow 里循环执行:
Agent 循环:take_step 让 LLM 决策 → 调工具就执行、结果喂回、再 take_step → 直到 LLM 给出答案。
这就是 Workflow 循环的用武之地
"想(take_step)-做(调工具)-看(结果)-再想"是个循环——正好用 Day 16 的 Workflow 事件循环表达。这就是"Agent 建在 Workflow 上"的原因。
L05
ReActAgent:用文字推理
agent/workflow/react_agent.py:38:用 ReAct(Reasoning+Acting)范式,让 LLM 用文字输出:
📝 ReAct 的文字循环(:169-171 的提示词格式)
Thought: 我需要先查北京气温 # 推理
Action: get_weather
Action Input: {"city": "北京"} # 行动
Observation: 北京 15°C # 观察(工具返回)
Thought: 再查上海…
... Thought: 我知道答案了
Answer: 北京比上海高 3 度FunctionAgent vs ReActAgent
FunctionAgent 用模型原生函数调用(结构化、可靠,需模型支持);ReActAgent 让模型用文字输出 Thought/Action/Observation(任何模型都能用,但要解析文字、稍不稳)。回想你学过的 crewAI/langgraph 里的 ReAct——同一经典范式。有原生函数调用的模型优先 FunctionAgent;开源/老模型用 ReActAgent。
L06
RAG 作为工具(两主线汇合)
💡 QueryEngineTool 把 RAG 包成工具
QueryEngineTool.from_defaults(query_engine, name, description) 把 Day 12 的查询引擎包成工具给 Agent 用。📝 一个客服 Agent 有多个工具
工具1:
工具2:
用户问啥,Agent 自主选:问"产品参数"→ 调 RAG 工具;问"我的订单"→ 调订单工具。
RAG工具(查产品手册,前三周的 RAG)工具2:
订单查询、工具3:退款用户问啥,Agent 自主选:问"产品参数"→ 调 RAG 工具;问"我的订单"→ 调订单工具。
Agentic RAG
RAG 不再是固定流程,而是 Agent 能按需调用的能力之一。本课两条主线(RAG + Agent)在这里汇合。
L07
多智能体
agent/workflow/multi_agent_workflow.py 的 AgentWorkflow:多个 Agent 协作——各有专长和工具,互相"移交"(handoff)任务。
读法:复杂任务拆给多个专家 Agent:研究员 + 写作者 + 审核者,互相传递。它们也建在 Workflow 上(Agent 间用事件通信)。回想你学过的 crewAI(多智能体协作)、AutoGPT——AgentWorkflow 是对标能力。
codeact_agent.py 还有能写代码执行的 CodeAct Agent。L08
今日小结 + 动手
🧠 今天你应该能回答
- Agent 比普通 LLM 多哪两样(工具 + 自主循环)?
- 工具的"描述"为什么重要?Agent 循环"想-做-看"怎么工作?
- FunctionAgent vs ReActAgent 的区别?各适合什么模型?
- "Agentic RAG"怎么把本课两条主线汇合?
✋ 动手
cd /Users/bitmart/work/codes/github/llama_index/llama-index-core/llama_index/core
ls agent/workflow/
sed -n '19,50p' agent/workflow/function_agent.py
sed -n '165,205p' agent/workflow/react_agent.py
ls tools/
明天预告 · Day 18:单轮问答升级为多轮对话——ChatEngine + Memory。"它多少钱?"里的"它"怎么理解(指代)、对话历史太长怎么管理(缓冲/摘要/向量记忆)。