langchain 入门指南 - 自动选择不同的大模型

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
简介: langchain 入门指南 - 自动选择不同的大模型

自动选择不同的大模型

在先前的文章中,我们学会了可以让 Agent 自动选择不同的工具来处理不同的问题。

在现实场景中,我们可能还会面临另外一种场景是,使用不同的大模型来处理用户的问题,

比如根据用户输入的不同问题选择使用 OpenAI 或者是本地部署的大模型。

RouterChain

为了解决这个问题,langchain 引入了 RouterChain,它是一个可以自动选择不同大模型(实际上是 chain)的工具。

比如我们有两个大模型,一个是 OpenAI 的 GPT-3.5,擅长解答关于 Python 的问题;另一个是 OpenAI 的 gpt-4,擅长解答关于 Golang 的问题。

我们可以根据用户的输入来选择是使用 GPT-3.5 还是 GPT-4 来回答用户的问题。

比如:

  1. 输入:“python 如何写入文件”,那么选择的应该是 GPT-3.5。
  2. 输入:“Golang 中如何启动协程”,那么选择的应该是 GPT-4。

整体框架

RouterChain,也叫路由链,能动态选择用于给定输入的下一个链。我们会根据用户的问题内容,首先使用路由链确定问题更适合哪个处理模板,

然后将问题发送到该处理模板进行回答。如果问题不适合任何已定义的处理模板,它会被发送到默认链。

在这里,我们会使用 LLMRouterChainMultiPromptChain(也是一种路由链)组合实现路由功能,

MultiPromptChain 会调用 LLMRouterChain 选择与给定问题最相关的提示,然后使用该提示回答问题。

具体步骤如下:

  1. 构建处理模板:为 “解答 python 问题” 和 “解答 Golang 问题” 分别构建一个目标链(LLMChain),并存储在一个字典中。
  2. 构建 LLM 路由链:这是决策的核心部分。首先,它根据提示信息构建了一个路由模板,然后使用这个模板创建了一个 LLMRouterChain
  3. 构建默认链:如果输入不适合任何已定义的处理模板,这个默认链会被触发。
  4. 构建多提示链:使用 MultiPromptChainLLMRouterChain 和默认链组合在一起,形成一个完整的决策系统。

具体实现

先定义两个 LLMChain

下面是两个 LLMChain 的定义,一个是用于回答 Python 问题的,另一个是用于回答 Golang 问题的。

from langchain.chains.llm import LLMChain
from langchain_community.llms import OpenAI
from langchain_core.prompts import PromptTemplate
# 创建一个 GPT-3.5 的 LLMChain
def create_py_chain() -> LLMChain:
    prompt_template = """
    你是一名 Python 工程师,擅长解答关于 Python 编程的问题。
    下面是需要你来回答的问题:
    {input}
    """
    prompt = PromptTemplate(
        template=prompt_template,
        input_variables=["input"],
    )
    llm = OpenAI()
    return LLMChain(llm=llm, prompt=prompt, verbose=True)
# 创建一个 GPT-4 的 LLMChain
def create_go_chain() -> LLMChain:
    prompt_template = """
    你是一名 Golang 工程师,擅长解答关于 Golang 编程的问题。
    下面是需要你来回答的问题:
    {input}
    """
    prompt = PromptTemplate(
        template=prompt_template,
        input_variables=["input"],
    )
    llm = OpenAI()
    return LLMChain(llm=llm, prompt=prompt, verbose=True)
# 创建两个 LLMChain
chain_map = {
    "Python": create_py_chain(),
    "Golang": create_go_chain(),
}

定义一个 RouterChain

RouterChain 是一个可以自动选择不同大模型(实际上是 chain)的工具。

from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE
destinations = [
    "Python: 适合回答关于 Python 编程的问题",
    "Golang: 适合回答关于 Golang 编程的问题",
]
router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(destinations="\n".join(destinations))
router_prompt = PromptTemplate(
    template=router_template,
    input_variables=["input"],
    output_parser=RouterOutputParser(),
)
router_chain = LLMRouterChain.from_llm(
    llm=OpenAI(),
    prompt=router_prompt,
    verbose=True
)

这其实是本文关键的地方,router_prompt 实际上是一个 Prompt

  • 其中 input_variables 是输入的变量,这里只有一个 input
  • output_parser 是输出解析器,这里使用了 RouterOutputParser
  • template 是一个模板,用于生成提示。

简而言之,这个 RouterChain 允许你将用户的输入送入路由器,然后路由器会决定将该输入发送到哪个具体的模型,或者是否需要对输入进行修订以获得最佳的响应。

定义一个默认 chain

