Chat Models
聊天模型是一种语言模型,它使用聊天消息作为输入并返回聊天消息作为输出(而不是使用纯文本)。
聊天模型是语言模型的变体。
关键问题:
- 如何缓存ChatModel响应
- 如何使用支持函数调用的ChatModels
- 如何从ChatModel流式传输响应
- 如何跟踪ChatModel调用中的令牌使用情况
- 如何自定义ChatModel
Function calling
- 函数调用
函数调用对于构建使用工具的链和代理以及更普遍地从模型中获取结构化输出非常有用。
LangChain附带了许多实用程序来简化函数调用。即,langchain带有:
- 将函数绑定到模型的简单语法
- 用于将各种类型的对象格式化为预期函数模式的转换器
- 用于从 API 响应中提取函数调用的输出解析器
- 用于从模型获取结构化输出的链,构建在函数调用之上
Binding functions
许多模型实现了帮助器方法,这些方法将负责格式化不同的类似函数的对象并将其绑定到模型。
ChatOpenAI.bind_tools(Multiply)
方法来处理转换 Multiply
为 OpenAI 函数并将其绑定到模型
Defining functions schemas
- 定义函数模式
如果需要直接访问函数模式,LangChain 有一个内置转换器,可以将 Python 函数、Pydantic 类和 LangChain Tools 转换为 OpenAI 格式的 JSON 模式:
Python function
import json
from langchain_core.utils.function_calling import convert_to_openai_tool
def multiply(a: int, b: int) -> int:
"""Multiply two integers together.
Args:
a: First integer
b: Second integer
"""
return a * b
print(json.dumps(convert_to_openai_tool(multiply), indent=2))
Pydantic class
from langchain_core.pydantic_v1 import BaseModel, Field
class multiply(BaseModel):
"""Multiply two integers together."""
a: int = Field(..., description="First integer")
b: int = Field(..., description="Second integer")
print(json.dumps(convert_to_openai_tool(multiply), indent=2))
- 在 pydantic 中定义对象的主要方法是通过模型(模型继承 BaseModel )。pydantic主要是一个解析库,而不是验证库。验证是达到目的的一种手段:建立一个符合所提供的类型和约束的模型。
- 换句话说,pydantic保证输出模型的类型和约束,而不是输入数据。
- 虽然验证不是pydantic的主要目的,但您可以使用此库进行自定义验证。
LangChain Tool
from typing import Any, Type
from langchain_core.tools import BaseTool
class MultiplySchema(BaseModel):
"""Multiply tool schema."""
a: int = Field(..., description="First integer")
b: int = Field(..., description="Second integer")
class Multiply(BaseTool):
args_schema: Type[BaseModel] = MultiplySchema
name: str = "multiply"
description: str = "Multiply two integers together."
def _run(self, a: int, b: int, **kwargs: Any) -> Any:
return a * b
# Note: we're passing in a Multiply object not the class itself.
print(json.dumps(convert_to_openai_tool(Multiply()), indent=2))
Caching
- 缓存
LangChain为聊天模型提供了可选的缓存层。
- 如果经常进行多次请求相同的完成,它可以通过减少对LLM提供商的API调用次数
- 可以通过减少对LLM提供商的API调用次数来加快申请次数
from langchain.globals import set_llm_cache
from langchain_openai import ChatOpenAI
llm = ChatOpenAI()
In Memory Cache
- 内存缓存
%%time
from langchain.cache import InMemoryCache
set_llm_cache(InMemoryCache())
# 第一次,还没有在缓存中,所以应该需要更长的时间
llm.predict("Tell me a joke")
CPU times: user 17.7 ms, sys: 9.35 ms, total: 27.1 ms
Wall time: 801 ms
%%time
# The second time it is, so it goes faster
llm.predict("Tell me a joke")
CPU times: user 1.42 ms, sys: 419 µs, total: 1.83 ms
Wall time: 1.83 ms
SQLite Cache
- SQLite 缓存
使用SQLite缓存做相同的事情
!rm .langchain.db
# We can do the same thing with a SQLite cache
from langchain.cache import SQLiteCache
set_llm_cache(SQLiteCache(database_path=".langchain.db"))
%%time
# The first time, it is not yet in cache, so it should take longer
llm.predict("Tell me a joke")
%%time
# The second time it is, so it goes faster
llm.predict("Tell me a joke")
Custom Chat Model
- 学习如何使用 LangChain 抽象创建自定义聊天模型。
用标准ChatModel
接口包装LLM,LLM将自动成为LangChain Runnable,并将受益于一些开箱即用的优化(例如,通过线程池批处理)、支持异步、 astream_events
API等等。
Inputs and outputs
Messages
聊天模型将消息作为输入并返回消息作为输出。
LangChain有一些内置的消息类型:
SystemMessage
:用于启动 AI 行为,通常作为输入消息序列中的第一个传入。HumanMessage
:表示来自与聊天模型交互的人的消息。AIMessage
:代表来自聊天模型的消息。这可以是文本,也可以是调用工具的请求。FunctionMessage
/ToolMessage
:用于将工具调用结果传递回模型的消息。
from langchain_core.messages import (
AIMessage,
BaseMessage,
FunctionMessage,
HumanMessage,
SystemMessage,
ToolMessage,
)
Streaming Variant
- 流媒体版本
所有聊天消息都有一个流变体,名称中包含 Chunk。
from langchain_core.messages import (
AIMessageChunk,
FunctionMessageChunk,
HumanMessageChunk,
SystemMessageChunk,
ToolMessageChunk,
)
这些块在从聊天模型流式输出时使用,它们都定义了附加属性。
Simple Chat Model
继承SimpleChatModel
对于原型设计非常有用,但不允许实现您可能想要从聊天模型中获得的所有功能,但它实现起来很快,如果您需要更多功能,您可以过渡到BaseChatModel
。
Base Chat Model
Identifying Params
- 识别参数
LangChain 有一个回调系统,允许实现记录器来监控 LLM 应用程序的行为。
Streaming
所有 ChatModel 都实现 Runnable 接口,该接口附带所有方法的默认实现,即。ainvoke、批处理、abatch、流、astream。这为所有 ChatModel 提供了对流的基本支持。
流支持默认返回单个值的迭代器(或异步流情况下的 AsyncIterator),即底层 ChatModel 提供程序返回的最终结果。这显然不会为您提供逐个令牌的流式传输,这需要 ChatModel 提供商的本机支持,但确保需要令牌迭代器的代码可以适用于我们的任何 ChatModel 集成。
Tracking token usage
- 跟踪令牌使用情况
目前仅针对OpenAI API实现
from langchain.callbacks import get_openai_callback
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model_name="gpt-4")
with get_openai_callback() as cb:
result = llm.invoke("Tell me a joke")
print(cb)
上下文管理器内的任何内容都会被跟踪。以下是使用它按顺序跟踪多个呼叫的示例。
with get_openai_callback() as cb:
result = llm.invoke("Tell me a joke")
result2 = llm.invoke("Tell me a joke")
print(cb.total_tokens)
如果使用包含多个步骤的链或代理,它将跟踪所有这些步骤。
from langchain.agents import AgentType, initialize_agent, load_tools
from langchain_openai import OpenAI
tools = load_tools(["serpapi", "llm-math"], llm=llm)
agent = initialize_agent(tools, llm, agent=AgentType.OPENAI_FUNCTIONS, verbose=True)
with get_openai_callback() as cb:
response = agent.run(
"Who is Olivia Wilde's boyfriend? What is his current age raised to the 0.23 power?"
)
print(f"Total Tokens: {cb.total_tokens}")
print(f"Prompt Tokens: {cb.prompt_tokens}")
print(f"Completion Tokens: {cb.completion_tokens}")
print(f"Total Cost (USD): ${cb.total_cost}")