前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

有时候,我们只是想利用 LLM 来帮助我们完成一些特定类型的任务,
但每次可能我们跟 LLM 对话的内容只是有一些细微的差别,这时候我们可以使用提示词模板来帮助我们更方便地构建对话。

PromptTemplate

langchain 中,我们可以使用 PromptTemplate 来定义一个提示词模板:

from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI

prompt_template = "What is a good name for a company that makes {product}?"
prompt = PromptTemplate(template=prompt_template, input_variables=["product"])

llm = ChatOpenAI(
    model_name="gpt-3.5-turbo",
    temperature=0,
    max_tokens=200,
    api_key="your key",
    base_url="https://api.openai-hk.com/v1",
)

chain = prompt | llm | StrOutputParser()

response = chain.invoke({"product": "shoes"})

print(response)

输出:

SoleStride Footwear Co.

在上面这个例子中,我们的 PromptTemplateWhat is a good name for a company that makes {product}?
在这里,product 是一个变量,我们可以在调用 chain.invoke 的时候传入一个字典,来替换这个变量。

这样,我们就实现了一个模板化的提示词,可以方便地构建对话。

RunnableSerializable

在上面的例子中,chain = prompt | llm | StrOutputParser() 这一行代码我们可能会看得有点懵逼。

这里的 | 并不是常见的 or 运算,而是 prompt 里面的 __or__ 方法调用,等于是运算符重载了。

这一行代码的最终结果是,返回一个 RunnableSequence 的实例,我们可以调用它的 invoke 方法。
接着就执行类似管道的操作,前一个操作的输出作为后一个操作的输入。

管道抽象

如果熟悉 linux 命令行的话,我们会知道,其实 linux 中的管道操作符也是 |。与之类似的,langchain 重载 | 操作符也是为了抽象管道这种操作。
在这行代码中,prompt 的输出会作为 llm 的输入,同时,llm 的输出也会作为 StrOutputParser() 的输入。然后最终得到多个管道处理后的结果。

invoke 实现管道操作的源码

# invoke all steps in sequence
try:
    for i, step in enumerate(self.steps):
        # mark each step as a child run
        config = patch_config(
            config, callbacks=run_manager.get_child(f"seq:step:{i+1}")
        )
        if i == 0:
            input = step.invoke(input, config, **kwargs)
        else:
            input = step.invoke(input, config)
# finish the root run
except BaseException as e:
    run_manager.on_chain_error(e)
    raise

批量调用

我们也可以使用 chainbatch 方法来传入多个模板参数:

response = chain.batch([
    {"product": "shoes"},
    {"product": "cup"},
])

这样我们就可以同时得到多个问题的答案了。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