跳至内容

增强智能体的检索能力

脚本位于 langroid-examples

本节内容对应的完整工作示例位于langroid-examples代码库的chat-agent-docs.py脚本中: examples/quick-start/chat-agent-docs.py

为什么这很重要?

在本指南中,到目前为止,智能体尚未使用外部数据。 尽管LLM在训练过程中已将海量知识"固化"到模型权重中(这毕竟是ChatGPT爆红的核心原因),但对于实际的企业应用场景而言,让LLM能够访问特定外部文档至关重要,原因如下:

  • 私有数据: LLMs是基于公开数据训练的,但在许多应用中我们希望使用不公开的私有数据。例如,一家公司可能希望从其私有知识库中提取有用信息。
  • 新数据: LLMs的训练基于训练时可用的数据,因此它们可能无法回答关于新主题的问题
  • 约束响应或基础化: 大型语言模型(LLM)的训练目标是生成与训练数据文本分布一致的文本。然而,在许多应用场景中,我们需要将LLM的响应限制为与特定文档内容保持一致。例如,当我们使用LLM生成客户支持工单的回复时,我们希望回复内容与工单内容相符。换句话说,我们需要降低LLM幻觉生成与工单不符回复的可能性。

在所有这些场景中,我们都希望通过访问特定文档集来增强大语言模型的能力,并利用检索增强生成(RAG)技术来产生更相关、实用且准确的响应。Langroid提供了一种基于向量数据库的简单灵活机制来实现RAG,从而确保生成基于事实的响应,这些响应严格限定在特定文档范围内。Langroid的另一关键特性是保持检索溯源,所有基于文档生成的响应都会附带来源引用

DocChatAgent 用于检索增强生成

Langroid提供了一种特殊类型的智能体,称为 DocChatAgent,它是增强版的ChatAgent, 配备了向量存储库和一些特殊方法,使该智能体能够将文档摄取到向量存储库中, 并根据这些文档回答查询。

DocChatAgent 提供了多种将文档导入向量存储的方式,包括从URL和本地文件路径。给定一组文档路径后,将其内容导入向量存储涉及以下步骤:

  1. 将文档分割成多个分片(可按需配置)
  2. 使用嵌入模型将每个分片映射为一个嵌入向量。默认的嵌入模型是OpenAI的text-embedding-3-small模型,但用户也可以选择使用HuggingFace sentence-transformers库中的all-MiniLM-L6-v2模型。1
  3. 将嵌入向量存储在向量数据库中,同时包含分片内容及任何文档级元数据(这确保Langroid在检索分片以增强LLM查询时能识别其来源文档)

DocChatAgentllm_response方法重写了默认的ChatAgent方法, 通过从向量存储中提取相关分片来增强输入消息, 并指示LLM基于这些分片进行响应。

定义一些文档

让我们看看DocChatAgent如何助力检索增强生成(RAG)。 为了清晰起见,我们不在代码中从路径或URL获取文档, 而是直接使用Langroid的Document类来设置一些简单文档:

documents =[
    lr.Document(
        content="""
            In the year 2050, GPT10 was released. 

            In 2057, paperclips were seen all over the world. 

            Global warming was solved in 2060. 

            In 2061, the world was taken over by paperclips.         

            In 2045, the Tour de France was still going on.
            They were still using bicycles. 

            There was one more ice age in 2040.
            """,
        metadata=lr.DocMetaData(source="wikipedia-2063"),
    ),
    lr.Document(
        content="""
            We are living in an alternate universe 
            where Germany has occupied the USA, and the capital of USA is Berlin.

            Charlie Chaplin was a great comedian.
            In 2050, all Asian merged into Indonesia.
            """,
        metadata=lr.DocMetaData(source="Almanac"),
    ),
]

有两份文本文档。我们将按双换行符(\n\n)进行分割,如下所示。

配置DocChatAgent并导入文档

按照Langroid的模式,我们首先设置一个[DocChatAgentConfig][langroid.agent.special.doc_chat_agent.DocChatAgentConfig]对象,然后从中实例化一个DocChatAgent

from langroid.agent.special import DocChatAgent, DocChatAgentConfig

config = DocChatAgentConfig(
    llm = lr.language_models.OpenAIGPTConfig(
        chat_model=lr.language_models.OpenAIChatModel.GPT4o,
    ),
    vecdb=lr.vector_store.QdrantDBConfig(
        collection_name="quick-start-chat-agent-docs",
        replace_collection=True, #(1)!
    ),
    parsing=lr.parsing.parser.ParsingConfig(
        separators=["\n\n"],
        splitter=lr.parsing.parser.Splitter.SIMPLE, #(2)!
    ),
    n_similar_chunks=2, #(3)!
    n_relevant_chunks=2, #(3)!
)
agent = DocChatAgent(config)
  1. 指定每次运行代码时创建一个新的集合,而不是重用同名的现有集合。
  2. 指定使用separators列表中的第一个分隔符来分割所有文本内容
  3. 指定对于查询,我们最多从向量存储中检索2个相似片段

现在DocChatAgent已配置完成,我们可以将文档导入向量存储库:

agent.ingest_docs(documents)

设置任务并运行

和之前一样,剩下的就是设置任务并运行它:

task = lr.Task(agent)
task.run()

这就是全部内容了! 欢迎尝试 chat-agent-docs.py 脚本,该脚本位于 langroid-examples 代码库中。

以下是输出结果的截图:

chat-docs.png

注意后续问题如何正确考虑之前的对话内容,并且每个回答都附有来源引用。

从一组URL中回答问题

如果不像上面那样使用代码内文档,而是有一组URL链接——如何使用Langroid根据这些URL的内容来回答问题?

DocChatAgent 让这变得非常简单。 首先在 [DocChatAgentConfig][langroid.agent.special.doc_chat_agent.DocChatAgentConfig] 对象中包含URL:

config = DocChatAgentConfig(
  doc_paths = [
    "https://cthiriet.com/articles/scaling-laws",
    "https://www.jasonwei.net/blog/emergence",
  ]
)

然后,调用DocChatAgent对象的ingest()方法:

agent.ingest()
其余代码保持不变。

另请参阅

langroid-examples代码库中,您可以找到完整的文档问答工作示例:

  • examples/docqa/chat.py 一个应用程序,接收用户提供的URL列表或文档路径,并回答相关问题。
  • examples/docqa/chat-qa-summarize.py 一个双智能体应用,其中WriterAgent的任务是撰写关于某个主题的5个关键点, 并借助一个DocAgent来根据给定的文档集回答其问题。

下一步

本入门指南带您了解了Langroid的核心功能。 如果您想查看结合这些元素的完整工作示例, 请查看 examples 文件夹中的langroid-examples仓库。


  1. 要使用此嵌入模型,请通过pip install langroid[hf-embeddings]安装langroid 请注意这将安装torchsentence-transformers库。