Skip to content

Conversation

seunggil1
Copy link

@seunggil1 seunggil1 commented Sep 2, 2025

Why are these changes needed?

1. OpenAIChatCompletionClient.count_tokens (from autogen_ext.models.openai) ignores several JSON Schema fields of Tools (e.g., anyOf, default, title), printing Not supported field ... warnings and producing consistent gaps between the pre-send estimate and usage.prompt_tokens.

Autogen Tool description example

def tool3(
        test1: Annotated[Optional[str], "example"] = None,
        test2: Literal["1", "2"] = "2"
) -> str:
    return str(test1) + str(test2)

tools = [ FunctionTool(tool3, description="example tool 3") ]
client.count_tokens(messages, tools=tools)

Printed warning log

Not supported field anyOf
Not supported field default
Not supported field title

Changes

  • Add anyOf, default, title in count_tokens_openai
elif field == "anyOf":
    tool_tokens -= 3
    for o in v["anyOf"]:
        tool_tokens += 3
        tool_tokens += len(encoding.encode(o["type"]))
elif field == "default":
    tool_tokens += 2
    tool_tokens += len(encoding.encode(json.dumps(v["default"])))
elif field == "title":
    tool_tokens += 2
    tool_tokens += len(encoding.encode(v["title"]))

Limitations

  • This change reduces—but does not eliminate—the discrepancy between estimated token counts and actual usage.
  • I don't currently know the exact logic behind counting message tokens in the count_tokens_openai function, so I just made it similar to other fields.

2. In actual requests, Autogen omits the tools parameter when no tools are provided. But the current implementation adds +12 unconditionally, which overcounts tokens for tool-less calls.

# num_tokens += 12 # before
 if oai_tools:     # changed
    num_tokens += 12
return num_tokens
  • Difference in results before / after modification
messages = [UserMessage(content="What is the current time in Seoul?", source="user")]
model_client = OpenAIChatCompletionClient(model="gpt-4o")
token_estimate = model_client.count_tokens(messages=messages)

create_result = await model_client.create(
    messages=messages,
    cancellation_token=ctx.cancellation_token,
)
token_usage = create_result.usage.prompt_tokens

if token_usage != token_estimate:
    print(f"Token usage mismatch: estimated {token_estimate}, actual {token_usage}")
# before
Token usage mismatch: estimated 29, actual 16
# after
Token usage mismatch: estimated 17, actual 16

Related issue number

Closes #6980

Checks

@seunggil1
Copy link
Author

@microsoft-github-policy-service agree

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OpenAIChatCompletionClient.count_tokens undercounts due to missing Tool-schema fields and emits Not supported field warnings
1 participant