Ügynökök futtatása

Az alapügynök absztrakciója különböző lehetőségeket tesz elérhetővé az ügynök futtatásához. A hívók dönthetnek úgy, hogy nulla, egy vagy több bemeneti üzenetet adnak meg. A hívók választhatnak a streamelés és a nem streamelés között is. Vizsgáljuk meg a különböző használati forgatókönyveket.

Streamelés és nem streamelés

Microsoft Ügynök-keretrendszer támogatja az ügynök futtatásának streamelési és nem streamelési módszereit is.

Nem streamelés esetén használja a metódust RunAsync .

Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));

Streameléshez használja a metódust RunStreamingAsync .

await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
    Console.Write(update);
}

Nem streamelés esetén használja a metódust run .

result = await agent.run("What is the weather like in Amsterdam?")
print(result.text)

Streameléshez használja a metódust a run következővel stream=True: . Ez egy ResponseStream aszinkron módon iterálható objektumot ad vissza:

async for update in agent.run("What is the weather like in Amsterdam?", stream=True):
    if update.text:
        print(update.text, end="", flush=True)

ResponseStream

A ResponseStream visszaadott run(..., stream=True) objektum két használati mintát támogat:

1. minta: Aszinkron iteráció – valós idejű megjelenítéshez érkező folyamatfrissítések:

response_stream = agent.run("Tell me a story", stream=True)
async for update in response_stream:
    if update.text:
        print(update.text, end="", flush=True)

2. minta: Közvetlen véglegesítés – kihagyhatja az iterációt, és megkapja a teljes választ:

response_stream = agent.run("Tell me a story", stream=True)
final = await response_stream.get_final_response()
print(final.text)

3. minta: Kombinált – iterálás valós idejű megjelenítéshez, majd az összesített eredmény lekérése:

response_stream = agent.run("Tell me a story", stream=True)

# First, iterate to display streaming output
async for update in response_stream:
    if update.text:
        print(update.text, end="", flush=True)

# Then get the complete response (uses already-collected updates, does not re-iterate)
final = await response_stream.get_final_response()
print(f"\n\nFull response: {final.text}")
print(f"Messages: {len(final.messages)}")

A Go-ban RunText a ResponseStream párok iterátorát (ResponseUpdate, error) adja vissza.

Nem streamelés esetén hívja meg Collect() a streamet, hogy az összes frissítést egyetlen válaszban gyűjtse össze:

resp, err := a.RunText(ctx, "What is the weather like in Amsterdam?").Collect()
fmt.Println(resp, err)

Streameléshez iterálja át közvetlenül a streamet egy range hurok használatával:

for update, err := range a.RunText(ctx, "What is the weather like in Amsterdam?", agent.Stream(true)) {
    fmt.Print(update, err)
}

Ügynök futtatási beállítások

Az alapügynök absztrakciója lehetővé teszi egy beállításobjektum átadását minden ügynökfuttatáshoz, azonban a futtatás absztrakciós szinten történő testreszabása meglehetősen korlátozott. Az ügynökök jelentősen eltérhetnek, ezért nem igazán gyakori testreszabási lehetőségek.

Azokban az esetekben, amikor a hívó ismeri az ügynök típusát, a futtatás testreszabásához megadhat típusspecifikus beállításokat.

Itt például az ügynök egy ChatClientAgent , és át lehet adni egy ChatClientAgentRunOptions olyan objektumot, amelytől AgentRunOptionsöröklődik. Ez lehetővé teszi, hogy a hívó olyan egyéni ChatOptions beállításokat adjon meg, amelyek egyesítve vannak az ügynökszintű beállításokkal, mielőtt átadják őket a IChatClientChatClientAgent beépítettnek.

var chatOptions = new ChatOptions() { Tools = [AIFunctionFactory.Create(GetWeather)] };
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?", options: new ChatClientAgentRunOptions(chatOptions)));

Python ügynökök támogatják az egyes futtatásokat a options paraméteren keresztül. A beállítások TypedDict-ként vannak átadva, és az építési időpontban (via default_options) és futtatásonként (via options) is beállíthatók. Minden szolgáltató saját TypedDict osztálysal rendelkezik, amely teljes IDE automatikus kiegészítést és típusellenőrzést biztosít a szolgáltatóspecifikus beállításokhoz.

