【可能是全网最丝滑的LangChain教程】九、LangChain进阶之Chat Model

01 Model介绍

任何语言模型应用程序的核心元素都是…模型(Model)。LangChain 提供了与任何语言模型进行交互的构建块(building blocks)。

LangChain 的 Model I/O 组件包括:两种不同类型的模型 - LLM(【可能是全网最丝滑的LangChain教程】八、LangChain进阶之LLM - 掘金 (juejin.cn)) 和 Chat model;格式化模型输入 Prompt;输出解析器 Output parser。

图片

本文将重点介绍:Model I/O子组件—>Chat Model

02 Chat Model介绍

Chat Model 是 LangChain的核心组件,同时 Chat Model 也是语言模型的一种。

它使用 Chat Message 作为输入,并将 Chat Message作 为输出返回(而不是使用纯文本)。LangChain 与许多模型提供商(OpenAI、Cohere、Hugging Face等)都有良好的集成,并公开了一个标准接口来与这些模型进行交互。

LangChain 允许我们在同步、异步、批处理和流模式下使用模型,并且 LangChain还提供其他功能(例如:缓存)等。
😝有需要的小伙伴,可以V扫描下方二维码免费领取🆓

我们可以看下 LangChain 中目前已经支持的 Chat Model 有哪些,我格式化打印了下直接子类和间接子类。
python复制代码class BaseChatModel
  class SimpleChatModel
    class FakeListChatModel
    class FakeChatModel
    class ChatMaritalk
    class FakeListChatModel
  class FakeMessagesListChatModel
  class GenericFakeChatModel
  class ParrotFakeChatModel
  class ChatOpenAI
    class AzureChatOpenAI
  class ChatOpenAI
    class AzureChatOpenAI
    class ChatAnyscale
    class ChatEverlyAI
    class ChatKonko
    class PromptLayerChatOpenAI
  class ChatAnthropic
  class BedrockChat
  class ChatBaichuan
  class ChatCohere
  class ChatMlflow
    class ChatDatabricks
  class ChatDeepInfra
  class ChatFireworks
  class ChatFriendli
  class ChatGooglePalm
  class ChatHuggingFace
  class ChatHunyuan
  class ChatJavelinAIGateway
  class ChatKinetica
  class ChatLiteLLM
    class ChatLiteLLMRouter
  class ChatMLflowAIGateway
  class ChatOllama
  class ChatPerplexity
  class ChatSparkLLM
  class ChatTongyi
  class ChatVertexAI
  class ChatYandexGPT
  class ChatYuan2
  class ChatZhipuAI
  class ErnieBotChat
  class FakeMessagesListChatModel
  class GPTRouter
  class GigaChat
  class HumanInputChatModel
  class JinaChat
  class LlamaEdgeChatService
  class MiniMaxChat
  class PaiEasChatEndpoint
  class QianfanChatEndpoint
  class VolcEngineMaasChat
  class ChatPremAI
  class ChatLlamaAPI

从上面的打印结果可以看出,基本目前国内国外的大模型都是支持的。比如:BaiChuan(百川)、Tongyi(通义)、Hunyuan(混元)、Zhipu(智谱)…等等国产模型都是支持的。

03 Chat Model案例实操

聊天模型是语言模型的变体。虽然聊天模型在后台使用语言模型,但它们使用的方式略有不同。他们没有使用“文本输入,文本输出”的 API,而是使用“聊天消息”作为输入和输出。

1 安装依赖

bash

复制代码pip install -qU langchain-openai

2 初始化Chat Model

python复制代码from langchain_openai import ChatOpenAI

# xxxxxx是你们自己传递的参数
chat_model = ChatOpenAI(xxxxxx)

3 设置Message

聊天模型界面基于消息而不是原始文本。LangChain 目前支持的消息类型是AIMessage、HumanMessage、SystemMessage、FunctionMessage和ChatMessage——ChatMessage 可以采用任意角色参数。大多数时候,开发者只会处理 HumanMessage、AIMessage 和 SystemMessage

聊天模型实现了 Runnable 接口,这是 LangChain 表达式语言 (LCEL) 的基本构建块。这意味着它们支持 invoke、ainvoke、stream、astream、batch、abatch、astream_log 调用。

