基本代理程式抽象概念會公開執行代理程式的各種選項。 呼叫者可選擇提供零、一或多個輸入訊息。 來電者還可以在流媒體和非流媒體之間進行選擇。 讓我們深入研究不同的使用場景。
串流和非串流
Microsoft Agent Framework 支援串流與非串流兩種方式來執行代理程式。
對於非串流,請使用RunAsync
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));
對於串流,請使用RunStreamingAsync
await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
Console.Write(update);
}
對於非串流,請使用run
result = await agent.run("What is the weather like in Amsterdam?")
print(result.text)
對於串流,請使用run_stream
async for update in agent.run_stream("What is the weather like in Amsterdam?"):
if update.text:
print(update.text, end="", flush=True)
代理程式執行選項
基本代理程式抽象化允許為每個代理程式執行傳遞選項物件,但在抽象層級自訂執行的能力非常有限。 代理可能會有很大差異,因此沒有真正常見的自定義選項。
對於呼叫者知道他們正在使用的代理的類型,可以傳遞特定於類型的選項以允許自訂運行。
例如,這裡的代理程式是 , ChatClientAgent 並且可以傳遞繼 ChatClientAgentRunOptions 承自 AgentRunOptions的物件。
這允許呼叫者提供與任何代理級別選項合併的自定義ChatOptions,然後再傳遞給構建的IChatClient。ChatClientAgent
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 代理程式支援透過 options 參數自訂每次執行。 選項以 TypedDict 形式傳遞,並可在建構時(透過 default_options)或每次執行(透過 options)設定。 每個提供者都有自己的 TypedDict 類別,提供完整的 IDE 自動補全功能,並為提供者特定設定進行類型檢查。
常用選項包含:
-
max_tokens:要產生的權杖數目上限 -
temperature:控制響應生成的隨機性 -
model_id:覆寫此特定執行的模型 -
top_p: 核取樣參數 -
response_format:指定回應格式(例如結構化輸出)
備註
tools和instructions參數仍作為直接關鍵字參數,不會透過options字典傳遞。
from agent_framework.openai import OpenAIChatClient, OpenAIChatOptions
# Set default options at construction time
agent = OpenAIChatClient().create_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_stream(
"Tell me a detailed weather forecast",
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)
每個提供者都有自己的 TypedDict 類別(例如 OpenAIChatOptions, , AnthropicChatOptions), OllamaChatOptions該類別會揭露該提供者所支援的完整選項集合。
當 default_options 同時提供 和 每次運行 options 時,每次運行選項優先,並與預設值合併。
回應類型
來自客服人員的串流和非串流回應都包含客服人員產生的所有內容。 內容可能包含與代理人非結果(即用戶問題的答案)有關的資料。 傳回的其他資料範例包括函式工具呼叫、函式工具呼叫的結果、推理文字、狀態更新等等。
由於並非所有傳回的內容都是結果,因此在嘗試將結果與其他內容隔離時,請務必尋找特定的內容類型。
若要從回應擷取文字結果, TextContent 必須彙總所有 ChatMessages 專案中的所有專案。
為了簡化說明,所有 Text 回應類型都有一個屬性,可以聚合所有 TextContent。
針對非串流案例,所有專案都會傳回在一個 AgentResponse 物件中。
AgentResponse 允許透過屬性存取 Messages 產生的訊息。
var response = await agent.RunAsync("What is the weather like in Amsterdam?");
Console.WriteLine(response.Text);
Console.WriteLine(response.Messages.Count);
針對串流案例, AgentResponseUpdate 物件會在產生時串流。
每次更新可能包含代理的部分結果,以及其他各種內容項目。
與非串流案例類似,可以使用 Text 屬性來取得更新中包含的結果部分,並透過屬性切 Contents 入詳細數據。
await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
Console.WriteLine(update.Text);
Console.WriteLine(update.Contents.Count);
}
針對非串流案例,所有專案都會傳回在一個 AgentResponse 物件中。
AgentResponse 允許透過屬性存取 messages 產生的訊息。
若要從回應擷取文字結果, TextContent 必須彙總所有 ChatMessage 專案中的所有專案。
為了簡化說明,所有 Text 回應類型都有一個屬性,可以聚合所有 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}")
針對串流案例, AgentResponseUpdate 物件會在產生時串流。
每次更新可能包含代理的部分結果,以及其他各種內容項目。
與非串流案例類似,可以使用 text 屬性來取得更新中包含的結果部分,並透過屬性切 contents 入詳細數據。
async for update in agent.run_stream("What is the weather like in Amsterdam?"):
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}")
訊息類型
代理程式的輸入和輸出會表示為訊息。 訊息會細分為內容項目。
Microsoft Agent Framework 會使用抽象概念所 Microsoft.Extensions.AI 提供的訊息和內容類型。
訊息由類別表示 ChatMessage ,而所有內容類別都繼承自基類 AIContent 。
存在各種 AIContent 子類別,可用來表示不同類型的內容。 有些是作為基本 Microsoft.Extensions.AI 抽象的一部分提供的,但提供者也可以根據需要添加自己的類型。
以下是一些流行的類型 Microsoft.Extensions.AI:
| 類型 | Description |
|---|---|
| TextContent | 文字內容可以是輸入的,例如來自使用者或開發者,也可以是代理人的輸出。 通常包含來自客服專員的文字結果。 |
| DataContent | 既可以是輸入,也可以是輸出的二進位內容。 可用於將影像、音訊或視訊資料傳遞至代理程式或從代理程式傳遞(如果支援)。 |
| UriContent | 一個通常指向託管內容的網址,例如圖片、音訊或影片。 |
| FunctionCallContent | 推論服務叫用函式工具的要求。 |
| FunctionResultContent | 函數工具呼叫的結果。 |
Python 代理程式架構會使用套件中的 agent_framework 訊息和內容類型。
訊息由類別表示 ChatMessage ,而所有內容類別都繼承自基類 BaseContent 。
存在各種 BaseContent 子類別,可用來表示不同類型的內容:
| 類型 | Description |
|---|---|
TextContent |
可以是代理程式輸入和輸出的文字內容。 通常包含來自客服專員的文字結果。 |
DataContent |
二進位內容以資料 URI 表示(例如 base64 編碼的影像)。 可用來將二進位資料傳遞至代理程式或從代理程式傳遞。 |
UriContent |
指向託管內容的 URI,例如影像、音訊檔案或文件。 |
FunctionCallContent |
AI 服務叫用函式工具的要求。 |
FunctionResultContent |
函數工具呼叫的結果。 |
ErrorContent |
處理失敗時的錯誤資訊。 |
UsageContent |
來自 AI 服務的權杖使用情況和計費資訊。 |
以下是如何使用不同的內容類型:
from agent_framework import ChatMessage, TextContent, DataContent, UriContent
# Create a text message
text_message = ChatMessage(role="user", text="Hello!")
# Create a message with multiple content types
image_data = b"..." # your image bytes
mixed_message = ChatMessage(
role="user",
contents=[
TextContent("Analyze this image:"),
DataContent(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 isinstance(content, TextContent):
print(f"Text: {content.text}")
elif isinstance(content, DataContent):
print(f"Data URI: {content.uri}")
elif isinstance(content, UriContent):
print(f"External URI: {content.uri}")