字节青训营AI课程笔记一:初识LangChain | 豆包MarsCode AI刷题

222 阅读12分钟

1. 背景介绍

AI技术自诞生以来,其发展之路并非一帆风顺,现代AI的核心驱动力神经网络,70年间经历了两落三起;自然语言处理技术亦不例外,在ChatGPT和GPT-4出现之前,NLP技术也曾受过质疑,长期经历低谷期。然而近些年ChatGPT和GPT-4等大模型的出现再一次掀起了AI领域的热潮,其覆盖范围之广,影响程度之大远超之前,可以说大模型领域的突破标志着一个新时代的到来。

不少业界领袖都认为AI大模型的出现是一个划时代的里程碑,将深刻改变社会生产力和人们的生活方式。大模型技术被英伟达的创始人、CEO黄仁勋视为AI的“iPhone时刻”,甚至有人认为,“iPhone 时刻”都不足以形容大模型的技术影响力和未来前景,应该将其视为“互联网时刻”。“面向AI时代,所有产品都值得用大模型重新升级”,这也预示着,未来的人工智能应用企业有可能会超过 Apple、微软、谷歌等科技巨头。

无论如何,可以明确的一点是,我们正站在一个崭新的历史节点上。ChatGPT、GPT-4和其他大语言模型为我们提供了新的视角和新的可能性,在大语言模型的基础上,有可能成长出跨平台的企业,改变未来的科技格局。

而LangChain,作为一个专门为利用大语言模型(LLMs)创建应用程序而设计的开源框架,几乎和 ChatGPT 一起面世,旨在帮助开发人员轻松构建基于语言模型的应用。程序设计者可以利用大模型的潜力和LangChain的便捷开发出令人惊叹的智能应用。LangChain作为新一代AI开发框架,必将受到程序员的追捧,点燃AI应用开发的新热潮。

2. 什么是LangChain?

作为一种专为开发基于语言模型的应用而设计的框架,通过LangChain,我们不仅可以通过API调用如 ChatGPT、GPT-4、Llama 2 等大型语言模型,还可以实现更高级的功能。

一个优秀的AI应用,应该不只局限于通过API调用大模型完成预设任务,还应该具备以下两个特性:

  1. 数据感知:  能够将语言模型与其他数据源连接起来,从而实现对更丰富、更多样化数据的理解和利用。
  2. 具有代理性:  能够让语言模型与其环境进行交互,使得模型能够对其环境有更深入的理解,并能够进行有效的响应。

LangChain就是基于这个目的被设计出来的,利用LangChain提供的工具和抽象层,开发者能够将语言模型与外部数据源、工具、工作流集成,从而增强语言模型的功能和适用性,并简化创建由LLMs和聊天模型提供支持的应用程序的过程。

3. LangChain的核心概念和组件

  1. Models(LLMs)

    • LangChain 的核心模块,支持多种语言模型的无缝集成。
    • 通过简单的 API 调用,用户可以访问各种 LLM,如 OpenAI 的 GPT-4GPT-3.5、Anthropic 的 Claude、Cohere 的 Command、以及本地化部署的模型如 Llama 系列。
  2. Prompts(提示模板)

    • LangChain提供预定义的文本模板,用于结构化提示(prompts),从而提高 LLM 的生成效果和一致性。
    • 允许用户定义变量、占位符和上下文,使生成的文本更加符合实际需求。
  3. Chains(链式调用)

    • 这是 LangChain 的核心功能之一,允许开发者将多个 LLM 调用和处理步骤串联起来。例如,可以让模型先生成文本摘要,再进行翻译,最后提取关键信息。通过链式调用,模型可以将多个任务集成在一个流程中。
  4. Agents(代理)

    • 代理是 LangChain 中的一个高级功能,允许模型在不同工具之间自动决策,选择合适的工具来完成任务。例如,可以配置一个代理,让模型根据任务需求自动调用搜索引擎、计算器、数据库等工具,从而完成更复杂的任务。
  5. Memory(记忆)

    • 提供会话记忆功能,使 LLM 能够在多轮对话中保留上下文信息。
    • 支持短期和长期记忆,可以在对话中更好地理解用户意图,并做出一致的回答。
  6. Indexes(数据检索)

    • 构建并操作文档的方法,接受用户的查询并返回最相关的文档,轻松搭建本地知识库。

这些组件是LangChain的基石,是赋予其智慧和灵魂的核心要素,它们相互协作,形成一个强大而灵活的系统。除了上面的六大核心组件之外,LangChain还为我们提供了一系列的Toolkits(工具集) ,允许将我们外部 API、数据库、文档搜索引擎等集成到 LLM 的调用中,从而增强其功能。目前LangChain的工具集支持 Google Search、SQL 数据库、Python 代码执行等多种工具集成,Agents不少功能的实现离不开这些丰富的Toolkits。

4. LangChain的简单使用示例

青训营的课程帮我们把所有的环境都配好了,省去了繁琐的环境配置步骤,并且还帮我们配好了豆包模型的API KEY,大部分代码都可以一键运行,该说不说真的很Nice!

虽然AI练中学帮我们配好了豆包的API,但是毕竟还是跟原生的OpenAI不一样,如果你想要调用GPT模型的话可以去OpenAI官网注册一个自己的OpenAI Key,官网文档中有API相关调用和付费的详细细节。

在正式使用之前我们需要先了解一下两类模型:文本模型(Text Model)和聊天模型(Chat Model)。这两类Model,是大语言模型的代表。当然,OpenAI还提供Image、Audio和其它类型的模型,目前它们不是LangChain所支持的重点,模型数量也比较少。下面是这两类模型的一个简单对比。

  1. 交互性

    • 聊天模型:通常设计为与用户进行双向交互,能够理解用户的输入并给出相应的回复。它们通常用于模拟对话,需要能够处理上下文信息,以维持连贯的对话流程。
    • 文本模型:可能更侧重于处理单向的文本任务,如文本分类、情感分析、文本生成等,不一定需要处理交互式的对话。
  2. 上下文管理

    • 聊天模型:需要能够理解和维护对话的上下文,以便在多轮对话中提供合适的回应。
    • 文本模型:可能不需要处理上下文信息,或者只在处理长文本时才需要考虑上下文(如文档分类或摘要)。
  3. 输出格式

    • 聊天模型:输出通常是对话的一部分,需要以自然语言的形式回复用户。
    • 文本模型:输出可能是分类标签、评分、摘要或其他非对话形式的文本。
  4. 输入处理

    • 聊天模型:输入处理可能包括对自然语言的理解和意图识别,以便确定如何回应。
    • 文本模型:输入处理可能更侧重于特征提取和文本表示,以便进行分类或其他任务。

通常我们需要根据具体的业务需求选择不同的模型,比如聊天模型适用于客户服务、虚拟助手、社交机器人等需要对话的场景,而文本模型则更适用于搜索引擎、推荐系统、内容审核、自动摘要等文本处理任务。

由于火山引擎的API兼容OpenAI,因此课程的代码可以直接使用OpenAI官方的调用方式进行API调用,下面我们以两个程序为例体验一下LangChain的使用:

注意:OpenAI的Completions API已经在2023年7月完成最后一次更新并废弃,该接口仅适用于早期版本的少量模型("gpt-3.5-turbo-instruct", "davinci-002", "babbage-002"); 相关功能可以被ChatCompletion接口代替。而课程代码默认配置的Doubao API兼容最新版本的API调用,对废弃接口不再支持。因此我们的示例代码不特意区分文本模型和聊天模型的调用。

(1)Text Model的调用示例

import os
from langchain_openai import ChatOpenAI

# os.environ["OPENAI_API_KEY"] = '你的 OpenAI API Key'
# os.environ["OPENAI_BASE_URL"] = 'OpenAI 的 API URL'

llm = ChatOpenAI(
    model=os.environ.get("LLM_MODELEND"),
    temperature=0.8,
    max_tokens=600,
)
response = llm.predict("请给我的花店起个名")

print(response)

我们通过模型的predict方法进行了单句文本的生成,可以看到,豆包模型给出的答案还是很不错的~

(2)Chat Model的调用示例

import os
from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage, SystemMessage

# 你所调用模型的相关信息配置,这里注释掉的话就会使用环境默认的豆包API
os.environ["OPENAI_API_KEY"] = "你调用模型的 API KEY"
os.environ["OPENAI_BASE_URL"] = "你调用模型的 Base Url"
os.environ["LLM_MODELEND"] = "你调用模型的名称"

# 创建 ChatOpenAI 实例
chat = ChatOpenAI(model=os.environ.get("LLM_MODELEND"), temperature=0.8, max_tokens=600)

# 准备消息
messages = [
    SystemMessage(content="你是一个很棒的智能助手"),
    HumanMessage(content="请给我的花店起个名"),
]

# 发送请求并获取响应
response = chat(messages)
print(response.content)

这里准备消息的代码也可以写成这样:

# 这里需要注意的是使用这种方式调用模型最后得到的回复格式跟上面不太一样
# 要获取模型的文本回复我们需要使用:print(response.choices[0].message.content)

response = client.chat.completions.create(
    model=os.environ.get("LLM_MODELEND"),
    messages=[
        {"role": "system", "content": "You are a creative AI."},
        {"role": "user", "content": "请给我的花店起个名"},
    ],
    temperature=0.8,
    max_tokens=600,
)

屏幕截图 2024-11-14 195036.png

可以看到,通过对话形式调用的聊天模型给出的答案也是很不错的,这里不同于文本模型的是我们在调用聊天模型时给消息设定了角色从而给模型提供了一定的背景信息。这里提到了两个专属于Chat模型的概念,一个是消息,一个是角色

先说消息,消息就是传入模型的提示。上文代码中的messages参数是一个列表,包含了多个消息。每个消息都有一个role(可以是system、user或assistant)和content(消息的内容)。系统消息设定了对话的背景(你是一个很棒的智能助手),然后用户消息提出了具体请求(请给我的花店起个名)。模型的任务是基于这些消息来生成回复。

再说角色,在OpenAI的Chat模型中,system、user和assistant都是消息的角色。每一种角色都有不同的含义和作用。

  • system:系统消息主要用于设定对话的背景或上下文,通常在对话开始时给出。这可以帮助模型理解它在对话中的角色和任务。例如,你可以通过系统消息来设定一个场景,让模型知道它是在扮演一个医生、律师或者一个知识丰富的AI助手。
  • user:用户消息是从用户或人类角色发出的。它们通常包含了用户想要模型回答或完成的请求。用户消息可以是一个问题、一段话,或者任何其他用户希望模型响应的内容。
  • assistant:助手消息是模型的回复。例如,在你使用API发送多轮对话中新的对话请求时,可以通过助手消息提供先前对话的上下文。然而,请注意在对话的最后一条消息应始终为用户消息,因为模型总是要回应最后这条用户消息。

——直接看程序你可能感觉不到LangChain的特点,这里我们对比一下官方的API调用方式

Text Model的调用

import openai

# 导入API Key有多种方式,下面是两种在程序中直接使用的方式
# openai.api_key = '你的 Open API Key'
import os
os.environ["OPENAI_API_KEY"] = '你的 Open API Key'

# 你还可以在终端中使用如下命令进行导入,这样可以避免你的API KEY直接暴露在程序中,更加安全
# export OPENAI_API_KEY='你的Open API Key'

from openai import OpenAI
client = OpenAI()

response = client.completions.create(
  model="gpt-3.5-turbo-instruct",
  temperature=0.5,
  max_tokens=100,
  prompt="请给我的花店起个名")

print(response.choices[0].text.strip())

Chat Model的调用

import openai

# 导入API Key有多种方式,下面是两种在程序中直接使用的方式
# openai.api_key = '你的 Open API Key'
import os
os.environ["OPENAI_API_KEY"] = '你的 Open API Key'

# 你还可以在终端中使用如下命令进行导入,这样可以避免你的API KEY直接暴露在程序中,更加安全
# export OPENAI_API_KEY='你的Open API Key'

from openai import OpenAI
client = OpenAI()

response = client.chat.completions.create(  
  model="gpt-4",
  messages=[
        {"role": "system", "content": "You are a creative AI."},
        {"role": "user", "content": "请给我的花店起个名"},
    ],
  temperature=0.8,
  max_tokens=60
)

print(response['choices'][0]['message']['content'])

跟LangChain调用方式对比,一个很明显的区别就是程序对模型返回响应的输出处理。无论是langchain.llms中的OpenAI(Text模型),还是langchain.chat_models中的ChatOpenAI(Chat模型),其返回的response变量的结构都比直接调用OpenAI API来得简单一些。这是因为LangChain已经对大语言模型的output进行了解析,只保留了响应中最重要的文字部分,这也是LangChain的便捷之处。

总结

LangChain 是一个全方位的、基于大语言模型这种预测能力的应用开发工具,它的灵活性和模块化特性使得处理语言模型变得极其简便。它对各种大模型提供的API的套壳极大地便利了我们项目的开发和搭建。不论在何时何地,开发者都能利用它流畅地调用语言模型,并基于语言模型的“预测”或者说“推理”能力开发新的AI应用。