聊天模型接受 List[BaseMessage] 作为输入,或者接受一个可以转换成Message的输入,包括 str(转换为 HumanMessage)和 PromptValue。

这里我们设置了 SytemMessage 和 HumanMessage。其中 SytemMessage一般用于定义模型的角色和技能,目的是为了回答更加准确;HumanMessage 设置真正的用户输入,也就是你的问题。

python复制代码from langchain_core.messages import HumanMessage, SystemMessage

messages = [
    SystemMessage(content="你是一个顶级的历史学家,尤其华夏历史。"),
    HumanMessage(content="请用一句话总结秦始皇的家庭情况。")
]

4 执行

python复制代码# 一般执行 
chat.invoke(messages)

# 流式输出 
for chunk in chat.stream(messages):     
    print(chunk.content, end="", flush=True) 

# 批量执行 
chat.batch([messages])

# 异步执行
await chat.ainvoke(messages)

# 异步流式执行
async for chunk in chat.astream(messages):
    print(chunk.content, end="", flush=True)

# 异步流式执行,并输出执行日志
async for chunk in chat.astream_log(messages):
    print(chunk)

输出:

python复制代码AIMessage(content='秦始皇是秦庄襄王嬴异人的儿子,母亲是赵姬,他在秦国宫廷中度过了自己的童年。 ')

# 实际上这里给到模型的输入具体有如下消息:
# {
#  "prompts": [
#     "System: 你是一个顶级的历史学家,尤其华夏历史。\nHuman: 请用一句话总结秦# 始皇的家庭情况。"
#   ]
# }

04 Message介绍

ChatModel 将 Message 列表作为输入并返回 Message。有几种不同类型的 Message。所有消息都具有 role 和 content 属性。LangChain 为不同的角色提供了不同的消息类。content 属性描述消息的内容。

  • content 可以是一个字符串(99% 的情况我们试用这个)
  • content 也可以是一个字典列表(用于多模态输入,其中字典包含有关该输入类型和输入位置的信息)

此外,Message 还具有 additional_kwargs 属性。可以传递有关 Message 的其他信息。主要用于特定程序要求而不是常规的输入参数。最著名的例子是 OpenAI 的 function_call。

1 HumanMessage(常用)

这表示来自用户的消息。通常仅由content(内容)组成。

2 AIMessage(常用)

这表示来自模型的消息。这可能包含 additional_kwargs。例如:如果使用 OpenAI 工具调用,则为 tool_calls信息。

3 SystemMessage(常用)

这表示一条系统消息,它告诉模型如何操作。这通常只包含内容。并非每个模型都支持这个消息。

4 FunctionMessage**

这表示函数调用的结果。除了 role 和 content 之外,此消息还有一个 name 参数,该参数传达为生成此结果而调用的函数的名称。一般我们在function_call的调用中能看到这个消息。

5 ToolMessage

这表示工具调用的结果。这与 FunctionMessage 不同,这是为了在调用 OpenAI 的 function 和 tool 而使用的消息类型。除了 role 和 content 之外,此消息还有一个 tool_call_id 参数,该参数将调用的 ID 传达给相应的调用工具。

05 Tool/Function Calling

LangChain 中的 Tool Calling 与 Function Calling 基本是一回事,Tool Calling 内部做了处理,让 Chat Model 能同时调用多个函数(或者叫 tool)。主要功能就是让模型通过使用用户自定义的一些工具或者叫函数来响应用户的输入。模型为工具提供运行参数,而实际运行该工具(或不运行)取决于用户——例如:如果你想从非结构化文本中提取与某个模式匹配的输出,你可以为模型提供一个“提取”工具,该工具使用与所需模式匹配的参数,然后将生成的输出视为最终结果。

工具调用包括名称、参数字典和一个可选标识符。参数字典是结构化的{argument\_name: argument\_value}

许多 LLM 提供商,包括 Anthropic、Cohere、Google、Mistral、OpenAI 等,都支持工具调用功能的变体。这些功能通常允许 LLM 的请求工具,并获取工具的响应。例如:给定一个搜索引擎工具,LLM 可能会通过首先向搜索引擎发出调用来处理查询。然后 LLM 接收工具的输出并处理,最后将最终结果返回给用户。LangChain包含一套内置工具,并支持多种方法来定义您自己的自定义工具。工具调用对于构建使用工具的链和代理,以及更好地从模型中获取结构化输出非常有用。