Gyakori lehetőségek a következők:

  • max_tokens: A létrehozandó jogkivonatok maximális száma
  • temperature: Szabályozza a véletlenszerűséget a válaszgenerálásban
  • model: Az adott futtatás modelljének felülbírálása
  • top_p: Mag mintavételezési paramétere
  • response_format: Adja meg a válaszformátumot (például strukturált kimenetek)

Megjegyzés:

A tools paraméterek közvetlen instructions kulcsszóargumentumok maradnak, és nem kerülnek át a options szótáron keresztül.

from agent_framework.openai import OpenAIChatClient, OpenAIChatOptions

# Set default options at construction time
agent = OpenAIChatClient().as_agent(
    instructions="You are a helpful assistant",
    default_options={
        "temperature": 0.7,
        "max_tokens": 500
    }
)

# Run with custom options (overrides defaults)
# OpenAIChatOptions provides IDE autocomplete for all OpenAI-specific settings
options: OpenAIChatOptions = {
    "temperature": 0.3,
    "max_tokens": 150,
    "model": "gpt-4o",
    "presence_penalty": 0.5,
    "frequency_penalty": 0.3
}

result = await agent.run(
    "What is the weather like in Amsterdam?",
    options=options
)

# Streaming with custom options
async for update in agent.run(
    "Tell me a detailed weather forecast",
    stream=True,
    options={"temperature": 0.7, "top_p": 0.9},
    tools=[additional_weather_tool]  # tools is still a keyword argument
):
    if update.text:
        print(update.text, end="", flush=True)

Minden szolgáltató saját TypedDict osztálysal (pl. , , OpenAIChatOptions) AnthropicChatOptionsrendelkezik, OllamaChatOptionsamely az adott szolgáltató által támogatott lehetőségek teljes készletét teszi elérhetővé.

Ha a futtatásonként és a futtatásonként default_options is options meg van adva, a futtatási beállítások elsőbbséget élveznek, és egyesülnek az alapértelmezett beállításokkal.

A beállítások variadikus agent.Option argumentumként lesznek átadva. Az elérhető lehetőségek a következők:

  • agent.Stream(true) – Streamelés engedélyezése
  • agent.WithSession(session) – Munkamenet csatolása többfordulós beszélgetésekhez
  • agent.WithStructuredOutput(&v) – Strukturált kimenet kérése gépelt értékre
  • agent.WithResponseFormat(format) – Adja meg a válaszformátumot
  • agent.WithTool(tool) – Eszköz hozzáadása ehhez a futtatáshoz
  • agent.AllowBackgroundResponses(true) – Háttérválaszok engedélyezése
resp, err := a.RunText(ctx, "Tell me a joke.",
    agent.Stream(true),
    agent.WithSession(session),
).Collect()

Választípusok

Az ügynököktől érkező streamelési és nem streamelési válaszok egyaránt tartalmazzák az ügynök által előállított összes tartalmat. A tartalom tartalmazhat olyan adatokat, amelyek nem az ügynök eredményének (vagyis a felhasználói kérdésre adott válasznak) adnak választ. Más visszaadott adatok közé tartoznak például a függvényeszközök hívásai, a függvényeszköz-hívások eredményei, az érvelés szövege, az állapotfrissítések és még sok más.

Mivel nem minden visszaadott tartalom az eredmény, fontos, hogy konkrét tartalomtípusokat keressen, amikor megpróbálja elkülöníteni az eredményt a többi tartalomtól.

A szöveges eredmény válaszból való kinyeréséhez az összes TextContent elem összes ChatMessages elemét összesíteni kell. Ennek egyszerűsítése érdekében egy Text tulajdonság minden olyan választípuson elérhető, amely összesíti az összeset TextContent.

A nem streamelt eset esetén minden egy AgentResponse objektumban jelenik meg. AgentResponse lehetővé teszi a létrehozott üzenetek elérését a Messages tulajdonságon keresztül.

var response = await agent.RunAsync("What is the weather like in Amsterdam?");
Console.WriteLine(response.Text);
Console.WriteLine(response.Messages.Count);

A streamelési eset AgentResponseUpdate esetében az objektumok streamelése az előállításuk során történik. Az egyes frissítések tartalmazhatják az ügynök eredményének egy részét, valamint más tartalomelemeket is. A nem streamelt esethez hasonlóan a Text tulajdonság használatával lekérheti az eredménynek a frissítésben szereplő részét, és a tulajdonságon keresztül részletezheti a Contents részleteket.

