Query analysis#
查询分析的意思是,将原始的查询通过llm来生成一些新的查询,将这些结果,套入retrieve中做检索。
查询分析中增加一些示例#
随着查询变得复杂,模型在某些情况下,模型不太明确应该怎么回答问题,可以在提示中加一些例子引导llm
先来个查询分析#
from typing import List, Optional
from langchain_core.pydantic_v1 import BaseModel, Field
sub_queries_description = """
如果原始的问题包含了多个不同的子问题,或者可以变为更加通用的问题,回答这些问题有助于回答原始问题的话,
需要写下这些相关子问题的列表
要求:
1. 你要确保这些列表是全面的,涵盖了原始问题的所有部分
2. 允许子问题存在冗余,确保子问题要聚焦
"""
# 定义一个model。
class Search(BaseModel):
"""搜索电影数据库"""
query: str = Field(
...,
description="应用于电影的主要相似性搜索查询",
)
sub_queries: List[str] = Field(
default_factory=list, description=sub_queries_description
)
publish_year: Optional[int] = Field(None, description="电影发布年份")
## 定义查询的Chain
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
system = """您擅长将用户问题转换为数据库查询。\
您可以访问一个关于构建基于LLM的应用程序的电影视频数据库。\
给定一个问题,返回一组经过优化以检索最相关结果的数据库查询列表。"""
prompt = ChatPromptTemplate.from_messages(
[
("system", system),
MessagesPlaceholder("examples", optional=True),
("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
from langchain.globals import set_verbose,set_debug
set_verbose(True)
set_debug(True)
query_analyzer.invoke(
"Web Voyager和Reflection Agents之间有什么区别?它们都使用LangGraph吗?"
)
[chain/start] [chain:RunnableSequence] Entering Chain run with input:
{
"input": "Web Voyager和Reflection Agents之间有什么区别?它们都使用LangGraph吗?"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question>] Entering Chain run with input:
{
"input": "Web Voyager和Reflection Agents之间有什么区别?它们都使用LangGraph吗?"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question> > chain:RunnablePassthrough] Entering Chain run with input:
{
"input": "Web Voyager和Reflection Agents之间有什么区别?它们都使用LangGraph吗?"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question> > chain:RunnablePassthrough] [1ms] Exiting Chain run with output:
{
"output": "Web Voyager和Reflection Agents之间有什么区别?它们都使用LangGraph吗?"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question>] [2ms] Exiting Chain run with output:
{
"question": "Web Voyager和Reflection Agents之间有什么区别?它们都使用LangGraph吗?"
}
[chain/start] [chain:RunnableSequence > prompt:ChatPromptTemplate] Entering Prompt run with input:
{
"question": "Web Voyager和Reflection Agents之间有什么区别?它们都使用LangGraph吗?"
}
[chain/end] [chain:RunnableSequence > prompt:ChatPromptTemplate] [1ms] Exiting Prompt run with output:
[outputs]
[llm/start] [chain:RunnableSequence > llm:ChatOpenAI] Entering LLM run with input:
{
"prompts": [
"System: 您擅长将用户问题转换为数据库查询。您可以访问一个关于构建基于LLM的应用程序的电影视频数据库。给定一个问题,返回一组经过优化以检索最相关结果的数据库查询列表。\nHuman: Web Voyager和Reflection Agents之间有什么区别?它们都使用LangGraph吗?"
]
}
[llm/end] [chain:RunnableSequence > llm:ChatOpenAI] [2.70s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "",
"generation_info": {
"finish_reason": "stop",
"logprobs": null
},
"type": "ChatGeneration",
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "",
"additional_kwargs": {
"tool_calls": [
{
"id": "call_85sJ5GpZDsSp9oDztYzftied",
"function": {
"arguments": "{\"query\":\"区别: Web Voyager和Reflection Agents\",\"sub_queries\":[\"Web Voyager 使用 LangGraph 吗\",\"Reflection Agents 使用 LangGraph 吗\"]}",
"name": "Search",
"parameters": null
},
"type": "function"
}
]
},
"response_metadata": {
"token_usage": {
"completion_tokens": 31,
"prompt_tokens": 296,
"total_tokens": 327
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null,
"finish_reason": "stop",
"logprobs": null
},
"type": "ai",
"id": "run-8a8d00a5-beab-4752-b73f-3a3390d86147-0",
"tool_calls": [
{
"name": "Search",
"args": {
"query": "区别: Web Voyager和Reflection Agents",
"sub_queries": [
"Web Voyager 使用 LangGraph 吗",
"Reflection Agents 使用 LangGraph 吗"
]
},
"id": "call_85sJ5GpZDsSp9oDztYzftied"
}
],
"usage_metadata": {
"input_tokens": 296,
"output_tokens": 31,
"total_tokens": 327
},
"invalid_tool_calls": []
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 31,
"prompt_tokens": 296,
"total_tokens": 327
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null
},
"run": null
}
[chain/start] [chain:RunnableSequence > parser:PydanticToolsParser] Entering Parser run with input:
[inputs]
[chain/end] [chain:RunnableSequence > parser:PydanticToolsParser] [1ms] Exiting Parser run with output:
[outputs]
[chain/end] [chain:RunnableSequence] [2.71s] Exiting Chain run with output:
[outputs]
Search(query='区别: Web Voyager和Reflection Agents', sub_queries=['Web Voyager 使用 LangGraph 吗', 'Reflection Agents 使用 LangGraph 吗'], publish_year=None)
可以看到。从用户的输入中已经提取出了问题。并且拓展出了一些子问题,但是这些问题覆盖的面不够,增加example来帮助生成更好的问题。
在prompt中增加一些示例#
为了提高性能,增加一些example
examples = []
question = "langchain是什么,它是一个langchain模板吗?"
query = Search(
query="langchain是什么,它是一个langchain模板吗?",
sub_queries=["langchain是什么", "langchain template是什么"],
)
examples.append({"input": question, "tool_calls": [query]})
question = "如何构建多智能体系统并从中流式传输中间步骤"
query = Search(
query="如何构建多智能体系统并从中流式传输中间步骤",
sub_queries=[
"如何构建多智能体系统",
"如何从多智能体系统中流式传输中间步骤",
"如何流式传输中间步骤",
],
)
examples.append({"input": question, "tool_calls": [query]})
question = "LangChain agents vs LangGraph?"
query = Search(
query="LangChain的agent和LangGraph有什么不同,如何部署他们呢",
sub_queries=[
"LangChain的agent是什么?",
"LangGraph是什么?",
"如何部署LangChain的agent?",
"如何部署LangGraph?",
],
)
examples.append({"input": question, "tool_calls": [query]})
上面已经构建好了示例,下面需要将他组装在prompt中
import uuid
from typing import Dict
from langchain_core.messages import (
AIMessage,
BaseMessage,
HumanMessage,
SystemMessage,
ToolMessage,
)
def tool_example_to_messages(example: Dict) -> List[BaseMessage]:
messages = [HumanMessage(content=example["input"])]
openai_tool_calls = []
for tool_call in example["tool_calls"]:
openai_tool_calls.append(
{
"id": str(uuid.uuid4()),
"type": "function",
"function": {
"name": tool_call.__class__.__name__,
"arguments": tool_call.json(),
},
}
)
messages.append(
AIMessage(content="", additional_kwargs={"tool_calls": openai_tool_calls})
)
tool_outputs = example.get("tool_outputs") or [
"You have correctly called this tool."
] * len(openai_tool_calls)
for output, tool_call in zip(tool_outputs, openai_tool_calls):
messages.append(ToolMessage(content=output, tool_call_id=tool_call["id"]))
return messages
tool_example_to_messages(examples[0])
[HumanMessage(content='langchain是什么,它是一个langchain模板吗?'),
AIMessage(content='', additional_kwargs={'tool_calls': [{'id': '88e8e325-a1a4-4a07-a17f-f2b2200de1d8', 'type': 'function', 'function': {'name': 'Search', 'arguments': '{"query": "langchain\\u662f\\u4ec0\\u4e48\\uff0c\\u5b83\\u662f\\u4e00\\u4e2alangchain\\u6a21\\u677f\\u5417?", "sub_queries": ["langchain\\u662f\\u4ec0\\u4e48", "langchain template\\u662f\\u4ec0\\u4e48"], "publish_year": null}'}}]}, tool_calls=[{'name': 'Search', 'args': {'query': 'langchain是什么,它是一个langchain模板吗?', 'sub_queries': ['langchain是什么', 'langchain template是什么'], 'publish_year': None}, 'id': '88e8e325-a1a4-4a07-a17f-f2b2200de1d8'}]),
ToolMessage(content='You have correctly called this tool.', tool_call_id='88e8e325-a1a4-4a07-a17f-f2b2200de1d8')]
带入一个example看,一个example生成了三个message,这代表一次完整的响应,首先,HumanMessage代表人问AI的问题,AIMessage代表AI需要调用 Search工具,ToolMessage 代表工具的输出。
# 现在生成了示例的prompt
example_msgs = [msg for ex in examples for msg in tool_example_to_messages(ex)]
# 下面只需要将所有的链接在一起就好了
query_analyzer_with_examples = (
{"question": RunnablePassthrough()}
| prompt.partial(examples=example_msgs)
| structured_llm
)
from langchain.globals import set_debug
set_debug(True)
query_analyzer_with_examples.invoke(
"刘德华和吴彦祖,到底谁帅呢?谁是彦祖呢?"
)
[chain/start] [chain:RunnableSequence] Entering Chain run with input:
{
"input": "刘德华和吴彦祖,到底谁帅呢?谁是彦祖呢?"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question>] Entering Chain run with input:
{
"input": "刘德华和吴彦祖,到底谁帅呢?谁是彦祖呢?"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question> > chain:RunnablePassthrough] Entering Chain run with input:
{
"input": "刘德华和吴彦祖,到底谁帅呢?谁是彦祖呢?"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question> > chain:RunnablePassthrough] [1ms] Exiting Chain run with output:
{
"output": "刘德华和吴彦祖,到底谁帅呢?谁是彦祖呢?"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question>] [2ms] Exiting Chain run with output:
{
"question": "刘德华和吴彦祖,到底谁帅呢?谁是彦祖呢?"
}
[chain/start] [chain:RunnableSequence > prompt:ChatPromptTemplate] Entering Prompt run with input:
{
"question": "刘德华和吴彦祖,到底谁帅呢?谁是彦祖呢?"
}
[chain/end] [chain:RunnableSequence > prompt:ChatPromptTemplate] [1ms] Exiting Prompt run with output:
[outputs]
[llm/start] [chain:RunnableSequence > llm:ChatOpenAI] Entering LLM run with input:
{
"prompts": [
"System: 您擅长将用户问题转换为数据库查询。您可以访问一个关于构建基于LLM的应用程序的电影视频数据库。给定一个问题,返回一组经过优化以检索最相关结果的数据库查询列表。\nHuman: langchain是什么,它是一个langchain模板吗?\nAI: \nTool: You have correctly called this tool.\nHuman: 如何构建多智能体系统并从中流式传输中间步骤\nAI: \nTool: You have correctly called this tool.\nHuman: LangChain agents vs LangGraph?\nAI: \nTool: You have correctly called this tool.\nHuman: 刘德华和吴彦祖,到底谁帅呢?谁是彦祖呢?"
]
}
[llm/end] [chain:RunnableSequence > llm:ChatOpenAI] [3.86s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "",
"generation_info": {
"finish_reason": "stop",
"logprobs": null
},
"type": "ChatGeneration",
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "",
"additional_kwargs": {
"tool_calls": [
{
"id": "call_188dpxY0npXTJsjbr9wWQTDt",
"function": {
"arguments": "{\"query\":\"刘德华和吴彦祖谁更帅,吴彦祖是谁\",\"sub_queries\":[\"刘德华帅吗?\",\"吴彦祖帅吗?\",\"吴彦祖是谁?\"],\"publish_year\":null}",
"name": "Search",
"parameters": null
},
"type": "function"
}
]
},
"response_metadata": {
"token_usage": {
"completion_tokens": 73,
"prompt_tokens": 629,
"total_tokens": 702
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null,
"finish_reason": "stop",
"logprobs": null
},
"type": "ai",
"id": "run-c1b94838-e9a3-4a6b-aff3-174cc539b626-0",
"tool_calls": [
{
"name": "Search",
"args": {
"query": "刘德华和吴彦祖谁更帅,吴彦祖是谁",
"sub_queries": [
"刘德华帅吗?",
"吴彦祖帅吗?",
"吴彦祖是谁?"
],
"publish_year": null
},
"id": "call_188dpxY0npXTJsjbr9wWQTDt"
}
],
"usage_metadata": {
"input_tokens": 629,
"output_tokens": 73,
"total_tokens": 702
},
"invalid_tool_calls": []
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 73,
"prompt_tokens": 629,
"total_tokens": 702
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null
},
"run": null
}
[chain/start] [chain:RunnableSequence > parser:PydanticToolsParser] Entering Parser run with input:
[inputs]
[chain/end] [chain:RunnableSequence > parser:PydanticToolsParser] [1ms] Exiting Parser run with output:
[outputs]
[chain/end] [chain:RunnableSequence] [3.87s] Exiting Chain run with output:
[outputs]
Search(query='刘德华和吴彦祖谁更帅,吴彦祖是谁', sub_queries=['刘德华帅吗?', '吴彦祖帅吗?', '吴彦祖是谁?'], publish_year=None)
没有生成查询分析的情况改怎么处理#
这种情况下从本质上区分不了,根本原因是压根儿没有子问题,只能从代码上做考虑,解析Response如果有子问题就返回子问题,没有就返回原始的响应。在没有什么别的好的处理
from langchain_core.runnables import chain
from langchain_core.output_parsers.openai_tools import PydanticToolsParser
output_parser = PydanticToolsParser(tools=[Search])
structured_llm = llm.bind_tools([Search])
query_analyzer = {"question": RunnablePassthrough()} | prompt | structured_llm
@chain
def custom_chain(question):
response = query_analyzer.invoke(question)
if "tool_calls" in response.additional_kwargs:
query = output_parser.invoke(response)
# 这里可以做业务逻辑,比如在套入一个chain或者。。。
# Could add more logic - like another LLM call - here
print("*" * 100)
return query
else:
return response
custom_chain.invoke("where did Harrison Work")
[chain/start] [chain:custom_chain] Entering Chain run with input:
{
"input": "where did Harrison Work"
}
[chain/start] [chain:custom_chain > chain:RunnableSequence] Entering Chain run with input:
{
"input": "where did Harrison Work"
}
[chain/start] [chain:custom_chain > chain:RunnableSequence > chain:RunnableParallel<question>] Entering Chain run with input:
{
"input": "where did Harrison Work"
}
[chain/start] [chain:custom_chain > chain:RunnableSequence > chain:RunnableParallel<question> > chain:RunnablePassthrough] Entering Chain run with input:
{
"input": "where did Harrison Work"
}
[chain/end] [chain:custom_chain > chain:RunnableSequence > chain:RunnableParallel<question> > chain:RunnablePassthrough] [1ms] Exiting Chain run with output:
{
"output": "where did Harrison Work"
}
[chain/end] [chain:custom_chain > chain:RunnableSequence > chain:RunnableParallel<question>] [4ms] Exiting Chain run with output:
{
"question": "where did Harrison Work"
}
[chain/start] [chain:custom_chain > chain:RunnableSequence > prompt:ChatPromptTemplate] Entering Prompt run with input:
{
"question": "where did Harrison Work"
}
[chain/end] [chain:custom_chain > chain:RunnableSequence > prompt:ChatPromptTemplate] [1ms] Exiting Prompt run with output:
[outputs]
[llm/start] [chain:custom_chain > chain:RunnableSequence > llm:ChatOpenAI] Entering LLM run with input:
{
"prompts": [
"System: 您擅长将用户问题转换为数据库查询。您可以访问一个关于构建基于LLM的应用程序的电影视频数据库。给定一个问题,返回一组经过优化以检索最相关结果的数据库查询列表。\nHuman: where did Harrison Work"
]
}
[llm/end] [chain:custom_chain > chain:RunnableSequence > llm:ChatOpenAI] [1.81s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "",
"generation_info": {
"finish_reason": "tool_calls",
"logprobs": null
},
"type": "ChatGeneration",
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "",
"additional_kwargs": {
"tool_calls": [
{
"id": "call_lne733PJ2aiQ2GKnpc19SvNZ",
"function": {
"arguments": "{\"query\":\"Harrison Ford\",\"sub_queries\":[\"Where did Harrison Ford work?\"]}",
"name": "Search",
"parameters": null
},
"type": "function"
}
]
},
"response_metadata": {
"token_usage": {
"completion_tokens": 25,
"prompt_tokens": 268,
"total_tokens": 293
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null,
"finish_reason": "tool_calls",
"logprobs": null
},
"type": "ai",
"id": "run-1e6edc3f-41d1-45bc-abd3-ec6ae207280f-0",
"tool_calls": [
{
"name": "Search",
"args": {
"query": "Harrison Ford",
"sub_queries": [
"Where did Harrison Ford work?"
]
},
"id": "call_lne733PJ2aiQ2GKnpc19SvNZ"
}
],
"usage_metadata": {
"input_tokens": 268,
"output_tokens": 25,
"total_tokens": 293
},
"invalid_tool_calls": []
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 25,
"prompt_tokens": 268,
"total_tokens": 293
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null
},
"run": null
}
[chain/end] [chain:custom_chain > chain:RunnableSequence] [1.82s] Exiting Chain run with output:
[outputs]
[chain/start] [chain:custom_chain > parser:PydanticToolsParser] Entering Parser run with input:
[inputs]
[chain/end] [chain:custom_chain > parser:PydanticToolsParser] [1ms] Exiting Parser run with output:
[outputs]
****************************************************************************************************
[chain/end] [chain:custom_chain] [1.83s] Exiting Chain run with output:
[outputs]
[Search(query='Harrison Ford', sub_queries=['Where did Harrison Ford work?'], publish_year=None)]
custom_chain.invoke("hi!")
[chain/start] [chain:custom_chain] Entering Chain run with input:
{
"input": "hi!"
}
[chain/start] [chain:custom_chain > chain:RunnableSequence] Entering Chain run with input:
{
"input": "hi!"
}
[chain/start] [chain:custom_chain > chain:RunnableSequence > chain:RunnableParallel<question>] Entering Chain run with input:
{
"input": "hi!"
}
[chain/start] [chain:custom_chain > chain:RunnableSequence > chain:RunnableParallel<question> > chain:RunnablePassthrough] Entering Chain run with input:
{
"input": "hi!"
}
[chain/end] [chain:custom_chain > chain:RunnableSequence > chain:RunnableParallel<question> > chain:RunnablePassthrough] [1ms] Exiting Chain run with output:
{
"output": "hi!"
}
[chain/end] [chain:custom_chain > chain:RunnableSequence > chain:RunnableParallel<question>] [4ms] Exiting Chain run with output:
{
"question": "hi!"
}
[chain/start] [chain:custom_chain > chain:RunnableSequence > prompt:ChatPromptTemplate] Entering Prompt run with input:
{
"question": "hi!"
}
[chain/end] [chain:custom_chain > chain:RunnableSequence > prompt:ChatPromptTemplate] [1ms] Exiting Prompt run with output:
[outputs]
[llm/start] [chain:custom_chain > chain:RunnableSequence > llm:ChatOpenAI] Entering LLM run with input:
{
"prompts": [
"System: 您擅长将用户问题转换为数据库查询。您可以访问一个关于构建基于LLM的应用程序的电影视频数据库。给定一个问题,返回一组经过优化以检索最相关结果的数据库查询列表。\nHuman: hi!"
]
}
[llm/end] [chain:custom_chain > chain:RunnableSequence > llm:ChatOpenAI] [2.63s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "Hello! How can I assist you today?",
"generation_info": {
"finish_reason": "stop",
"logprobs": null
},
"type": "ChatGeneration",
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "Hello! How can I assist you today?",
"response_metadata": {
"token_usage": {
"completion_tokens": 10,
"prompt_tokens": 266,
"total_tokens": 276
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null,
"finish_reason": "stop",
"logprobs": null
},
"type": "ai",
"id": "run-2edeb9e6-d60e-44e2-bfbb-9aa068967732-0",
"usage_metadata": {
"input_tokens": 266,
"output_tokens": 10,
"total_tokens": 276
},
"tool_calls": [],
"invalid_tool_calls": []
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 10,
"prompt_tokens": 266,
"total_tokens": 276
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null
},
"run": null
}
[chain/end] [chain:custom_chain > chain:RunnableSequence] [2.64s] Exiting Chain run with output:
[outputs]
[chain/end] [chain:custom_chain] [2.64s] Exiting Chain run with output:
[outputs]
AIMessage(content='Hello! How can I assist you today?', response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 266, 'total_tokens': 276}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-2edeb9e6-d60e-44e2-bfbb-9aa068967732-0', usage_metadata={'input_tokens': 266, 'output_tokens': 10, 'total_tokens': 276})
这里的思路是自己解析Response,如果有工具调用就走工具调用,然后就可以自己做逻辑,否则就直接返回
处理多个查询#
有时,查询分析技术可能允许生成多个查询。在这些情况下,需要记住运行所有的查询,然后将结果合并。将展示一个简单的例子(使用模拟数据)来说明如何做到这一点。
这里就是使用async,将上面的chain结合起来,自定义个chain
set_debug(False)
@chain
async def custom_chain(question):
response = await query_analyzer.ainvoke(question)
docs = [response]
# for query in response.queries:
# # 这里做一些额外的处理
# # new_docs = await retriever.ainvoke(query)
# docs.extend("new_docs")
# # You probably want to think about reranking or deduplicating documents here
# # But that is a separate topic
return docs
await custom_chain.ainvoke("where did Harrison Work")
[AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_BhRUTWdBhhINAGuah3faaxqN', 'function': {'arguments': '{"query":"Harrison Work"}', 'name': 'Search'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 268, 'total_tokens': 283}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-3a4a3e7e-f347-451b-84c5-1164c402b5e4-0', tool_calls=[{'name': 'Search', 'args': {'query': 'Harrison Work'}, 'id': 'call_BhRUTWdBhhINAGuah3faaxqN'}], usage_metadata={'input_tokens': 268, 'output_tokens': 15, 'total_tokens': 283})]
await custom_chain.ainvoke("where did Harrison and ankush Work")
[AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_thnLQggH7i65wH5YtiRaCbgJ', 'function': {'arguments': '{"query": "Workplace of Harrison", "sub_queries": ["Harrison\'s workplace"]}', 'name': 'Search', 'parameters': None}, 'type': 'function'}, {'id': 'call_lFar2Cjq9XYFVom2uc5Y4zDe', 'function': {'arguments': '{"query": "Workplace of Ankush", "sub_queries": ["Ankush\'s workplace"]}', 'name': 'Search', 'parameters': None}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 66, 'prompt_tokens': 271, 'total_tokens': 337}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-483f12b9-0e95-4898-9243-647f39105c7e-0', tool_calls=[{'name': 'Search', 'args': {'query': 'Workplace of Harrison', 'sub_queries': ["Harrison's workplace"]}, 'id': 'call_thnLQggH7i65wH5YtiRaCbgJ'}, {'name': 'Search', 'args': {'query': 'Workplace of Ankush', 'sub_queries': ["Ankush's workplace"]}, 'id': 'call_lFar2Cjq9XYFVom2uc5Y4zDe'}], usage_metadata={'input_tokens': 271, 'output_tokens': 66, 'total_tokens': 337})]
处理多个检索#
原理:他就是让生成的查询中返回了对应的key,从而找到对应的检索器,这样就可以做具体的检索了。
# 在chroma中添加一些数据
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
texts = ["Harrison worked at Kensho"]
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_texts(texts, embeddings, collection_name="harrison")
retriever_harrison = vectorstore.as_retriever(search_kwargs={"k": 1})
texts = ["Ankush worked at Facebook"]
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_texts(texts, embeddings, collection_name="ankush")
retriever_ankush = vectorstore.as_retriever(search_kwargs={"k": 1})
from typing import List, Optional
from langchain_core.pydantic_v1 import BaseModel, Field
class Search(BaseModel):
"""Search for information about a person."""
query: str = Field(
...,
description="Query to look up",
)
person: str = Field(
..., # 指定资料类型
description="Person to look things up for. Should be `HARRISON` or `ANKUSH`.",
)
from langchain_core.output_parsers.openai_tools import PydanticToolsParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
output_parser = PydanticToolsParser(tools=[Search])
system = """You have the ability to issue search queries to get information to help answer user information."""
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
query_analyzer.invoke("where did Harrison Work")
Search(query='work history', person='HARRISON')
query_analyzer.invoke("where did ankush Work")
Search(query='work', person='ANKUSH')
可以将person中的值和检索器结合起来
retrievers = {
"HARRISON": retriever_harrison,
"ANKUSH": retriever_ankush,
}
@chain
def custom_chain(question):
response = query_analyzer.invoke(question)
retriever = retrievers[response.person]
# 这里最终调用检索器来做操作
return retriever.invoke(response.query)
# 这里
custom_chain.invoke("where did Harrison Work")
[Document(page_content='Harrison worked at Kensho')]
custom_chain.invoke("where did ankush Work")
[Document(page_content='Ankush worked at Facebook')]
构造filters#
langchan提供了方法,可以将查询拓展出来的结构转换为对应检索器的查询语句,比如es的查询语句,chroma的查询语句
from typing import Optional
from langchain.chains.query_constructor.ir import (
Comparator,
Comparison,
Operation,
Operator,
StructuredQuery,
)
from langchain_community.query_constructors.chroma import ChromaTranslator
from langchain_community.query_constructors.elasticsearch import ElasticsearchTranslator
from langchain_core.pydantic_v1 import BaseModel
class Search(BaseModel):
query: str
start_year: Optional[int]
author: Optional[str]
# 这里的query就可以通过前面的查询分析来做
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)
到这里,都是langchain独立,自己提供的查询的filter语句
# 转换为es
ElasticsearchTranslator().visit_operation(_filter)
{'bool': {'must': [{'range': {'metadata.start_year': {'gt': 2022}}},
{'term': {'metadata.author.keyword': 'LangChain'}}]}}
# 转换为 Chroma的语句
ChromaTranslator().visit_operation(_filter)
{'$and': [{'start_year': {'$gt': 2022}}, {'author': {'$eq': 'LangChain'}}]}
和Retrieve的结合#
生成查询分析的时候可以和Retrieve结合,让模型生成的问题在既定范围之内,而不是随意发散,简单的处理方式将所有的值全部塞给模型,这样会导致,context过长,信息密度低,可以和Retrieve结合 减少context的长度。
from faker import Faker
# 制造一些假数据
fake = Faker()
names = [fake.name() for _ in range(1000)]
print(names[0])
print(names[10])
print(names[20])
Andrea Rodriguez
Jacob Diaz
Darius Gates
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
# 写基础的base prompt
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
query_analyzer.invoke("what are books about aliens by Andrea Rodriguez")
Search(query='books about aliens', author='Andrea Rodriguez')
注意看这里,有时候写的时候时候可能会写错,这里将错误的问题传递给llm,llm也会生成错误的答案,
query_analyzer.invoke("what are books about aliens by adrea Rodriguez")
Search(query='books about aliens', author='Adrea Rodriguez')
简单的处理方式,将所有的数据在给大模型。这是最简单的方式,但是会导致context过长
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
from langchain.globals import set_debug
set_debug(True)
query_analyzer_all.invoke("what are books about aliens by adrea Rodriguez")
[chain/start] [chain:RunnableSequence] Entering Chain run with input:
{
"input": "what are books about aliens by adrea Rodriguez"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question>] Entering Chain run with input:
{
"input": "what are books about aliens by adrea Rodriguez"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question> > chain:RunnablePassthrough] Entering Chain run with input:
{
"input": "what are books about aliens by adrea Rodriguez"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question> > chain:RunnablePassthrough] [0ms] Exiting Chain run with output:
{
"output": "what are books about aliens by adrea Rodriguez"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question>] [1ms] Exiting Chain run with output:
{
"question": "what are books about aliens by adrea Rodriguez"
}
[chain/start] [chain:RunnableSequence > prompt:ChatPromptTemplate] Entering Prompt run with input:
{
"question": "what are books about aliens by adrea Rodriguez"
}
[chain/end] [chain:RunnableSequence > prompt:ChatPromptTemplate] [1ms] Exiting Prompt run with output:
[outputs]
[llm/start] [chain:RunnableSequence > llm:ChatOpenAI] Entering LLM run with input:
{
"prompts": [
"System: Generate a relevant search query for a library system.\n\n`author` attribute MUST be one of:\n\nAndrea Rodriguez, Sandra Davis, Michael Howard, Charles Martinez, Jeremy Wright, Elizabeth Shepard, John Mcgee, Kevin Martin, Shawn Yang, Daniel Jones, Jacob Diaz, Katie Sanford, Jesse Nelson, Peter Collins, Michelle Collins, Ryan Jones, Vanessa Delgado, Karen Pratt, Pamela Mullen, Robert Vargas, Darius Gates, Michael Johnson, Walter Austin, Molly Byrd, Mark Foster, David Reynolds, Jeffrey Fleming, Stephen Santos, Jessica Dalton, Tamara Aguirre, Adam Gonzalez, Karen Hernandez, Devon Forbes, Jeff Dean, Jason Henderson, Ryan Lyons, Linda Nolan, Joseph Sanford DDS, Catherine Hale, Michelle Cameron, Mark Baird, Regina Morales, Alicia Carr, James Ali, Tristan Ware, Brian Tyler, James Sandoval, Heather Rogers, Patricia Cantrell, Erin Barnes, Richard Bright, Leroy Bryant, Luke Galvan, Timothy Ashley, Patrick Santana, Mr. Kevin Scott, Audrey Holmes, David Pearson, Alexandra Harrell, Isabel Coleman, Larry Webb, Stephen Estrada, Tracy Rodgers, Autumn Flores, Michelle Warren, Jason Hill, Gabriel Jackson, Kimberly Alvarez, Charles Thompson, Corey Curry, Maria Black, Troy Miller, Arthur Chandler, Becky Reynolds, Angela Johnson, Stephanie Santiago, Mary Nguyen, Lisa Ramirez, Donald Lester, Casey Freeman, John Brooks, Carrie Allen, Misty Torres, Michael Johnson, Megan Massey, Taylor Robinson, George Mccall, Brian Scott, Jeffrey Rios, Charles Garcia, Julian Rodriguez, Jennifer Lane, Heather Nguyen, Christine Davis, John Cooper, Matthew King, Katherine Boyer, Kelly Price, Donna Melton, Steven Thomas, Charles Tate, Whitney Silva, Bryan Mason, Karen Cook, Amber Pitts, Lawrence Patrick, Joel Ortiz, Heather Leach, Michelle Browning, Breanna Marquez, Michael Hunter, Stacy Sheppard, Jessica Martinez, Christopher Bell, Michael Griffin, Victor Sparks, Steven Johnson, Laura Vazquez, Christopher Kelly, Ellen Allison, Charles Campos, Wendy Anderson, Shane Hernandez, John Wong, John Duran, Douglas Sweeney, Kaitlyn Peterson, Mark Oliver, Marissa Anderson, Victoria Smith, Kenneth Williams, John Nelson, Katie Torres, Jason Abbott, Richard Myers, Nancy Hill, Dustin Gonzalez, Adam Ware, Melissa Davenport, Matthew Marquez PhD, Teresa Johnson, Heather Stephens, Amber Terry, Laura Graves, Steven Brown, Sheila Estes, Gary Sparks, Taylor Miller, Heather Garcia, Abigail Smith, Matthew Lee, Mrs. Rose Henry, Sara Noble, Janice Price, Sheryl Wang, Christina Tran, Frederick Turner, Connie Rollins, Douglas Hardy, Kelli Hampton, Raymond Sosa, Jonathan Castro, Michael Bradshaw, Keith Young, Daniel Richardson, Thomas Mccullough, David Davis, Alexandra Lopez, Jamie Smith, Kyle Ryan, Alexander Johnson, Adam Gibbs, Elizabeth Ortiz, Mary Raymond, Tonya Gutierrez, Miguel Anderson, Matthew Watson, Kevin Kelly, Holly Velasquez, Leslie Burke, Dennis Knight, Matthew Martin, Megan Brown, John Rojas, Mikayla Anderson, David Thomas, Thomas Lamb, Debbie Chang, Stuart Hunt, Dana Pittman, Carlos Wright MD, David Erickson, Ruben Franklin, Jerry Mann, Kylie Ruiz, Sharon Richards, Sandra Petersen, Nicole Pace, Mary Peterson, Sarah Flores, Chelsea Garrett, Cynthia Alvarado, Monica Lynch, Brian Clark, Lauren Wu, Stephanie Williams, Tyler Terry, Jerome Olson, Melissa Coffey, Alexandria Ramos, Amy French, Shaun Hall, Stephen Villa MD, Kevin Clarke, Gwendolyn Jennings, Loretta House, Kevin Winters, Amber Scott, Steven Petty, Joshua Johnson, Nicole Pena, Ann Carr, Sabrina Gibson, Gwendolyn Gray, Kathryn Fisher, Patrick Archer, Mark Bowen, Lucas Pena, Brian Church, Corey Alvarez, Taylor Hernandez, Jessica Dalton, Adam Williams, Michelle Berger, Mark Sosa, Mikayla Cook, Sylvia Jacobson, Kristin Gay, Susan Zimmerman, Kathleen Harrison, Christina Gutierrez, Dawn Smith, Jonathan Jones, Anna Herman, Roy Gray, Martin Alexander, Benjamin Garcia, Lisa Stevens, Shane Jimenez, Julia Webb, Daniel Watson, Stacey Baker, Jennifer Arnold, Michael Nguyen, Ryan Bowers, Randy Alexander, Dustin Davis, William Armstrong, Paul Sanchez, Laura Smith, Kevin Reynolds, Gregory Harris, Ms. Rebecca Le, Justin Wright, Rebekah Hart, Cindy Orr, Aaron Watson, Anna Jackson, Patricia Lowe, Joshua Johnson, Larry Mccoy, Sue Russell, Emily Yates, Jill Martin, Richard Herring, Joseph Huang, Christopher Brewer, Brenda Jackson, John Thompson, Keith Reynolds, Ryan Rojas, David Johnson, Heather Hawkins, Benjamin Eaton, Kenneth Dyer, Meredith Fuller, Thomas Hoffman, Lisa Rose, James Hall, Victor Johnson, Patricia Mitchell, Robert Sanders, Lori Mueller MD, William Hill, Ashley White, Michael Fisher, Christopher Cross, Michelle Ramos, Jeffrey Irwin, Jason Bender, Kathy Horton, Heather Simpson, Amanda Johnson, Brett Carter, Matthew Wells, Andrew Chang, Bryan Summers, James Valencia, Lindsey Jackson, Erika Alexander, Janice Caldwell, Kristin Anderson, Barbara Anderson, Dana Bennett, Daniel Mclaughlin, Mr. Jeremy Hall DDS, Theresa Miller, Miranda Ramos, Alicia Williams, Brian Meyer, Joseph Smith MD, Taylor Silva, Christina Butler MD, Autumn Miller, Zachary Sosa, Gregory Johnson, Christy Graham, Stephen Martinez, Ashley Green DVM, Vickie Gibson, Meghan Phillips, Deanna Stephens, Victoria Ford, Nicholas Payne, Duane Werner, Timothy Leach, Christine Simpson, Jon Singh, Thomas Thompson, Joe Martinez, Jaime Franco, Matthew Hoover, George Green, Adam Higgins, Patricia Estes, Bridget Clark, Victoria Campbell, Stephanie Park, Joshua Dominguez, Molly Perez, Nicholas Jackson, Tracey Welch, Jessica Bean, Todd Marshall, Patricia Russell, Tyler Mitchell, Bruce Edwards, Jose Stevenson, Jennifer Mcintosh, Madison Jackson, Maureen Martinez, Ryan Chapman, Raymond Delgado, Justin Martinez, Raymond Malone, Roy Dawson, Eric Velazquez, Dakota Russell, Brenda Watson, Christopher Gray, Tammy Thompson, Sharon Martinez, Jerry Baker, Dorothy Freeman, Regina Kim, Pamela Cook, Kathleen Frazier, Janice Mendez, Courtney Scott, Becky Murphy, Mark Riley, Samantha Patterson, Cory Brock, Michael Richardson, Gary Hunt, Ashley Smith MD, Tara Randolph, Brian Francis, Anthony Fernandez, Thomas Clark, Kathryn Rose, Mr. Daniel Kennedy, Steven Mitchell, Jamie Huber, Daniel Wong, Katherine Smith, Bianca Harmon, Barbara James, Jessica Gomez, Michelle Lopez, Kimberly Bowen, Jessica Turner, Jennifer Garcia, Mrs. Katherine Brooks, Mrs. Jennifer Allen MD, Penny Lee, James Dyer, Thomas Romero, Mark Melendez, Ryan Burton PhD, Danielle Martin, Christopher Thompson, Marie Hernandez, Timothy King, Mitchell Morris, Glenda Carr, Cassandra Davis, April Hill, Ronald Rogers, Cheryl Byrd, Mary Yang, Lauren Kim, Maria Warren, Thomas Lyons, William Yang, Ashley Garcia, Kathy Woods, Scott Oliver, Kenneth Mcintyre, Matthew Yang, Oscar Baker, Rebecca Cameron, Shirley Powell, Steven Chandler, Tammy Ryan, Jaime Oliver, Justin Brown, Kaitlin White, David Christian, Austin Young, Tonya Taylor, Kathy Wilcox, Zachary Barrera, Timothy Levine, Zachary Ramirez, Melissa Thomas, David May, Caitlin Koch DDS, Katie Lynch, Steven Lozano, Donald Benson MD, Samantha Butler, April Nielsen, Justin Wagner, Alicia Sanchez, Curtis Estrada, Christy Fields, Sean Mays, Barbara Stuart, Nicholas Lewis, Melanie Alvarado, Danielle Burton, Claire Jackson, Alexander Adkins, David Murphy, Amy Huber, Wendy Lawson, Karina Beltran, Jared Ruiz, Carol Ramos, Tina Taylor, Emily Rocha, Christina Bryant, Elizabeth Mcclain, Sarah Ochoa, Joshua Jensen, Rachel Hall, Rebecca Jones, Robert Woods, Justin Patel Jr., Paul Wright, Kimberly Hall, Albert Holden, Tiffany Ayers, Jennifer Johnson, Joshua Andersen, Kevin Casey, Joshua Grant, Dave Barry, Roger Livingston, Tyrone Davis, Nicole Wright, Jack Cole, Shannon Ellis, Thomas Page, James Robinson, Glen Miller, Douglas Jacobs, Elizabeth Walker, Robert Aguirre, Melanie Haynes, Carlos Newman, Robert Fields, Jeremy Collins, Jamie Benson DVM, Joseph Bender, Andrew Salazar, Andrea Jones, Ricardo Robinson, Christopher Hayden, Marissa Clark, Amber Flores, Amanda Dodson, Maureen Anthony, Michael Ballard, Austin Nunez, Allison Patel, Dr. Melissa Cunningham, Zoe Zuniga, Gregory Young, David Chen, Lauren Lyons, Michael Meadows, Alexis Massey, Valerie Mathews, Harold Fisher, Todd Vasquez, Edward Flores, Wendy Thompson, John Richardson, Derek Davis, Diana Phillips, Patricia Moody, Gerald Ward, Tanya Weiss, Christine Anderson, Ann Ward, Samantha Wilson, Heather Gilbert, Cynthia Smith MD, Alexandra Hawkins, Caitlin Aguilar, Gregg Butler, Thomas Waller, Russell Hubbard, Lindsay Lowe, Michele Rocha, Darrell Pace, Jack Ayala, Charlotte Murphy, Rebecca Pierce, Tara Ramirez, Linda Garrison, Ann Hill, Richard Webb, Ronald Paul, Emily Black, Kenneth Stevenson, Stephen Williams, Rebecca Benton, Wendy Cochran, Evan Thomas, Nicole Knight, Jody Perez, Donna Ashley, Amy Collins, Julie Bell, Pamela Porter, Alexander Montes Jr., Tina Perez, Michael Robinson, Elizabeth Gonzales, Miss Renee Dawson, Shane Gonzalez, Alejandro Spears, Dylan Bell, Cathy Kennedy, Raymond Obrien, Kara Bell, Cynthia Briggs, Daniel Dixon, Kenneth Garcia, Marie Harper, Ellen Drake, Maureen Rogers, Kristin Brennan, Sarah Martin, Kimberly Padilla MD, Jason Smith, Jose Alexander, Christopher Banks, Lindsey Brown, Patricia Bennett, Christina Hill, Kevin Miranda, Melissa Parker MD, Nina May, Kiara Jenkins, David Walker, David Gill, Brian Valencia, Michael Carr, Beth Arellano, Robert Quinn, Michael Walker, Samantha Bailey, Eric Blair, Ronald Taylor, Christine Ward, Frances Harris, Shane Smith, Barbara Silva, Tyler Skinner, Justin Potter, Stephanie Cain, Kim Pace, Ralph Conner, James White, Richard Myers, Brandon Smith, Shelley Ward, Shawn Hensley, Vincent Allen, Nicole Hanson, Erica Cooper, Roberta Nelson, Laura King, Alexandra Middleton, Heather Smith, Willie Moody, Peter Duncan, Ruben Carter, Samantha Goodman, Michelle Wagner, Alexandria Hendrix, Todd Keller, Ruth Nelson, Lindsey Ryan, Monique Williams, Travis Mcdonald, Robert Jackson, Sarah Lamb, Benjamin Rodriguez, Jeffrey Hughes, Gary Lawrence, Daniel Jones, Samuel Zuniga, Brian Hill, Timothy Fitzgerald, Timothy Golden, Luis Benson, Jeffrey Frederick, Ann Cooper, Wendy Wilson, Nicole Freeman, Sarah Wise, Nancy Jenkins, Kristin Vincent, Daniel Bishop, Alisha Martinez, Austin Bauer, Ryan Jacobson, Carlos Hernandez, Michael Campbell, Charles Everett, Sarah Walker, David Flores, Amy Holmes, Erica Oliver, Lisa Hernandez, Shawn Martinez, Lauren Hebert, Raven Rogers, Thomas Roberts, Taylor Martin, Angela Nichols, Angela Cummings, Steven Knapp, Julian Jones, Gary Reyes, Marissa Campbell, Charles Winters, Randy Evans, Tony Jimenez, Heather Jackson, Kenneth Hansen, Zachary Thompson, Kevin Haney, Ashley Thomas, Roberto Snyder, Jeremy Hill, Jack Castaneda, Rachel Meyer, Mariah Brooks, Sarah Odonnell, David Smith, Scott Lopez, Keith Phillips, Carlos Thompson, Tracy Ramirez, Donald Krueger, Shelly Smith, Sherri Salazar, Carolyn Aguilar, Tracy Smith, Jennifer Lewis, Dr. Cynthia Nelson, Carlos Lewis, Leslie Jones, Philip Jones, Julie Bryant, Justin Avila, Dalton Wade, Felicia Fowler, Jonathan Livingston, Audrey Hood, Stephanie Meyer, Kathryn Miller, Dr. Adrian Valenzuela, Alyssa Porter, Diana West, Parker Phillips, Samuel Davis, Dana Cooper, Benjamin Kelly, Matthew Aguirre, Ryan Guerra, Michelle Smith, Karen Gray, Jimmy Jennings, Denise Bonilla, Amanda Morales DVM, Stephen Davis, Brian Marshall, Jill Gonzales, Joanna Lee, Joseph Kelly, Brian Hernandez, Dennis Soto, David Lopez, Aaron Boyd, Amber Wagner, Lynn Martinez, Melissa Schmidt, Zachary Collins, Amber Thompson, Carl Allen, Paul Hayes, Robert Lowery, Erika Lyons, Tiffany Hines, April Wright, Jeffery Wilson, Eileen Phillips, Jessica Johnson, Lisa Warren, Heather Vaughn, Jacqueline Robinson, Scott Hill, Melissa Hahn, Ryan Lyons, Tracy Moyer, Dale Lee, Stacy Martin, Amy Brown, Marcus Herring, Karen Petersen DDS, Vanessa Smith, David Mathis, Katie Morrison, Diane Sharp, Amanda Price, Karl Navarro, Jessica Reed, Michele Herring, Douglas Lewis, Kathleen Johnson, Roger Kirby, Shannon Spears, Joel Lawrence Jr., William Dunn, Stephen Robertson, John Barker, Joseph Jenkins, Ashley Francis, Jonathan Rodriguez, Angela Williams DVM, Brittney Brown, Mark Matthews, Lisa Rivera, Aaron Camacho, Kimberly Anderson, Leslie Wade, Daniel Gordon, Teresa James, Tamara Hernandez, Melissa Watkins, Daniel Mccormick, Jill Williams, Jennifer Moreno, Tamara Rogers, Michael Nichols, Wesley Patrick, Jennifer Ali, Bridget Cuevas, Janet Williams MD, Brianna Henry, Alexis Mendez, Cole Conway, Marc Smith, Kathy Schultz, Robert Henderson, Shawn Perez, Olivia Anderson, Stephen Cohen, Alyssa Brooks, Melanie Holland, Eddie Pearson, Ana Perry PhD, Tyler White, Donna Santiago, Michael Rodriguez, Tyler Hickman, Katherine Gomez, Katherine Williams, Scott Landry, Rachael Bates, Leonard Cobb, Amanda Romero, Emily Carney DDS, Shawna Scott, Heather Chambers, Austin Waters, Thomas Kennedy, Brandon Simmons, Jennifer Kim, Brian Ray, Sharon Price, Ashley Cantu, Robert Tran, Ashley Green, Gabrielle Adams MD, Tammy Swanson, Richard Baker, Bethany Rivera, Erin Arroyo, Benjamin Reese, Ana Clayton, Melody Turner, Cory Bradford, Joshua Ward, Stephanie Nelson, Dominique Harris, James Silva, Melinda Byrd, Cindy Bowen, Charles Martin, Michael Walker, Lisa Carr, Angela Williams, Sarah Davis, Melissa Foster, Mark Baxter, Juan Jones, Alisha Price, Ruth Fisher, Patricia Rodriguez, Dawn Escobar, Timothy Simpson, Rose Young, Robert Peterson, Gina Hammond, Seth Torres, Cynthia Spencer, Connie Williams, Christopher Cobb, Jacob Sosa, Jimmy Vaughn, Shaun Kent, Lucas Bates, Cody Barnett, Christopher Burns, Tiffany Evans, Andrew Lopez, Marcia Gonzalez, Carlos Avery, Matthew Gomez, Crystal Anderson, Kenneth Smith, Michele Hernandez, Heather Berry, Dustin Brown, Robert Hernandez, Maria Smith, George Lawson, Sean Thomas, Anthony Hoffman, Jesus Schneider, Jennifer Martin, William Ritter, Aaron Harris, Tara Brown, Wendy Bowman, Ronnie Benitez, Wendy Jones, Eugene James, Kenneth Jones, Mark Lambert, Howard Cisneros, Amy Robbins, Rebecca Thompson, Albert Perkins, Patricia Ross, Daniel Schaefer, Amy Wright, Sarah Johnson, Rachel Cox, Christopher Henderson, Kimberly Nichols, Lance Chung Jr., Lisa Brown, Amanda Brooks, David Marshall, Daniel Reid, Bailey Reyes, Kathleen Johnson, Cheyenne Hernandez, Chelsea Wheeler, Kirk Smith, Jerome Landry, Ashley Duran, John Brooks, Adam Nelson, Andrea Fleming, Christopher Montgomery, Gregory Hardy, James Garrett, Vanessa Taylor, Angel Warren, Aaron Johnson, Shawn Morris, Anne Rosales, Matthew Brooks, Joseph Hale, Samantha Vang, Anthony Beard, Travis Richards, Stephen Hayes, Christopher Blevins, Kelsey Solis, Luis Sanchez, Erika Lee, Patricia Nelson, Joseph Campbell, Katie Sanchez, Brenda Watkins, Robert Mckenzie, Jessica Mcmillan, Melody Klein, Michael Ibarra, Lori Nguyen, Mary Mendoza, Eric Grant, Luis Mcdonald, Julia Campbell, Erin Hill, Shari Carlson, Stephen Roberts, Beth Wilson, Cory Burnett, Shawn Harvey, Jonathan Wong, Brent Newton, David Cruz, Clifford Ferguson, Kelly Smith, Michelle Wagner, Alison Jackson, Maria Andersen, Tina Johnson, Katie Watts, Joanna Mejia, Ashley Smith, Jessica Pham, Rebecca Everett, Tiffany Flores, Kathryn Garrett, Juan Ryan, Timothy Gilbert, Jason Bailey, Natasha Fletcher, Eugene Cook, Savannah Armstrong, Mark Salinas, Cynthia Blake, Christopher Morgan, Randy Nelson, Kelly Mcbride, Michael Lawson, Mark Mcguire\n\nDo NOT hallucinate author name!\nHuman: what are books about aliens by adrea Rodriguez"
]
}
[llm/end] [chain:RunnableSequence > llm:ChatOpenAI] [2.34s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "",
"generation_info": {
"finish_reason": "stop",
"logprobs": null
},
"type": "ChatGeneration",
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "",
"additional_kwargs": {
"tool_calls": [
{
"id": "call_2Grpq9G8uDdezOG6u5OaG9U3",
"function": {
"arguments": "{\"author\":\"Andrea Rodriguez\",\"query\":\"books about aliens\"}",
"name": "Search",
"parameters": null
},
"type": "function"
}
]
},
"response_metadata": {
"token_usage": {
"completion_tokens": 13,
"prompt_tokens": 3452,
"total_tokens": 3465
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null,
"finish_reason": "stop",
"logprobs": null
},
"type": "ai",
"id": "run-ec359395-c4f0-4681-bf8d-862bed3e9c1f-0",
"tool_calls": [
{
"name": "Search",
"args": {
"author": "Andrea Rodriguez",
"query": "books about aliens"
},
"id": "call_2Grpq9G8uDdezOG6u5OaG9U3"
}
],
"usage_metadata": {
"input_tokens": 3452,
"output_tokens": 13,
"total_tokens": 3465
},
"invalid_tool_calls": []
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 13,
"prompt_tokens": 3452,
"total_tokens": 3465
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null
},
"run": null
}
[chain/start] [chain:RunnableSequence > parser:PydanticToolsParser] Entering Parser run with input:
[inputs]
[chain/end] [chain:RunnableSequence > parser:PydanticToolsParser] [1ms] Exiting Parser run with output:
[outputs]
[chain/end] [chain:RunnableSequence] [2.34s] Exiting Chain run with output:
[outputs]
Search(query='books about aliens', author='Andrea Rodriguez')
将所有的数据,传递给大模型,这样再问他错误的问题的时候,他会自动修复 。 还有一种方式是通过向量数据库搜索。在传递给模型之前先做一遍,先走一遍向量化搜索,这样可以保证有限的上下文 。
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# 构建向量数据库
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
create_prompt.invoke("what are books by adrea Rodriguez")
[chain/start] [chain:RunnableSequence] Entering Chain run with input:
{
"input": "what are books by adrea Rodriguez"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question,authors>] Entering Chain run with input:
{
"input": "what are books by adrea Rodriguez"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question,authors> > chain:RunnablePassthrough] Entering Chain run with input:
{
"input": "what are books by adrea Rodriguez"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question,authors> > chain:RunnablePassthrough] [0ms] Exiting Chain run with output:
{
"output": "what are books by adrea Rodriguez"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question,authors> > chain:select_names] Entering Chain run with input:
{
"input": "what are books by adrea Rodriguez"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question,authors> > chain:select_names] [1.14s] Exiting Chain run with output:
{
"output": "Andrea Rodriguez, Andrea Rodriguez, Jonathan Rodriguez, Jonathan Rodriguez, Patricia Rodriguez, Patricia Rodriguez, Michael Rodriguez, Michael Rodriguez, Andrea Jones, Andrea Jones"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question,authors>] [1.14s] Exiting Chain run with output:
{
"question": "what are books by adrea Rodriguez",
"authors": "Andrea Rodriguez, Andrea Rodriguez, Jonathan Rodriguez, Jonathan Rodriguez, Patricia Rodriguez, Patricia Rodriguez, Michael Rodriguez, Michael Rodriguez, Andrea Jones, Andrea Jones"
}
[chain/start] [chain:RunnableSequence > prompt:ChatPromptTemplate] Entering Prompt run with input:
{
"question": "what are books by adrea Rodriguez",
"authors": "Andrea Rodriguez, Andrea Rodriguez, Jonathan Rodriguez, Jonathan Rodriguez, Patricia Rodriguez, Patricia Rodriguez, Michael Rodriguez, Michael Rodriguez, Andrea Jones, Andrea Jones"
}
[chain/end] [chain:RunnableSequence > prompt:ChatPromptTemplate] [1ms] Exiting Prompt run with output:
[outputs]
[chain/end] [chain:RunnableSequence] [1.14s] Exiting Chain run with output:
[outputs]
ChatPromptValue(messages=[SystemMessage(content='Generate a relevant search query for a library system.\n\n`author` attribute MUST be one of:\n\nAndrea Rodriguez, Andrea Rodriguez, Jonathan Rodriguez, Jonathan Rodriguez, Patricia Rodriguez, Patricia Rodriguez, Michael Rodriguez, Michael Rodriguez, Andrea Jones, Andrea Jones\n\nDo NOT hallucinate author name!'), HumanMessage(content='what are books by adrea Rodriguez')])
这里可以看到传递给模型的prompt中已经有相关的答案了。
query_analyzer_select.invoke("what are books about aliens by adrea Rodriguez")
[chain/start] [chain:RunnableSequence] Entering Chain run with input:
{
"input": "what are books about aliens by adrea Rodriguez"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question,authors>] Entering Chain run with input:
{
"input": "what are books about aliens by adrea Rodriguez"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question,authors> > chain:RunnablePassthrough] Entering Chain run with input:
{
"input": "what are books about aliens by adrea Rodriguez"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question,authors> > chain:RunnablePassthrough] [1ms] Exiting Chain run with output:
{
"output": "what are books about aliens by adrea Rodriguez"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<question,authors> > chain:select_names] Entering Chain run with input:
{
"input": "what are books about aliens by adrea Rodriguez"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question,authors> > chain:select_names] [1.20s] Exiting Chain run with output:
{
"output": "Andrea Rodriguez, Andrea Rodriguez, Michael Rodriguez, Michael Rodriguez, Jonathan Rodriguez, Jonathan Rodriguez, Andrea Jones, Andrea Jones, Patricia Rodriguez, Patricia Rodriguez"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<question,authors>] [1.20s] Exiting Chain run with output:
{
"question": "what are books about aliens by adrea Rodriguez",
"authors": "Andrea Rodriguez, Andrea Rodriguez, Michael Rodriguez, Michael Rodriguez, Jonathan Rodriguez, Jonathan Rodriguez, Andrea Jones, Andrea Jones, Patricia Rodriguez, Patricia Rodriguez"
}
[chain/start] [chain:RunnableSequence > prompt:ChatPromptTemplate] Entering Prompt run with input:
{
"question": "what are books about aliens by adrea Rodriguez",
"authors": "Andrea Rodriguez, Andrea Rodriguez, Michael Rodriguez, Michael Rodriguez, Jonathan Rodriguez, Jonathan Rodriguez, Andrea Jones, Andrea Jones, Patricia Rodriguez, Patricia Rodriguez"
}
[chain/end] [chain:RunnableSequence > prompt:ChatPromptTemplate] [1ms] Exiting Prompt run with output:
[outputs]
[llm/start] [chain:RunnableSequence > llm:ChatOpenAI] Entering LLM run with input:
{
"prompts": [
"System: Generate a relevant search query for a library system.\n\n`author` attribute MUST be one of:\n\nAndrea Rodriguez, Andrea Rodriguez, Michael Rodriguez, Michael Rodriguez, Jonathan Rodriguez, Jonathan Rodriguez, Andrea Jones, Andrea Jones, Patricia Rodriguez, Patricia Rodriguez\n\nDo NOT hallucinate author name!\nHuman: what are books about aliens by adrea Rodriguez"
]
}
[llm/end] [chain:RunnableSequence > llm:ChatOpenAI] [2.45s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "",
"generation_info": {
"finish_reason": "stop",
"logprobs": null
},
"type": "ChatGeneration",
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "",
"additional_kwargs": {
"tool_calls": [
{
"id": "call_LDLxdqWdzv8TcUfqq9saf3M9",
"function": {
"arguments": "{\"author\":\"Andrea Rodriguez\",\"query\":\"aliens\"}",
"name": "Search",
"parameters": null
},
"type": "function"
}
]
},
"response_metadata": {
"token_usage": {
"completion_tokens": 12,
"prompt_tokens": 114,
"total_tokens": 126
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null,
"finish_reason": "stop",
"logprobs": null
},
"type": "ai",
"id": "run-56567bdd-d53f-4aa1-a4b3-d287612f714c-0",
"tool_calls": [
{
"name": "Search",
"args": {
"author": "Andrea Rodriguez",
"query": "aliens"
},
"id": "call_LDLxdqWdzv8TcUfqq9saf3M9"
}
],
"usage_metadata": {
"input_tokens": 114,
"output_tokens": 12,
"total_tokens": 126
},
"invalid_tool_calls": []
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 12,
"prompt_tokens": 114,
"total_tokens": 126
},
"model_name": "gpt-3.5-turbo-0125",
"system_fingerprint": null
},
"run": null
}
[chain/start] [chain:RunnableSequence > parser:PydanticToolsParser] Entering Parser run with input:
[inputs]
[chain/end] [chain:RunnableSequence > parser:PydanticToolsParser] [2ms] Exiting Parser run with output:
[outputs]
[chain/end] [chain:RunnableSequence] [3.66s] Exiting Chain run with output:
[outputs]
Search(query='aliens', author='Andrea Rodriguez')