LangChain 实现了用于定义 tool、传递 tool 给LLM以及调用 tool 的标准接口。之所以有标准接口,目的就是为了适配市面上各种模型的工具调用能力。

因为 Tool Calling 或者说 Function Calling 只在 Chat Model 模式下才生效,所以这里提一下,这部分后续会单独开一篇文章来专门讲述。

06 Structured Output

顾名思义,结构化输出。

让 LLM 返回结构化输出通常至关重要。这是因为 LLM 的输出通常用于需要特定参数的下游应用程序。为此,必须让 LLM 可靠地返回结构化输出。

如何实现结构化输出呢?LangChain 支持的方式有如下几种:

  1. Prompting:我们主动要求 LLM 以所需格式(JSON、XML)返回输出。这很好用,因为它适用于所有 LLM。同时,也并不好用,因为不能保证所有 LLM 都能以正确的格式返回输出。
  2. Function calling:当 LLM 经过微调支持函数调用后,LLM 将可以调用的函作为额外参数传递给模型 API。函数名称和描述应被视为提示的一部分,因为是执行指定函数,而函数方法体又是用户自己定义的,所以可以正确返回之地你个格式的输出。
  3. Tool Calling:一种类似于函数调用的技术,但它允许 LLM 同时调用多个函数。
  4. Json mode:当我们需要 LLM 返回Json格式输出的时候,可以用这个。

因为不同的 LLM 结构化输出的方式可能不同,所以 LangChain 添加了一个通用接口:.with\_structured\_output

同理,因为 Structured Output 只在 Chat Model 模式下才生效,所以这里提一下,这部分后续会单独开一篇文章来专门讲述。

07 缓存支持