await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
    Console.WriteLine(update.Text);
    Console.WriteLine(update.Contents.Count);
}

A nem streamelt eset esetén minden egy AgentResponse objektumban jelenik meg. AgentResponse lehetővé teszi a létrehozott üzenetek elérését a messages tulajdonságon keresztül.

A szöveges eredmény válaszból való kinyeréséhez az összes TextContent elem összes Message elemét összesíteni kell. Ennek egyszerűsítése érdekében egy Text tulajdonság minden olyan választípuson elérhető, amely összesíti az összeset TextContent.

response = await agent.run("What is the weather like in Amsterdam?")
print(response.text)
print(len(response.messages))

# Access individual messages
for message in response.messages:
    print(f"Role: {message.role}, Text: {message.text}")

A streamelési eset AgentResponseUpdate esetében a rendszer az objektumokat a visszaadott ResponseStreammódon streameli.run(..., stream=True) Az egyes frissítések tartalmazhatják az ügynök eredményének egy részét, valamint más tartalomelemeket is. A nem streamelt esethez hasonlóan a text tulajdonság használatával lekérheti az eredménynek a frissítésben szereplő részét, és a tulajdonságon keresztül részletezheti a contents részleteket.

response_stream = agent.run("What is the weather like in Amsterdam?", stream=True)
async for update in response_stream:
    print(f"Update text: {update.text}")
    print(f"Content count: {len(update.contents)}")

    # Access individual content items
    for content in update.contents:
        if hasattr(content, 'text'):
            print(f"Content: {content.text}")

# Get the aggregated final response after streaming
final = await response_stream.get_final_response()
print(f"Complete text: {final.text}")

ResponseStream értékeket ad *agent.ResponseUpdate . Minden frissítés a következőket tartalmazza:

  • Contents - Értékek szeletelése message.Content , például szöveg, függvényhívások és használat
  • Role - Az üzenetszerepkör, például az asszisztens vagy a rendszer
  • MessageID / ResponseID - Az üzenet és a válasz azonosítói

Ha a teljes szöveges eredményt nem streamelési válaszból szeretné lekérni, használja a következőt Collect():

resp, err := a.RunText(ctx, "What is the weather like in Amsterdam?").Collect()
fmt.Println(resp, err)

Üzenettípusok

Az ügynökök bemenete és kimenete üzenetként jelenik meg. Az üzenetek tartalomelemekre vannak felosztva.

A Microsoft Agent Framework a Microsoft.Extensions.AI absztrakciók által biztosított üzenetet és tartalomtípusokat használja. Az üzeneteket az ChatMessage osztály jelöli, és az összes tartalomosztály öröklődik az alaposztálytól AIContent .

Különböző AIContent alosztályok léteznek, amelyek különböző tartalomtípusok megjelenítésére szolgálnak. Néhányat az alap Microsoft.Extensions.AI absztrakciók részeként biztosítunk, de szükség esetén a szolgáltatók saját típusokat is hozzáadhatnak.

Íme néhány népszerű típus a Microsoft.Extensions.AI:

Típus Description
TextContent Szöveges tartalom, amely lehet például egy felhasználó vagy egy fejlesztő bemenete és az ügynök kimenete is. Általában egy ügynök szöveges eredményét tartalmazza.
DataContent Bináris tartalom, amely lehet bemenet és kimenet is. Kép-, hang- vagy videoadatokat továbbíthat az ügynöknek (ahol támogatott).
UriContent Olyan URL-cím, amely általában az üzemeltetett tartalomra mutat, például egy képre, hangra vagy videóra.
FunctionCallContent Egy következtetési szolgáltatás kérése függvényeszköz meghívására.
FunctionResultContent Egy függvényeszköz meghívásának eredménye.

A Python Agent Framework a agent_framework csomag üzenet- és tartalomtípusát használja. Az üzeneteket az osztály, az Message összes tartalomelemet pedig a Content tulajdonság által type megkülönböztetett osztály jelöli.

Minden tartalmat az egyesített Content osztály jelöl, az egyes tartalomtípusokhoz pedig gyári metódusokkal. type A tulajdonság használatával ellenőrizze a tartalom típusát. A következő tartalomtípusok érhetők el:

Tartalomtípus Factory módszer Description
"text" Content.from_text() Szöveges tartalom a bemenethez és a kimenethez. Általában egy ügynök szöveges eredményét tartalmazza.
"text_reasoning" Content.from_text_reasoning() A gondolatlánc-érvelést támogató modellek szövegének érvelése. Védett adatokat is tartalmazhat.
"data" Content.from_data(), Content.from_uri() Adat URI-ként kódolt bináris tartalom. Képekhez, hanganyagokhoz, videókhoz és dokumentumokhoz használható.
"uri" Content.from_uri() Az üzemeltetett tartalomra, például képre, hangra vagy videóra mutató URL-cím.
"error" Content.from_error() Hibainformációk a feldolgozás sikertelenségéről. Opcionális hibakódot és részleteket tartalmaz.
"function_call" Content.from_function_call() Egy AI-szolgáltatás kérése függvényeszköz meghívására.
"function_result" Content.from_function_result() Egy függvényeszköz meghívásának eredménye.
"usage" Content.from_usage() Jogkivonatok használati és számlázási adatai az AI-szolgáltatásból.
"hosted_file" Content.from_hosted_file() Hivatkozás a szolgáltató által üzemeltetett fájlra (például az OpenAI-ba feltöltve).
"hosted_vector_store" Content.from_hosted_vector_store() Hivatkozás a szolgáltató által üzemeltetett vektortárolóra.
"code_interpreter_tool_call" Content.from_code_interpreter_tool_call() Az AI-szolgáltatás kérése a kód kódértelmezőn keresztüli végrehajtására.
"code_interpreter_tool_result" Content.from_code_interpreter_tool_result() A kódértelmező végrehajtásának eredménye.
"image_generation_tool_call" Content.from_image_generation_tool_call() Az AI-szolgáltatás kérése lemezkép létrehozására.
"image_generation_tool_result" Content.from_image_generation_tool_result() Képgenerálási kérés eredménye.
"mcp_server_tool_call" Content.from_mcp_server_tool_call() Eszköz mcp-kiszolgálón való meghívására vonatkozó kérés.
"mcp_server_tool_result" Content.from_mcp_server_tool_result() Egy MCP-kiszolgálóeszköz meghívásának eredménye.
"shell_tool_call" Content.from_shell_tool_call() Az AI-szolgáltatás kérése a rendszerhéjparancsok végrehajtására.
"shell_tool_result" Content.from_shell_tool_result() A rendszerhéj-eszköz hívásának összesített eredménye.
"shell_command_output" Content.from_shell_command_output() Egyetlen rendszerhéj-parancsvégrehajtás kimenete.
"function_approval_request" Content.from_function_approval_request() Felhasználói jóváhagyás kérése függvényhívás végrehajtása előtt.
"function_approval_response" Content.from_function_approval_response() A felhasználó válasza egy függvény-jóváhagyási kérelemre.
"oauth_consent_request" Content.from_oauth_consent_request() Kérés a felhasználótól, hogy egy megadott hivatkozáson keresztül fejezze be az OAuth-hozzájárulást.

A különböző tartalomtípusok a következőképpen működnek:

from agent_framework import Message, Content

# Create a text message
text_message = Message(role="user", contents=["Hello!"])

# Create a message with multiple content types
image_data = b"..."  # your image bytes
mixed_message = Message(
    role="user",
    contents=[
        Content.from_text("Analyze this image:"),
        Content.from_data(data=image_data, media_type="image/png"),
    ]
)

# Access content from responses
response = await agent.run("Describe the image")
for message in response.messages:
    for content in message.contents:
        if content.type == "text":
            print(f"Text: {content.text}")
        elif content.type == "data":
            print(f"Data URI: {content.uri}")
        elif content.type == "uri":
            print(f"External URI: {content.uri}")

A Go Agent-keretrendszer a csomag üzenet- és tartalomtípusát message használja. A válaszfrissítések több tartalomelemet is tartalmazhatnak; vizsgálja meg az egyes elemeket a szükséges tartalomtípushoz.

A streameléshez a frissítéseket a beérkezéskor egyenként dolgozza fel:

for update, err := range a.RunText(ctx, "Tell me a story.", agent.Stream(true)) {
    fmt.Print(err)
    for _, c := range update.Contents {
        if text, ok := c.(*message.TextContent); ok {
            fmt.Print(text.Text)
        }
    }
}

Tip

A teljes minta egy teljes futtatható példát mutat be.

Következő lépések