토큰 카운터
토큰 카운터 (Token Counters)
토큰 카운터는 ChatMessage 객체 리스트와 선택적 도구 스키마가 차지하는 토큰 수를 추정해요. 대화를 모델로 보내기 전에 그 크기를 알아야 할 때 유용해요. 예를 들어 대화가 모델의 컨텍스트 윈도우에 들어맞는지 확인하거나, 얼마만큼의 컨텍스트를 제거할지 결정할 때 말이죠.
출처: 공식문서
Haystack은 TokenCounter 프로토콜과 세 가지 내장 구현, 그리고 통합(integration)에서 제공하는 provider별 구현을 함께 제공해요.
| 카운터 | 텍스트를 세는 방식 | 추가 의존성 | 가장 잘 맞는 경우 |
|---|---|---|---|
ApproximateTokenCounter |
렌더링된 텍스트 길이를 설정 가능한 characters-per-token 비율로 나눔 | 없음 | 빠르고 의존성이 없는 추정 |
TiktokenCounter |
OpenAI의 tiktoken 바이트-페어 인코더 사용 |
tiktoken |
OpenAI 모델에 더 정확한 추정 |
OpenAITokenCounter |
OpenAI의 input token counting API 호출 | OpenAI API 키 | 이미지·파일·도구 포함, 모델별 정확한 카운트 |
AnthropicTokenCounter |
Anthropic의 token counting API 호출 | anthropic-haystack 패키지와 Anthropic API 키 |
Claude 모델에 대한 모델별 정확한 카운트 |
GoogleGenAITokenCounter |
Google의 token counting API 호출 | google-genai-haystack 패키지와 Google 자격증명 |
Gemini 모델에 대한 모델별 정확한 카운트 |
모든 카운터는 메시지 역할, 텍스트, 도구 호출, 도구 결과, 선택적 도구 스키마를 포함해요. 로컬 카운터는 설정 가능한 고정 비율(flat rates)로 이미지와 파일을 계산하고, 도구 결과에 중첩된 이미지·파일도 포함해요. OpenAITokenCounter, AnthropicTokenCounter, GoogleGenAITokenCounter는 지원되는 non-text 콘텐츠를 provider로 보내 모델별 카운트를 얻어요.
모든 생성자 파라미터와 메서드는 Token Counters API 레퍼런스를 참고하세요.
도구 스키마 세기
도구 스키마는 메시지와 함께 모델로 전송되고 컨텍스트 토큰을 소비해요. 추정에 도구 스키마를 포함하려면 count()에 도구를 전달하세요.
from typing import Annotated
from haystack.dataclasses import ChatMessage
from haystack.token_counters import ApproximateTokenCounter
from haystack.tools import tool
@tool
def search(query: Annotated[str, "The search query"]) -> str:
"""Search for documents that match the query."""
return "Search results"
messages = [ChatMessage.from_user("Find information about Haystack.")]
counter = ApproximateTokenCounter()
token_count = counter.count(messages, tools=[search])
메시지 없이 도구 스키마만 셀 수도 있어요. counter.count([], tools=[search])처럼 호출하면 돼요.
이미지와 파일
이미지와 파일은 휴대 가능한 텍스트 기반 토큰 카운트가 없어요. 각 토큰 카운터는 사용하는 토크나이저나 provider에 따라 다르게 처리해요.
사용 중인 카운터의 문서에서 non-text 콘텐츠를 어떻게 세는지, 설정이 필요한지 확인하세요. ApproximateTokenCounter, TiktokenCounter, OpenAITokenCounter, AnthropicTokenCounter, GoogleGenAITokenCounter 문서를 참고하면 돼요.
커스텀 토큰 카운터 만들기
provider의 토큰 카운팅 엔드포인트를 사용하는 것처럼 다른 카운팅 동작이 필요하면 TokenCounter 프로토콜을 구현하세요. 커스텀 구현은 count()와 to_dict() 메서드를 제공해야 해요. 기본 from_dict() 구현은 평범한 생성자 값을 복원해요.
from typing import Any
from haystack.core.serialization import default_to_dict
from haystack.dataclasses import ChatMessage
from haystack.token_counters import TokenCounter
from haystack.tools import ToolsType
class ProviderTokenCounter(TokenCounter):
def count(
self,
messages: list[ChatMessage],
tools: ToolsType | None = None,
) -> int:
# Call the provider's token-counting endpoint here.
...
def to_dict(self) -> dict[str, Any]:
return default_to_dict(self)
to_dict()가 Secret이나 중첩 컴포넌트처럼 생성자에 넘기기 전에 재구성해야 할 값을 직렬화한다면 from_dict()를 오버라이드하세요.