kmail.at
← learning

langchain · difficulty ◆◆

Deterministic Token Counting

Stable, consistent token counts for tools in your chains.

Identical schemas were returning different counts. Now they do not.

2026-07-25 · 6 min read

$ count_tokens_approximately(messages)

What it does

count_tokens_approximately is LangChain’s approximate token counter used for prompting, cost estimation, and context management. The bug fix in langchain-core 1.5.1 (PR #39020) corrects how tool_call_schema is cached when counting tokens for BaseTool objects. Before the fix, BaseTool token counts could be inaccurate or recomputed on every call due to a stale or missing cache lookup. After it, the cache is used correctly, making counts consistent and faster for tools in AgentExecutor or ToolCallingAgent chains.

Why it matters

If your tool-augmented agent shows fluctuating token counts, or seems to blow past context windows on simple calls, this fix targets exactly that. Tools defined via BaseTool or @tool now cache their schema properly so token counting is deterministic and efficient. It matters most when you have many tools in one agent, run agents in production tracking per-call cost, or debug context-length issues in complex multi-tool chains.

Example

$ @tool
def get_weather(city: str) -> str:
    """Get the current weather for a given city."""
    return f"The weather in {city} is sunny."

tokens_1 = count_tokens_approximately([HumanMessage(content=get_weather.description)])
print(f"First call tokens: {tokens_1}")
tokens_2 = count_tokens_approximately([HumanMessage(content=get_weather.description)])
print(f"Second call tokens (cached): {tokens_2}")
tool_call_msg = ToolMessage(name="get_weather", content="The weather in Vienna is sunny.", tool_call_id="abc123")
print(f"Tool-use call tokens: {count_tokens_approximately([HumanMessage(content="What’s the weather?"), tool_call_msg])}")
First call tokens: 12
Second call tokens (cached): 12
Tool-use call tokens: 18

Token counts are approximate and model-dependent. The key is consistency: identical tool schemas now return identical counts.

Common flags

count_tokens_approximately()
Approximate token counter for messages/tools
@tool decorator
Converts a Python function into a LangChain BaseTool
tool_call_schema
Property on BaseTool returning the cached JSON schema

History

A stale-cache bug

Prior to langchain-core 1.5.1, consecutive calls with identical tool schemas could return different counts because the cache lookup was stale or missing. PR #39020 wired the tool_call_schema cache into the counting path, restoring determinism.

Fun facts

Pros & cons

pros

  • + Stable counts for identical input
  • + Lower per-call latency
  • + Reliable cost estimation

cons

  • − Bug fix only, no feature
  • − Requires langchain-core 1.5.1+

Takeaways

  1. 1Identical tool schemas now return identical counts.
  2. 2Upgrade langchain-core to 1.5.1.
  3. 3Profile your agent token usage after upgrading.

Related commands

← all learning