7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【LangChain】リクエスト前にトークン数を確認するには

Last updated at Posted at 2023-05-20

トークン数が上限に到達すると困ったことになります。
リクエストを行う前にメッセージリストのトークン数を確認したい時、ありますよね。
それも、お金をかけずに。

忙しい人向け: 結論へジャンプ

トークン数には上限がある

しかも、往復の合計トークン数を上限以下にしなければならない

リクエスト時のトークン数は、AIの回答(レスポンス)のトークン数も考慮しておく必要があります。

例えば、gpt-3.5-turboの上限は4096トークンです。
回答で600トークン程度消費するならば、リクエスト時のトークン数は3500トークン程度になるようした方が良いでしょう。

API Reference - OpenAI API
https://platform.openai.com/docs/models/gpt-3-5
https://platform.openai.com/docs/api-reference/chat

リクエスト時にトークン数を消費しすぎると?

レスポンス用にトークン数を残しておかないと、レスポンス時にAIの回答が期待通りになりません。
途切れたり、空になります。

トークン数上限を超えてリクエストすると、例外が発生する

そもそも上限近くのリクエストをしたところで、期待通りの回答は得られませんが、一応紹介しておきます。

トークン数上限を超えたメッセージリストをリクエストすると、例外が発生します。

例えば、以下のようなコードでトークン数上限を超えた8814トークンでリクエストしようとすると、例外が発生します。やばいよ。

以下のコードは、.envファイルにOPENAI_API_KEY="OpenAI APIキー"を設定している前提です。

import dotenv
from langchain.schema import (
    AIMessage,
    HumanMessage,
    SystemMessage,
)
from langchain.chat_models import ChatOpenAI
dotenv.load_dotenv()
messages = [
    [
        SystemMessage(content="振る舞いなどを記述したプロンプト"),
        HumanMessage(content="スーパー長い文章"),
        AIMessage(content="それっぽいAIの回答のキッカケとか"),
    ],
]
chat = ChatOpenAI()
response = chat.generate(messages)
This model's maximum context length is 4097 tokens. However, your messages resulted in 8814 tokens. Please reduce the length of the messages.

リクエスト前にメッセージリストのトークン数を確認するには

get_num_tokens_from_messages()メソッドで確認できた

ふとライブラリの実装を見に行くと、ChatOpenAIクラスの中に使えそうなメソッドがありました。

それがget_num_tokens_from_messages()メソッドです。

このメソッドでは、トークン数を内部的に算出しているので、API利用料はかかりません。

例えば、先述のコードに、送信予定のトークン数で処理を分岐するような実装を追加するならば、以下のようになります。

import dotenv
from langchain.schema import (
    AIMessage,
    HumanMessage,
    SystemMessage,
)
from langchain.chat_models import ChatOpenAI
dotenv.load_dotenv()
messages = [
    [
        SystemMessage(content="振る舞いなどを記述したプロンプト"),
        HumanMessage(content="スーパー長い文章"),
        AIMessage(content="それっぽいAIの回答のキッカケとか"),
    ],
]
chat = ChatOpenAI()
token_size = chat.get_num_tokens_from_messages(messages=messages[0])
token_limit = 4096 - 800    # 復路のトークン数を確保するため減算
if token_size <= token_limit:
    response = chat.generate(messages)
else:
    print(f"トークン数が多すぎます。トークン数: {token_size}")
トークン数が多すぎます。トークン数: 8814

get_num_tokens_from_messages()メソッドは、ライブラリ内部で呼び出されるメソッドとして用意されているようです。
このメソッドをライブラリ外から呼び出すことについて、それが推奨されている行為か否かは確認していません。
使用する場合は自己責任で。

hwchase17/langchain/langchain/chat_models/openai.py - GitHub
https://github.com/hwchase17/langchain/blob/master/langchain/chat_models/openai.py

あとがき

自前でtiktokenを用いたトークンカウンタなどを作ったりしていましたが、算出されるトークン数が実際のトークン数と中々合わずに苦戦していました。
これで要約系の実装が捗るぜ。

参考

hwchase17 / langchain
https://github.com/hwchase17/langchain

LangChain Docs
https://python.langchain.com/en/latest/index.html

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?