Chat Model 缓存与 LLM 缓存使用基本一致,这里不再赘述,大家可以看这篇文章了解缓存使用(【可能是全网最丝滑的LangChain教程】八、LangChain进阶之LLM - 掘金 (juejin.cn)

08 自定义Chat Model

既然 LLM 可以自定义,必然 Chat Model 也可以自定义。这部分实际上和自定义 LLM 非常相似…

自定义 Chat Model 必须实现两个方法:

  • _generate:用户根据用户输入消息,执行具体逻辑,然后返回输出消息
  • _llm_type:获取此聊天模型使用的语言模型的类型。仅用于日志记录。

我们在自定义 LLM 的代码上,稍作修改就能得到自己的自定义 Chat Model。具体代码如下:

python复制代码from langchain_core.messages import AIMessageChunk
from typing import Any, Dict, Iterator, List, Optional
from langchain_core.callbacks.manager import CallbackManagerForLLMRun
from langchain_core.language_models import BaseChatModel


class CustomChatModel(BaseChatModel):
    """
    自定义一个Chat Model,在用户输入的基础上加上前缀:oh,我的天哪~
    """

    def _generate(
        self,
        messages: List[BaseMessage],
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> ChatResult:
        """
        根据用户输入,执行具体逻辑,然后返回输出
        """
        last_message = messages[-1]
        ai_message = AIMessage(content="oh,我的天哪~" + last_message.content)
        chat_generation = ChatGeneration(message = ai_message)
        return ChatResult(generations=[chat_generation])

    def _stream(
        self,
        messages: List[BaseMessage],
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> Iterator[ChatGenerationChunk]:
        """
        根据用户输入,执行具体逻辑,然后流式返回输出
        """
        last_message = messages[-1]
        tokens = last_message.content
        for token in "oh,我的天哪~" + tokens:
            chunk = ChatGenerationChunk(message=AIMessageChunk(content=token))
            if run_manager:
                run_manager.on_llm_new_token(chunk.message.content, chunk=chunk)
            yield chunk
        
        # 这里还可以添加一些其他的额外信息
        # ......

    @property
    def _identifying_params(self) -> Dict[str, Any]:
        """返回模型自定义参数字典"""
        return {
            "model_name": "Custommm",
            "model_version":"1.0.0"
        }

    @property
    def _llm_type(self) -> str:
        """获取此聊天模型使用的语言模型的类型。仅用于日志记录。"""
        return "custom"

使用方式也和其他 Chat Model 一样,我们打印一点信息看看效果。

python复制代码chat_model = CustomChatModel()

chat_model.invoke([HumanMessage(content="你好呀!")])
# AIMessage(content='oh,我的天哪~~你好呀!', id='run-e5984b0b-a18f-49f0-b82f-fd3049b37495-0')

chat_model.batch(["hello", "goodbye"])
# [AIMessage(content='oh,我的天哪~~hello', id='run-15cc053a-0832-4540-a660-5864fb7d33c1-0'),  AIMessage(content='oh,我的天哪~~goodbye', id='run-6c83c667-a5e1-4522-9ad9-a6377b44522d-0')]

for chunk in chat\_model.stream("cat"):
    print(chunk.content, end="|")
# o|h|,|我|的|天|哪|~~|c|a|t|

async for chunk in chat_model.astream("cat"):
    print(chunk.content, end="|")
# o|h|,|我|的|天|哪|~~|c|a|t|

async for event in chat_model.astream_events("cat", version="v1"):
    print(event)
# {'event': 'on_chat_model_start', 'run_id': '0a6a9864-2e9b-46ee-a9b4-6079b58199bc', 'name': 'CustomChatModel', 'tags': [], 'metadata': {}, 'data': {'input': 'cat'}}
# ......
# {'event': 'on_chat_model_end', 'name': 'CustomChatModel', 'run_id': '0a6a9864-2e9b-46ee-a9b4-6079b58199bc', 'tags': [], 'metadata': {}, 'data': {'output': AIMessageChunk(content='oh,我的天哪~~cat', id='run-0a6a9864-2e9b-46ee-a9b4-6079b58199bc')}}

09 Response metadata 与 Tracking token usage

相比于 LLM,Chat Model支持获取响应元数据。

许多模型会在在其Chat Model 模式下的响应中包含一些元数据。可以通过 AIMessage.response_metadata: Dict 属性访问此元数据。根据模型提供程序和模型配置,这可能包含令牌计数、logprob 等信息。

具体使用如下(这里以OpenAI为例):

python复制代码from langchain_openai import ChatOpenAI

llm = ChatOpenAI()
msg = llm.invoke([("human", "What's the oldest known example of cuneiform")])
msg.response_metadata

# {'token_usage': {'completion_tokens': 164,
#  'prompt_tokens': 17,
#  'total_tokens': 181},
# 'model_name': 'gpt-4-turbo',
# 'system_fingerprint': 'fp_76f018034d',
# 'finish_reason': 'stop',
# 'logprobs': None}

从结果中,我们可以看到 token 的使用情况。

10 总结

做个总结吧,这篇主要是对Model I/O中的 Chat Model 组件进行详细解析。

我们介绍了 Chat Model 组件是什么,与 LLM 组件有什么不同;我们查看了目前 LangChain 框架中支持的所有 Chat Model;我们知道如何使用 Chat Model;我们还能自定义自己的 Chat Model;我们知道 Chat Model 与 LLM 一样都能设置缓存;我们知道所谓的Tool/Function Calling与Structured Output只能在 Chat Model 组件下使用;我们还能通过查看元数据信息,了解 Chat Model 的执行token使用情况等等。

那么,我们该如何学习大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

一、大模型全套的学习路线

学习大型人工智能模型,如GPT-3、BERT或任何其他先进的神经网络模型,需要系统的方法和持续的努力。既然要系统的学习大模型,那么学习路线是必不可少的,下面的这份路线能帮助你快速梳理知识,形成自己的体系。

L1级别:AI大模型时代的华丽登场

L2级别:AI大模型API应用开发工程

L3级别:大模型应用架构进阶实践

L4级别:大模型微调与私有化部署

一般掌握到第四个级别,市场上大多数岗位都是可以胜任,但要还不是天花板,天花板级别要求更加严格,对于算法和实战是非常苛刻的。建议普通人掌握到L4级别即可。

以上的AI大模型学习路线,不知道为什么发出来就有点糊,高清版可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

  • 13
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值