Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Note
De API voor de gefaseerde beschikbaarstelling van tools (FunctionInvocationContext.add_tools / remove_tools) is momenteel alleen beschikbaar voor Python.
Deze pagina bevat drie aanvullende technieken voor het beheren van welke hulpprogramma's een model kan aanroepen en in welke volgorde, allemaal binnen één agent worden uitgevoerd, zonder dat hiervoor een werkstroom nodig is:
- Progressieve blootstelling aan hulpprogramma's : u kunt hulpprogramma's tijdens runtime toevoegen aan of verwijderen uit een hulpprogramma of functie-middleware, zodat het model alleen hulpprogramma's ziet die u kunt gebruiken.
- Middleware-gating : gebruik functie-middleware om aanroepargumenten te valideren en corrigerende feedback te retourneren zonder de onderliggende functie uit te voeren.
-
Geforceerde eerste aanroep : gebruik
tool_choicedit om te vereisen dat het model een specifiek hulpprogramma aanroept voordat andere.
Note
Paarsgewijze volgordebeperkingen, zoals 'altijd aanroepen get_record voor update_record' vereisen geen werkstroom. De technieken op deze pagina verwerken dat patroon binnen één uitvoering. Workflows zijn bedoeld voor echte meerstapsorkestratie over meerdere uitvoeringen heen of via parallelle takken.
Gefaseerde beschikbaarstelling van hulpmiddelen
Met progressieve toolblootstelling kunt u een uitvoering starten met een kleine set hulpprogramma's en hulpprogramma's toevoegen of verwijderen in reactie op eerdere resultaten van het hulpprogramma, allemaal binnen dezelfde uitvoering. Het model ziet alleen de bijgewerkte set voor de volgende iteratie van de functie-aanroepende lus; hulpprogramma-aanroepen die al zijn aangevraagd in de in-flight batch, worden nog steeds uitgevoerd voordat de wijziging van kracht wordt.
De API is experimenteel en leeft op FunctionInvocationContext:
| Lid | Description |
|---|---|
ctx.tools |
De actuele, wijzigbare list tools voor de huidige uitvoering.
None wanneer de functie wordt aangeroepen buiten een lus voor functieaanroepen. |
ctx.add_tools(tools) |
Voeg een of meer hulpprogramma's toe. Aanroepbare objecten worden verpakt als FunctionTool. Het opnieuw toevoegen van hetzelfde object is een no-op; een ander object met een dubbele naam veroorzaakt ValueError. Alles of niets: als een van de hulpprogramma's in de batch een fout zou veroorzaken, wordt er niets toegevoegd. |
ctx.remove_tools(tools) |
Verwijderen op naam, hulpmiddelobject of aanroepbaar. Namen die niet aanwezig zijn in de lijst, worden op de achtergrond genegeerd. |
Beide helpers verzenden ExperimentalWarning de eerste keer dat ze worden aangeroepen in een proces (functie-id PROGRESSIVE_TOOLS). Het aanroepen van een van beide helpers buiten een lus voor functieaanroepen leidt tot RuntimeError.
Important
De lijst met hulpprogramma's wordt opnieuw ingesteld op de oorspronkelijke set voor elke nieuwe agent.run() aanroep, zodat alle poorten automatisch opnieuw worden ingeschakeld voor elke beurt.
Note
Progressieve blootstelling aan hulpprogramma's is alleen van toepassing op de standaardfunctieaanroepende lus. Het is niet beschikbaar voor CodeAct-providers (agent-framework-monty, agent-framework-hyperlight), waarbij het model één surface voor het uitvoeren van code ziet in plaats van afzonderlijke hulpprogrammaschema's. Het aanroepen van add_tools of remove_tools binnen een CodeAct-sandbox leidt tot RuntimeError. Als u de set hulpprogramma's voor een CodeAct-agent wilt wijzigen, gebruikt u de eigen add_tools / remove_tool / clear_tools methoden van de provider tussen uitvoeringen.
Laadprogrammapatroon
Registreer vooraf een kleine set 'loadertools' en laat het model naar behoefte aanvullende tools ophalen. Hierdoor blijft het eerste schema klein, waardoor de nauwkeurigheid van de selectie van hulpprogramma's wordt verbeterd en de kosten worden verlaagd.
import asyncio
import warnings
from typing import Annotated
from agent_framework import Agent, FunctionInvocationContext, tool
from agent_framework.openai import OpenAIChatClient
from pydantic import Field
warnings.filterwarnings("ignore", category=UserWarning) # suppress ExperimentalWarning for brevity
@tool(approval_mode="never_require")
def factorial(n: Annotated[int, Field(description="A non-negative integer.")]) -> str:
"""Compute the factorial of n."""
if n < 0:
return "Error: n must be a non-negative integer."
result = 1
for value in range(2, n + 1):
result *= value
return f"{n}! = {result}"
@tool(approval_mode="never_require")
def fibonacci(n: Annotated[int, Field(description="The 0-based index in the Fibonacci sequence.")]) -> str:
"""Compute the n-th Fibonacci number."""
if n < 0:
return "Error: n must be a non-negative integer."
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return f"fib({n}) = {a}"
# The ctx parameter is injected by the framework and is NOT visible to the model.
@tool(approval_mode="never_require")
def load_math_tools(ctx: FunctionInvocationContext) -> str:
"""Load additional math tools (factorial, fibonacci) so they can be used."""
ctx.add_tools([factorial, fibonacci])
return "Loaded math tools: factorial, fibonacci. You can now call them."
async def main() -> None:
agent = Agent(
client=OpenAIChatClient(),
name="MathAgent",
instructions=(
"You are a math assistant. "
"If you need math capabilities that are not yet available, call load_math_tools first."
),
tools=[load_math_tools], # agent starts with only the loader
)
print(await agent.run("What is 5 factorial?"))
asyncio.run(main())
Het volledige uitvoerbare voorbeeld bevindt zich op python/samples/02-agents/tools/dynamic_tool_exposure.py.
Schakelpatroon
Registreer in eerste instantie alleen het leeshulpprogramma. De read-tool voegt de write-tool pas toe na een succesvolle fetch, zodat het model de write-tool niet kan aanroepen voordat de read-tool is uitgevoerd.
from agent_framework import Agent, FunctionInvocationContext, tool
from agent_framework.openai import OpenAIChatClient
_last_fetched_id: str | None = None
@tool(approval_mode="never_require")
def get_record(record_id: str, ctx: FunctionInvocationContext) -> str:
"""Fetch a record. Unlocks update_record for the same record."""
global _last_fetched_id
_last_fetched_id = record_id
ctx.add_tools(update_record) # gate: expose the write tool now
return f"Record {record_id}: title='Example record', status='open'"
@tool(approval_mode="never_require")
def update_record(record_id: str, status: str) -> str:
"""Update the status of a record."""
return f"Updated record {record_id} to status '{status}'."
agent = Agent(
client=OpenAIChatClient(),
name="RecordAgent",
instructions="You help manage records. Fetch a record before updating it.",
tools=[get_record], # update_record is hidden until get_record runs
)
Omdat ctx.tools aan het begin van elke uitvoering wordt teruggezet naar [get_record], wordt de controle automatisch opnieuw geactiveerd voor elke gespreksbeurt.
Middleware-gating
Functiemiddleware kan de argumenten van een in behandeling zijnde hulpprogramma-aanroep inspecteren en deze weigeren voordat de onderliggende functie wordt uitgevoerd, door context.result in te stellen zonder call_next() aan te roepen. De tekenreeks die aan het model is toegewezen context.result , wordt geretourneerd als het resultaat van de functie, waardoor deze corrigerende feedback geeft.
Dit is handig voor controles op argumentniveau die informatie nodig hebben die niet beschikbaar is op schemadefinitietijd, bijvoorbeeld om te controleren of een update is gericht op hetzelfde item dat eerder in de uitvoering is opgehaald.
from collections.abc import Awaitable, Callable
from agent_framework import FunctionInvocationContext
_last_fetched_id: str | None = None
async def enforce_read_before_write(
context: FunctionInvocationContext,
call_next: Callable[[], Awaitable[None]],
) -> None:
"""Reject update_record calls that target a different record than the one fetched."""
if context.function.name == "update_record":
requested_id = context.arguments.get("record_id") if hasattr(context.arguments, "get") else None
if requested_id != _last_fetched_id:
# Set result without calling call_next — the function never executes.
context.result = (
f"Error: you must fetch record '{requested_id}' before updating it. "
f"Last fetched record was '{_last_fetched_id}'."
)
return
await call_next()
Voeg de middleware toe aan de agent:
agent = Agent(
client=OpenAIChatClient(),
name="RecordAgent",
instructions="Fetch a record before updating it.",
tools=[get_record, update_record],
middleware=[enforce_read_before_write],
)
Zie Middleware definiëren en resultaatoverschrijvingen voor meer informatie over functiemiddleware.
Een aanroep van een hulpprogramma afdwingen met tool_choice
Als u wilt dat het model een specifiek hulpprogramma als eerste actie aanroept, geeft u door tool_choice met de modus "required" en een required_function_name. Het framework wordt automatisch opnieuw ingesteld tool_choiceNone na de eerste iteratie, zodat het model vrij is op volgende iteraties.
result = await agent.run(
"Update record REC-42 to status 'in-progress'.",
tool_choice={"mode": "required", "required_function_name": "get_record"},
)
Het tool_choice veld accepteert een ToolMode dict of de verkorte tekenreeksen "auto", "required"of "none":
from agent_framework import ToolMode
tool_choice: ToolMode = {"mode": "required", "required_function_name": "get_record"}
Semantiek en opmerkingen
| Gedrag | Het detail |
|---|---|
| Effect van de volgende iteratie |
add_tools
/
remove_tools mutaties zijn zichtbaar voor het model op de volgende lus iteratie. Toolaanroepen die al in de huidige batch zijn verzonden, worden toch voltooid. |
| In-flight batch | Als het model verschillende hulpprogramma's in één batch aanvraagt, worden alle uitgevoerd voordat de bijgewerkte lijst met hulpprogramma's wordt teruggestuurd. |
| Dubbele namen | Het opnieuw toevoegen van hetzelfde object is een no-op. Het toevoegen van een ander object met dezelfde naam als een bestaand hulpmiddel veroorzaakt ValueError. De volledige batch wordt gevalideerd voordat er iets wordt toegevoegd, dus een duplicaat halverwege een lijst laat de actuele lijst ongewijzigd. |
| Fout buiten de lus | Het aanroepen van add_tools of remove_tools wanneer ctx.tools is None leidt tot RuntimeError. Dit gebeurt wanneer de functie rechtstreeks wordt aangeroepen (bijvoorbeeld via FunctionTool.invoke) in plaats van via de agentlus. |
| Experimentele status | Beide hulpfuncties genereren ExperimentalWarning bij de eerste aanroep per proces. Onderdrukken met warnings.filterwarnings("ignore", category=UserWarning) indien gewenst. |
| Toepassingsgebied per uitvoering | De lijst met live tools is een verse kopie die aan het begin van elke agent.run()-aanroep wordt gemaakt op basis van normalize_tools. De oorspronkelijke tools-container van de aanroeper wordt nooit gewijzigd. |
| CodeAct-uitsluiting | Niet beschikbaar voor agent-framework-monty of agent-framework-hyperlight CodeAct-providers. |