在CAMEL框架中实现检索增强生成(RAG)的完整指南
引言
本文将详细介绍如何在CAMEL框架中实现检索增强生成(RAG)功能。RAG是一种结合检索系统和生成模型的技术,能够提高大语言模型回答的准确性和相关性。我们将通过实际代码示例,展示四种不同的RAG实现方式。
环境配置
首先需要配置环境变量,这里我们使用硅基流动的嵌入模型作为示例:
from camel.embeddings import OpenAICompatibleEmbedding
from camel.storages import QdrantStorage
from camel.retrievers import VectorRetriever
import PyPDF2
import pathlib
import os
from dotenv import load_dotenv
# 加载环境变量
base_dir = pathlib.Path(__file__).parent.parent
env_path = base_dir / ".env"
load_dotenv(dotenv_path=str(env_path))
# 获取配置参数
model_type = os.getenv("Embedding_Model_ID")
api_key = os.getenv("SiliconCloud_API_KEY")
base_url = os.getenv("SiliconCloud_Base_URL")
# 初始化嵌入模型
embedding_instance = OpenAICompatibleEmbedding(model_type=model_type, api_key=api_key, url=base_url)
自定义RAG实现
自定义RAG需要手动配置嵌入模型和向量数据库。我们使用Qdrant作为向量存储:
# 初始化向量存储
storage_instance = QdrantStorage(
vector_dim=1024,
path="local_data",
collection_name="custom_rag"
)
# 创建向量检索器
vector_retriever = VectorRetriever(
embedding_model=embedding_instance,
storage=storage_instance
)
# PDF文本提取函数
def extract_pdf_text(file_path):
with open(file_path, "rb") as file:
reader = PyPDF2.PdfReader(file)
text_content = ""
for page_num in range(len(reader.pages)):
page = reader.pages[page_num]
text_content += page.extract_text()
return text_content
# 处理PDF文档
pdf_path = "local_data/document.pdf"
pdf_text = extract_pdf_text(pdf_path)
vector_retriever.process(content=pdf_text)
# 查询示例
query_results = vector_retriever.query(
query="你最喜欢的编程语言是什么?",
top_k=1
)
print(query_results)
自动RAG实现
自动RAG简化了配置过程,可以自动处理文档检索:
from camel.retrievers import AutoRetriever
from camel.types import StorageType
# 初始化自动检索器
auto_retriever = AutoRetriever(
vector_storage_local_path="auto_rag_data",
storage_type=StorageType.QDRANT,
embedding_model=embedding_instance
)
# 从URL检索信息
retrieved_data = auto_retriever.run_vector_retriever(
query="本届消博会共实现意向交易多少亿元?",
contents=[
"https://news.cctv.com/2025/04/17/ARTIbMtuugrC3uxmNKsQRyci250417.shtml"
],
top_k=1,
return_detailed_info=True,
similarity_threshold=0.5
)
print(retrieved_data)
单代理RAG实现
将检索结果整合到代理上下文中:
from camel.agents import ChatAgent
from camel.models import ModelFactory
from camel.types import ModelPlatformType
# 创建大语言模型
llm_model = ModelFactory.create(
model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
model_type=os.getenv("Silicon_Model_ID"),
api_key=api_key,
url=base_url,
model_config_dict={"temperature": 0.4, "max_tokens": 4096}
)
# 初始化代理
agent = ChatAgent(
system_message="你是一个知识渊博的助手,能够基于检索到的信息回答问题",
model=llm_model
)
# 检索并整合信息
def answer_with_rag(query):
# 检索相关信息
retrieval_result = auto_retriever.run_vector_retriever(
query=query,
contents=["https://news.cctv.com/2025/04/17/ARTIbMtuugrC3uxmNKsQRyci250417.shtml"],
top_k=1
)
# 将检索结果作为上下文
context = retrieval_result['Retrieved Context'][0]['text']
agent.record_message(context)
# 生成回答
response = agent.step(query)
return response.msg.content
# 使用示例
print(answer_with_rag("3场官方供需对接会共签约多少个项目?"))
角色扮演RAG实现
在多代理场景中实现RAG:
from camel.societies import RolePlaying
from camel.toolkits import FunctionTool
from typing import List, Union
# 信息检索函数
def retrieve_information(
query: str,
contents: Union[str, List[str]],
top_k: int = 3,
similarity_threshold: float = 0.5
) -> str:
result = auto_retriever.run_vector_retriever(
query=query,
contents=contents,
top_k=top_k,
similarity_threshold=similarity_threshold
)
return str(result)
# 创建工具
retrieval_tool = FunctionTool(retrieve_information)
# 角色扮演会话
def role_playing_rag_session(task_prompt, turns=5):
session = RolePlaying(
assistant_role_name="研究员",
assistant_agent_kwargs=dict(
model=llm_model,
tools=[retrieval_tool]
),
user_role_name="提问者",
user_agent_kwargs=dict(
model=ModelFactory.create(
model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
model_type=os.getenv("ZHIPU_Model_ID"),
api_key=api_key,
url=base_url
)
),
task_prompt=task_prompt
)
# 运行对话
for _ in range(turns):
assistant_response, user_response = session.step()
print(f"研究员: {assistant_response.msg.content}")
print(f"提问者: {user_response.msg.content}")
if "CAMEL_TASK_DONE" in user_response.msg.content:
break
# 启动会话
role_playing_rag_session(
task_prompt="4月17日凌晨,OpenAI正式宣布推出了什么?请参考https://www.thepaper.cn/newsDetail_forward_30670507",
turns=3
)
关键注意事项
- 嵌入模型的选择对RAG效果影响显著
- 向量数据库的配置需要匹配嵌入模型的输出维度
- 相似度阈值需要根据具体应用场景调整
- 在多代理场景中,工具调用可能需要额外的错误处理