找回密码
 立即注册
首页 业界区 业界 使用CAMEL实现RAG过程记录

使用CAMEL实现RAG过程记录

方方仪 2025-6-5 09:29:17
本文为学习使用CAMEL实现RAG的学习总结。
参考自官方cookbook,地址:https://docs.camel-ai.org/cookbooks/advanced_features/agents_with_rag.html
在官方cookbook分为了Customized RAG、Auto RAG、Single Agent with Auto RAG与Role-playing with Auto RAG四个部分。
Customized RAG

实现RAG需要有嵌入模型,为了简单验证,我这里使用的是硅基流动的嵌入模型。
现在先来看看在CAMEL中如何使用硅基流动的嵌入模型。
在.env文件中这样写:
  1. Silicon_Model_ID="Qwen/Qwen2.5-72B-Instruct"
  2. ZHIPU_Model_ID="THUDM/GLM-4-32B-0414"
  3. DEEPSEEK_Model_ID="deepseek-ai/DeepSeek-V3"
  4. Embedding_Model_ID="BAAI/bge-m3"
  5. SiliconCloud_API_KEY="你的api key"
  6. SiliconCloud_Base_URL="https://api.siliconflow.cn/v1"
复制代码
我使用的是BAAI/bge-m3这个嵌入模型。
现在使用这个嵌入模型可以通过OpenAICompatibleEmbedding,因为它的格式与OpenAI是兼容的。
可以这样写:
  1. from camel.embeddings import OpenAICompatibleEmbedding
  2. from camel.storages import QdrantStorage
  3. from camel.retrievers import VectorRetriever
  4. import PyPDF2
  5. import pathlib
  6. import os
  7. from dotenv import load_dotenv
  8. base_dir = pathlib.Path(__file__).parent.parent
  9. env_path = base_dir / ".env"
  10. load_dotenv(dotenv_path=str(env_path))
  11. modeltype = os.getenv("Embedding_Model_ID")
  12. api_key = os.getenv("SiliconCloud_API_KEY")
  13. base_url = os.getenv("SiliconCloud_Base_URL")
  14. embedding_instance = OpenAICompatibleEmbedding(model_type=modeltype, api_key=api_key, url=base_url)
复制代码
可以通过这个脚本快速测试是否能成功调用。
脚本可以这样写:
  1. from camel.embeddings import OpenAICompatibleEmbedding
  2. import pathlib
  3. import os
  4. from dotenv import load_dotenv
  5. base_dir = pathlib.Path(__file__).parent.parent
  6. env_path = base_dir / ".env"
  7. load_dotenv(dotenv_path=str(env_path))
  8. modeltype = os.getenv("Embedding_Model_ID")
  9. api_key = os.getenv("SiliconCloud_API_KEY")
  10. base_url = os.getenv("SiliconCloud_Base_URL")
  11. embedding_instance = OpenAICompatibleEmbedding(model_type=modeltype, api_key=api_key, url=base_url)
  12. # Embed the text
  13. text_embeddings = embedding_instance.embed_list(["What is the capital of France?"])
  14. print(len(text_embeddings[0]))
复制代码
成功调用的输出如下所示:
1.png

有了嵌入模型之后,还需要有向量数据库。
这里使用的是QdrantStorage,要注意指定维度。
可以这样写:
  1. storage_instance = QdrantStorage(
  2.     vector_dim=1024,
  3.     path="local_data",
  4.     collection_name="test",
  5. )
复制代码
在CAMEL中实现Customized RAG需要使用VectorRetriever类,需要指定嵌入模型与向量数据库。
可以这样写:
  1. vector_retriever = VectorRetriever(embedding_model=embedding_instance,
  2.                                    storage=storage_instance)
复制代码
在官方文档中使用的是一个PDF做的示例,但是我跑起来有问题,原因是一个相关依赖没有成功安装。
但是实现RAG很多时候确实是更加针对PDF文档的,如果不能适配PDF文档那就很鸡肋了。
因此可以自己简单写一下从pdf中提取文本的代码。
可以这样写:
  1. import PyPDF2
  2. def read_pdf_with_pypdf2(file_path):
  3.     with open(file_path, "rb") as file:
  4.         reader = PyPDF2.PdfReader(file)
  5.         text = ""
  6.         for page_num in range(len(reader.pages)):
  7.             page = reader.pages[page_num]
  8.             text += page.extract_text()
  9.     return text
  10. input_path = "local_data/test.pdf"
  11. pdf_text = read_pdf_with_pypdf2(input_path)
  12. print(pdf_text)
