主题
本教程演示如何开始用 LlamaIndex 构建智能体(agent)。我们先从一个最基础的示例入手,再说明如何加入 RAG(检索增强生成)能力。
提示
请先完成安装这一步。
提示
想用本地模型?如果你希望只用本地模型完成这个起步教程,请改看这篇教程。
设置你的 OpenAI API key
LlamaIndex 默认使用 OpenAI 的 gpt-3.5-turbo,不过本示例用 gpt-4o-mini 作为 LLM。请把它设为环境变量,让你的代码能取用 API key:
终端窗口
# MacOS/Linux
export OPENAI_API_KEY=XXXXX
# Windows
set OPENAI_API_KEY=XXXXX提示
如果你使用的是与 OpenAI 兼容的 API,可以改用 OpenAILike 这个 LLM 类。相关信息见 OpenAILike LLM 集成与 OpenAILike Embeddings 集成。
基础的 Agent 示例
先来看一个简单的例子:一个能调用工具做基础乘法的 agent。新建一个名为 starter.py 的文件:
import asyncio
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.openai import OpenAI
# Define a simple calculator tool
def multiply(a: float, b: float) -> float:
"""Useful for multiplying two numbers."""
return a * b
# Create an agent workflow with our calculator tool
agent = FunctionAgent(
tools=[multiply],
llm=OpenAI(model="gpt-4o-mini"),
system_prompt="You are a helpful assistant that can multiply two numbers.",
)
async def main():
# Run the agent
response = await agent.run("What is 1234 * 4567?")
print(str(response))
# Run the agent
if __name__ == "__main__":
asyncio.run(main())它会输出类似这样的内容:The result of \( 1234 \times 4567 \) is \( 5,678,678 \).
刚才发生的事是:
- 我们给 agent 提了一个问题:
What is 1234 * 4567? - 底层会把这个问题,连同工具的 schema(名称、docstring 与参数)一起传给 LLM
- Agent 选中了
multiply工具,并写好了传给工具的参数 - Agent 拿到工具的返回结果,把它整合进最终回答
提示
如你所见,我们用的是 async 的 Python 函数。许多 LLM 和模型都支持异步调用,为了提升应用性能,推荐使用异步代码。想更多了解异步编程与 Python,建议读一读这篇异步 + Python 简述。
加入聊天历史
AgentWorkflow 还能记住之前的消息。这些记忆保存在 AgentWorkflow 的 Context 里。
如果传入了 Context,agent 会用它继续这段对话。
from llama_index.core.workflow import Context
# create context
ctx = Context(agent)
# run agent with context
response = await agent.run("My name is Logan", ctx=ctx)
response = await agent.run("What is my name?", ctx=ctx)加入 RAG 能力
接下来通过给 agent 加上检索文档的能力来做增强。先在终端里准备一些示例数据:
终端窗口
mkdir data
wget https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt -O data/paul_graham_essay.txt此时你的目录结构应该像这样:
├── starter.py └── data └── paul_graham_essay.txt现在我们可以用 LlamaIndex 做一个检索文档的工具。没有配置 Settings.embed_model 时,VectorStoreIndex 会退回到 OpenAIEmbedding,默认使用 text-embedding-ada-002 模型。新项目建议显式传入 OpenAIEmbedding(model="text-embedding-3-small")。
提示
想在本地跑嵌入、不用任何 API key?只需两行,把托管的 embedder 换成本地的 Sentence Transformers 模型:
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.core import Settings
Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")全本地化的流程见本地起步教程。
改动后的 starter.py 应该像这样:
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.openai import OpenAI
import asyncio
import os
# Create a RAG tool using LlamaIndex
documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
def multiply(a: float, b: float) -> float:
"""Useful for multiplying two numbers."""
return a * b
async def search_documents(query: str) -> str:
"""Useful for answering natural language questions about an personal essay written by Paul Graham."""
response = await query_engine.aquery(query)
return str(response)
# Create an enhanced workflow with both tools
agent = FunctionAgent(
tools=[multiply, search_documents],
llm=OpenAI(model="gpt-4o-mini"),
system_prompt="""You are a helpful assistant that can perform calculations
and search through documents to answer questions.""",
)
# Now we can ask questions about the documents or do calculations
async def main():
response = await agent.run(
"What did the author do in college? Also, what's 7 * 8?"
)
print(response)
# Run the agent
if __name__ == "__main__":
asyncio.run(main())现在这个 agent 已经能在计算器和文档检索之间自如切换来回答问题了。
持久化 RAG 索引
为了避免每次都重新处理文档,你可以把索引持久化到磁盘:
# Save the index
index.storage_context.persist("storage")
# Later, load the index
from llama_index.core import StorageContext, load_index_from_storage
storage_context = StorageContext.from_defaults(persist_dir="storage")
index = load_index_from_storage(storage_context)
query_engine = index.as_query_engine()提示
如果你用了默认之外的向量库集成,通常可以直接从那个向量库重新加载:
index = VectorStoreIndex.from_vector_store(vector_store)下一步做什么?
这还只是 LlamaIndex agent 能力的开端。你可以:
- 给 agent 加入更多工具
- 换用不同的 LLM
- 用系统提示词定制 agent 的行为
- 加入流式输出能力
- 实现在环(human-in-the-loop)工作流
- 让多个 agent 协作完成任务
几个有用的下一步链接: