1. 入门教程(使用本地LLMs) #
本教程将展示如何开始使用LlamaIndex构建智能体。我们将从一个基础示例入手,随后演示如何添加RAG(检索增强生成)功能。
我们将使用 BAAI/bge-base-en-v1.5 作为我们的嵌入模型,llama3.1 通过 Ollama 提供。
2. 设置 #
Ollama是一款工具,能帮助您以最简设置在本机部署LLMs。
跟随自述文件了解如何安装它。
要下载Llama3模型,只需执行:
# 使用Ollama下载llama3.1模型
# 这将从Ollama的模型库中下载llama3.1 8B模型到本地
ollama pull llama3.1注意: 你需要一台内存至少约32GB的机器。
正如我们在安装指南中提到的,llama-index 实际上是一个软件包的集合。要运行Ollama和Huggingface,我们需要安装这些集成组件:
# 安装LlamaIndex的Ollama集成包
# llama-index-llms-ollama: 提供与Ollama本地LLM的集成
# 这个包允许LlamaIndex使用通过Ollama运行的本地语言模型
pip install llama-index-llms-ollama
# 安装LlamaIndex的HuggingFace嵌入模型集成包
# llama-index-embeddings-huggingface: 提供与HuggingFace嵌入模型的集成
# 这个包允许LlamaIndex使用HuggingFace上的各种嵌入模型
pip install llama-index-embeddings-huggingfacellama-index-llms-ollama:
- 提供与Ollama的集成接口
- 允许使用本地部署的LLM模型(如llama3.1、mistral等)
- 支持异步调用和流式输出
- 无需网络连接,完全本地运行
llama-index-embeddings-huggingface:
- 提供与HuggingFace嵌入模型的集成
- 支持多种嵌入模型(如BGE、sentence-transformers等)
- 可以离线使用预下载的模型
- 提供高质量的文本向量化功能
更多集成功能均列于 https://llamahub.ai。
3. 基础Agent示例 #
让我们从一个简单的例子开始,使用一个能通过调用工具执行基本乘法运算的agent。创建一个名为 starter.py 的文件:
# 导入异步编程所需的模块
import asyncio
# 导入LlamaIndex的核心组件
# FunctionAgent: 用于创建基于函数的智能代理
# Ollama: Ollama本地语言模型的集成
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.ollama import Ollama
# 定义一个简单的计算器工具函数
# 这个函数接受两个浮点数参数,返回它们的乘积
def multiply(a: float, b: float) -> float:
"""用于计算两个数字的乘积。"""
return a * b
# 创建一个带有计算器工具的智能代理
# tools: 代理可以使用的工具列表
# llm: 使用的语言模型(这里使用Ollama的llama3.1)
# system_prompt: 定义代理行为的系统提示
# request_timeout: 设置请求超时时间为360秒
# context_window: 手动设置上下文窗口大小以限制内存使用
agent = FunctionAgent(
tools=[multiply],
llm=Ollama(
model="llama3.1",
request_timeout=360.0,
# 手动设置上下文窗口以限制内存使用
context_window=8000,
),
system_prompt="你是一名乐于助人的助手,可以计算两个数字的乘积。",
)
# 定义主异步函数
async def main():
# 运行代理,向其提出一个数学问题
response = await agent.run("请帮我计算7乘以8等于多少?")
# 打印代理的回答
print(str(response))
# 程序入口点
# 如果直接运行此脚本,则执行main函数
if __name__ == "__main__":
asyncio.run(main())
这将输出类似以下内容:17乘以8等于56
3.1 发生了什么? #
- 代理收到了一个问题:
请帮我计算7乘以8等于多少? - 在底层实现中,这个问题连同工具的架构(包括名称、文档字符串及参数)被传递给了LLM
- 代理选择了
multiply工具并写入了参数 - 代理从工具接收到结果,并将其内插至最终响应中
💡 提示: 如你所见,我们正在使用
asyncPython函数。许多LLM和模型支持异步调用,建议使用异步代码来提升应用程序性能。想了解更多关于异步代码和Python的知识,我们推荐阅读关于异步与Python的简短章节。
4. 添加聊天历史记录 #
AgentWorkflow 还能够记住之前的消息。这一功能内置于 Context 的 AgentWorkflow 中。
如果 Context 参数被传入时,代理将使用它来继续对话:
# 导入FunctionAgent类,用于创建基于函数的智能代理
from llama_index.core.agent.workflow import FunctionAgent
# 导入Ollama类,用于集成本地Ollama语言模型
from llama_index.llms.ollama import Ollama
# 导入Context类,用于管理代理的对话上下文
from llama_index.core.workflow import Context
# 导入asyncio模块,用于异步编程
import asyncio
# 创建一个带有记忆功能的智能代理,只指定llm和system_prompt,不指定tools
agent = FunctionAgent(
# 指定使用的本地Ollama模型及相关参数
llm=Ollama(
model="llama3.1", # 使用llama3.1模型
request_timeout=360.0, # 设置请求超时时间为360秒
context_window=8000, # 设置上下文窗口大小为8000
),
# 设置系统提示,要求代理记住用户信息并进行多轮对话
system_prompt="你是一名乐于助人的助手,可以记住用户信息并进行多轮对话。请始终友好、自然地与用户交流。",
)
# 定义主异步函数
async def main():
try:
# 打印智能代理对话演示标题
print("🤖 智能代理对话演示")
# 打印分隔线
print("=" * 50)
# 创建对话上下文对象,用于存储代理的对话历史
ctx = Context(agent)
# 第一轮对话:告诉代理我的名字
print("\n📝 第一轮对话:")
print("-" * 30)
# 运行代理,传入用户输入和上下文
response = await agent.run("我的名字是张三", ctx=ctx)
# 打印用户输入
print(f"👤 用户: 我的名字是张三")
# 打印代理回复
print(f"🤖 代理: {response}")
# 第二轮对话:询问代理我的名字
print("\n📝 第二轮对话:")
print("-" * 30)
# 运行代理,传入用户输入和上下文
response = await agent.run("你还记得我的名字吗?", ctx=ctx)
# 打印用户输入
print(f"👤 用户: 你还记得我的名字吗?")
# 打印代理回复
print(f"🤖 代理: {response}")
# 打印对话演示完成提示
print("\n✅ 对话演示完成!")
except Exception as e:
# 捕获异常并打印错误信息
print(f"❌ 运行出错: {e}")
print("请检查Ollama服务是否正在运行")
# 程序入口点,如果直接运行此脚本,则执行main函数
if __name__ == "__main__":
asyncio.run(main())5. 添加RAG功能 #
现在我们可以使用LlamaIndex创建一个工具来搜索文档。我们将使用HuggingFace的BGE嵌入模型和Ollama的llama3.1模型。
我们修改过的 starter.py 应该看起来像这样:
# 导入异步编程所需的模块
import asyncio
# 导入os模块,用于设置环境变量
import os
# 从llama_index.core模块导入核心组件
# VectorStoreIndex用于创建向量存储索引
# SimpleDirectoryReader用于从目录读取文档
# Settings用于设置全局默认值
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
# 从llama_index.core.agent.workflow导入AgentWorkflow,用于创建工作流代理
from llama_index.core.agent.workflow import AgentWorkflow
# 从llama_index.llms.ollama导入Ollama,用于集成本地Ollama语言模型
# 从llama_index.embeddings.huggingface导入HuggingFaceEmbedding,用于集成HuggingFace嵌入模型
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
# 设置HuggingFace镜像源,提升模型下载速度
os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
# 设置全局默认的嵌入模型为BGE-base-en-v1.5
Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-base-en-v1.5")
# 设置全局默认的语言模型为Ollama的llama3.1,超时时间为360秒,上下文窗口为8000
Settings.llm = Ollama(
model="llama3.1",
request_timeout=360.0,
context_window=8000,
)
# 从data目录加载所有文档
documents = SimpleDirectoryReader("data").load_data()
# 使用加载的文档创建向量存储索引,自动分块并生成向量嵌入
index = VectorStoreIndex.from_documents(
documents,
# 可以在此处覆盖embed_model
# embed_model=Settings.embed_model,
)
# 从索引创建查询引擎,提供自然语言查询接口
query_engine = index.as_query_engine(
# 可以在此处覆盖llm
# llm=Settings.llm,
)
# 定义乘法计算工具函数,接收两个浮点数参数,返回它们的乘积
def multiply(a: float, b: float) -> float:
"""用于计算两个数字的乘积。"""
return a * b
# 定义文档搜索工具函数,异步检索文档并返回答案
async def search_documents(query: str) -> str:
"""用于根据自然语言问题检索文档内容并返回答案。"""
# 使用查询引擎异步查询文档
response = await query_engine.aquery(query)
# 返回查询结果的字符串表示
return str(response)
# 创建一个包含乘法和文档搜索工具的工作流代理
agent = AgentWorkflow.from_tools_or_functions(
[multiply, search_documents],
llm=Settings.llm,
system_prompt="""你是一名乐于助人的助手,可以进行数学计算并检索文档来回答用户问题。""",
)
# 定义主异步函数
async def main():
# 向代理提出一个包含文档检索和数学计算的复合问题
response = await agent.run("红楼梦主要人物有哪些?另外,7乘以8等于多少?")
# 打印代理的回答
print(response)
# 程序入口点,如果直接运行此脚本,则执行main函数
if __name__ == "__main__":
asyncio.run(main())
现在,该代理能够无缝切换使用计算器和搜索文档来回答问题。
6. 存储RAG索引 #
为避免每次重新处理文档,你可以将索引持久化保存到磁盘:
# 导入异步编程所需的模块
import asyncio
import os
# 导入LlamaIndex的核心组件
# VectorStoreIndex: 用于创建向量存储索引
# SimpleDirectoryReader: 用于从目录读取文档
# Settings: 用于设置全局默认值
# StorageContext: 用于管理存储上下文
# load_index_from_storage: 用于从存储加载索引
from llama_index.core import (
VectorStoreIndex,
SimpleDirectoryReader,
Settings,
StorageContext,
load_index_from_storage,
)
# 导入模型集成组件
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
# 设置全局默认值
Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-base-en-v1.5")
Settings.llm = Ollama(
model="llama3.1",
request_timeout=360.0,
context_window=8000,
)
# 判断storage目录是否存在
if os.path.exists("storage2"):
# 如果storage目录存在,则从磁盘加载索引
print("📂 从磁盘加载现有索引...")
# 创建存储上下文,指定持久化目录
storage_context = StorageContext.from_defaults(persist_dir="storage2")
# 从存储中加载索引,这样就不需要重新处理文档了
index = load_index_from_storage(
storage_context,
# 我们可以选择性地在这里覆盖embed_model
# 重要的是使用与构建索引时相同的embed_model
# embed_model=Settings.embed_model,
)
# 从加载的索引创建查询引擎
query_engine = index.as_query_engine(
# 我们可以选择性地在这里覆盖llm
# llm=Settings.llm,
)
print("✅ 索引加载成功!")
else:
# 如果storage目录不存在,则新建索引并持久化到磁盘
print("🔄 创建新索引...")
# 从data目录加载所有文档
documents = SimpleDirectoryReader("data").load_data()
# 使用加载的文档创建向量存储索引
index = VectorStoreIndex.from_documents(documents)
# 将索引数据保存到"storage"目录
index.storage_context.persist("storage")
# 从索引创建查询引擎
query_engine = index.as_query_engine()
print("✅ 索引创建并保存成功!")
# 定义文档搜索工具函数
async def search_documents(query: str) -> str:
"""用于根据自然语言问题检索文档内容并返回答案。"""
response = await query_engine.aquery(query)
return str(response)
# 定义主异步函数
async def main():
# 测试文档搜索功能
response = await search_documents("红楼梦主要人物有哪些?")
print(f"🤖 回答: {response}")
# 程序入口点
if __name__ == "__main__":
asyncio.run(main())
7. 配置ollama镜像 #
国内可用镜像源列表
- 阿里云:
https://registry.ollama.ai - DeepSeek 官方镜像:
https://ollama.deepseek.com - 浙江大学镜像站:
https://ollama.zju.edu.cn - 魔搭社区:
https://ollama.modelscope.cn
7.1 镜像源配置方法 #
7.1.1 Linux/macOS 配置 #
mkdir -p ~/.ollama
cat << EOF > ~/.ollama/config.json
{
"registry": {
"mirrors": {
"registry.ollama.ai": "https://registry.ollama.ai"
}
}
}
EOF7.1.2 Windows 配置 #
- 在资源管理器地址栏输入:
%USERPROFILE%\.ollama - 新建
config.json文件,内容如下:{ "registry": { "mirrors": { "registry.ollama.ai": "https://registry.ollama.ai" } } }
7.1.3 重启服务使配置生效 #
sudo systemctl restart ollama7.2 常见问题解决方案 #
7.2.1 下载速度慢 #
- 尝试手动下载模型文件并放置到
~/.ollama/models目录
7.2.2 网络问题 #
- 检查是否启用了代理/VPN,可能会影响镜像源连接
8. 配置HuggingFac镜像 #
8.1 永久配置(环境变量) #
编辑系统环境变量,添加:
HF_ENDPOINT=https://hf-mirror.com8.2 临时配置(命令行) #
8.2.1 Windows 系统: #
set HF_ENDPOINT=https://hf-mirror.com8.2.2 Linux/Mac 系统: #
export HF_ENDPOINT=https://hf-mirror.com8.3 Python 代码中配置 #
import os
os.environ['HF_ENDPOINT'] = "https://hf-mirror.com"