如果输入不适合任何已定义的 chain,这个默认 chain 会被使用。

default_chain = ConversationChain(llm=OpenAI(), output_key="text", verbose=True)

定义一个 MultiPromptChain

MultiPromptChain 根据用户输入尝试选择一个 destination_chains 中的 chain 来处理问题。

如果没有找到合适的 chain,会使用 default_chain 来处理问题。

from langchain.chains.router import MultiPromptChain
chain = MultiPromptChain(
    router_chain=router_chain,
    default_chain=default_chain,
    destination_chains=chain_map,
    verbose=True
)

MultiPromptChain 有三个关键元素:

  1. router_chain(类型 RouterChain):这是用于决定目标链和其输入的链。当给定某个输入时,这个 router_chain 决定哪一个 destination_chain 会被使用,以及传给它的具体输入是什么。
  2. destination_chains(类型 Mapping[str, LLMChain]):这是一个映射,将名称映射到可以将输入路由到的候选链。例如,你可能有多种处理文本数据的方法(或 “链”),每种方法针对特定类型的问题。
  3. default_chain(类型 LLMChain):当 router_chain 无法将输入映射到 destination_chains 中的任何链时,LLMChain 将使用此默认链。

它的工作流程如下:

  1. 输入首先传递给 router_chain
  2. router_chain 根据某些标准或逻辑决定应该使用哪一个 destination_chain
  3. 输入随后被路由到选定的 destination_chain,该链进行处理并返回结果。
  4. 如果 router_chain 不能决定正确的 destination_chain,则输入将被传递到 default_chain

这样,MultiPromptChain 就为我们提供了一个在多个处理链之间动态路由输入的机制,以得到最相关或最优的输出。

调用

下面是一个调用的例子:

print(chain.invoke({"input": "如何在 Python 中定义一个函数?"}))

这会使用 Python 的 LLMChain 来回答这个问题。

我们会看到有类似如下的输出:

Prompt after formatting:
    你是一名 Python 工程师,擅长解答关于 Python 编程的问题。
    下面是需要你来回答的问题:
    如何在 Python 中定义一个函数?

原理

本质上,其实是在 RouterChain 中定义了一个 Prompt,让 LLM 来判断分析使用哪一个 destination_chain

我们可以打印一下看看:

print(router_prompt.format(input="如何在 Python 中定义一个函数?"))

输出如下:

Given a raw text input to a language model select the model prompt best suited for the input. 
You will be given the names of the available prompts and a description of what 
the prompt is best suited for. You may also revise the original input if you 
think that revising it will ultimately lead to a better response from the language model.
<< FORMATTING >>
Return a markdown code snippet with a JSON object formatted to look like:
```json
{
    "destination": string \ name of the prompt to use or "DEFAULT"
    "next_inputs": string \ a potentially modified version of the original input
}
```
REMEMBER: "destination" MUST be one of the candidate prompt names specified below OR it 
can be "DEFAULT" if the input is not well suited for any of the candidate prompts.
REMEMBER: "next_inputs" can just be the original input if you don't think any modifications are needed.
<< CANDIDATE PROMPTS >>
Python: 适合回答关于 Python 编程的问题
Golang: 适合回答关于 Golang 编程的问题
<< INPUT >>
如何在 Python 中定义一个函数?
<< OUTPUT (must include ```json at the start of the response) >>
<< OUTPUT (must end with ```) >>

这个 Prompt 包含了如下内容:

  1. 先是一个简单的引导语句,告诉模型你将给它一个输入,它需要根据这个输入选择最适合的模型。
  2. 进一步提醒模型,它将获得各种模型提示的名称和描述。同时告诉模型,还有一个可选的步骤,它可以更改原始输入,以便最终获得更好的响应。
  3. 接下来是格式说明:指导模型如何格式化其输出,使其以特定的方式返回结果:表示模型的输出应该是一个 Markdown 格式,其中包含一个 JSON 对象。然后指定了 JSON 的格式。
  4. 额外的说明和要求:告诉模型,如果输入不适合任何候选提示,则应该返回 DEFAULT
  5. 候选提示:列出了所有可用的模型及其描述。
  6. 输入:给出了一个示例输入。

这个模板的目的是让模型知道如何处理用户的输入,并根据提供的提示列表选择一个最佳的模型提示来回应。

总结

RouterChain 是一个可以自动选择不同大模型(实际上是 chain)的工具,可以根据用户的输入来选择使用不同的大模型来回答用户的问题。


