路由
有时候,我们有多个不同主题的本地知识库,针对不同的类型的问题,我们希望用不同的本地知识库来回答问题,这里就涉及到一个问题如何实现根据不同的问题路由(选择)到不同的本地知识库。
例如,假设我们有一个用于回答 LangChain Python 文档问题的知识库,以及一个用于回答 LangChain JavaScript 文档问题的知识库。 对于关于 LangChain 用法的问题,我们希望推断问题指的是哪种语言,然后根据语言选择不同的知识库。
设置
安装依赖
%pip install -qU langchain-core langchain-openai
设置环境变量
在这个示例中我们会使用 OpenAI:
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass()
# Optional, uncomment to trace runs with LangSmith. Sign up here: https://smith.langchain.com.
# os.environ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
使用函数调用模型进行路由
使用函数调用模型对于分类问题(路由就是一种分类问题)来说非常简单:
from typing import Literal
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI
# 定义路由数据结构
class RouteQuery(BaseModel):
"""将用户查询路由到最相关的数据源。"""
datasource: Literal["python_docs", "js_docs", "golang_docs"] = Field(
...,
description="给定一个用户问题,选择哪个数据源对于回答他们的问题最相关",
)
# 定义模型
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
# 要求模型按路由数据结构返回数据
structured_llm = llm.with_structured_output(RouteQuery)
system = """你是问题分类专家。
根据问题涉及的编程语言,将其路由到相关的数据源。"""
prompt = ChatPromptTemplate.from_messages(
[
("system", system),
("human", "{question}"),
]
)
router = prompt | structured_llm
question = """为什么下面的代码不起作用:
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages(["human", "以{language}说话"])
prompt.invoke("法语")
"""
router.invoke({"question": question})
返回路由参数
RouteQuery(datasource='python_docs')
question = """为什么下面的代码不起作用:
import { ChatPromptTemplate } from "@langchain/core/prompts";
const chatPrompt = ChatPromptTemplate.fromMessages([
["human", "以{language}说话"],
]);
const formattedChatPrompt = await chatPrompt.invoke({
input_language: "法语"
});
"""
router.invoke({"question": question})
返回路由参数
RouteQuery(datasource='js_docs')
路由到多个索引
如果我们可能需要查询多个索引,我们也可以做到,方法是更新我们的模式以接受数据源的列表:
from typing import List
class RouteQuery(BaseModel):
"""将用户查询路由到最相关的数据源。"""
datasources: List[Literal["python_docs", "js_docs", "golang_docs"]] = Field(
...,
description="给定一个用户问题,选择哪些数据源对于回答他们的问题最相关",
)
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm = llm.with_structured_output(RouteQuery)
router = prompt | structured_llm
router.invoke(
{
"question": "Python 和 JS 在 OpenAI 聊天模型的实现中是否具有功能对齐"
}
)
RouteQuery(datasources=['python_docs', 'js_docs'])