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:19class 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-48take_step:把对话 + 工具喂 LLM,LLM 要么"决定调工具"要么"给最终答案"。这个 take_step 被包在 Workflow 里循环执行:

take_step:LLM 看对话+工具决定:调工具 or 给答案? 要调工具 → 执行工具结果加进对话 ✅ 给最终答案 → 结束 调工具 能答了 带着新结果再 take_step
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:RAG工具(查产品手册,前三周的 RAG)
工具2:订单查询、工具3:退款
用户问啥,Agent 自主选:问"产品参数"→ 调 RAG 工具;问"我的订单"→ 调订单工具。
Agentic RAG RAG 不再是固定流程,而是 Agent 能按需调用的能力之一。本课两条主线(RAG + Agent)在这里汇合。
L07

多智能体

agent/workflow/multi_agent_workflow.pyAgentWorkflow:多个 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。"它多少钱?"里的"它"怎么理解(指代)、对话历史太长怎么管理(缓冲/摘要/向量记忆)。
← Day 16 Day 18 · 聊天记忆 →