引言
在进行查询分析时,我们可能需要对一个类别列进行过滤。一个常见的挑战是需要指定确切的类别值。当可用的类别值较少时,可以通过提示轻松解决此问题。然而,当有效值数量很大时,情况就变得复杂,因为这些值可能无法装入语言模型(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
)
常见问题和解决方案
- 上下文长度限制:使用较长上下文窗口或减少上下文信息。
- 作者名称拼写不准确:通过向量搜索进行校正。
总结和进一步学习资源
通过创建向量索引和使用Pydantic类进行校正,可以有效处理高基数类别变量的查询分析。推荐进一步了解LangChain以探索更多高级功能。
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
—END—