一架梯子,一头程序猿,仰望星空!
LangChain查询分析 > 内容正文

路由


路由

有时候,我们有多个不同主题的本地知识库,针对不同的类型的问题,我们希望用不同的本地知识库来回答问题,这里就涉及到一个问题如何实现根据不同的问题路由(选择)到不同的本地知识库。

例如,假设我们有一个用于回答 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'])


关联主题