跳至主要内容

使用 LangChain 的提示工程入门

探索 LangChain 中提示工程的威力,这是一项从 AI 模型获取准确且相关响应的关键技术。
· 11分钟 阅读

使用 AI 探索

LangChain 是一个开源框架,可轻松使用诸如 构建应用程序 的语言模型,如 GPT、LLaMA、Mistral 等。

LangChain 最强大的功能之一是其对高级提示工程的支持。提示工程是指设计与优化提示,以便从语言模型中获得最准确、最相关的响应。

在本文中,我们将介绍提示的基础知识、LangChain 如何利用提示、提示模板、记忆、代理和链。针对这些核心概念,我们都将提供多个 Python 代码示例,帮助您在教程结束时能够熟练使用 Python 中的 LangChain 框架构建自己的应用程序。

想知道如何使用 LangChain 和 GPT 创建一个简单的 AI 代理吗?欢迎查看我们的“使用 GPT 与 LangChain 进行提示工程”同步编程课程:

什么是提示工程?

图片来源:作者

我们有一份完整指南介绍提示工程。简单回顾一下,它是创建能够与生成式 AI 模型有效沟通的文本输入的实践。这些以自然语言编写的提示会明确我们希望 AI 执行的任务。

它们的形式多样,可以是简单的问题,比如请求解释某个数学定理;也可以是更具创造性的需求,比如围绕特定主题写一首诗。

在提示工程中,关键不只是问什么,还在于怎么问。这可能包括选择合适的措辞、设定特定的语气或风格、提供必要的上下文,甚至为 AI 设定一个角色,例如让它以某种语言的母语者身份作答。

在某些情况下,提示还可以包含示例来引导 AI 的学习过程。这种被称为“少样本学习”的技术对于复杂任务特别有效。

在处理生成图像或音频的模型时,提示通常会详细描述期望的输出,从主题与风格到最终作品的构图与情绪。提示工程的艺术在于调整这些要素,引导 AI 产出理想结果。

提示的基础

图片来源:作者

提示是提供给大型语言模型(LLM)的输入,用于引出期望的响应。要从 LLM 获得有用的输出,良好设计的提示至关重要。提示工程的目标是精心构造提示,从而得到准确、相关且有帮助的 LLM 响应。

一个好的提示通常包含以下四个组成部分:

  1. 说明——告诉模型该做什么、如何使用提供的信息、如何处理查询,以及如何组织输出。
  2. 示例输入——提供示例输入,以向模型展示预期内容。
  3. 示例输出——提供相应的示例输出。
  4. 查询——您真正希望模型处理的输入。

除查询外,其他部分都是可选的,但可能会显著影响响应质量,尤其是为 LLM 提供任务与期望响应指引的说明。

示例用于演示在给定示例输入下期望的输出格式。

查询是您向 LLM 提出的具体问题或请求。

构建有效的提示,需要根据所要解决的问题,将这些要素进行创造性组合。

LangChain 提示

LangChain 提供多种类与函数,帮助构建和使用提示,使处理涉及语言模型的复杂任务更加容易。

LangChain 通过 `PromptTemplate` 对象为提示工程提供一等公民的支持。

提示模板充当结构化的指南,用于为语言模型制定查询。

这些模板通常包含指令、若干示例输入(少样本示例),以及针对特定任务定制的问题与上下文。

LangChain 的目标是设计可与多种语言模型兼容的模板,从而更容易在不同模型之间迁移模板。

简而言之,您可以使用 PromptTemplate 类来创建字符串提示的模板。

from langchain.prompts import PromptTemplate


prompt_template = PromptTemplate.from_template(
    "Tell me a {adjective} joke about {content}."
)
prompt_template.format(adjective="sad", content="data scientists")

输出:

>>> 'Tell me a sad joke about data scientists.'

并非一定需要变量。即使没有任何变量,您也可以使用此类来创建提示。

from langchain.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template("Tell me a joke")
prompt_template.format()

输出:

>>> 'Tell me a joke'

如果您在构建聊天应用,需要在用户每次发送新消息时保存并将消息历史发送到 LLM,手动完成这件事会非常耗时。

对于受支持的聊天模型,您可以使用 ChatPromptTemplate:

from langchain.prompts import ChatPromptTemplate


chat_template = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful AI bot. Your name is {name}."),
        ("human", "Hello, how are you doing?"),
        ("ai", "I'm doing well, thanks!"),
        ("human", "{user_input}"),
    ]
)


messages = chat_template.format_messages(name="Bob", user_input="What is your name?")


print(messages)

输出:

>>> [SystemMessage(content='You are a helpful AI bot. Your name is Bob.'),

>>> HumanMessage(content='Hello, how are you doing?'),

>>> AIMessage(content="I'm doing well, thanks!"),

>>> HumanMessage(content='What is your name?')]

您可能会想,为什么需要 PromptTemplates?为什么不能直接将字符串提示传给 LLM?以下是使用 LangChain 的 PromptTemplate 的一些充分理由:

  • 提示模板可复用,您可以创建一次提示,在多种场景中使用,比如总结不同文章而无需每次重写提示。
  • 它们将提示的格式化与实际的模型调用分离,使代码更加模块化,并允许独立更新模板或模型。
  • 使用模板能提升代码可读性,因为模板用更清晰的命名变量封装了复杂逻辑。
  • 有了提示模板,维护更容易,因为只需在一个中心位置修改提示逻辑,而不必在每个单独的提示中逐一更改。

LangChain 记忆(Memory)

在涉及聊天的语言模型应用中,系统记住以往对话非常重要。

就像普通聊天一样,系统应能够回溯之前说过的话。

在最简单的情况下,这意味着系统能看到之前的几条消息。但更高级的系统会记住更多细节,例如关于不同主题的事实以及它们之间的关联。

这种记住过往对话的能力称为“记忆”。LangChain 可帮助为此类聊天系统添加记忆。

在 LangChain 中,记忆主要做两件事:

  1. 在将查询发送给 LLM 之前,系统会从记忆中读取,以增强其从用户接收到的初始输入提示。
  2. 一旦 LLM 返回响应,系统会在向用户返回最终输出之前,将该响应写入记忆,以用于后续交互。

LangChain 中的记忆(图片来源)

要在 LangChain 中使用 Memory 功能,您可以使用 ConversationBufferMemory 类。

from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(return_messages=True)
memory.chat_memory.add_user_message("hi!")
memory.chat_memory.add_ai_message("what's up?")
memory.chat_memory.add_user_message("how are you doing?")
memory.chat_memory.add_ai_message("I am fine, thank you and you?")


# to check the variables history
memory.load_memory_variables({})

输出:

>>> {'history': [HumanMessage(content='hi!'),

>>> AIMessage(content="what's up?"),

>>> HumanMessage(content='how are you doing?'),

>>> AIMessage(content='I am fine, thank you and you?')]}

它返回一个字典,默认键为 history。该键对应一组消息,这些消息可能来自人类(HumanMessage)或来自 LLM(AIMessage)。

LangChain 链(Chains)

对于简单任务,使用单个 LLM(大型语言模型)就足够了。然而,对于更复杂的任务,通常需要将多个步骤和/或模型串联起来。

在 LangChain 中,使用 Chains 的旧方式是通过 Chain 接口。

更新且推荐的方法是使用 LangChain 表达式语言(LCEL)。尽管 LCEL 更适合新项目,但 Chain 方法依然有用且受到支持。

from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema import StrOutputParser


model = ChatOpenAI(openai_api_key = “...”)


prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "You're a expert data scientist and machine learning engineer who offer its expertise and responds to the point and accurately.",
        ),
        ("human", "{question}"),
    ]
)
runnable = prompt | model | StrOutputParser()


for chunk in runnable.stream({"question": "How is machine learning different than deep learning?"}):
    print(chunk, end="", flush=True)

输出:

>>> Machine learning and deep learning are subfields of artificial intelligence (AI) that involve training models to make predictions or decisions based on data. While there is an overlap between the two, they ……..

runnable 的创建方式在 Python 中并不常见,但这里的 | 是管道运算符。Prompt | model | StrOutputParser() 表示先将 Prompt 传给 model,其输出再传给 StrOutputParser()。链中的每个环节都会以某种方式对数据进行转换。

想进一步了解可以用 LangChain 构建的有趣用例和应用吗?请查看我们的工程与数据应用用例教程。

LangChain 代理(Agents)

代理的基本概念是利用语言模型来选择一系列动作。

与在链中预先确定并写入代码的动作序列不同,代理将语言模型作为决策工具,以确定合适的动作及其顺序。

在 LangChain 的 Agents 中有三个关键概念:

  1. 工具:向 LLM 描述可用的工具
  2. 用户输入:任务的高层目标
  3. 中间步骤:为实现用户输入而先前执行的任意(动作、工具输出)对

工具代表代理可以调动的功能。工具设计的两个关键方面包括:

  • 确保代理能够访问合适的工具。
  • 以最大化其对代理有用性的方式来定义工具。

对于各种日常活动,代理需要一组相互关联的工具。为此,LangChain 引入了工具包(toolkits)的概念。LangChain 提供了丰富的工具包以便快速上手。

想要进一步了解 Agents,请查看这份LangChain 官方指南。

致谢:本文中的部分示例来自官方LangChain 文档。

结论

通过提供一种结构化的提示设计方法,LangChain 不仅简化了与不同语言模型交互的过程,还最大化了其输出的效率与相关性。诸如 PromptTemplate 和 Memory 等功能,体现了 LangChain 在提示工程中对灵活性与精确性的深思熟虑的融合,能够适配从简单查询到复杂对话场景的广泛任务。

LangChain 的 Chains 与 Agents 中的高级特性,进一步拓展了基于任意底层 LLM、仅用少量代码即可构建应用的可能性,而可选的 LLM 也有很多。

无论是简单任务还是复杂应用,LangChain 的提示工程方法都相当简洁、清晰且易于采用。

想继续学习?请查看 DataCamp 上《如何使用 LangChain 构建 LLM 应用(第一部分)》。

Moez Ali

作者

Moez Ali

数据科学家,PyCaret 的创始人兼作者

主题