相关实践学习
阿里云百炼xAnalyticDB PostgreSQL构建AIGC应用
通过该实验体验在阿里云百炼中构建企业专属知识库构建及应用全流程。同时体验使用ADB-PG向量检索引擎提供专属安全存储,保障企业数据隐私安全。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
目录
相关文章
|
4月前
|
前端开发 机器人 API
前端大模型入门(一):用 js+langchain 构建基于 LLM 的应用
本文介绍了大语言模型(LLM)的HTTP API流式调用机制及其在前端的实现方法。通过流式调用,服务器可以逐步发送生成的文本内容,前端则实时处理并展示这些数据块,从而提升用户体验和实时性。文章详细讲解了如何使用`fetch`发起流式请求、处理响应流数据、逐步更新界面、处理中断和错误,以及优化用户交互。流式调用特别适用于聊天机器人、搜索建议等应用场景,能够显著减少用户的等待时间,增强交互性。
862 2
|
4月前
LangChain-26 Custom Agent 自定义一个Agent并通过@tool绑定对应的工具 同时让大模型自己调用编写的@tools函数
LangChain-26 Custom Agent 自定义一个Agent并通过@tool绑定对应的工具 同时让大模型自己调用编写的@tools函数
134 3
LangChain-26 Custom Agent 自定义一个Agent并通过@tool绑定对应的工具 同时让大模型自己调用编写的@tools函数
|
4月前
|
机器学习/深度学习 人工智能 开发框架
解锁AI新纪元:LangChain保姆级RAG实战,助你抢占大模型发展趋势红利,共赴智能未来之旅!
【10月更文挑战第4天】本文详细介绍检索增强生成(RAG)技术的发展趋势及其在大型语言模型(LLM)中的应用优势,如知识丰富性、上下文理解和可解释性。通过LangChain框架进行实战演练,演示从知识库加载、文档分割、向量化到构建检索器的全过程,并提供示例代码。掌握RAG技术有助于企业在问答系统、文本生成等领域把握大模型的红利期,应对检索效率和模型融合等挑战。
270 14
|
4月前
|
人工智能 前端开发 JavaScript
前端大模型入门(二):掌握langchain的核心Runnable接口
Langchain.js 是 Langchain 框架的 JavaScript 版本,专为前端和后端 JavaScript 环境设计。最新 v0.3 版本引入了强大的 Runnable 接口,支持灵活的执行方式和异步操作,方便与不同模型和逻辑集成。本文将详细介绍 Runnable 接口,并通过实现自定义 Runnable 来帮助前端人员快速上手。
100 1
|
4月前
|
存储 人工智能 搜索推荐
揭秘LangChain+RAG如何重塑行业未来?保姆级实战演练,解锁大模型在各领域应用场景的神秘面纱!
【10月更文挑战第4天】随着AI技术的发展,大型语言模型在各行各业的应用愈发广泛,检索增强生成(RAG)技术成为推动企业智能化转型的关键。本文通过实战演练,展示了如何在LangChain框架内实施RAG技术,涵盖金融(智能风控与投资决策)、医疗(辅助诊断与病历分析)及教育(个性化学习推荐与智能答疑)三大领域。通过具体示例和部署方案,如整合金融数据、医疗信息以及学生学习资料,并利用RAG技术生成精准报告、诊断建议及个性化学习计划,为企业提供了切实可行的智能化解决方案。
135 5
|
4月前
|
JSON 计算机视觉 数据格式
LangChain-17 FunctionCalling 利用大模型对函数进行回调 扩展大模型的额外的能力 比如实现加减乘除等功能
LangChain-17 FunctionCalling 利用大模型对函数进行回调 扩展大模型的额外的能力 比如实现加减乘除等功能
78 4
|
4月前
|
前端开发 API
LangChain-25 ReAct 让大模型自己思考和决策下一步 AutoGPT实现途径、AGI重要里程碑
LangChain-25 ReAct 让大模型自己思考和决策下一步 AutoGPT实现途径、AGI重要里程碑
147 0
|
4月前
|
机器学习/深度学习 存储 自然语言处理
LangChain-22 Text Embedding 续接21节 文本切分后 对文本进行embedding向量化处理 后续可保存到向量数据库后进行检索 从而扩展大模型的能力
LangChain-22 Text Embedding 续接21节 文本切分后 对文本进行embedding向量化处理 后续可保存到向量数据库后进行检索 从而扩展大模型的能力
85 0
|
9月前
|
Shell Android开发
Android系统 adb shell push/pull 禁止特定文件
Android系统 adb shell push/pull 禁止特定文件
683 1
|
9月前
|
Android开发 Python
Python封装ADB获取Android设备wifi地址的方法
Python封装ADB获取Android设备wifi地址的方法
190 0