Ordren ba meg behandle sitt eget premiss som et premiss: «PM-ens 87/45 er korrigert
til 85/47 ved maaling ... Behandle ogsaa 85/47 som et premiss og re-maal det foer du
bygger.» Re-målt over de 389 ref-filene holder 85/47 heller ikke — og feilen ligger i
KLASSIFIKATOREN, ikke i tellingen. Summen 132 står; fordelingen er 62/70.
TRE FUNN, alle pinnet i test:
1. FJORTEN bold-etiketter er DIALOG-ATTRIBUSJONER, ikke etiketter. Dialog-bøtta
matchet bare kursivformen `*Cosmo:*`. Fetformen står foran sitert tale —
`**Naar kunden sier:** "..."` / `**Cosmo svarer:** "..."` — så å slette den
etterlater replikken uten taler. Redaksjonelt, ikke mekanisk.
2. TI tabellceller er PROVENIENSPÅSTANDER i kildekvalitets-kolonnen. Celleposisjon
deler de 26 tabellforekomstene i tre klasser, ikke én: 12 radetiketter (kolonne 0),
4 kolonneoverskrifter, 10 proveniensverdier (`Moenstre er Cosmo-design`,
`Raadgivende innhold basert paa Cosmo-persona`). Å skrive om en av dem er å avgi en
ny påstand om hvor innholdet kommer fra, og den siste har ikke noe slettemål i det
hele tatt. Seks av ordrens ni sammensetninger ligger helt inne i denne klassen —
ordrens egen advarsel traff, målingen lokaliserte den.
3. Lekkasje ANDRE veien, +1 mekanisk: `- **For arkitekten (Cosmo):** ...` i
reasoning-models-o1-o3-optimization.md:549 er nøyaktig målklassen, men et
linjestart-forankret nett ser den ikke bak `- ` og bokførte den som prosa.
Operatøren ratifiserte 2026-09-15 alt. A: kjør de 62, hold dialog og proveniens for
R14. Begge tilbakeholdte klasser henger på #R14-persona-ramme som aldri er besvart;
de 62 gjør ikke det, fordi R13 ALT har kjørt `For Cosmo` -> `For arkitekten` over 401
headinger — dette gjør bare etiketter og tabellrader konsistente med en beslutning
som allerede er utført.
UTFØRT: 62 forekomster i 50 filer (ordren sa 47) — 46 etiketter i 16 ratifiserte
varianter, 16 celler i 4. Diffen er 62 fjernet = 62 lagt til, ren in-place-erstatning;
hver endret linje klassifisert, ANNET = 0. Ingen måltekst innfører et ord kilden ikke
hadde, utover R13s sanksjonerte `arkitekten` (samme invariant-test, gjenbrukt).
GATEN, DEKOMPONERT I TRE KLAUSULER, hver validert BEGGE veier før den ble konsumert:
R1 REFERENT mekaniske sites 62 -> 0, produkt 451 uendret.
Kjent-pos: `**For Cosmo:**` OG `| Cosmos raad |` (genitiven er den
et bold-only nett mister) feller begge. Kjent-neg:
`**Cosmos DB-anbefaling:**` — ser ut som persona, er produkt —
og `| Azure Cosmos DB |` passerer urørt.
R2 REKKEVIDDE 0 umålte varianter, 0 utenfor rekkevidde. Kjent-pos: en ukjent
etikettform rapporteres som umålt OG transformen KASTER, den
hopper ikke stille over. Kjent-neg: dialog + proveniens bokføres
utenfor scope og er byte-identiske.
R3 HVA SOM STÅR 16 redaksjonelle etiketter + 10 celler uendret, heading/TOC
fortsatt 0 (R13 ikke regradert), prosa 132 -> 70. Kjent-pos: et
fjernet tegn i `Cosmos DB` feller produkt-differansen. Kjent-neg:
alle kun-produkt-filer byte-identiske gjennom transformen.
Gaten ble kjørt FØR transformen og felte R1 (exit 1) — et nullresultat som aldri er
tvunget til det andre svaret er ingen måling. R13b har egen baseline-fil;
cosmo-gate-baseline.json er et referansepunkt-artefakt (personaHeadings 401) og er
IKKE re-emittert. Ny .gitignore-negasjon (6 entries), aldri `git add -f`.
Målt underveis: 0 av de 62 målinjene ligger i en kodeblokk, så fence-agnostisk
transform er trygg her — samme konklusjon R13 nådde for headinger. Nøyaktig 1 linje
bærer begge klasser; dens `Cosmo-persona` står igjen, som den skal.
Suite 1134/1134 (1120 + 14 nye), validate-plugin 250/0/0, transform idempotent,
R13-driveren fortsatt no-op. RX-OPS1 adversarial-scan kjørt MANUELT på de 56 stagede
filene (OK, exit 0) — `core.hooksPath` skygger repoets pre-commit, fiksen eies av
`.claude`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
484 lines
20 KiB
Markdown
484 lines
20 KiB
Markdown
# Tool Use and Function Calling - Advanced Patterns
|
|
|
|
**Last updated:** 2026-06-19
|
|
**Status:** GA
|
|
**Category:** Agent Orchestration & Automation
|
|
**Type:** reference
|
|
**Source:** https://learn.microsoft.com/semantic-kernel/frameworks/agent/agent-functions
|
|
|
|
---
|
|
|
|
## 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](#for-arkitekten)
|
|
- [Kilder og verifisering](#kilder-og-verifisering)
|
|
|
|
## Introduksjon
|
|
|
|
Function calling og tool use er fundamentale mekanismer som lar AI-agenter utvide sine kapabiliteter utover ren språkgenerering. Ved å kalle predefinerte funksjoner kan agenter hente data fra eksterne kilder, utføre beregninger, oppdatere databaser, og samhandle med andre systemer — alt på en kontrollert og sikker måte.
|
|
|
|
I Microsoft-stakken støttes function calling på tvers av Azure OpenAI, Semantic Kernel, Microsoft Agent Framework, og Foundry Agent Service. Disse plattformene tilbyr ulike grader av abstraksjon, automatisering og enterprise-funksjoner, men deler samme grunnleggende konsept: modellen genererer strukturert JSON som beskriver funksjonsanrop, mens utvikleren kontrollerer når og hvordan funksjonen faktisk kjøres.
|
|
|
|
Avanserte mønstre for tool use inkluderer parallelle funksjonsanrop, hierarkisk agentkomposisjon (agent-as-tool), dynamisk toolvalg, og human-in-the-loop approval workflows. Disse mønstrene gjør det mulig å bygge robuste, skalerbare og ansvarlige AI-løsninger som balanserer autonomi med kontroll.
|
|
|
|
---
|
|
|
|
## Kjernekomponenter
|
|
|
|
| Komponent | Beskrivelse | Tilgjengelig i |
|
|
|-----------|-------------|----------------|
|
|
| **Function Definition** | JSON Schema som beskriver funksjonsnavn, parametere og beskrivelse | Azure OpenAI, SK, Agent Framework |
|
|
| **Tool Choice** | Kontroll over hvorvidt modellen må, kan eller ikke skal kalle funksjoner (`auto`, `required`, `none`, spesifikk funksjon) | Azure OpenAI API (2023-12-01+) |
|
|
| **Parallel Function Calling** | Modellen kan kalle flere funksjoner samtidig i én respons | GPT-4, GPT-4o, GPT-5-serien, o1/o3-mini |
|
|
| **Automatic Invocation** | Agentframework utfører funksjonskall automatisk uten ekstra kode | Semantic Kernel (FunctionChoiceBehavior.Auto), Agent Framework |
|
|
| **Structured Outputs** | Pydantic-basert skjemavalidering for funksjonsargumenter | Azure OpenAI (gpt-4o 2024-08-06+) |
|
|
| **Agent-as-Tool** | Én agent kan eksponeres som funksjon til en annen agent | Agent Framework (`AsAIFunction()`, `as_tool()`) |
|
|
| **Human-in-the-Loop** | Approval-workflows før funksjoner kjøres | AG-UI middleware, custom logic |
|
|
|
|
### Eksempel: Enkel funksjonsdefinisjon (Azure OpenAI)
|
|
|
|
```python
|
|
tools = [
|
|
{
|
|
"type": "function",
|
|
"function": {
|
|
"name": "get_weather",
|
|
"description": "Get the current weather for a location",
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"location": {"type": "string", "description": "City name, e.g. Oslo"},
|
|
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
|
|
},
|
|
"required": ["location"]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
```
|
|
|
|
### Parallelle funksjonsanrop
|
|
|
|
```python
|
|
# Én request, flere funksjonsanrop
|
|
messages = [{"role": "user", "content": "What's the weather in Oslo, Paris, and Tokyo?"}]
|
|
response = client.chat.completions.create(model="gpt-4o", messages=messages, tools=tools)
|
|
|
|
# response.choices[0].message.tool_calls inneholder nå 3 funksjonsanrop
|
|
for tool_call in response.choices[0].message.tool_calls:
|
|
function_name = tool_call.function.name
|
|
args = json.loads(tool_call.function.arguments)
|
|
# Kjør funksjon og legg til resultat i messages
|
|
```
|
|
|
|
---
|
|
|
|
## Arkitekturmønstre
|
|
|
|
### 1. Basic Function Calling (Request-Response)
|
|
|
|
**Beskrivelse:** Utvikleren definerer funksjoner, sender dem til modellen sammen med brukerforespørselen, og behandler funksjonsanrop manuelt.
|
|
|
|
**Fordeler:**
|
|
- Full kontroll over eksekveringslogikk
|
|
- Fungerer med alle støttede modeller
|
|
- Enkel feilhåndtering og logging
|
|
|
|
**Ulemper:**
|
|
- Krever manuell håndtering av funksjonsanrop
|
|
- Må håndtere multi-turn conversations selv
|
|
|
|
**Bruksområder:** Enkel datainnhenting, prototype-utvikling, tilpasset sikkerhetslogikk.
|
|
|
|
**Kodeeksempel (Python, Azure OpenAI):**
|
|
|
|
```python
|
|
import json
|
|
from openai import OpenAI
|
|
|
|
client = OpenAI(base_url="https://RESOURCE.openai.azure.com/openai/v1/", api_key="KEY")
|
|
|
|
def get_weather(location: str) -> str:
|
|
# Simulert funksjon
|
|
return json.dumps({"location": location, "temperature": "15°C"})
|
|
|
|
messages = [{"role": "user", "content": "What's the weather in Oslo?"}]
|
|
response = client.chat.completions.create(
|
|
model="gpt-4o",
|
|
messages=messages,
|
|
tools=tools,
|
|
tool_choice="auto"
|
|
)
|
|
|
|
# Behandle tool_calls
|
|
if response.choices[0].message.tool_calls:
|
|
for tool_call in response.choices[0].message.tool_calls:
|
|
result = get_weather(**json.loads(tool_call.function.arguments))
|
|
messages.append({
|
|
"tool_call_id": tool_call.id,
|
|
"role": "tool",
|
|
"name": "get_weather",
|
|
"content": result
|
|
})
|
|
# Send tilbake til modellen for final response
|
|
final = client.chat.completions.create(model="gpt-4o", messages=messages)
|
|
```
|
|
|
|
---
|
|
|
|
### 2. Automatic Function Invocation (Semantic Kernel / Agent Framework)
|
|
|
|
**Beskrivelse:** Agentframeworket håndterer tool calls automatisk. Utvikleren definerer funksjoner med dekoratorer eller plugin-klasser, og agenten kaller dem automatisk når nødvendig.
|
|
|
|
**Fordeler:**
|
|
- Minimal boilerplate-kode
|
|
- Automatisk retry og feilhåndtering
|
|
- Integrert med Semantic Kernel plugins
|
|
|
|
**Ulemper:**
|
|
- Mindre kontroll over eksekveringsflyt
|
|
- Krever forståelse av framework-spesifikke konsepter (Kernel, Plugins, FunctionChoiceBehavior)
|
|
|
|
**Bruksområder:** Multi-turn conversations, komplekse agentic workflows, hurtig prototyping.
|
|
|
|
**Kodeeksempel (Python, Agent Framework):**
|
|
|
|
```python
|
|
from agent_framework import ChatAgent, tool
|
|
from agent_framework.azure import AzureChatCompletion
|
|
|
|
@tool
|
|
def get_weather(location: str) -> str:
|
|
return f"The weather in {location} is 15°C."
|
|
|
|
agent = ChatAgent(
|
|
chat_client=AzureChatCompletion(),
|
|
instructions="You are a helpful assistant.",
|
|
tools=[get_weather]
|
|
)
|
|
|
|
response = await agent.run("What's the weather in Oslo?")
|
|
# get_weather kalles automatisk av agenten
|
|
```
|
|
|
|
---
|
|
|
|
### 3. Agent-as-Tool (Hierarchical Agent Composition)
|
|
|
|
**Beskrivelse:** Én agent eksponeres som en funksjon til en annen agent. Dette skaper hierarkier av spesialiserte agenter.
|
|
|
|
**Fordeler:**
|
|
- Modulær arkitektur med spesialiserte agenter
|
|
- Enklere testing og vedlikehold
|
|
- Hver agent kan ha egne modeller, instructions og tools
|
|
|
|
**Ulemper:**
|
|
- Økt kompleksitet i debugging
|
|
- Potensielt høyere token-forbruk
|
|
|
|
**Bruksområder:** Multi-domain assistenter, delegering til ekspertagenter, composable workflows.
|
|
|
|
**Kodeeksempel (C#, Agent Framework):**
|
|
|
|
```csharp
|
|
// Spesialisert agent med egen funksjon
|
|
var weatherAgent = new ChatClientAgent(chatClient, instructions: "You answer weather questions.", tools: [WeatherTool]);
|
|
|
|
// Hovedagent som bruker weatherAgent som tool
|
|
var mainAgent = new ChatClientAgent(
|
|
chatClient,
|
|
instructions: "You are a helpful assistant who responds in Norwegian.",
|
|
tools: [weatherAgent.AsAIFunction()]
|
|
);
|
|
|
|
// mainAgent kan nå "kalle" weatherAgent som et verktøy
|
|
var result = await mainAgent.RunAsync("Hvordan er været i Oslo?");
|
|
```
|
|
|
|
---
|
|
|
|
### 4. Human-in-the-Loop Approval
|
|
|
|
**Beskrivelse:** Før funksjonskall utføres, spør systemet bruker om godkjenning. Dette er kritisk for handlinger med reell konsekvens (f.eks. slette data, sende e-post).
|
|
|
|
**Fordeler:**
|
|
- Økt kontroll og ansvarlig AI
|
|
- Redusert risiko for uønskede handlinger
|
|
- Compliance med AI Act og GDPR (transparens, brukermedvirkning)
|
|
|
|
**Ulemper:**
|
|
- Krever brukerinteraksjon (ikke fullt automatisert)
|
|
- Kan redusere opplevd "intelligens"
|
|
|
|
**Bruksområder:** Finansielle transaksjoner, administrative handlinger, dataredigering.
|
|
|
|
**Implementering (AG-UI + Agent Framework):**
|
|
|
|
AG-UI backend tool rendering stoetter HITL via to mekanismer:
|
|
|
|
**C# - AIFunctionFactory med serializerOptions (Verified MCP 2026-04):**
|
|
```csharp
|
|
// Definer tool med Description-attributter
|
|
[Description("Search for restaurants in a location.")]
|
|
static RestaurantSearchResponse SearchRestaurants(
|
|
[Description("The restaurant search request")] RestaurantSearchRequest request)
|
|
{
|
|
// implementasjon
|
|
}
|
|
|
|
// Registrer tool - NB: serializerOptions PÅKREVD for komplekse typer
|
|
var jsonOptions = app.Services.GetRequiredService<IOptions<JsonOptions>>().Value;
|
|
AITool[] tools = [
|
|
AIFunctionFactory.Create(SearchRestaurants, serializerOptions: jsonOptions.SerializerOptions)
|
|
];
|
|
|
|
// FunctionCallContent og FunctionResultContent streames til klient
|
|
// FunctionCallContent: .Name, .Arguments (key-value pairs)
|
|
// FunctionResultContent: .CallId, .Result eller .Exception
|
|
```
|
|
|
|
**Python - @tool decorator (Verified MCP 2026-04):**
|
|
```python
|
|
from typing import Annotated
|
|
from pydantic import Field
|
|
from agent_framework import tool
|
|
|
|
@tool
|
|
def get_weather(
|
|
location: Annotated[str, Field(description="The city")],
|
|
) -> str:
|
|
"""Get the current weather for a location."""
|
|
return f"The weather in {location} is 22 degrees C."
|
|
|
|
# Klasse-baserte tools for gruppering
|
|
class WeatherTools:
|
|
@tool
|
|
def get_current_weather(self, location: Annotated[str, Field(description="City")]) -> str:
|
|
"""Get current weather."""
|
|
return f"Current weather in {location}: Sunny"
|
|
```
|
|
|
|
**Backend tool events streames til klient i sanntid (Verified MCP 2026-04):**
|
|
```json
|
|
{"type": "TOOL_CALL_START", "toolCallId": "call_abc123", "toolCallName": "get_weather"}
|
|
{"type": "TOOL_CALL_ARGS", "toolCallId": "call_abc123", "delta": "{"location": "Oslo"}"}
|
|
{"type": "TOOL_CALL_END", "toolCallId": "call_abc123"}
|
|
{"type": "TOOL_CALL_RESULT","toolCallId": "call_abc123", "content": "The weather in Oslo is 22C."}
|
|
```
|
|
|
|
---
|
|
|
|
## Beslutningsveiledning
|
|
|
|
### Velg riktig mønster
|
|
|
|
| Scenario | Anbefalt mønster | Hvorfor |
|
|
|----------|------------------|---------|
|
|
| Enkel datahenting (API-kall, DB-spørring) | Basic Function Calling | Full kontroll, minimal overhead |
|
|
| Multi-turn konversasjon med flere funksjoner | Automatic Invocation (SK/Agent Framework) | Automatisk orkestrering, mindre kode |
|
|
| Spesialiserte subagenter (f.eks. HR-agent, IT-agent) | Agent-as-Tool | Modulær arkitektur, enklere vedlikehold |
|
|
| Kritiske handlinger (slette data, godkjenne betalinger) | Human-in-the-Loop | Compliance, ansvarlig AI |
|
|
| Real-time streaming UI | AG-UI backend tools | SSE-streaming, UX-optimalisert |
|
|
|
|
### Vanlige feil
|
|
|
|
| Feil | Konsekvens | Løsning |
|
|
|------|-----------|---------|
|
|
| Manglende eller vag `description` | Modellen kaller feil funksjoner | Inkluder detaljerte beskrivelser med eksempler |
|
|
| Ingen validering av funksjonsargumenter | Runtime errors, sikkerhetshull | Bruk Pydantic-modeller for structured outputs (gpt-4o 2024-08-06+) |
|
|
| For mange funksjoner i én request (>20) | Token-forbruk, dårlig presisjon | Bruk dynamisk toolvalg eller agentkomposisjon |
|
|
| Ikke håndtere parallelle anrop | Race conditions, inkonsistent state | Kjør parallelle kall asynkront, isoler state |
|
|
| Hardkodet tool_choice="required" | Modellen kan ikke gi vanlige svar | Bruk `auto` og la modellen velge |
|
|
|
|
### Røde flagg
|
|
|
|
- **Funksjonen har side-effects (sletter data, sender meldinger) uten approval-workflow** → Implementer human-in-the-loop.
|
|
- **Funksjoner kalles fra upålitelig brukerinput uten validering** → Risiko for prompt injection. Valider all input.
|
|
- **Sensitivt data returneres fra funksjoner uten tilgangskontroll** → Bruk least-privilege prinsipper, valider brukeridentitet.
|
|
- **Token-forbruk eksploderer pga. for mange funksjonsdefinisjoner** → Reduser antall tools, bruk agentkomposisjon.
|
|
|
|
---
|
|
|
|
## Integrasjon med Microsoft-stakken
|
|
|
|
| Plattform | Function Calling Support | Auto-invocation | Agent-as-Tool | Parallel Calls | Structured Outputs |
|
|
|-----------|--------------------------|-----------------|---------------|----------------|-------------------|
|
|
| **Azure OpenAI** | ✅ (API 2023-12-01+) | ❌ (manuell) | ❌ | ✅ (gpt-4o+) | ✅ (gpt-4o 2024-08-06+) |
|
|
| **Semantic Kernel** | ✅ (Plugins) | ✅ (FunctionChoiceBehavior.Auto) | ✅ (KernelPlugin) | ✅ | ✅ (Pydantic via SK) |
|
|
| **Agent Framework** | ✅ (ChatAgent, tools=[]) | ✅ (default) | ✅ (AsAIFunction, as_tool) | ✅ | ✅ |
|
|
| **Foundry Agent Service** | ✅ (via OpenAPI endpoints) | ✅ (managed service) | ⚠️ (via tool composition) | ✅ | ✅ |
|
|
| **Copilot Studio** | ✅ (Actions, Plugins) | ✅ (automatic) | ⚠️ (via topic routing) | ⚠️ (begrensninger) | ❌ |
|
|
|
|
### Eksempel: Semantic Kernel Plugin
|
|
|
|
```csharp
|
|
public class WeatherPlugin
|
|
{
|
|
[KernelFunction, Description("Get weather for a location")]
|
|
public string GetWeather([Description("City name")] string location)
|
|
{
|
|
return $"Weather in {location}: 15°C";
|
|
}
|
|
}
|
|
|
|
// Legg til plugin i kernel
|
|
kernel.ImportPluginFromType<WeatherPlugin>();
|
|
|
|
// ChatCompletionAgent med auto-invocation
|
|
var agent = new ChatCompletionAgent
|
|
{
|
|
Kernel = kernel,
|
|
Arguments = new KernelArguments(
|
|
new OpenAIPromptExecutionSettings
|
|
{
|
|
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
|
|
}
|
|
)
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## Offentlig sektor (Norge)
|
|
|
|
### Compliance-krav
|
|
|
|
| Regelverk | Krav | Implikasjon for function calling |
|
|
|-----------|------|----------------------------------|
|
|
| **GDPR** | Transparens, data minimization | Logg alle funksjonsanrop som behandler personopplysninger; ikke hent mer data enn nødvendig |
|
|
| **AI Act (EU)** | Risikovurdering for høyrisiko-AI | Funksjoner som påvirker rettigheter krever human oversight (HITL) |
|
|
| **Forvaltningsloven** | Enkeltvedtak må være etterprøvbare | Logg input/output for alle funksjoner som bidrar til beslutninger |
|
|
| **NSM Grunnprinsipper** | Least privilege, logging | Funksjoner skal kun ha tilgang til data/APIer de faktisk trenger |
|
|
| **Schrems II** | Datasuverenitet (EU-EEA) | Funksjoner som kaller eksterne APIer må validere dataplassering |
|
|
|
|
### Ansvarlig AI-praksis
|
|
|
|
**Spørsmål arkitekten bør stille:**
|
|
1. Har vi approval-workflow for funksjoner som påvirker brukerrettigheter?
|
|
2. Logger vi alle funksjonsanrop med input/output for revidering?
|
|
3. Har vi validert at funksjoner ikke lekker PII til modellen?
|
|
4. Er funksjoner begrenset til minimum nødvendige privilegier?
|
|
5. Har vi testet for prompt injection-angrep på funksjonsargumenter?
|
|
|
|
**Eksempel: Logging for etterprøvbarhet**
|
|
|
|
```python
|
|
import logging
|
|
|
|
@tool
|
|
def update_citizen_record(ssn: str, field: str, value: str) -> str:
|
|
# Log før utførelse
|
|
logging.info(f"Function call: update_citizen_record(ssn={ssn[:4]}****, field={field}, value=REDACTED)")
|
|
|
|
# Valider input
|
|
if not is_valid_ssn(ssn):
|
|
raise ValueError("Invalid SSN")
|
|
|
|
# Utfør handling
|
|
result = db.update(ssn, field, value)
|
|
|
|
# Log resultat
|
|
logging.info(f"Function result: success={result['success']}")
|
|
return f"Record updated: {result['success']}"
|
|
```
|
|
|
|
---
|
|
|
|
## Kostnad og lisensiering
|
|
|
|
### Token-forbruk
|
|
|
|
**Function definitions forbruker input-tokens:**
|
|
- Hver funksjon: ~50-150 tokens (avhengig av kompleksitet)
|
|
- 10 funksjoner: ~500-1500 tokens per request
|
|
- Parallelle anrop: Én request, men flere funksjoner kjøres
|
|
|
|
**Optimaliseringstips:**
|
|
1. Bruk korte, presise beskrivelser
|
|
2. Reducer antall funksjoner per request (dynamisk toolvalg)
|
|
3. Bruk agent-as-tool for å isolere funksjoner til subagenter
|
|
4. Cache funksjonsresultater når mulig (Azure OpenAI caching)
|
|
|
|
### Lisenskrav
|
|
|
|
| Plattform | Funksjonalitet | Lisenskrav |
|
|
|-----------|----------------|------------|
|
|
| **Azure OpenAI** | Function calling | Azure-abonnement + OpenAI deployment |
|
|
| **Semantic Kernel** | Plugins, auto-invocation | Open source (MIT), krever AI-modell |
|
|
| **Agent Framework** | ChatAgent, tools | Open source, krever AI-modell |
|
|
| **Foundry Agent Service** | Managed agents, built-in tools | Microsoft Foundry-lisens |
|
|
| **Copilot Studio** | Actions, Plugins | Power Apps/Power Automate Premium eller Copilot Studio-lisens |
|
|
|
|
**Kostnadsestimat (NOK, Azure OpenAI gpt-4o):**
|
|
- Input: ~0.25 kr / 1M tokens
|
|
- Output: ~1.00 kr / 1M tokens
|
|
- 100 requests/dag med 10 funksjoner (1000 tokens input): ~250 kr/måned
|
|
- Parallelle anrop reduserer antall requests (besparelse ~30-50%)
|
|
|
|
---
|
|
|
|
## For arkitekten
|
|
|
|
### Spørsmål å stille klienten
|
|
|
|
1. **Hvilke handlinger skal agenten kunne utføre?** (Les data, skriv data, kall eksterne APIer, slett?)
|
|
2. **Krever noen funksjoner godkjenning fra bruker?** (Finansielle transaksjoner, sletting, GDPR-påvirkning)
|
|
3. **Hvor mange ulike funksjoner trenger agenten?** (<5: Basic, 5-15: Auto-invocation, 15+: Agent-as-tool)
|
|
4. **Er det spesialiserte domener?** (HR, IT, Finance → vurder agent-as-tool)
|
|
5. **Har dere krav til logging/revidering?** (Forvaltningsloven, ISO 27001)
|
|
6. **Hvilke data skal funksjoner ha tilgang til?** (PII, forretningskritisk → vurder least privilege)
|
|
7. **Skal agenten streame svar i real-time?** (AG-UI backend tools)
|
|
8. **Hva er budsjettet for token-forbruk?** (Vurder PTU for høyt volum)
|
|
|
|
### Fallgruver
|
|
|
|
| Fallgruve | Hvorfor det skjer | Hvordan unngå |
|
|
|-----------|-------------------|---------------|
|
|
| **For mange funksjoner i én agent** | Ønsker "alt i ett" | Bruk agent-as-tool, del opp i subagenter |
|
|
| **Funksjoner uten validering** | Stoler på at modellen alltid gir korrekt JSON | Bruk Pydantic structured outputs, valider alle argumenter |
|
|
| **Ingen logging av funksjonsanrop** | Glemmer compliance-krav | Implementer logging fra starten |
|
|
| **Hardkodet tool_choice="required"** | Misforstår at modellen må kalle funksjoner | Bruk `auto`, la modellen velge |
|
|
| **Funksjoner med høy latency blokkerer agent** | Synkrone API-kall | Bruk async/await, AG-UI async tools |
|
|
|
|
### Anbefalinger per modenhetsnivå
|
|
|
|
| Modenhetsnivå | Anbefalt tilnærming | Plattform |
|
|
|---------------|---------------------|-----------|
|
|
| **Pilot (PoC)** | Basic function calling, 1-3 funksjoner | Azure OpenAI + Python |
|
|
| **Produksjon (lav kompleksitet)** | Automatic invocation (Agent Framework), <10 funksjoner | Agent Framework + Azure OpenAI |
|
|
| **Produksjon (høy kompleksitet)** | Agent-as-tool, HITL for kritiske funksjoner | Agent Framework + AG-UI |
|
|
| **Enterprise (multi-domain)** | Foundry Agent Service med managed tools | Foundry Agent Service + M365 integrasjon |
|
|
|
|
---
|
|
|
|
## Kilder og verifisering
|
|
|
|
### Microsoft Learn-kilder (Verified via MCP)
|
|
|
|
1. [Azure OpenAI Function Calling](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/function-calling) — **Verified 2026-02**
|
|
2. [Semantic Kernel Agent Functions](https://learn.microsoft.com/en-us/semantic-kernel/frameworks/agent/agent-functions) — **Verified 2026-02**
|
|
3. [Agent Framework - Agent as Function Tool](https://learn.microsoft.com/en-us/agent-framework/tutorials/agents/agent-as-function-tool) — **Verified 2026-02**
|
|
4. [AG-UI Backend Tool Rendering](https://learn.microsoft.com/en-us/agent-framework/integrations/ag-ui/backend-tool-rendering) — **Verified (MCP 2026-06-19)** — AIFunctionFactory.Create() med serializerOptions for komplekse typer (C#), @tool decorator med Annotated/Field (Python), TOOL_CALL_START/ARGS/END/RESULT events, FunctionCallContent/.Arguments og FunctionResultContent/.Result (C#), klasse-baserte tools-moenster (Python)
|
|
5. [Azure OpenAI Assistants Function Calling](https://learn.microsoft.com/en-us/azure/foundry-classic/openai/how-to/assistant-functions) — **Verified 2026-02**
|
|
6. [Structured Outputs](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/structured-outputs) — **Verified 2026-02**
|
|
|
|
### Konfidensnivå per seksjon
|
|
|
|
| Seksjon | Konfidens | Kilde |
|
|
|---------|-----------|-------|
|
|
| Kjernekomponenter | **Verified** | Microsoft Learn MCP-search (6 kilder) |
|
|
| Arkitekturmønstre | **Verified** | Azure OpenAI docs, Agent Framework docs |
|
|
| Integrasjon med Microsoft-stakken | **Verified** | Semantic Kernel docs, Foundry docs |
|
|
| Offentlig sektor | **Baseline** | Modellkunnskap + norsk lovverk (GDPR, Forvaltningsloven) |
|
|
| Kostnad og lisensiering | **Baseline** | Azure pricing (2026-02), modellkunnskap |
|
|
|
|
---
|
|
|
|
**For arkitekten:** Dette dokumentet dekker både grunnleggende og avanserte mønstre for function calling. Bruk det til å velge riktig tilnærming basert på klientens behov (antall funksjoner, kompleksitet, compliance-krav). Husk alltid: **Start enkelt (Basic), skalér til Auto-invocation, og bygg modulært med Agent-as-Tool når kompleksiteten vokser.**
|