复制代码
测试文档:
2.png

查看效果:
3.png

将这个代码写入脚本中,获取pdf文本之后,将文本进行向量化。
可以这样写:
  1. def read_pdf_with_pypdf2(file_path):
  2.     with open(file_path, "rb") as file:
  3.         reader = PyPDF2.PdfReader(file)
  4.         text = ""
  5.         for page_num in range(len(reader.pages)):
  6.             page = reader.pages[page_num]
  7.             text += page.extract_text()
  8.     return text
  9. input_path = "local_data/test.pdf"
  10. pdf_text = read_pdf_with_pypdf2(input_path)
  11. print("向量化中...")
  12. vector_retriever.process(
  13.     content=pdf_text,
  14. )
  15. print("向量化完成")
复制代码
然后可以进行提问,我这里问两个相关的与一个不相关的问题。
可以这样写:
  1. retrieved_info = vector_retriever.query(
  2.     query="你最喜欢的编程语言是什么?",
  3.     top_k=1
  4. )
  5. print(retrieved_info)
  6. retrieved_info2 = vector_retriever.query(
  7.     query="你最喜欢的桌面开发框架是什么?",
  8.     top_k=1
  9. )
  10. print(retrieved_info2)
  11. retrieved_info_irrevelant = vector_retriever.query(
  12.     query="今天晚上吃什么?",
  13.     top_k=1,
  14. )
  15. print(retrieved_info_irrevelant)
复制代码
效果如下所示:
4.png

通过以上步骤,我们就在CAMEL中实现了Customized RAG。
Auto RAG

现在再来看看如何在CAMEL中实现Auto RAG。
CAMEL中实现Auto RAG需要使用AutoRetriever类。
可以这样写:
  1. from camel.embeddings import OpenAICompatibleEmbedding
  2. from camel.storages import QdrantStorage
  3. from camel.retrievers import AutoRetriever
  4. from camel.types import StorageType
  5. import pathlib
  6. import os
  7. from dotenv import load_dotenv
  8. base_dir = pathlib.Path(__file__).parent.parent
  9. env_path = base_dir / ".env"
  10. load_dotenv(dotenv_path=str(env_path))
  11. modeltype = os.getenv("Embedding_Model_ID")
  12. api_key = os.getenv("SiliconCloud_API_KEY")
  13. base_url = os.getenv("SiliconCloud_Base_URL")
  14. embedding_instance = OpenAICompatibleEmbedding(model_type=modeltype, api_key=api_key, url=base_url)
  15. embedding_instance.output_dim=1024
  16. auto_retriever = AutoRetriever(
  17.         vector_storage_local_path="local_data2/",
  18.         storage_type=StorageType.QDRANT,
  19.         embedding_model=embedding_instance)
  20. retrieved_info = auto_retriever.run_vector_retriever(
  21.     query="本届消博会共实现意向交易多少亿元?",
  22.     contents=[      
  23.         "https://news.cctv.com/2025/04/17/ARTIbMtuugrC3uxmNKsQRyci250417.shtml?spm=C94212.PBZrLs0D62ld.EKoevbmLqVHC.156",  # example remote url
  24.     ],
  25.     top_k=1,
  26.     return_detailed_info=True,
  27.     similarity_threshold=0.5
  28. )
  29. print(retrieved_info)
复制代码
可以直接传入一个链接。
5.png

查看效果:
6.png

Single Agent with Auto RAG

刚刚已经成功实现了相关信息的获取,但是还没有真正实现RAG。
实现的思路其实很简单,我这里提供了两个例子。
第一个将相关信息存入模型上下文:
7.png

