这篇适合谁,读完能做到什么
如果你已经知道大模型能做什么,想做一个能调用自己的函数、查询自己的文档或与其他智能体协作的智能体,这篇适合你。读完你应该能写出一个基础的 LlamaIndex 智能体,让它保留对话状态,把查询引擎包装成工具,并把几个智能体组合成一个工作流。
三类智能体
LlamaIndex 支持三类主要的推理智能体[1]:
- Function Calling Agents,适用于能调用特定函数的模型[1]。
- ReAct Agents,适用于任何提供聊天或文本接口的模型,能处理复杂推理,并展示每个动作背后的推理过程[1]。
- Advanced Custom Agents,使用更复杂的方法处理更难的任务和工作流[1]。
做第一个智能体,只需要给它一组函数或工具,智能体就由这些工具搭建起来[1]。三类之间的差别主要在于模型能力:能直接调用函数的模型适合 Function Calling Agents,只提供聊天或文本接口的模型则可以用 ReAct Agents[1]。
搭建一个最小的智能体
下面的例子定义了一个 multiply 函数,配置好 Hugging Face 的推理 LLM,然后用 AgentWorkflow.from_tools_or_functions() 创建智能体。函数的类型注解、名称和文档字符串都会被包含在模型读取的结构描述里[1]:
from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
from llama_index.core.agent.workflow import AgentWorkflow
from llama_index.core.tools import FunctionTool
# define sample Tool -- type annotations, function names, and docstrings, are all included in parsed schemas!
def multiply(a: int, b: int) -> int:
"""Multiplies two integers and returns the resulting integer"""
return a * b
# initialize llm
llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")
# initialize agent
agent = AgentWorkflow.from_tools_or_functions(
[FunctionTool.from_defaults(multiply)],
llm=llm
)智能体默认是无状态的,每次运行都不记得之前的内容。要让对话连续下去,需要创建一个 Context 对象,并在每次调用时传入[1]:
# stateless
response = await agent.run("What is 2 times 2?")
# remembering state
from llama_index.core.workflow import Context
ctx = Context(agent)
response = await agent.run("My name is Bob.", ctx=ctx)
response = await agent.run("What was my name again?", ctx=ctx)注意代码里的 await。LlamaIndex 的智能体是异步的,调用必须放在异步代码中执行[1]。
LlamaIndex 的工具
模型看到的就是工具的接口,所以一组定义清楚的工具对效果很关键[2]。LlamaIndex 的工具主要有四类:FunctionTool、QueryEngineTool、ToolSpec 和实用工具[2]。
FunctionTool 可以包装任何 Python 函数。它既接受同步函数,也接受异步函数,可选的 name 和 description 参数会帮助智能体判断何时、如何使用这个工具[2]。name 和 description 虽然是可选的,但模型就是靠它们选择工具,建议认真写。也可以直接调用工具来测试:
from llama_index.core.tools import FunctionTool
def get_weather(location: str) -> str:
"""Useful for getting the weather for a given location."""
print(f"Getting weather for {location}")
return f"The weather in {location} is sunny"
tool = FunctionTool.from_defaults(
get_weather,
name="my_weather_tool",
description="Useful for getting the weather for a given location.",
)
tool.call("New York")用 QueryEngineTool 做智能体式 RAG
检索增强生成(RAG)是回答自有文档问题的常用做法。在智能体式的设置中,智能体自己决定是用查询引擎,还是使用其他工具或流程,而不是直接基于检索到的文本自动作答[1]。要做到这一点,需要给查询引擎起一个名字并写清描述。模型正是依靠这两项信息来正确选择工具[1]。
下面的例子在持久化的 Chroma 集合上建立向量索引,再把它的查询引擎转换成 QueryEngineTool[2],嵌入模型是 BAAI/bge-small-en-v1.5[2]:
from llama_index.core import VectorStoreIndex
from llama_index.core.tools import QueryEngineTool
from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.vector_stores.chroma import ChromaVectorStore
embed_model = HuggingFaceEmbedding("BAAI/bge-small-en-v1.5")
db = chromadb.PersistentClient(path="./alfred_chroma_db")
chroma_collection = db.get_or_create_collection("alfred")
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
index = VectorStoreIndex.from_vector_store(vector_store, embed_model=embed_model)
llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")
query_engine = index.as_query_engine(llm=llm)
tool = QueryEngineTool.from_defaults(query_engine, name="some useful name", description="some useful description")这段代码用到了 chromadb,但没有导入它,运行前要自己补上 import chromadb。
多个智能体组成工作流
AgentWorkflow 也支持多智能体系统。给每个智能体起名字并写描述,系统会保证同一时间只有一个活跃的发言者,智能体之间还可以把任务交接给对方[1]。把每个智能体的职责收窄,通常能提高它回答对应问题时的准确度[1]。
智能体也可以直接当作其他智能体的工具。下面的例子先为计算器智能体定义两个普通函数[1]:
from llama_index.core.agent.workflow import (
AgentWorkflow,
FunctionAgent,
ReActAgent,
)
# Define some tools
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
def subtract(a: int, b: int) -> int:
"""Subtract two numbers."""
return a - b计算器是一个 ReActAgent,它有自己的名称、描述、系统提示词和工具[1]:
calculator_agent = ReActAgent(
name="calculator",
description="Performs basic arithmetic operations",
system_prompt="You are a calculator assistant. Use your tools for any math operation.",
tools=[add, subtract],
llm=llm,
)随后,工作流把 calculator 设为根智能体,并把一条用户消息交给它处理[1]:
# Create and run the workflow
agent = AgentWorkflow(
agents=[calculator_agent, query_agent], root_agent="calculator"
)
# Run the system
response = await agent.run(user_msg="Can you add 5 and 3?")这段代码引用了 query_agent,但没有在同一段里定义它。它是另一个智能体,负责包装前面 RAG 部分的查询工具。
选择智能体类,要看模型的能力。FunctionAgent 适合带函数调用接口的模型,ReActAgent 则可以用于任何 LLM[1]。
用实用工具处理大量数据
直接查询 API 有时会返回远超需要的数据,这些数据可能挤占上下文窗口,或者推高 token 用量。实用工具就是为这种情况准备的[2]。
OnDemandToolLoader 可以包装任何 LlamaIndex 数据加载器,也就是 BaseReader 类。一次工具调用里,它会依次完成加载数据、建立索引和按需查询[2]。LoadAndSearchToolSpec 接收一个已有的工具,返回两个新工具:一个负责加载并索引输出,另一个负责在这个索引中搜索[2]。
接入 MCP 工具
LlamaIndex 可以通过 LlamaHub 上的 ToolSpec 使用 MCP 工具,LlamaHub 上也列着各种 ToolSpec 和实用工具[2]。先安装 MCP 的 ToolSpec[2]:
pip install llama-index-tools-mcp示例假设 MCP 服务器已经在 127.0.0.1:8000 上运行,你也可以把客户端指向自己的服务器[2]。
下面的代码连接本地地址上的 MCP 服务器,用 McpToolSpec 包装它,然后创建智能体上下文[2]:
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec
# We consider there is a mcp server running on 127.0.0.1:8000, or you can use the mcp client to connect to your own mcp server.
mcp_client = BasicMCPClient("http://127.0.0.1:8000/sse")
mcp_tool = McpToolSpec(client=mcp_client)
# get the agent
agent = await get_agent(mcp_tool)
# create the agent context
agent_context = Context(agent)代码中的 get_agent 没有定义,运行前需要自己实现这个函数。
限制和常见问题
- 工具的名称和描述决定模型怎么选工具。描述含糊,就容易选错工具或填错参数[2]。
- 多智能体系统里,每个智能体都要有清楚的名称和描述,系统正是靠这两项决定由谁发言[1]。
- 只在原始结果大到无法直接回传给模型时才用实用工具[2]。
- 示例依赖 Hugging Face 的推理 LLM 和本地的 Chroma 存储,两者都需要先配置好才能运行。
- 工具选择取决于数据在哪里、问题是什么样的。用 QueryEngineTool 回答文档问题,还是用其他工具,要按任务来定[1]。
- 多个智能体之间交接任务时,名称和描述写得含糊,系统就可能把请求交给不合适的智能体,所以要把职责边界说清楚[1]。
下一步
想了解 MCP,可以先从那门免费的 MCP 课程开始[2]。ToolSpec 和实用工具的列表在 LlamaHub 上,网址是 https://llamahub.ai/[2]。
本文改编自 Hugging Face 开源智能体课程(Agents Course)中 LlamaIndex 部分的智能体与工具两节[1][2],原文以 Apache-2.0 许可证发布。
来源
- 1Using Agents in LlamaIndexHugging Face agents-course (Apache-2.0)
- 2Using Tools in LlamaIndexHugging Face agents-course (Apache-2.0)
引用本页: LlamaIndex 智能体与工具. TellWorld, https://www.tellworld.net/zh/practice/practice-llamaindex-agents. 更新于 2026-11-14