文章目录
- 前言
- [1. 构建智能体大模型应用的关键步骤](#1. 构建智能体大模型应用的关键步骤)
-
- [1.1 大模型基础调用能力](#1.1 大模型基础调用能力)
- [1.2 构建智能体](#1.2 构建智能体)
- [1.3 工作流(Workflows)开发](#1.3 工作流(Workflows)开发)
- [1.4 智能体 RAG 能力集成](#1.4 智能体 RAG 能力集成)
- [2. 使用大模型(阿里云百炼)](#2. 使用大模型(阿里云百炼))
-
- [2.1 统一 LLM 抽象](#2.1 统一 LLM 抽象)
- [2.2 先理解:OpenAILike 是什么](#2.2 先理解:OpenAILike 是什么)
- [2.3 基础文本补全](#2.3 基础文本补全)
- [2.4 流式输出](#2.4 流式输出)
- [2.5 对话接口](#2.5 对话接口)
-
- [2.5.1 基础对话调用](#2.5.1 基础对话调用)
- [2.5.2 同步流式对话](#2.5.2 同步流式对话)
- [2.5.3 异步流式对话](#2.5.3 异步流式对话)
- [2.6 指定模型名称](#2.6 指定模型名称)
- [2.7 多模态大模型调用](#2.7 多模态大模型调用)
- [2.8 模型工具调用(Function Calling)](#2.8 模型工具调用(Function Calling))
- [2.9 接入本地大模型(Ollama)](#2.9 接入本地大模型(Ollama))
前言
LlamaIndex 为大模型应用开发提供了从基础模型调用、RAG 知识库搭建、智能体开发到高阶工作流定制、落地优化的全链路解决方案,模块化、标准化的开发模式,极大降低了企业级 AI 应用的开发门槛。
后续我们将从大模型基础调用开始,循序渐进拆解每一个核心功能的开发逻辑、实操方法与优化技巧,带大家从零完成完整的大模型智能应用开发落地。
1. 构建智能体大模型应用的关键步骤
基于 LlamaIndex 开发智能体大模型应用,拥有标准化、模块化的开发流程。
1.1 大模型基础调用能力
大模型调用是所有 AI 应用开发的基础。LlamaIndex 提供统一的调用接口,兼容市面上数十种主流大模型。
支持两种部署调用模式 :既可以调用云端远程 API 服务快速开发,也支持本地私有化部署模型,适配不同场景的算力、隐私、成本需求,帮助开发者快速完成大模型能力接入。
1.2 构建智能体
智能体是由大模型驱动的自动化执行单元,核心能力是依托各类工具与外部环境交互,不仅能完成信息检索,还可自主执行各类业务动作,是复杂 AI 应用的核心载体。
本模块核心开发内容包含:
-
基础单智能体搭建:从零构建轻量化智能体,配置基础工具,实现与外部场景的基础交互能力。
-
预制工具快速复用 :依托官方
LlamaHub资源库,直接调用海量成熟预制工具,无需重复开发,大幅提升开发效率。 -
状态持久化维护:支持智能体运行状态保存与迭代,满足复杂、多轮、长链路的业务场景需求。
-
流式事件输出:提供实时流式输出能力,展示任务执行过程,为用户提供可视化反馈,优化交互体验。
-
人在回路机制:支持人工介入反馈与校正,有效规避智能体自主执行的偏差,保障业务准确性。
-
多智能体协同系统 :基于
AgentWorkflow搭建多智能体架构,实现多角色智能体分工协作,支撑超复杂业务系统落地。
1.3 工作流(Workflows)开发
工作流是 LlamaIndex 高阶智能体应用的底层核心架构,属于事件驱动的轻量化抽象层,是开发定制化、高阶智能应用的基础。
开发者可基于高层封装快速开发,也可从零完全自定义业务逻辑,核心能力包含:
-
搭建基础工作流,快速实现简易智能体业务逻辑;
-
支持循环、分支等核心控制流,组合搭建复杂业务逻辑;
-
任务并发执行,高效拆分并行任务,提升整体运行效率;
-
支持流式事件推送,同步展示任务执行状态;
-
具备状态持久化能力,适配长周期、复杂业务场景;
-
完善的可观测能力,可对接各类链路追踪组件,实现应用调试、故障排查。
1.4 智能体 RAG 能力集成
RAG 检索增强生成是打通私有数据与大模型的核心技术,解决了大模型知识滞后、私有场景适配性差的问题,是智能体具备专业知识库问答能力的关键。
完整的 RAG 流水线开发包含七大核心环节:
-
多源数据接入 :依托
LlamaHub数百种专属连接器,兼容文本、PDF、数据库、第三方API等全类型数据源,实现异构数据统一接入。 -
索引构建与向量化:通过多样化数据组织策略,对原始数据进行切分、向量化处理,生成语义向量,保障检索上下文的精准度。
-
结构化数据存储:将向量数据、文档摘要、元数据统一存入向量数据库,实现数据持久化,降低重复计算成本,提升访问效率。
-
智能检索优化:匹配多样化索引查询策略,从检索速度、相关性、准确率多维度优化,同时支持输出标准化结构化数据。
-
全场景业务落地:适配智能问答、聊天机器人、API服务、自主智能体等多类应用场景,支持项目产业化部署。
-
链路追踪调试:依托可观测能力,洞察应用内部运行逻辑,快速定位检索、生成环节的故障与问题。
-
应用效果评估:从准确率、性能、可读性、成本等多维度评估迭代效果,持续优化应用体验与落地效果。
2. 使用大模型(阿里云百炼)
2.1 统一 LLM 抽象
在构建基于私有数据的大模型应用时,首要环节就是接入大语言模型 。但这里有一个很现实的问题:不同厂商的 API 风格各不相同,OpenAI 用 chat.completions,通义千问有自己的 SDK 调用方式,Ollama 是本地 HTTP 接口,Gemini 又是另一套协议。
如果直接在业务代码里对接各家 SDK,你很快会陷入大量重复的适配代码中:参数格式不一样、流式响应不一样、错误处理不一样、异步支持也不一样。
LlamaIndex 的解法是设计一套统一 LLM 抽象接口 :把调用一个大模型这件事抽象成 complete() / chat() / stream_*() 等几个标准方法,你写的业务代码只面向这套接口。
切换模型厂商时,只需要换一个类、改几个参数,其余代码一概不动:
python
你的业务代码
│ 只依赖统一抽象
▼
┌─────────────────────────────────────────┐
│ BaseLLM(统一接口) │
│ complete / chat / stream / acomplete ...│
└─────────────────────────────────────────┘
│ 按厂商实现
├──────► OpenAI (llama-index-llms-openai)
├──────► OpenAILike (llama-index-llms-openai-like,兼容协议服务)
├──────► Ollama (llama-index-llms-ollama,本地模型)
├──────► DashScope (通义千问原生集成)
└──────► 自定义 (继承 CustomLLM 自行实现)
2.2 先理解:OpenAILike 是什么
在动手写代码之前,先讲清楚一个概念:OpenAI 兼容协议。
OpenAI 定义了一套事实标准的 HTTP API 形态(/chat/completions、/embeddings、/models 等端点 + JSON 请求/响应格式)。很多厂商为了让生态成熟的开源工具能直接接入自己,会提供"兼容 OpenAI 协议"的端点。
阿里云百炼就是这样:它在自己的大模型服务上包了一层与 OpenAI 完全一致的接口。
所以 LlamaIndex 接入百炼不需要百炼专属集成包 ,而是用 openai-like 这个"万能适配器":
powershell
pip install llama-index-llms-openai-like
它的核心类是 OpenAILike。注意类名后面的 Like------它继承自 OpenAI 类 ,只是把 OpenAI 类里硬编码的官方地址和模型假设放开,让你可以自由指定 api_base(端点地址)和模型名。
安装后,在项目根目录创建 .env 文件,写入你的密钥(在百炼控制台创建 API-KEY):
python
DASHSCOPE_API_KEY=sk-xxx
.env是社区通用的本地配置约定,配合python-dotenv库加载,避免把密钥写进代码、避免泄露到Git仓库。配套代码里的config.py已内置load_dotenv()。
2.3 基础文本补全
complete() 的语义是:给模型一句话,让它接着往下写 (文本补全),适合续写、翻译、摘要等一次性生成场景:
python
import os
from llama_index.llms.openai_like import OpenAILike
llm = OpenAILike(
model="qwen-plus",
api_key=os.environ["DASHSCOPE_API_KEY"],
api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
is_chat_model=True, # qwen 均为 chat 模型,必须开启
is_function_calling_model=True, # qwen-plus 支持工具调用,必须显式声明
)
response = llm.complete("William Shakespeare is ")
print(response)
逐行解读:
model:指定模型版本。qwen-plus是百炼的通用主力模型,性价比与能力平衡;api_key/api_base:从环境变量读密钥,api_base指向百炼的OpenAI兼容端点(整个兼容模式的关键就这两个参数);is_chat_model=True:告诉LlamaIndex这是"对话式"模型。qwen系列只提供chat接口(没有传统的completion接口),complete()内部会自动包装成一次单轮对话。如果这里不设True,框架会尝试走旧的补全接口,行为异常;is_function_calling_model=True:声明模型支持工具调用。这个开关第6节会用到,建议与is_chat_model一起写上,一步到位。
预期输出 (qwen-plus 实测):
William Shakespeare was an English playwright, poet, and actor, widely regarded as one of the greatest writers in the English language...
配套异步版本 :acomplete()
2.4 流式输出
上一节的 complete() 是"等全部生成完,一次性返回"。但在很多场景下我们希望边生成边显示,聊天机器人逐字输出的打字机效果、长文档生成的进度反馈,都是流式输出。
原理:模型实际是逐个 token(词元)生成的。流式接口把这一过程"摊开"------服务端每生成一个 token 就推送一次,客户端收到的是增量(delta),而不是等完整的答案:
python
import os
from llama_index.llms.openai_like import OpenAILike
llm = OpenAILike(
model="qwen-plus",
api_key=os.environ["DASHSCOPE_API_KEY"],
api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
is_chat_model=True,
is_function_calling_model=True,
)
handle = llm.stream_complete("William Shakespeare is ")
for token in handle:
print(token.delta, end="", flush=True)
代码里有两个细节值得注意:
token.delta是本次收到的增量文本 ,end=""表示不换行,让所有增量拼成一句话;flush=True强制立即刷新标准输出,否则Python会缓冲输出,在终端里就看不到"逐字"效果了。
配套异步版本 :astream_complete()。
LlamaIndex 为海量大模型提供统一调用接口。使用新模型往往只需要安装对应集成包:
bash
pip install llama-index-llms-openai
一行代码即可完成调用:
python
from llama_index.llms.openai import OpenAI
response = OpenAI().complete("William Shakespeare is ")
print(response)
注意:环境变量需要配置
OPENAI_API_KEY,更多细节参考入门教程。
complete 也提供异步版本 acomplete。
调用 stream_complete 获取流式返回,返回生成器,逐token输出内容:
python
handle = OpenAI().stream_complete("William Shakespeare is ")
for token in handle:
print(token.delta, end="", flush=True)
stream_complete 的异步版本为 astream_complete。
2.5 对话接口
如果说 complete() 是"一句话接龙",chat() 就是"真正的对话"。对话场景需要区分谁在说话 :系统设定、用户消息、助手回复。LlamaIndex 用 ChatMessage 结构表达这一点:
python
from llama_index.core.llms import ChatMessage
messages = [
ChatMessage(role="system", content="You are a helpful assistant."), # 系统角色:设定人设与规则
ChatMessage(role="user", content="Tell me a joke."), # 用户角色:本轮提问
]
消息列表是累积的------多轮对话就是把每一轮的问答都追加进列表,模型才能记住上下文。
2.5.1 基础对话调用
python
import os
from llama_index.core.llms import ChatMessage
from llama_index.llms.openai_like import OpenAILike
messages = [
ChatMessage(role="system", content="You are a helpful assistant."),
ChatMessage(role="user", content="Tell me a joke."),
]
llm = OpenAILike(
model="qwen-plus",
api_key=os.environ["DASHSCOPE_API_KEY"],
api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
is_chat_model=True,
is_function_calling_model=True,
)
chat_response = llm.chat(messages)
print(chat_response.message.content)
返回对象是 ChatResponse,chat_response.message.content 才是助手回复的文本。预期输出:
Why don't scientists trust atoms?
Because they make up everything.
2.5.2 同步流式对话
普通脚本 / Jupyter Notebook 场景,希望看到逐字输出:
python
stream_response = llm.stream_chat(messages)
for token in stream_response:
print(token.delta, end="", flush=True)
2.5.3 异步流式对话
Web 服务场景(FastAPI 等异步框架)的标准姿势:异步 + 流式组合,既不阻塞事件循环,又能边生成边推送给前端:
python
stream_response = await llm.astream_chat(messages)
async for token in stream_response:
print(token.delta, end="", flush=True)
为什么推荐异步 :异步接口把"等待网络响应"的时间让出来,同一进程可以并发处理成百上千个请求。LlamaIndex 的 agent(如 FunctionAgent)内部也是异步驱动的,官方推荐使用异步写法。记住一条规律:同步版用于脚本/调试,异步版用于服务。
2.6 指定模型名称
同一个厂商有多个模型版本,能力、速度、价格各不相同。通过 model 参数指定:
python
import os
from llama_index.llms.openai_like import OpenAILike
llm = OpenAILike(
model="qwen-plus", # 通用主力:qwen-plus / qwen-max / qwen-turbo
api_key=os.environ["DASHSCOPE_API_KEY"],
api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
is_chat_model=True,
is_function_calling_model=True,
)
response = llm.complete("Who is Laurie Voss?")
print(response)
2.7 多模态大模型调用
文本之外,很多任务需要看图说话 :图片理解、截图分析、文档 OCR。LlamaIndex 的 blocks 机制把多模态消息表达为"内容块"列表------一条消息可以同时包含图片块和文本块:
python
import os
from llama_index.core.llms import ChatMessage, TextBlock, ImageBlock
from llama_index.llms.openai_like import OpenAILike
llm = OpenAILike(
model="qwen-vl-max", # 百炼视觉理解模型
api_key=os.environ["DASHSCOPE_API_KEY"],
api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
is_chat_model=True,
is_function_calling_model=True,
)
messages = [
ChatMessage(
role="user",
blocks=[
ImageBlock(path="image.png"), # 图片块:从本地路径加载
TextBlock(text="Describe the image in a few sentences."), # 文本块:指令
],
)
]
resp = llm.chat(messages)
print(resp.message.content)
注意:多模态模型的 is_chat_model 同样要设为 True;ImageBlock(path=...) 支持本地路径,也可以传 base64 数据(ImageBlock(image_base64=...))或 URL。
预期输出(实测,用一张蓝底白字的测试图):
The image displays a plain, light blue background with a single line of black
text positioned in the upper-left corner. The text reads: "Hello LlamaIndex + Qwen VL"...
如果想做图文 RAG (文本搜图、以图搜图、图文混合问答),单靠 llm.chat 不够------LlamaIndex 还提供了独立的 MultiModalLLM 抽象,配合多模态向量索引使用。当前主流支持 GPT-4V、Gemini、LLaVa、Qwen-VL、CogVLM 等。
注意:框架对音频、视频的端到端
RAG尚不完善,目前多模态RAG主要支持图片模态。
2.8 模型工具调用(Function Calling)
这是让 LLM 从"聊天机器人"升级为"智能体"的关键能力。先讲原理------Function Calling 是一个四步循环:
python
① 工具注册:把你的 Python 函数转成 JSON Schema(参数名、类型、描述)
│
▼
② 模型决策:LLM 分析用户问题,决定"该调用哪个函数、填什么参数"
│
▼
③ 框架执行:按模型给出的参数调用你的函数,拿到真实结果
│
▼
④ 结果回填:把函数结果作为消息喂回 LLM,让它基于结果生成最终回答
关键在于第 ② 步------选择权在模型 。你的代码不需要写"如果用户问 XX 就调 YY"的规则,模型根据函数描述自主判断。
LlamaIndex 用 predict_and_call 把整个四步循环封装成一次调用:
python
import os
from llama_index.core.tools import FunctionTool
from llama_index.llms.openai_like import OpenAILike
def generate_song(name: str, artist: str) -> dict:
"""Generates a song with provided name and artist."""
return {"name": name, "artist": artist}
tool = FunctionTool.from_defaults(fn=generate_song)
llm = OpenAILike(
model="qwen-plus",
api_key=os.environ["DASHSCOPE_API_KEY"],
api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
is_chat_model=True,
is_function_calling_model=True, # ← 工具调用必须为 True,否则报 ValueError
)
response = llm.predict_and_call(
[tool],
"Pick a random song for me",
)
print(str(response))
关键点解读:
FunctionTool.from_defaults(fn=...):框架会自动解析函数签名和 docstring 生成工具schema------函数名、参数类型、默认值、描述都来自你的代码本身,无需手写JSON。predict_and_call([tool], prompt):第一个参数是工具列表,第二个参数是用户请求;模型自主决定是否调用、调用哪个、填什么参数;
预期输出(实测,模型随机选了一首歌并正确填入了两个参数):
{'name': 'Here Comes the Sun', 'artist': 'The Beatles'}
该接口兼容所有支持函数调用的大模型。工具与智能体的进阶用法(FunctionAgent、AgentWorkflow------让模型自主决定"何时调工具、调几次、如何综合结果")是另一篇教程的内容。
2.9 接入本地大模型(Ollama)
前面几节都是云端 API。有些场景你希望模型数据不出内网 :私有数据合规、离线环境、控制成本。Ollama 是当前最流行的本地模型运行时,LlamaIndex 通过 llama-index-llms-ollama 集成:
python
from llama_index.llms.ollama import Ollama
llm = Ollama(
model="llama3.3",
request_timeout=60.0,
context_window=8000, # 限制上下文窗口,控制内存占用
)
切换成本几乎为零 ------这是统一抽象最大的价值:第 2~6 节的代码,只要把 OpenAILike(...) 换成 Ollama(...),其余逻辑(complete/chat/流式/异步)完全不用改。两个参数的含义:
request_timeout:本地模型生成长文本可能较慢,放宽超时避免误报;context_window:按你的显存限制上下文窗口,防止内存溢出。
本地部署前先
ollama pull llama3.3拉取模型;本地模型是否支持工具调用,取决于模型本身。