chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
dotnet-build-and-test / dotnet-test-functions (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-foundry-hosted-it (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
dotnet-build-and-test / Integration Test Report (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
dotnet-build-and-test / dotnet-test-functions (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-foundry-hosted-it (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
dotnet-build-and-test / Integration Test Report (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
# /// script
|
||||
# requires-python = ">=3.10"
|
||||
# dependencies = [
|
||||
# "agent-framework-core",
|
||||
# "tiktoken",
|
||||
# ]
|
||||
# ///
|
||||
# Run with: uv run samples/02-agents/compaction/tiktoken_tokenizer.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
from typing import Any
|
||||
|
||||
import tiktoken # type: ignore
|
||||
from agent_framework import (
|
||||
Message,
|
||||
TokenizerProtocol,
|
||||
TruncationStrategy,
|
||||
annotate_message_groups,
|
||||
apply_compaction,
|
||||
included_token_count,
|
||||
)
|
||||
|
||||
"""This sample demonstrates a custom TokenizerProtocol implementation with tiktoken.
|
||||
|
||||
Key components:
|
||||
- `TiktokenTokenizer` backed by `tiktoken`
|
||||
- Token-based `TruncationStrategy` (`max_n` / `compact_to`)
|
||||
- Inspecting projected roles and remaining included token count
|
||||
"""
|
||||
|
||||
|
||||
class TiktokenTokenizer(TokenizerProtocol):
|
||||
"""TokenizerProtocol implementation backed by tiktoken's o200k_base (gpt-4.1 and up default) encoding."""
|
||||
|
||||
def __init__(self, *, encoding_name: str = "o200k_base", model: str | None = None) -> None:
|
||||
if model is not None:
|
||||
self._encoding = tiktoken.encoding_for_model(model)
|
||||
else:
|
||||
self._encoding: Any = tiktoken.get_encoding(encoding_name)
|
||||
|
||||
def count_tokens(self, text: str) -> int:
|
||||
return len(self._encoding.encode(text))
|
||||
|
||||
|
||||
def _build_messages() -> list[Message]:
|
||||
return [
|
||||
Message(role="system", contents=["You are a migration assistant."]),
|
||||
Message(
|
||||
role="user",
|
||||
contents=["List all migration risks and include detailed mitigations for each risk category."],
|
||||
),
|
||||
Message(
|
||||
role="assistant",
|
||||
contents=[
|
||||
(
|
||||
"Primary risks include schema drift, missing foreign key constraints, "
|
||||
"and data quality regressions. Mitigations include staged validation, "
|
||||
"shadow writes, and replay-based verification."
|
||||
)
|
||||
],
|
||||
),
|
||||
Message(
|
||||
role="user",
|
||||
contents=[("Now provide a detailed checklist with owners, rollback gates, and validation criteria.")],
|
||||
),
|
||||
Message(
|
||||
role="assistant",
|
||||
contents=[
|
||||
(
|
||||
"Checklist: baseline snapshots, migration dry-run, production "
|
||||
"canary, progressive deployment, automated integrity checks, and "
|
||||
"post-migration reconciliation."
|
||||
)
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
# 1. Create a tokenizer implementation that uses tiktoken.
|
||||
tokenizer = TiktokenTokenizer()
|
||||
|
||||
# 2. Configure token-based truncation.
|
||||
strategy = TruncationStrategy(
|
||||
max_n=250,
|
||||
compact_to=150,
|
||||
tokenizer=tokenizer,
|
||||
preserve_system=True,
|
||||
)
|
||||
|
||||
# 3. Build conversation and measure token count before compaction.
|
||||
messages = _build_messages()
|
||||
annotate_message_groups(messages, tokenizer=tokenizer)
|
||||
token_count_before = included_token_count(messages)
|
||||
|
||||
# 4. Apply compaction and measure token count after compaction.
|
||||
projected = await apply_compaction(messages, strategy=strategy, tokenizer=tokenizer)
|
||||
token_count_after = included_token_count(messages)
|
||||
|
||||
# 5. Print before/after token counts and projected conversation.
|
||||
print(f"Projected messages: {len(projected)}")
|
||||
print(f"Included token count before compaction: {token_count_before}")
|
||||
print(f"Included token count after compaction: {token_count_after}")
|
||||
print("Projected roles:", [message.role for message in projected])
|
||||
for message in projected:
|
||||
token_count = message.additional_properties.get("_group", {}).get("token_count")
|
||||
print(f"- [{message.role}] {message.text} ({token_count} tokens)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
"""
|
||||
Projected messages: 3
|
||||
Included token count before compaction: 263
|
||||
Included token count after compaction: 149
|
||||
Projected roles: ['system', 'user', 'assistant']
|
||||
- [system] You are a migration assistant. (40 tokens)
|
||||
- [user] Now provide a detailed checklist with owners, rollback gates, and validation criteria. (49 tokens)
|
||||
- [assistant] Checklist: baseline snapshots, migration dry-run, production canary,
|
||||
progressive deployment, automated integrity checks, and post-migration reconciliation. (60 tokens)
|
||||
"""
|
||||
Reference in New Issue
Block a user