ms-ai-architect/skills/ms-ai-security/references/cost-optimization/token-counting-optimization.md
Kjell Tore Guttormsen ddce43d8b2 feat(ms-ai-architect): Spor 1 — Port-1-substrat migrert på 4 ikke-advisor-skills (243 Source + 327 Type + 325 TOC + stale-verified poison fjernet) [skip-docs]
Steg 9 (R4): unified migrate-corpus.mjs --write over engineering/governance/
infrastructure/security. 327 filer mutert, verified=null, prosa byte-identisk
(fra første ## seksjon), advisor urørt (0 endringer).

To applier-fixes oppdaget under kjøring (TDD, RED→GREEN):
- insertHeaderFields: anker faller nå tilbake når en meta-linje selv passerer
  500B (2 filer pakket et avsnitt i **Status:** → Type/Source landet utenfor
  scan-vinduet, applierens post-write-assertion fanget + restaurerte).
- normalizeStaleVerified: fjerner nå ALLE stale non-date **Verified:** i
  500B-vinduet, inkl. stray body-dup rett under --- (9 mlops-genaiops-filer var
  ellers falskt "verified"/fresh, droppet fra worklist). Operatør-godkjent
  utvidelse av carve-out; kun stray metadata-linjer, aldri prosa.

test-transform-criterion: precondition oppdatert til post-migrasjons-sannhet
(fila bærer nå Source). Suite 728/728 grønn.
2026-07-04 10:19:11 +02:00

612 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Token Counting and Optimization Strategies
**Last updated:** 2026-06
**Status:** GA
**Category:** Cost Optimization & FinOps for AI
**Type:** reference
**Source:** https://learn.microsoft.com/azure/foundry/concepts/manage-costs
---
## Innhold
- [Introduksjon](#introduksjon)
- [Kjernekomponenter](#kjernekomponenter)
- [Arkitekturmønstre](#arkitekturmønstre)
- [Beslutningsveiledning](#beslutningsveiledning)
- [Integrasjon med Microsoft-stakken](#integrasjon-med-microsoft-stakken)
- [Offentlig sektor (Norge)](#offentlig-sektor-norge)
- [Kostnad og lisensiering](#kostnad-og-lisensiering)
- [For arkitekten (Cosmo)](#for-arkitekten-cosmo)
- [Kilder og verifisering](#kilder-og-verifisering)
## Introduksjon
Token counting og optimization er fundamentale teknikker for å kontrollere kostnader i Azure OpenAI og andre LLM-baserte løsninger. Siden fakturering baserer seg på antall tokens (både input og output), er presis måling og aktiv reduksjon av token-forbruk kritisk for økonomisk bærekraft — spesielt i høyvolum-scenarier.
**Hovedpoeng:**
- Tokens er basisenheten for prosessering — typisk ~4 tegn per token i engelsk tekst
- Kostnader påløper for både input-tokens (prompt) og output-tokens (completion)
- Ulike modeller har ulik pris per 1M tokens (typisk $2-100 USD / 1M tokens avhengig av modell)
- Prompt caching, context management og compression kan redusere kostnader med 50-90%
**Confidence:** High (basert på offisiell Microsoft-dokumentasjon)
---
## Kjernekomponenter
### Token Counting Tools
| Verktøy | Språk | Bruksområde | Nøyaktighet |
|---------|-------|-------------|-------------|
| **tiktoken** | Python, JS | OpenAI-modeller (GPT-4o, o1, o3, etc.) | Eksakt for støttede modeller |
| **Microsoft.ML.Tokenizers** | .NET/C# | Cross-model tokenisering, BPE, Tiktoken | Eksakt |
| **Hugging Face Tokenizers** | Python, JS, Java | Åpen-modell-tokenisering | Varierer per modell |
### tiktoken — Azure OpenAI Standard
```python
import tiktoken
# Encoding for GPT-4o og nyere modeller
encoding = tiktoken.get_encoding("o200k_base") # Default for gpt-4o, o1, o3
tokens = encoding.encode("Tell me about Azure AI")
token_count = len(tokens)
# Model-spesifikk encoding
try:
encoding = tiktoken.encoding_for_model("gpt-4o")
except KeyError:
encoding = tiktoken.get_encoding("o200k_base")
```
**Message Overhead Calculation:**
```python
def num_tokens_from_messages(messages, model="gpt-4o"):
"""Return the number of tokens used by a list of messages."""
try:
encoding = tiktoken.encoding_for_model(model)
except KeyError:
encoding = tiktoken.get_encoding("o200k_base")
if model in {"gpt-4o", "gpt-4o-mini", "gpt-5", "gpt-4.1", "o1", "o1-mini", "o3", "o3-mini", "o4-mini"}:
tokens_per_message = 3
tokens_per_name = 1
num_tokens = 0
for message in messages:
num_tokens += tokens_per_message
for key, value in message.items():
num_tokens += len(encoding.encode(value))
if key == "name":
num_tokens += tokens_per_name
num_tokens += 3 # every reply is primed with <|start|>assistant<|message|>
return num_tokens
```
### Microsoft.ML.Tokenizers (.NET)
```csharp
using Microsoft.ML.Tokenizers;
// Installer pakker:
// dotnet add package Microsoft.ML.Tokenizers
// dotnet add package Microsoft.ML.Tokenizers.Data.O200kBase
var tokenizer = Tokenizer.CreateTiktokenForModel("gpt-4o");
var tokens = tokenizer.CountTokens("Tell me about Azure AI");
// Trimming til token-limit
string TrimToTokenLimit(string text, int maxTokens, Tokenizer tokenizer)
{
var ids = tokenizer.Encode(text).Ids;
if (ids.Count <= maxTokens)
return text;
var trimmedIds = ids.Take(maxTokens).ToArray();
return tokenizer.Decode(trimmedIds);
}
```
### Token Usage Estimation (Azure OpenAI On Your Data)
> ⚠️ **On Your Data er deprecated og pensjoneres 2026-10-14.** Migrer til Foundry Agent Service + Foundry IQ for grounding. Token-estimering-metodikken under er fortsatt illustrativ for RAG-token-budsjettering.
```python
import tiktoken
class TokenEstimator(object):
GPT2_TOKENIZER = tiktoken.get_encoding("gpt2")
def estimate_tokens(self, text: str) -> int:
return len(self.GPT2_TOKENIZER.encode(text))
token_output = TokenEstimator().estimate_tokens(input_text)
```
**Merk:** On Your Data RAG har kompleks token-fordeling:
- **20% av context window** reservert for model response
- **80%** deles mellom meta prompt, spørsmål, conversation history og retrieved chunks
- User question og history: capped ved 2 000 tokens
- Retrieved documents: varierer basert på chunk size og antall retrieved chunks
---
## Arkitekturmønstre
### 1. Prompt Caching (Native Azure OpenAI)
**Automatisk aktivert for GPT-4o og nyere modeller**
| Parameter | Verdi | Effekt |
|-----------|-------|--------|
| Minimum prompt length | 1 024 tokens | Cache hit kan først oppnås |
| Granularitet | 128 tokens | Etter første 1024 tokens, cache hit per 128 tokens |
| Cache TTL (in-memory) | 5-10 min idle, max 1 time | Alle GPT-4o eller nyere |
| Cache TTL (extended) | Opptil 24 timer (`prompt_cache_retention: "24h"`) | GPT-5-serien + gpt-4.1; default 24h for nyere modeller |
| Kostnad (Standard) | 50% rabatt på cached tokens | Varierer per modell |
| Kostnad (Provisioned) | Opptil 100% rabatt | Inkludert i PTU-pris |
**Design-prinsipper:**
1. **Plasser repetitivt innhold først** — system messages, instructions, reference docs
2. **Bruk `prompt_cache_key`** for å påvirke routing og øke cache hit rate (NB: samme prefix + key over ~15 req/min → noen requests overflower til ekstra maskiner, og cache-effektiviteten faller)
3. **Unngå variasjon i første 1024 tokens** — én endring = cache miss
```python
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "Long system prompt..."}, # Cached
{"role": "user", "content": "Variable user question"}
],
extra_body={"prompt_cache_key": "my-app-v1"} # Optional routing hint
)
# Response inkluderer:
# usage.prompt_tokens_details.cached_tokens
```
**Kostnad-eksempel:**
- 10 000 requests/dag med 2 000 tokens prompt
- Uten caching: 10 000 × 2 000 = 20M input tokens/dag
- Med 90% cache hit: 10 000 × 200 + (10 000 × 1 800 × 0.5) = 11M "effective" tokens
- **Besparelse: 45% på input-kostnader**
### 2. Conversation History Management
**Problem:** Chat-applikasjoner akkumulerer context over tid → økte token costs
**Løsning:** Dynamisk trimming med preservation av system message
```python
system_message = {"role": "system", "content": "You are a helpful assistant."}
max_response_tokens = 250
token_limit = 4096
conversation = [system_message]
def manage_conversation_tokens(conversation, max_response_tokens, token_limit):
while True:
user_input = input("Q: ")
conversation.append({"role": "user", "content": user_input})
conv_tokens = num_tokens_from_messages(conversation, model="gpt-4o")
# Trim oldest messages (preserve system message)
while conv_tokens + max_response_tokens >= token_limit:
del conversation[1] # Remove oldest non-system message
conv_tokens = num_tokens_from_messages(conversation, model="gpt-4o")
response = client.chat.completions.create(
model="gpt-4o",
messages=conversation,
max_tokens=max_response_tokens
)
conversation.append({
"role": "assistant",
"content": response.choices[0].message.content
})
```
**Alternative strategier:**
- **Sliding window:** Behold kun N siste turns
- **Summarization:** Compress old history til summary
- **Session reset:** Start ny conversation ved token limit
- **Responses API:** La Azure OpenAI håndtere truncation automatisk
### 3. Space-Efficient Formatting
**Token-ineffektive formater:**
```json
{"date": "January 15, 2026"} // 7 tokens
{"date": "01/15/2026"} // 9 tokens (!)
```
**Token-effektive formater:**
```
January 15, 2026 // 5 tokens
2026-01-15 // 5 tokens
| Name | Age | Role | // Tabular > JSON
| Alice | 30 | Dev |
```
**Whitespace-regler:**
- Konsekutive whitespace = separate tokens (waste)
- Leading space on word = typisk samme token
- Bruk tabeller over verbose JSON når mulig
### 4. Max Prompt/Completion Tokens (Assistants API)
```python
run = client.beta.threads.runs.create(
thread_id=thread.id,
assistant_id=assistant.id,
max_prompt_tokens=20000, # Limit context usage
max_completion_tokens=1000, # Limit output
truncation_strategy={
"type": "last_messages",
"last_messages": 10
}
)
```
**Anbefalinger:**
- **File Search:** Min. 20 000 prompt tokens, ideelt 50 000+
- **Langvarige samtaler:** Fjern `max_prompt_tokens` limit for best quality
- **Cost-sensitive apps:** Set strict limits + handle `incomplete` status
### 5. Chunking for Embeddings & RAG
**Token-limit per chunk:**
- `text-embedding-ada-002`: 8 191 tokens
- `text-embedding-3-small/large`: 8 191 tokens
```python
from langchain.text_splitter import RecursiveCharacterTextSplitter
import tiktoken
tokenizer = tiktoken.get_encoding('cl100k_base')
def tiktoken_len(text):
tokens = tokenizer.encode(text, disallowed_special=())
return len(tokens)
# Analyze document token distribution
token_counts = [tiktoken_len(page.page_content) for page in pages]
print(f"Min: {min(token_counts)}, Avg: {sum(token_counts)/len(token_counts)}, Max: {max(token_counts)}")
# Create chunks with overlap
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # Target tokens
chunk_overlap=200, # Overlap for context
length_function=tiktoken_len
)
chunks = text_splitter.split_documents(pages)
```
### 6. Fine-Tuning Token Accounting
**Training cost formula (SFT/DPO):**
```
Cost = # training tokens × # epochs × price per token
```
> **RFT (Reinforcement Fine-Tuning)** bruker en *tidsbasert* kostnadsmodell (ikke token-basert) med per-job-tak på $5 000 — se «Fine-Tuning Costs» under.
**Token validation pre-training:**
```python
import json
import tiktoken
import numpy as np
encoding = tiktoken.get_encoding("o200k_base")
def num_tokens_from_messages(messages, tokens_per_message=3, tokens_per_name=1):
num_tokens = 0
for message in messages:
num_tokens += tokens_per_message
for key, value in message.items():
num_tokens += len(encoding.encode(value))
if key == "name":
num_tokens += tokens_per_name
num_tokens += 3
return num_tokens
# Validate training file
with open('training_set.jsonl', 'r', encoding='utf-8') as f:
dataset = [json.loads(line) for line in f]
total_tokens = [num_tokens_from_messages(ex["messages"]) for ex in dataset]
print(f"Mean: {np.mean(total_tokens)}, Median: {np.median(total_tokens)}")
print(f"p5 / p95: {np.quantile(total_tokens, 0.05)}, {np.quantile(total_tokens, 0.95)}")
```
**Token limits:**
- `gpt-4o-mini`: Training example max 64 536 tokens, input limit 128 000 tokens
- Overfør lange eksempler = feil ved training
- Kostnad: $2 per 1M training tokens (gpt-4.1 global, eksempel)
---
## Beslutningsveiledning
### Når skal du prioritere token optimization?
| Scenario | Anbefalt Tiltak | Forventet Besparelse |
|----------|-----------------|----------------------|
| **Høyvolum chatbot** (>10K requests/dag) | Prompt caching + conversation trimming | 40-60% input cost |
| **RAG-applikasjon** | Chunk size optimization + reranking | 30-50% total cost |
| **Long-context prompts** (>8K tokens) | Prompt caching + structured outputs | 50-90% input cost |
| **Multi-turn conversations** | Sliding window + summarization | 20-40% total cost |
| **Batch processing** | Global Standard deployment + compression | 10-30% total cost |
| **Fine-tuning** | Dataset pruning + epoch optimization | 30-60% training cost |
### Decision Tree: Optimization Strategy
```
Er prompt >1024 tokens og repetitiv?
├─ Ja → Implementer prompt caching (automatisk på GPT-4o+)
│ └─ Strukturer prompt med statisk innhold først
└─ Nei → Er det multi-turn conversation?
├─ Ja → Implementer conversation history trimming
│ └─ Sliding window eller summarization
└─ Nei → Er det RAG?
├─ Ja → Optimaliser chunk size + reranking
│ └─ Bruk strictness parameter
└─ Nei → Er output verbose/unstructured?
├─ Ja → Bruk structured outputs (JSON schema)
└─ Nei → Bruk space-efficient formatting (tabeller)
```
### Monitoring & Alerting
**Key metrics:**
- `prompt_tokens` / `completion_tokens` per request
- `cached_tokens` (prompt_tokens_details) — cache hit rate
- Cost per 1K tokens (varierer per model + deployment type)
- Total daily/monthly token consumption
**Azure Cost Management:**
- Filtrer på "Meter" for å se input/output tokens separat
- Filtrer på deployment tags for model-spesifikk cost
- Sett opp budgets med alerts (90% / 100% thresholds)
---
## Integrasjon med Microsoft-stakken
### Azure OpenAI Service
| Deployment Type | Input Token Pricing | Cached Token Discount | Output Token Pricing |
|----------------|---------------------|----------------------|---------------------|
| **Standard (Regional)** | $2.50-$100 per 1M | 50% rabatt | $10-$300 per 1M |
| **Global Standard** | 10-30% lavere | 50% rabatt | 10-30% lavere |
| **Provisioned (PTU)** | Inkludert i PTU | Opptil 100% rabatt | Inkludert i PTU |
**Merk:** Priser varierer betydelig per modell (gpt-4o vs. o1 vs. gpt-4.1)
### Microsoft Foundry
**Token Usage Estimation (On Your Data — deprecated, retires 2026-10-14):**
- Intent prompt: ~1 366 tokens (gjennomsnitt)
- Generation prompt: ~4 297 tokens (gjennomsnitt)
- Response: ~111 tokens (gjennomsnitt)
- Intent output: ~25 tokens (gjennomsnitt)
- **Total per request:** ~5 800 tokens
**Cost monitoring:**
1. Foundry portal → Operate → Overview → Estimated cost tile
2. Build → Models → Monitor tab → Token costs
3. Azure portal → Cost Management → Group by Meter
### Copilot Studio
- **Token-basert billing** for Generative Answers (Azure OpenAI)
- **Message-basert billing** for standard topics
- Token counting via `AI Builder credits` — prompt tokens + image/doc conversions
**Image token conversion:**
- Low-res (<512×512): 85 tokens flat
- High-res: Resize to 2048×2048, split into 512×512 tiles, 170 tokens per tile + 85 base
### Power Platform (AI Builder)
```
Token cost = Prompt tokens + completion tokens + image tokens
Image tokens (high-res) = (# tiles × 170) + 85
```
**Optimization:**
- Resize images før submission for å redusere tiles
- Bruk "low detail" setting når mulig
- Cache prompts i Power Automate flows
---
## Offentlig sektor (Norge)
### Compliance & Data Residency
**Token counting = metadata, ikke innhold:**
- Token-tellingen selv er ikke persondata
- Loggføring av token counts er OK for kostnadsoppfølging
- **Unngå:** Logging av faktisk prompt content uten GDPR-vurdering
**Anbefalt praksis:**
- Aggreger token metrics (daglig/ukentlig totals)
- Logg kun token counts, ikke text content
- Bruk Azure Monitor for telemetri (data residency i Norge)
### Kostnadsfordeling (Intern Fakturering)
**Tagging-strategi:**
```json
{
"tags": {
"cost_center": "IT-seksjonen",
"project": "Saksbehandling-AI",
"environment": "prod"
}
}
```
**Azure Cost Management:**
- Filtrer på tags for per-avdeling/prosjekt cost
- Eksporter cost data til Excel/Power BI for intern rapportering
- Bruk budgets med action groups for automatisk varsling
### Transparent kostnadsstyring
**Eksempel: Fylkeskommunal saksbehandling**
- Estimert 500 saker/dag × 10 000 tokens/sak = 5M tokens/dag
- Med prompt caching: 2.5M "effective" tokens/dag
- Kostnad (gpt-4o-mini, $0.15/$0.60 per 1M): ~$1/dag input + $3/dag output = **~$120/måned**
**Budsjettjustering:**
- Start med conservative estimates (worst case = no caching)
- Monitor faktisk forbruk over 1-2 måneder
- Juster deployment type (Standard vs. Provisioned) basert på volum
---
## Kostnad og lisensiering
### Azure OpenAI Pricing (verifisert juni 2026)
| Modell | Input (per 1M tokens) | Cached Input | Output (per 1M tokens) | Context Window |
|--------|-----------------------|--------------|------------------------|----------------|
| **gpt-5** | $1.25 | $0.125 | $10.00 | 400K |
| **gpt-5-mini** | $0.25 | — | $2.00 | 400K |
| **gpt-4o** | $2.50 | $1.25 | $10.00 | 128K |
| **gpt-4o-mini** | $0.15 | $0.075 | $0.60 | 128K |
| **o3-mini** | $1.10 | $0.55 | $4.40 | 200K |
| **gpt-4.1** | $2.00 | $0.50 | $8.00 | 128K |
**Merk:** Kanonisk prissannhet er `deterministic-cost-calculation-model.md` §1.1. Sjekk alltid [offisiell pricing page](https://azure.microsoft.com/pricing/details/cognitive-services/openai-service/) for din region.
### Fine-Tuning Costs
**Training (SFT/DPO):**
- Global Standard: $2 per 1M tokens (gpt-4.1, eksempel)
- Developer (spot): 50% rabatt, kan bli paused/resumed
**Training (RFT — Reinforcement Fine-Tuning):**
- Tidsbasert, IKKE token-basert: `pris = treningstid (timer) × timepris + grader-inferencing-tokens (hvis model-grader brukes)`
- Timepris: ~$100/time core training for `o4-mini-2025-04-16` (eksempel; se pricing-side for gjeldende sats)
- **Per-job-tak: $5 000** — når taket nås pauses training og et deploybart checkpoint opprettes; du kan validere og resume (videre billing uten pristak)
- Ingen kostnad for kø, failed jobs eller jobber kansellert før training starter; ved kansellering belastes arbeid frem til siste checkpoint
- Kostnadskontroll: `reasoning_effort=Low`, begrens validering/`eval_samples`, velg minste grader-modell, juster `compute_multiplier`
**Hosting:**
- $1.70/time per deployment (Standard/Global Standard)
- Påløper selv om modellen ikke brukes
- **VIKTIG:** Slett ubrukte deployments for å unngå "idle hosting cost"
**Inference:**
- Samme per-token pris som base model + hosting fee
- Developer tier: Ingen hosting fee, men deployment auto-deletes etter 24 timer
### Provisioned Throughput (PTU)
- **Flat månedlig kostnad** basert på antall PTUs
- Input/output tokens inkludert (ingen per-token cost)
- Prompt caching: Opptil 100% rabatt (effektivt "gratis" cached tokens)
- **Break-even:** Typisk ~50M tokens/måned (varierer per modell)
---
## For arkitekten (Cosmo)
### Når anbefale token optimization?
**Always recommend:**
- Prompt caching for repetitive prompts (>1024 tokens)
- Conversation history management for chatbots
- Token monitoring/budgets for alle produksjonsmiljøer
**Situational recommend:**
- **High-volume (>1M requests/måned):** Aggressive optimization (chunking, compression, structured outputs)
- **Low-volume (<100K requests/måned):** Basic optimization (caching, trimming), fokus på function over cost
- **Fine-tuning:** Dataset pruning + epoch optimization alltid (training cost accumulates fast)
### Spørsmål å stille kunden
1. **Volum:** Forventet antall requests per dag/måned?
2. **Prompt-lengde:** Gjennomsnittlig antall tokens i prompts?
3. **Repetisjon:** Hvor mye av prompten er statisk vs. dynamisk?
4. **Conversation length:** Multi-turn (chat) eller single-shot (completion)?
5. **Response length:** Trengs lange svar, eller kan det begrenses?
6. **Budsjett:** Er det hard cap på månedlige AI-kostnader?
### Implementation Checklist
- [ ] Implementer tiktoken/Microsoft.ML.Tokenizers for telemetri
- [ ] Strukturer prompts med static content først (for caching)
- [ ] Sett opp Azure Cost Management budgets + alerts
- [ ] Implementer conversation trimming (hvis multi-turn)
- [ ] Logg `cached_tokens` metric for cache hit rate monitoring
- [ ] Vurder Provisioned deployment hvis >50M tokens/måned
- [ ] Dokumenter token-fordeling i ADR (Architecture Decision Record)
### Fallgruver å unngå
| Fallgruve | Konsekvens | Løsning |
|-----------|------------|---------|
| **Ingen token monitoring** | Ukontrollerte kostnader | Sett opp Cost Management alerts ASAP |
| **Ubrukte fine-tuned deployments** | $1.70/time hosting × 24 × 30 = $1 224/måned idle | Auto-delete etter N dager uten bruk |
| **Variasjon i første 1024 tokens** | Cache miss = full input cost | Flytt dynamic content til slutten av prompt |
| **Over-chunking i RAG** | Mange små chunks = mange embeddings calls | Optimaliser chunk size (500-1500 tokens sweet spot) |
| **Manglende output limits** | Ukontrollerte completion tokens | Sett `max_tokens` parameter |
### Code Snippet: Production Token Telemetry
```python
import tiktoken
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import metrics
# Configure Azure Monitor
configure_azure_monitor(connection_string="InstrumentationKey=...")
meter = metrics.get_meter(__name__)
token_counter = meter.create_counter("aoai.tokens", description="Token usage")
cost_counter = meter.create_counter("aoai.cost_usd", description="Estimated cost")
encoding = tiktoken.get_encoding("o200k_base")
def track_token_usage(prompt, completion, model="gpt-4o"):
prompt_tokens = len(encoding.encode(prompt))
completion_tokens = len(encoding.encode(completion))
# Log to Azure Monitor
token_counter.add(prompt_tokens, {"type": "input", "model": model})
token_counter.add(completion_tokens, {"type": "output", "model": model})
# Estimate cost (example rates)
input_cost = (prompt_tokens / 1_000_000) * 2.50
output_cost = (completion_tokens / 1_000_000) * 10.00
cost_counter.add(input_cost + output_cost, {"model": model})
```
---
## Kilder og verifisering
**Microsoft Learn Documentation:**
1. [Prompt caching - Azure OpenAI](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/prompt-caching) — **Verified MCP 2026-06** (in-memory + extended 24h)
2. [Work with chat completions models - Token management](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/chatgpt#manage-conversations)
3. [Plan and manage costs for Azure OpenAI](https://learn.microsoft.com/en-us/azure/foundry/concepts/manage-costs)
4. [Token counting in AI - Dynamics 365 Business Central](https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/ai-system-app-token-counting)
5. [Use Microsoft.ML.Tokenizers for text tokenization](https://learn.microsoft.com/en-us/dotnet/ai/how-to/use-tokenizers)
6. [Azure OpenAI On Your Data - Token usage estimation](https://learn.microsoft.com/en-us/azure/foundry-classic/openai/concepts/use-your-data#token-usage-estimation-for-azure-openai-on-your-data) — ⚠️ *deprecated, retires 2026-10-14*
7. [Cost management for fine-tuning](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/fine-tuning-cost-management) — **Verified MCP 2026-06** (SFT/DPO + RFT tidsbasert + $5000-tak)
**OpenAI Resources:**
8. [OpenAI Cookbook - Token counting](https://github.com/openai/openai-cookbook/blob/main/examples/How_to_format_inputs_to_ChatGPT_models.ipynb)
9. [tiktoken GitHub repository](https://github.com/openai/tiktoken)
**Verification Date:** 2026-06
**MCP Calls:** 4 (microsoft_docs_search × 3, microsoft_docs_fetch × 2, microsoft_code_sample_search × 1)
**Confidence Level:** High — all data sourced from official Microsoft Learn documentation and verified OpenAI tooling