前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
让 LLM 自动选择不同的 Prompt
在上一篇文章中,我们学会了如何让 langchain 来自动选择不同的 LLM Chain,以便回答不同的问题,只需要使用 RouterChain
和 MultiPromptChain
就可以实现这一功能。
但 MultiPromptChain
被设计出来并不只是为了实现不同 LLM Chain 的选择,我们还能用它来实现让 LLM 选择不同的 Prompt,原理跟 RouterChain
差不多,只不过选择的是 Prompt
而不是 LLM Chain
。
也就是说,其实另外一种场景是:使用相同的大语言模型,只是让它选择不同的 Prompt 来回答问题。
例子
下面是一个例子,我们使用 MultiPromptChain
来让 LLM 自动选择不同的 Prompt 来回答问题:
- 当我们问关于 Python 编程的问题时,LLM 会选择 Python 的 Prompt 来回答。
- 当我们问关于 Golang 编程的问题时,LLM 会选择 Golang 的 Prompt 来回答。
python
from langchain.chains.router import MultiPromptChain
from langchain_openai import ChatOpenAI
py_template = """
你是一名 Python 工程师,擅长解答关于 Python 编程的问题。
下面是需要你来回答的问题:
{input}
"""
go_template = """
你是一名 Golang 工程师,擅长解答关于 Golang 编程的问题。
下面是需要你来回答的问题:
{input}
"""
prompt_infos = [
{
"name": "python",
"description": "适合回答关于 Python 编程的问题",
"prompt_template": py_template,
},
{
"name": "golang",
"description": "适合回答关于 Golang 编程的问题",
"prompt_template": go_template,
}
]
chain = MultiPromptChain.from_prompts(
llm=ChatOpenAI(model="gpt-3.5-turbo", temperature=0),
prompt_infos=prompt_infos,
verbose=True
)
print(chain.invoke({"input": "如何在 Python 中定义一个函数?"}))
原理
既然涉及到自动选择不同的 Prompt
的操作,其实底层还是使用了 RouterChain
,如果我们去看 from_prompts
代码,发现跟前一篇文章使用的是相同的 Prompt
,
也就是 MULTI_PROMPT_ROUTER_TEMPLATE
。
- 构建一个
router_prompt
,使用MULTI_PROMPT_ROUTER_TEMPLATE
模板,将所有Prompt
的信息传入。 - 使用
RouterChain
构建一个RouterChain
,并将router_prompt
传入。 - 构建
destination_chains
,这一步会为不同的Prompt
创建一个LLMChain
。 - 创建一个
default_chain
,这个链会在没有匹配到任何Prompt
时触发。 - 创建一个
MultiPromptChain
实例,将RouterChain
和default_chain
传入。
实际调用 chain.invoke
的时候,会经历如下过程:
- 将
RouterChain
的Prompt
(格式化之后的,带有我们的Prompt
简易描述)传递给 LLM,让 LLM 选择一个LLMChain
来处理。 - LLM 会根据输入的
Prompt
选择一个LLMChain
,然后调用这个LLMChain
(对应某个具体的Prompt
,也就是上面prompt_infos
中的一个)来处理输入。 - 如果没有匹配到任何
Prompt
,则会调用default_chain
来处理输入。 - 再次调用 LLM,让 LLM 回答用户的问题,最终,我们会得到一个回答。
自动选择 Prompt 的 Prompt
我们可以在 LangSmith 中看到实际发送给 LLM 选择 Prompt 的 Prompt 是怎样的:
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 ```) >>
说明:
- 先是一个简单的引导语句,告诉模型你将给它一个输入,它需要根据这个输入选择最适合的模型。
- 指定输出的格式,告诉模型输出应该是一个 JSON 对象。
- 一些关于输出的额外说明,比如如果没有匹配到任何
Prompt
,则应该返回DEFAULT
。 - 接着是所有可选的
Prompt
,以及它们的描述。 - 最后是用户输入的问题。
LLM 在拿到这个 Prompt
之后会进行分析推理,然后选择一个最适合的 Prompt
,然后返回给我们。
当然拿到选择的具体的 Prompt
之后,并不是拿到了最终的答案,接着,使用选中的 Prompt
以及用户的问题再次调用 LLM,最终得到一个回答。
总结
MultiPromptChain
是对 RouterChain
的一个扩展,它可以让 LLM 选择不同的 Prompt
来回答问题,这样我们可以更灵活地使用不同的 Prompt 来回答问题。
而 RouterChain
是可以自动选择不同的大模型来回答问题。也就是说:
- 如果我们只是想让 LLM 选择不同的 Prompt 来回答问题,可以使用
MultiPromptChain
。 - 如果我们想让 LLM 选择不同的大模型来回答问题,可以使用
RouterChain
结合MultiPromptChain
来实现。