AgentScope RAG 示例指南
导入与依赖说明
- 本节导入构建 RAG 所需的核心模块。
DashScopeTextEmbedding
将文本转换为向量;TextReader
/PDFReader
负责切分与读取;QdrantStore
提供向量检索;SimpleKnowledge
将模型与存储组合为易用知识库。- 首次运行请安装依赖:
qdrant-client
、pypdf
、nltk
、matplotlib
。
# 说明:导入本示例所需的核心模块(嵌入模型与 RAG 组件)
import os # 用于读取环境变量和处理文件路径from agentscope.embedding import DashScopeTextEmbedding # 文本嵌入模型(将文本转换为向量)
from agentscope.rag import (TextReader, # 文本读取器:把长文本按指定规则切分PDFReader, # PDF 读取器:将 PDF 转换为可检索的文档QdrantStore, # 向量存储:此示例使用内存型 QdrantSimpleKnowledge, # 简化的知识库封装:组合嵌入模型与存储
)
环境初始化与运行上下文
agentscope studio 安装:https://blog.csdn.net/qq_41472205/article/details/152011622?spm=1001.2014.3001.5501
# 说明:加载 .env 环境变量并初始化 AgentScope 运行环境
from dotenv import load_dotenv # 从 .env 文件读取密钥与配置
load_dotenv() # 确保环境变量(如 DASHSCOPE_API_KEY)可用import agentscope # AgentScope SDK 主入口agentscope.init( # 初始化项目与 Studio 连接(可选)project="test_examples", # 项目名称,便于在 Studio 中归档name="rag", # 本次运行名称studio_url="http://localhost:3000", # 本地 AgentScope Studio 地址;若不使用可移除
)
2025-10-17 23:20:50,586 | INFO | _user_input:on_connect:194 - Connected to AgentScope Studio at "http://localhost:3000" with run name "9ucid2K2w7Y9VtSXMEvVSQ".
2025-10-17 23:20:50,590 | INFO | _user_input:on_connect:200 - View the run at: http://localhost:3000/dashboard/projects/test_examples
基础 RAG 示例:从文本与 PDF 到检索
- 步骤:读取文本与 PDF → 生成嵌入 → 构建知识库 → 语义检索。
TextReader
/PDFReader
将内容切分为片段,便于嵌入与召回。SimpleKnowledge
封装了嵌入模型与向量存储的组合;dimensions
必须与嵌入模型输出维度一致。- 检索参数说明:
limit
控制返回文档数;score_threshold
为相似度阈值,调低可扩大召回、调高更严格。
示例文档:
async def main() -> None:"""The main entry point of the RAG example."""# 步骤总览:读取文本与 PDF -> 生成嵌入 -> 构建知识库 -> 语义检索示例# 文本与 PDF 读取器:将内容按句切分,便于嵌入与检索reader = TextReader(chunk_size=1024) # 文本读取器(默认按句切分)pdf_reader = PDFReader(chunk_size=1024, split_by="sentence") # PDF 读取器# 准备示例文本;真实场景请替换为你的业务文档documents = await reader(text="I'm Tony Stank, my password is 123456. My best friend is James ""Rhodes.",)# 读取示例 PDF 并转换为文档列表(确保文件存在)pdf_path = "example.pdf"pdf_documents = await pdf_reader(pdf_path=pdf_path)# 构建内存型知识库:维度需与嵌入模型输出一致knowledge = SimpleKnowledge(embedding_store=QdrantStore(location=":memory:", # 使用内存存储,便于快速试验collection_name="test_collection",dimensions=1024, # 向量维度(需与嵌入模型一致)),embedding_model=DashScopeTextEmbedding(api_key=os.environ["DASHSCOPE_API_KEY"], # 从环境变量读取 DashScope API Keymodel_name="text-embedding-v4", # 文本嵌入模型名称),)# 将文本与 PDF 文档写入知识库await knowledge.add_documents(documents + pdf_documents)# 示例检索 1:回答具体问题(阈值高,更严格)docs = await knowledge.retrieve(query="What is Tony Stank's password?",limit=3, # 返回 Top-K 文档数score_threshold=0.7, # 相似度阈值(调低可增加召回))print("Q1: What is Tony Stank's password?")for doc in docs:# 展示命中文档及分数print(f"Document ID: {doc.id}, Score: {doc.score}, "f"Content: {doc.metadata.content['text']}",)# 示例检索 2:主题检索(降低阈值以扩大召回范围)docs = await knowledge.retrieve(query="climate change",limit=3,score_threshold=0.2,)print("\n\nQ2: climate change")for doc in docs:print(f"Document ID: {doc.id}, Score: {doc.score}, "f"Content: {repr(doc.metadata.content['text'])}",)await main()
2025-10-17 22:58:39,371 | INFO | _text_reader:__call__:68 - Reading text with chunk_size=1024, split_by=sentence
2025-10-17 22:58:39,503 | INFO | _text_reader:__call__:132 - Finished splitting the text into 2 chunks.
2025-10-17 22:58:39,561 | INFO | _text_reader:__call__:68 - Reading text with chunk_size=1024, split_by=sentence
2025-10-17 22:58:39,561 | INFO | _text_reader:__call__:132 - Finished splitting the text into 16 chunks.
2025-10-17 22:58:39,951 | INFO | _dashscope_embedding:__call__:130 - The input texts (18) will be embedded with 2 API calls due to the batch size limit of 10 for DashScope embedding API.Q1: What is Tony Stank's password?
Document ID: KJjAuEA5F9DhsQH46HGaSy, Score: 0.9036251269952563, Content: I'm Tony Stank, my password is 123456.Q2: climate change
Document ID: dpgZQmbzpPrWXRN3q8sKng, Score: 0.6252090067978586, Content: 'Climate change represents one of the most pressing challenges of our time.'
Document ID: X3awuqtcpCukBCssefC4Us, Score: 0.4907227791760559, Content: 'Rising global \ntemperatures, changing weather patterns, and increasing natural disasters are affecting \ncommunities worldwide.'
Document ID: YsRWGHxGdgqfdce7Qgb4CL, Score: 0.39938773032256564, Content: 'Scientists warn that without significant action to reduce \ngreenhouse gas emissions, we face potentially catastrophic consequences for human \ncivilization and the natural world.'
ReAct + RAG:代理在检索支持下对话
- 通过为代理绑定
knowledge
,它会在回答时引用检索到的内容,提升依据性与可追溯性。 - 示例中使用
ReActAgent
与DashScopeChatModel
实现推理-行动-观察的交互流程。 - 文档先入库再对话,代理会自动进行检索并在消息中插入
<retrieved_knowledge>
块。
# -*- coding: utf-8 -*-
"""集成 ReAct 代理与 RAG 的示例。"""
import osfrom agentscope.agent import ReActAgent, UserAgent
from agentscope.embedding import DashScopeTextEmbedding
from agentscope.formatter import DashScopeChatFormatter
from agentscope.message import Msg
from agentscope.model import DashScopeChatModel
from agentscope.rag import SimpleKnowledge, QdrantStore, TextReaderasync def main() -> None:"""ReAct + RAG 示例的主入口。"""# 创建内存型知识库实例:维度需与嵌入模型一致print("正在创建知识库...")knowledge = SimpleKnowledge(embedding_store=QdrantStore(location=":memory:", # 使用内存存储,便于演示collection_name="test_collection",dimensions=1024, # 嵌入向量维度(需与模型一致)),embedding_model=DashScopeTextEmbedding(api_key=os.environ["DASHSCOPE_API_KEY"], # 从环境变量读取 API Keymodel_name="text-embedding-v4",),)# 插入示例文档到知识库(实际可线下批量处理后导入)print("正在向知识库插入文档...")reader = TextReader(chunk_size=100, split_by="char") # 按字符切分以控制块大小documents = await reader(# 演示用的虚构个人档案"我是约翰·多伊,28 岁。我的好朋友是詹姆斯·史密斯。""我住在旧金山,在 OpenAI 工作,是一名软件工程师。""我喜欢徒步和摄影。我的父亲是迈克尔·多伊,是一名医生,我为他感到非常自豪。""我的母亲是萨拉·多伊,是一名教师,她非常善良,总是帮助我学习。\n""我现在是斯坦福大学的博士生,主修计算机科学。我的导师是简·威廉姆斯教授,""她是人工智能领域的顶尖专家。我在 NeurIPS 和 ICML 等顶级会议上发表过多篇论文。")print("正在向知识库插入文档...")await knowledge.add_documents(documents) # 将文本加入知识库# 通过 knowledge 参数为代理装备知识库,使其能够在回复中引述检索到的内容print("正在创建代理...")agent = ReActAgent(name="Friday", # 代理名称sys_prompt="你是一名名为 Friday 的乐于助人的助手。", # 系统提示,设定助手人格model=DashScopeChatModel(api_key=os.environ["DASHSCOPE_API_KEY"], # 聊天模型的 API Keymodel_name="qwen-turbo", # 聊天模型名称(可替换)),formatter=DashScopeChatFormatter(),# Equip the agent with the knowledge baseknowledge=knowledge, # 为代理绑定知识库print_hint_msg=True, # 打印过程提示,便于调试)user = UserAgent(name="user")# 开始对话:代理会在内部进行检索并回答print("开始对话...")msg = Msg("user", "你知道我最好的朋友是谁吗?", "user")msg = await agent(msg)msg = await user(msg)await main()
2025-10-17 23:12:56,580 | INFO | _text_reader:__call__:68 - Reading text with chunk_size=100, split_by=char
2025-10-17 23:12:56,581 | INFO | _text_reader:__call__:132 - Finished splitting the text into 3 chunks.正在创建知识库...
正在向知识库插入文档...
正在向知识库插入文档...
正在创建代理...
开始对话...
user: <retrieved_knowledge>Use the following content from the knowledge base(s) if it's helpful:user: 我是约翰·多伊,28 岁。我的好朋友是詹姆斯·史密斯。我住在旧金山,在 OpenAI 工作,是一名软件工程师。我喜欢徒步和摄影。我的父亲是迈克尔·多伊,是一名医生,我为他感到非常自豪。我的母亲是萨拉·
user: 多伊,是一名教师,她非常善良,总是帮助我学习。
我现在是斯坦福大学的博士生,主修计算机科学。我的导师是简·威廉姆斯教授,她是人工智能领域的顶尖专家。我在 NeurIPS 和 ICML 等顶级会议上发表
user: 过多篇论文。
user: </retrieved_knowledge>
Friday: 根据你提供的信息,你最好的朋友是詹姆斯·史密斯。
agentscope studio:
RAG 工具化:代理主动调用检索工具
- 使用
Toolkit
注册检索函数,使代理可根据需要主动调用工具。 - 关键参数:
query
(查询文本)、limit
(Top-K)、score_threshold
(相似度阈值)。当无结果时,降低阈值可获得更多候选。 - 适用于复杂任务场景,让代理能够自适应地调参以获取最相关信息。
# -*- coding: utf-8 -*-
"""AgentScope 中 RAG 的“智能体化”用法示例:代理配备 RAG 工具,
基于知识库回答问题。该示例更具挑战性,需要代理调整检索参数以获得相关结果。"""
import asyncio
import osfrom agentscope.agent import ReActAgent, UserAgent
from agentscope.embedding import DashScopeTextEmbedding
from agentscope.formatter import DashScopeChatFormatter
from agentscope.message import Msg
from agentscope.model import DashScopeChatModel
from agentscope.rag import SimpleKnowledge, QdrantStore, TextReader
from agentscope.tool import Toolkit# 创建知识库实例(维度需与嵌入模型一致)
knowledge = SimpleKnowledge(embedding_store=QdrantStore(location=":memory:",collection_name="test_collection",dimensions=1024, # 向量维度),embedding_model=DashScopeTextEmbedding(api_key=os.environ["DASHSCOPE_API_KEY"], # 从环境读取 API Keymodel_name="text-embedding-v4",),
)async def main() -> None:"""AgentScope 中 RAG 智能体用法示例的主入口。"""# 为演示向知识库存入一些内容(实际场景中,库通常预先填充相关数据)reader = TextReader(chunk_size=1024, split_by="sentence")documents = await reader(text=("我是约翰·多伊,28 岁。我的好朋友是詹姆斯·史密斯。""我住在旧金山,在 OpenAI 工作,是一名软件工程师。""我喜欢徒步和摄影。我的父亲是迈克尔·多伊,是一名医生,我为他感到非常自豪。""我的母亲是萨拉·多伊,是一名教师,她非常善良,总是帮助我学习。\n""我现在是斯坦福大学的博士生,主修计算机科学。我的导师是简·威廉姆斯教授,""她是人工智能领域的顶尖专家。我在 NeurIPS 和 ICML 等顶级会议上发表过多篇论文。"),)await knowledge.add_documents(documents)# 创建工具包并注册检索工具,使代理可主动调用进行检索toolkit = Toolkit()toolkit.register_tool_function(knowledge.retrieve_knowledge, # 工具函数:从知识库检索相关文档func_description=("从知识库检索与 John Doe 档案相关的文档。""提示:合理设置 `query` 对检索质量很重要;根据需要调整 `limit`(Top-K)""与 `score_threshold`(相似度阈值)以控制结果数量与质量。"),)# 创建代理与用户:代理具备工具使用能力agent = ReActAgent(name="Friday",sys_prompt=("你是名为 Friday 的乐于助人的助手。""你配备了 'retrieve_knowledge' 工具来帮助你了解名为 John Doe 的用户。""注意:当无法得到相关结果时,请尝试调整 `score_threshold` 参数。"),toolkit=toolkit, # 将工具包交给代理model=DashScopeChatModel(api_key=os.environ["DASHSCOPE_API_KEY"],model_name="qwen-turbo",),formatter=DashScopeChatFormatter(),)user = UserAgent(name="User")# 从预设问题开始的简单对话循环(代理会自动调用检索工具)msg = Msg("user","我是约翰·多伊。你知道我的父亲吗?","user",)msg = await agent(msg)await main()
2025-10-17 23:18:14,996 | INFO | _text_reader:__call__:68 - Reading text with chunk_size=1024, split_by=sentence
2025-10-17 23:18:14,996 | INFO | _text_reader:__call__:132 - Finished splitting the text into 1 chunks.Friday: {"type": "tool_use","id": "call_c2e27492f3904a29b85d04","name": "retrieve_knowledge","input": {"query": "约翰·多伊的父亲","limit": 5,"score_threshold": 0.8}
}
system: {"type": "tool_result","id": "call_c2e27492f3904a29b85d04","name": "retrieve_knowledge","output": [{"type": "text","text": "No relevant documents found. TRY to reduce the `score_threshold` parameter to get more results."}]
}
Friday: {"type": "tool_use","id": "call_7daf14915c084ed5b99117","name": "retrieve_knowledge","input": {"query": "约翰·多伊的父亲","limit": 5,"score_threshold": 0.5}
}
system: {"type": "tool_result","id": "call_7daf14915c084ed5b99117","name": "retrieve_knowledge","output": [{"type": "text","text": "Score: 0.5593333067619584, Content: 我是约翰·多伊,28 岁。我的好朋友是詹姆斯·史密斯。我住在旧金山,在 OpenAI 工作,是一名软件工程师。我喜欢徒步和摄影。我的父亲是迈克尔·多伊,是一名医生,我为他感到非常自豪。我的母亲是萨拉·多伊,是一名教师,她非常善良,总是帮助我学习。\n我现在是斯坦福大学的博士生,主修计算机科学。我的导师是简·威廉姆斯教授,她是人工智能领域的顶尖专家。我在 NeurIPS 和 ICML 等顶级会议上发表过多篇论文。"}]
}
Friday: 根据我找到的信息,你的父亲是迈克尔·多伊,他是一名医生,你为他感到非常自豪。
准备演示图像:生成包含中文的图片
- 为保证图片中文显示正常,配置常用中文字体与负号显示。
- 动态生成一张包含“我的名字是李明”的示例图片并保存为
./example.png
,供后续多模态检索使用。
# -*- coding: utf-8 -*-
"""如何在 AgentScope 中使用多模态 RAG 的示例"""
import json
import osfrom matplotlib import pyplot as pltfrom agentscope.agent import ReActAgent
from agentscope.embedding import DashScopeMultiModalEmbedding
from agentscope.formatter import DashScopeChatFormatter
from agentscope.message import Msg
from agentscope.model import DashScopeChatModel
from agentscope.rag import ImageReader, SimpleKnowledge, QdrantStore# 为了在图像上显示中文,这里设置了常用中文字体与负号显示
from matplotlib import rcParams
rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'SimSun', 'KaiTi']
rcParams['axes.unicode_minus'] = False# 动态生成一张演示图片(包含中文文本),并保存到本地
path_image = "./example.png"
plt.figure(figsize=(8, 3))
plt.text(0.5, 0.5, "我的名字是李明", ha="center", va="center", fontsize=30)
plt.axis("off")
plt.savefig(path_image, bbox_inches="tight", pad_inches=0.1)
plt.close()
多模态 RAG:图像理解与检索问答
ImageReader
将图像转为向量文档;DashScopeMultiModalEmbedding
提供图文统一的嵌入。- 知识库与嵌入模型的
dimensions
必须一致;否则检索会失败或结果异常。 - 创建具备视觉理解能力的代理(如
qwen3-vl-plus
),结合知识库进行问答并在记忆中存储检索内容。 - 你可以在最后的打印内容中看到代理记忆中引用的图像与检索结果。
async def example_multimodal_rag() -> None:"""多模态 RAG 示例"""# 读取图像并转换为文档(把图像转为向量,可用于语义检索)reader = ImageReader()docs = await reader(image_url=path_image)# 创建知识库并添加文档:维度需与多模态嵌入模型一致knowledge = SimpleKnowledge(embedding_model=DashScopeMultiModalEmbedding(api_key=os.environ["DASHSCOPE_API_KEY"], # 从环境变量读取 API Keymodel_name="multimodal-embedding-v1", # 多模态嵌入模型(图像/文本)dimensions=1024, # 向量维度),embedding_store=QdrantStore(location=":memory:",collection_name="test_collection",dimensions=1024, # 与嵌入维度保持一致),)await knowledge.add_documents(docs) # 将图像文档加入知识库# 创建具备多模态能力的代理:可理解图像并进行检索agent = ReActAgent(name="Friday",sys_prompt="你是一名名为 Friday 的乐于助人的助手。",model=DashScopeChatModel(api_key=os.environ["DASHSCOPE_API_KEY"],model_name="qwen3-vl-plus", # 具备视觉理解能力的聊天模型),formatter=DashScopeChatFormatter(),knowledge=knowledge,)# 问答:代理会使用知识库检索并回答await agent(Msg("user","你知道我的名字吗?","user",),)# 展示代理记忆中保存的检索内容(含图像引用)print("\n代理记忆中存储的检索文档:")content = (await agent.memory.get_memory())[-4].contentprint(json.dumps(content, indent=2, ensure_ascii=False))await example_multimodal_rag()
Friday: 你的名字是李明。代理记忆中存储的检索文档:
[{"type": "text","text": "<retrieved_knowledge>Use the following content from the knowledge base(s) if it's helpful:\n"},{"type": "image","source": {"type": "url","url": "./example.png"}},{"type": "text","text": "</retrieved_knowledge>"}
]
参考链接:https://github.com/agentscope-ai/agentscope/tree/main/examples/functionality/rag