如何处理查询分析中的高基数类别变量

引言

在进行查询分析时,我们可能需要对一个类别列进行过滤。一个常见的挑战是需要指定确切的类别值。当可用的类别值较少时,可以通过提示轻松解决此问题。然而,当有效值数量很大时,情况就变得复杂,因为这些值可能无法装入语言模型(LLM)的上下文中,或者即使装进去,也可能太多而无法有效处理。

本文将探讨如何应对这个挑战。

主要内容

设置环境

安装依赖

# %pip install -qU langchain langchain-community langchain-openai faker langchain-chroma

设置环境变量

在此示例中,我们将使用OpenAI接口:

import getpass
import os

os.environ["OPENAI_API_KEY"] = getpass.getpass()

准备数据

我们将生成大量虚构的姓名:

from faker import Faker

fake = Faker()

names = [fake.name() for _ in range(10000)]

查询分析

设置基本查询分析:

from langchain_core.pydantic_v1 import BaseModel, Field

class Search(BaseModel):
    query: str
    author: str

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI

system = """Generate a relevant search query for a library system"""
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", system),
        ("human", "{question}"),
    ]
)
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm = llm.with_structured_output(Search)
query_analyzer = {"question": RunnablePassthrough()} | prompt | structured_llm

添加所有值

一种方法是将所有可能的值添加到提示中,但如果类别列表足够长,可能会导致错误。

system = """Generate a relevant search query for a library system.

`author` attribute MUST be one of:

{authors}

Do NOT hallucinate author name!"""
base_prompt = ChatPromptTemplate.from_messages(
    [
        ("system", system),
        ("human", "{question}"),
    ]
)
prompt = base_prompt.partial(authors=", ".join(names))

query_analyzer_all = {"question": RunnablePassthrough()} | prompt | structured_llm

索引相关值

使用Chroma和OpenAI Embeddings创建索引,然后查询N个最相关的值。

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings(model="text-embedding-3-small")  # 使用API代理服务提高访问稳定性
vectorstore = Chroma.from_texts(names, embeddings, collection_name="author_names")

def select_names(question):
    _docs = vectorstore.similarity_search(question, k=10)
    _names = [d.page_content for d in _docs]
    return ", ".join(_names)

create_prompt = {
    "question": RunnablePassthrough(),
    "authors": select_names,
} | base_prompt

query_analyzer_select = create_prompt | structured_llm

替换后的选择

让LLM填写任意值,然后使用Pydantic类将该值转换为有效值。

from langchain_core.pydantic_v1 import validator

class Search(BaseModel):
    query: str
    author: str

    @validator("author")
    def double(cls, v: str) -> str:
        return vectorstore.similarity_search(v, k=1)[0].page_content

corrective_structure_llm = llm.with_structured_output(Search)
corrective_query_analyzer = (
    {"question": RunnablePassthrough()} | prompt | corrective_structure_llm
)

常见问题和解决方案

  1. 上下文长度限制:使用较长上下文窗口或减少上下文信息。
  2. 作者名称拼写不准确:通过向量搜索进行校正。

总结和进一步学习资源

通过创建向量索引和使用Pydantic类进行校正,可以有效处理高基数类别变量的查询分析。推荐进一步了解LangChain以探索更多高级功能。

参考资料

  1. LangChain Documentation
  2. OpenAI API
  3. Faker Documentation
  4. Chroma Documentation

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

—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值