# 利用Langchain高效管理消息上下文窗口
## 引言
在使用大型语言模型时,我们经常面临上下文窗口限制的问题。为了保证模型的输入不超出其处理能力,需要对过长的消息进行裁剪。这篇文章将介绍如何使用Langchain的`trim_messages`工具,有效管理消息的长度,以确保它们适配模型的上下文窗口。
## 主要内容
### 理解上下文窗口
所有大型语言模型都有有限的上下文窗口,即它们能够接受的最大token数量。当消息过长时,我们必须裁剪这些消息,使其符合模型的上下文限制。
### 使用`trim_messages`工具
`trim_messages`工具提供了一些基础策略来裁剪消息列表,使其符合特定token长度。
#### 获取最后的`max_tokens`
通过设置`strategy="last"`,我们可以从消息列表的末尾获取指定数量的tokens:
```python
# pip install -U langchain-openai
from langchain_core.messages import (
AIMessage,
HumanMessage,
SystemMessage,
trim_messages,
)
from langchain_openai import ChatOpenAI
messages = [
SystemMessage("you're a good assistant, you always respond with a joke."),
HumanMessage("i wonder why it's called langchain"),
AIMessage("Well, I guess they thought 'WordRope' and 'SentenceString' just didn't have the same ring to it!"),
HumanMessage("and who is harrison chasing anyways"),
AIMessage("Hmmm let me think.\n\nWhy, he's probably chasing after the last cup of coffee in the office!"),
HumanMessage("what do you call a speechless parrot"),
]
trimmed_messages = trim_messages(
messages,
max_tokens=45,
strategy="last",
token_counter=ChatOpenAI(model="gpt-4o"),
)
print(trimmed_messages)
# 使用API代理服务提高访问稳定性
保留系统消息
通过设置include_system=True,可以确保系统消息始终被保留下来:
trimmed_messages_with_system = trim_messages(
messages,
max_tokens=45,
strategy="last",
token_counter=ChatOpenAI(model="gpt-4o"),
include_system=True,
)
print(trimmed_messages_with_system)
自定义token计数器
我们可以编写自定义的token计数器函数,来处理不同类型的消息:
from typing import List
import tiktoken
from langchain_core.messages import BaseMessage
def str_token_counter(text: str) -> int:
enc = tiktoken.get_encoding("o200k_base")
return len(enc.encode(text))
def tiktoken_counter(messages: List[BaseMessage]) -> int:
num_tokens = 3 # 每条消息的初始token数量
tokens_per_message = 3
for msg in messages:
if isinstance(msg, HumanMessage):
role = "user"
elif isinstance(msg, AIMessage):
role = "assistant"
elif isinstance(msg, SystemMessage):
role = "system"
else:
raise ValueError(f"Unsupported messages type {msg.__class__}")
num_tokens += tokens_per_message + str_token_counter(msg.content)
return num_tokens
trimmed_custom_counter_messages = trim_messages(
messages,
max_tokens=45,
strategy="last",
token_counter=tiktoken_counter,
)
print(trimmed_custom_counter_messages)
常见问题和解决方案
如何处理不同类型的消息?
确保定制的token计数器能够正确识别和处理所有消息类型。
如果网络访问受限怎么办?
由于某些地区的网络限制,开发者在使用API时可能需要考虑使用API代理服务以提高访问稳定性。
总结和进一步学习资源
使用Langchain的trim_messages工具,可以灵活裁剪消息,使其符合模型的上下文限制。通过理解消息裁剪策略,定制token计数器,开发者能够更高效地利用模型的上下文能力。
参考资料
- Langchain GitHub文档: Langchain on GitHub
- 用于计算token的
tiktoken库: tiktoken - Langchain核心API参考: API Reference
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---