可以这样写:
  1. from camel.agents import ChatAgent
  2. from camel.models import ModelFactory
  3. from camel.types import ModelPlatformType,StorageType
  4. from camel.embeddings import OpenAICompatibleEmbedding
  5. from camel.storages import QdrantStorage
  6. from camel.retrievers import AutoRetriever
  7. import pathlib
  8. import os
  9. from dotenv import load_dotenv
  10. sys_msg = 'You are a curious stone wondering about the universe.'
  11. base_dir = pathlib.Path(__file__).parent.parent
  12. env_path = base_dir / ".env"
  13. load_dotenv(dotenv_path=str(env_path))
  14. modeltype = os.getenv("Silicon_Model_ID")
  15. embedding_modeltype = os.getenv("Embedding_Model_ID")
  16. api_key = os.getenv("SiliconCloud_API_KEY")
  17. base_url = os.getenv("SiliconCloud_Base_URL")
  18. siliconcloud_model = ModelFactory.create(
  19.      model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
  20.             model_type=modeltype,
  21.             api_key=api_key,
  22.             url=base_url,
  23.             model_config_dict={"temperature": 0.4, "max_tokens": 4096},
  24. )
  25. embedding_instance = OpenAICompatibleEmbedding(model_type=embedding_modeltype, api_key=api_key, url=base_url)
  26. embedding_instance.output_dim=1024
  27. auto_retriever = AutoRetriever(
  28.         vector_storage_local_path="local_data2/",
  29.         storage_type=StorageType.QDRANT,
  30.         embedding_model=embedding_instance)
  31. # Define a user message
  32. usr_msg = '3场官方供需对接会共签约多少个项目?'
  33. retrieved_info = auto_retriever.run_vector_retriever(
  34.     query=usr_msg,
  35.     contents=[      
  36.         "https://news.cctv.com/2025/04/17/ARTIbMtuugrC3uxmNKsQRyci250417.shtml?spm=C94212.PBZrLs0D62ld.EKoevbmLqVHC.156",  # example remote url
  37.     ],
  38.     top_k=1,
  39.     return_detailed_info=True,
  40.     similarity_threshold=0.5
  41. )
  42. print(retrieved_info)
  43. text_content = retrieved_info['Retrieved Context'][0]['text']
  44. print(text_content)
  45. agent = ChatAgent(
  46.     system_message=sys_msg,
  47.     model=siliconcloud_model,
  48. )
  49. print(agent.memory.get_context())
  50. from camel.messages import BaseMessage
  51. new_user_msg = BaseMessage.make_assistant_message(
  52.     role_name="assistant",
  53.     content=text_content,  # Use the content from the retrieved info
  54. )
  55. # Update the memory
  56. agent.record_message(new_user_msg)
  57. print(agent.memory.get_context())
  58. # Sending the message to the agent
  59. response = agent.step(usr_msg)
  60. # Check the response (just for illustrative purpose)
  61. print(response.msgs[0].content)
复制代码
输出结果:
8.png

另一个就是通过写一个提示词,然后将获取的结果直接传给模型。
9.png

可以这样写:
  1. from camel.agents import ChatAgent
  2. from camel.retrievers import AutoRetriever
  3. from camel.types import StorageType
  4. from camel.embeddings import OpenAICompatibleEmbedding
  5. from camel.models import ModelFactory
  6. from camel.types import ModelPlatformType,StorageType
  7. import pathlib
  8. import os
  9. from dotenv import load_dotenv
  10. base_dir = pathlib.Path(__file__).parent.parent
  11. env_path = base_dir / ".env"
  12. load_dotenv(dotenv_path=str(env_path))
  13. modeltype = os.getenv("Silicon_Model_ID")
  14. embedding_modeltype = os.getenv("Embedding_Model_ID")
  15. api_key = os.getenv("SiliconCloud_API_KEY")
  16. base_url = os.getenv("SiliconCloud_Base_URL")
  17. siliconcloud_model = ModelFactory.create(
  18.      model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
  19.             model_type=modeltype,
  20.             api_key=api_key,
  21.             url=base_url,
  22.             model_config_dict={"temperature": 0.4, "max_tokens": 4096},
  23. )
  24. embedding_instance = OpenAICompatibleEmbedding(model_type=embedding_modeltype, api_key=api_key, url=base_url)
  25. embedding_instance.output_dim=1024
  26. def single_agent(query: str) ->str :
  27.     # Set agent role
  28.     assistant_sys_msg = """You are a helpful assistant to answer question,
  29.          I will give you the Original Query and Retrieved Context,
  30.         answer the Original Query based on the Retrieved Context,
  31.         if you can't answer the question just say I don't know."""
  32.     # Add auto retriever
  33.     auto_retriever = AutoRetriever(
  34.             vector_storage_local_path="local_data2/",
  35.             storage_type=StorageType.QDRANT,
  36.             embedding_model=embedding_instance)
  37.    
  38.     retrieved_info = auto_retriever.run_vector_retriever(
  39.         query=query,
  40.         contents=[      
  41.         "https://news.cctv.com/2025/04/17/ARTIbMtuugrC3uxmNKsQRyci250417.shtml?spm=C94212.PBZrLs0D62ld.EKoevbmLqVHC.156",  # example remote url
  42.     ],
  43.     top_k=1,
  44.     return_detailed_info=True,
  45.     similarity_threshold=0.5
  46.     )
  47.     # Pass the retrieved information to agent
  48.     user_msg = str(retrieved_info)
  49.     agent = ChatAgent(
  50.     system_message=assistant_sys_msg,
  51.     model=siliconcloud_model,
  52.     )
  53.     # Get response
  54.     assistant_response = agent.step(user_msg)
  55.     return assistant_response.msg.content
  56. print(single_agent("3场官方供需对接会共签约多少个项目?"))
