Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Abstrakcja agenta podstawowego uwidacznia różne opcje uruchamiania agenta. Osoby wywołujące mogą wybrać opcję dostarczania zera, jednego lub wielu komunikatów wejściowych. Osoby wywołujące mogą również wybierać między przesyłaniem strumieniowym i bez przesyłania strumieniowego. Przyjrzyjmy się różnym scenariuszom użycia.
Przesyłanie strumieniowe i nie przesyłane strumieniowo
Program Microsoft Agent Framework obsługuje metody przesyłania strumieniowego i nieprzesyłania strumieniowego na potrzeby uruchamiania agenta.
W przypadku braku przesyłania strumieniowego RunAsync użyj metody .
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));
W przypadku przesyłania strumieniowego RunStreamingAsync użyj metody .
await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
Console.Write(update);
}
W przypadku braku przesyłania strumieniowego run użyj metody .
result = await agent.run("What is the weather like in Amsterdam?")
print(result.text)
W przypadku przesyłania strumieniowego run użyj metody z stream=True. Spowoduje to zwrócenie ResponseStream obiektu, który można iterować asynchronicznie:
async for update in agent.run("What is the weather like in Amsterdam?", stream=True):
if update.text:
print(update.text, end="", flush=True)
OdpowiedźStream
Obiekt ResponseStream zwracany przez run(..., stream=True) program obsługuje dwa wzorce zużycia:
Wzorzec 1: iteracja asynchronizuj — przetwarzaj aktualizacje w miarę ich odbierania w czasie rzeczywistym:
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)
Wzorzec 2: Finalizacja bezpośrednia — pomiń iterację i uzyskaj pełną odpowiedź:
response_stream = agent.run("Tell me a story", stream=True)
final = await response_stream.get_final_response()
print(final.text)
Wzorzec 3: Połączony — iteracja dla wyświetlania w czasie rzeczywistym, a następnie uzyskiwanie zagregowanego wyniku:
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)}")
Opcje uruchamiania agenta
Abstrakcja agenta podstawowego umożliwia przekazywanie obiektu opcji dla każdego uruchomienia agenta, jednak możliwość dostosowania przebiegu na poziomie abstrakcji jest dość ograniczona. Agenci mogą się znacznie różnić i dlatego nie ma naprawdę typowych opcji dostosowywania.
W przypadku, gdy obiekt wywołujący zna typ agenta, z którym pracują, można przekazać określone opcje typu w celu umożliwienia dostosowywania przebiegu.
Na przykład agent jest elementem ChatClientAgent i można przekazać ChatClientAgentRunOptions obiekt, który dziedziczy z AgentRunOptionselementu .
Dzięki temu obiekt wywołujący może udostępnić niestandardowe ChatOptions , które są scalane z dowolnymi opcjami na poziomie agenta przed przekazaniem do IChatClient elementu, na który ChatClientAgent jest oparty.
var chatOptions = new ChatOptions() { Tools = [AIFunctionFactory.Create(GetWeather)] };
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?", options: new ChatClientAgentRunOptions(chatOptions)));
Agenci języka Python obsługują dostosowywanie każdego przebiegu za pomocą parametru options . Opcje są przekazywane jako TypedDict i można je ustawiać w czasie budowy (za pośrednictwem ) i na przebieg (za pośrednictwem default_options).options Każdy dostawca ma własną klasę TypedDict, która zapewnia pełne autouzupełnianie środowiska IDE i sprawdzanie typów pod kątem ustawień specyficznych dla dostawcy.
Dostępne są typowe opcje:
-
max_tokens: Maksymalna liczba tokenów do wygenerowania -
temperature: Kontroluje losowość w generowaniu odpowiedzi -
model_id: zastąpić model dla tego konkretnego przebiegu -
top_p: Parametr próbkowania jądra -
response_format: Określ format odpowiedzi (np. dane wyjściowe ze strukturą)
Uwaga / Notatka
Parametry tools i instructions pozostają jako argumenty słów kluczowych bezpośrednich i nie są przekazywane za pośrednictwem słownika options .
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_id": "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)
Każdy dostawca ma własną klasę TypedDict (np. OpenAIChatOptions, AnthropicChatOptions, ), OllamaChatOptionsktóra uwidacznia pełny zestaw opcji obsługiwanych przez tego dostawcę.
Po podaniu opcji zarówno, default_options jak i dla każdego uruchomienia options mają pierwszeństwo i są scalane z wartościami domyślnymi.
Typy odpowiedzi
Zarówno odpowiedzi przesyłane strumieniowo, jak i nie przesyłane strumieniowo z agentów zawierają całą zawartość utworzoną przez agenta. Zawartość może zawierać dane, które nie są wynikiem (czyli odpowiedzią na pytanie użytkownika) od agenta. Przykłady innych zwracanych danych obejmują wywołania narzędzi funkcji, wyniki wywołań narzędzi funkcji, tekst rozumowania, aktualizacje stanu i wiele innych.
Ponieważ nie zwracana jest cała zwracana zawartość, ważne jest, aby wyszukać określone typy zawartości podczas próby odizolowania wyniku od innej zawartości.
Aby wyodrębnić wynik tekstu z odpowiedzi, wszystkie TextContent elementy ze wszystkich ChatMessages elementów muszą zostać zagregowane.
Aby uprościć ten proces, Text właściwość jest dostępna we wszystkich typach odpowiedzi, które agregują wszystkie TextContenttypy odpowiedzi .
W przypadku przypadku braku przesyłania strumieniowego wszystko jest zwracane w jednym AgentResponse obiekcie.
AgentResponse umożliwia dostęp do wygenerowanych komunikatów za pośrednictwem Messages właściwości .
var response = await agent.RunAsync("What is the weather like in Amsterdam?");
Console.WriteLine(response.Text);
Console.WriteLine(response.Messages.Count);
W przypadku przypadku AgentResponseUpdate przesyłania strumieniowego obiekty są przesyłane strumieniowo w miarę ich tworzenia.
Każda aktualizacja może zawierać część wyniku agenta, a także różne inne elementy zawartości.
Podobnie jak w przypadku braku przesyłania strumieniowego, można użyć Text właściwości , aby pobrać część wyniku zawartego w aktualizacji i przejść do szczegółów za pośrednictwem Contents właściwości .
await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
Console.WriteLine(update.Text);
Console.WriteLine(update.Contents.Count);
}
W przypadku przypadku braku przesyłania strumieniowego wszystko jest zwracane w jednym AgentResponse obiekcie.
AgentResponse umożliwia dostęp do wygenerowanych komunikatów za pośrednictwem messages właściwości .
Aby wyodrębnić wynik tekstu z odpowiedzi, wszystkie TextContent elementy ze wszystkich Message elementów muszą zostać zagregowane.
Aby uprościć ten proces, Text właściwość jest dostępna we wszystkich typach odpowiedzi, które agregują wszystkie TextContenttypy odpowiedzi .
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}")
W przypadku przypadku AgentResponseUpdate przesyłania strumieniowego obiekty są przesyłane strumieniowo w miarę ich tworzenia za pośrednictwem zwracanego przez ResponseStreamrun(..., stream=True)element .
Każda aktualizacja może zawierać część wyniku agenta, a także różne inne elementy zawartości.
Podobnie jak w przypadku braku przesyłania strumieniowego, można użyć text właściwości , aby pobrać część wyniku zawartego w aktualizacji i przejść do szczegółów za pośrednictwem contents właściwości .
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}")
Typy komunikatów
Dane wejściowe i wyjściowe z agentów są reprezentowane jako komunikaty. Wiadomości są podzielone na elementy zawartości.
Program Microsoft Agent Framework używa typów komunikatów i zawartości udostępnianych przez Microsoft.Extensions.AI abstrakcje.
Komunikaty są reprezentowane przez klasę ChatMessage , a wszystkie klasy zawartości dziedziczą z klasy bazowej AIContent .
Istnieją różne AIContent podklasy, które są używane do reprezentowania różnych typów zawartości. Niektóre są udostępniane jako część abstrakcji podstawowych Microsoft.Extensions.AI , ale dostawcy mogą również dodawać własne typy, w razie potrzeby.
Oto kilka popularnych typów:Microsoft.Extensions.AI
| Typ | Opis |
|---|---|
| TextContent | Zawartość tekstowa, która może być zarówno danymi wejściowymi, jak i danymi wyjściowymi z agenta, na przykład z poziomu użytkownika lub dewelopera. Zazwyczaj zawiera wynik tekstowy agenta. |
| DataContent | Zawartość binarna, która może być zarówno danymi wejściowymi, jak i wyjściowymi. Może służyć do przekazywania danych obrazu, audio lub wideo do i z agenta (gdzie jest obsługiwana). |
| UriContent | Adres URL, który zazwyczaj wskazuje hostowaną zawartość, taką jak obraz, dźwięk lub wideo. |
| FunctionCallContent | Żądanie przez usługę wnioskowania w celu wywołania narzędzia funkcji. |
| FunctionResultContent | Wynik wywołania narzędzia funkcji. |
Struktura agenta języka Python używa typów komunikatów i zawartości z agent_framework pakietu.
Komunikaty są reprezentowane przez klasę Message , a wszystkie klasy zawartości dziedziczą z klasy bazowej Content .
Istnieją różne Content podklasy, które są używane do reprezentowania różnych typów zawartości:
| Typ | Opis |
|---|---|
Content |
Ujednolicony typ zawartości z metodami fabryki (Content.from_text(), Content.from_data(), Content.from_uri()).
type Użyj właściwości , aby sprawdzić typ zawartości ("text", "data", "uri"). |
FunctionCallContent |
Żądanie przez usługę sztucznej inteligencji w celu wywołania narzędzia funkcji. |
FunctionResultContent |
Wynik wywołania narzędzia funkcji. |
ErrorContent |
Informacje o błędzie podczas przetwarzania kończą się niepowodzeniem. |
UsageContent |
Informacje o użyciu tokenu i rozliczeniach z usługi sztucznej inteligencji. |
Oto jak pracować z różnymi typami zawartości:
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}")