复制代码
输出结果:
10.png

Role-playing with Auto RAG

最后来玩一下Role-playing with Auto RAG。在我这里好像效果并不好,第二次调用函数就会出现问题。
可以这样写:
  1. from camel.societies import RolePlaying
  2. from camel.models import ModelFactory
  3. from camel.types import ModelPlatformType, StorageType
  4. from camel.toolkits import FunctionTool
  5. from camel.embeddings import OpenAICompatibleEmbedding
  6. from camel.types.agents import ToolCallingRecord
  7. from camel.retrievers import AutoRetriever
  8. from camel.utils import Constants
  9. from typing import List, Union
  10. from camel.utils import print_text_animated
  11. from colorama import Fore
  12. import pathlib
  13. import os
  14. from dotenv import load_dotenv
  15. sys_msg = 'You are a curious stone wondering about the universe.'
  16. base_dir = pathlib.Path(__file__).parent.parent
  17. env_path = base_dir / ".env"
  18. load_dotenv(dotenv_path=str(env_path))
  19. modeltype = os.getenv("Silicon_Model_ID")
  20. modeltype2= os.getenv("ZHIPU_Model_ID")
  21. embedding_modeltype = os.getenv("Embedding_Model_ID")
  22. api_key = os.getenv("SiliconCloud_API_KEY")
  23. base_url = os.getenv("SiliconCloud_Base_URL")
  24. siliconcloud_model = ModelFactory.create(
  25.      model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
  26.             model_type=modeltype,
  27.             api_key=api_key,
  28.             url=base_url,
  29.             model_config_dict={"temperature": 0.4, "max_tokens": 4096},
  30. )
  31. siliconcloud_model2 = ModelFactory.create(
  32.      model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
  33.             model_type=modeltype2,
  34.             api_key=api_key,
  35.             url=base_url,
  36.             model_config_dict={"temperature": 0.4, "max_tokens": 4096},
  37. )
  38. embedding_instance = OpenAICompatibleEmbedding(model_type=embedding_modeltype, api_key=api_key, url=base_url)
  39. embedding_instance.output_dim=1024
  40. auto_retriever = AutoRetriever(
  41.         vector_storage_local_path="local_data2/",
  42.         storage_type=StorageType.QDRANT,
  43.         embedding_model=embedding_instance)
  44. def information_retrieval(
  45.         query: str,
  46.         contents: Union[str, List[str]],
  47.         top_k: int = Constants.DEFAULT_TOP_K_RESULTS,
  48.         similarity_threshold: float = Constants.DEFAULT_SIMILARITY_THRESHOLD,
  49.     ) -> str:
  50.         r"""Retrieves information from a local vector storage based on the
  51.         specified query. This function connects to a local vector storage
  52.         system and retrieves relevant information by processing the input
  53.         query. It is essential to use this function when the answer to a
  54.         question requires external knowledge sources.
  55.         Args:
  56.             query (str): The question or query for which an answer is required.
  57.             contents (Union[str, List[str]]): Local file paths, remote URLs or
  58.                 string contents.
  59.             top_k (int, optional): The number of top results to return during
  60.                 retrieve. Must be a positive integer. Defaults to
  61.                 `DEFAULT_TOP_K_RESULTS`.
  62.             similarity_threshold (float, optional): The similarity threshold
  63.                 for filtering results. Defaults to
  64.                 `DEFAULT_SIMILARITY_THRESHOLD`.
  65.         Returns:
  66.             str: The information retrieved in response to the query, aggregated
  67.                 and formatted as a string.
  68.         Example:
  69.             # Retrieve information about CAMEL AI.
  70.             information_retrieval(query = "How to contribute to CAMEL AI?",
  71.                                 contents="https://github.com/camel-ai/camel/blob/master/CONTRIBUTING.md")
  72.         """
  73.         retrieved_info = auto_retriever.run_vector_retriever(
  74.             query=query,
  75.             contents=contents,
  76.             top_k=top_k,
  77.             similarity_threshold=similarity_threshold,
  78.         )
  79.         return str(retrieved_info)
  80. RETRUEVE_FUNCS: list[FunctionTool] = [
  81.     FunctionTool(func) for func in [information_retrieval]
  82. ]
  83. def role_playing_with_rag(
  84.     task_prompt,
  85.     chat_turn_limit=5,
  86. ) -> None:
  87.     task_prompt = task_prompt
  88.     role_play_session = RolePlaying(
  89.         assistant_role_name="Searcher",
  90.         assistant_agent_kwargs=dict(
  91.             model=siliconcloud_model,
  92.             tools=[
  93.                 *RETRUEVE_FUNCS,
  94.             ],
  95.         ),
  96.         user_role_name="Professor",
  97.         user_agent_kwargs=dict(
  98.             model=siliconcloud_model2,
  99.         ),
  100.         task_prompt=task_prompt,
  101.         with_task_specify=False,
  102.     )
  103.     print(
  104.         Fore.GREEN
  105.         + f"AI Assistant sys message:\n{role_play_session.assistant_sys_msg}\n"
  106.     )
  107.     print(
  108.         Fore.BLUE + f"AI User sys message:\n{role_play_session.user_sys_msg}\n"
  109.     )
  110.     print(Fore.YELLOW + f"Original task prompt:\n{task_prompt}\n")
  111.     print(
  112.         Fore.CYAN
  113.         + "Specified task prompt:"
  114.         + f"\n{role_play_session.specified_task_prompt}\n"
  115.     )
  116.     print(Fore.RED + f"Final task prompt:\n{role_play_session.task_prompt}\n")
  117.     n = 0
  118.     input_msg = role_play_session.init_chat()
  119.     while n < chat_turn_limit:
  120.         n += 1
  121.         assistant_response, user_response = role_play_session.step(input_msg)
  122.         if assistant_response.terminated:
  123.             print(
  124.                 Fore.GREEN
  125.                 + (
  126.                     "AI Assistant terminated. Reason: "
  127.                     f"{assistant_response.info['termination_reasons']}."
  128.                 )
  129.             )
  130.             break
  131.         if user_response.terminated:
  132.             print(
  133.                 Fore.GREEN
  134.                 + (
  135.                     "AI User terminated. "
  136.                     f"Reason: {user_response.info['termination_reasons']}."
  137.                 )
  138.             )
  139.             break
  140.         # Print output from the user
  141.         print_text_animated(
  142.             Fore.BLUE + f"AI User:\n\n{user_response.msg.content}\n"
  143.         )
  144.         # Print output from the assistant, including any function
  145.         # execution information
  146.         print_text_animated(Fore.GREEN + "AI Assistant:")
  147.         tool_calls: List[ToolCallingRecord] = [
  148.             ToolCallingRecord(**call.as_dict())
  149.             for call in assistant_response.info['tool_calls']
  150.         ]
  151.         for func_record in tool_calls:
  152.             print_text_animated(f"{func_record}")
  153.         print_text_animated(f"{assistant_response.msg.content}\n")
  154.         if "CAMEL_TASK_DONE" in user_response.msg.content:
  155.             break
  156. if __name__ == "__main__":
  157.    role_playing_with_rag(
  158.         task_prompt="4月17日凌晨,OpenAI正式宣布推出了什么?请参考https://www.thepaper.cn/newsDetail_forward_30670507",
  159.         chat_turn_limit=5,
  160.     )
复制代码
调式运行:
11.png

会发现我们没有自己设置AI助手与AI用户的提示词,系统自动生成了提示词。
第一次成功进行了函数调用:
12.png

但是由于similarity_threshold设置的太高导致没有成功获取相关信息:
  1. {'Original Query': '4月17日凌晨,OpenAI正式宣布推出了什么?', 'Retrieved Context': ['No suitable information retrieved from https://www.thepaper.cn/newsDetail_forward_30670507 with similarity_threshold = 0.75.']}
复制代码
第二次调用把similarity_threshold调低了:

然后就会遇到错误:
14.png

暂时没有解决,不过也不影响学习Role-playing with Auto RAG。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册