探索 AgentChat
中的代理程式共同作業
重要
這項功能處於實驗階段。 在這個階段的功能仍在開發中,而且在前進到預覽或發行候選階段之前可能會變更。
如需此討論的詳細 API 檔,請參閱:
代理程式目前無法在Java中使用。
什麼是 AgentChat
?
AgentChat
提供一個架構,可讓您在多個代理程式之間進行互動,即使它們屬於不同類型的代理程式也一樣。 這可讓 ChatCompletionAgent
和 OpenAIAssistantAgent
在同一個交談中一起運作。
AgentChat
也會定義起始代理程式之間共同作業的進入點,無論是透過多重回應還是單一代理程式回應。
做為抽象類,AgentChat
可以子類別化以支援自定義案例。
其中一個子類別 AgentGroupChat
,使用策略型方法來管理對話動態,提供 AgentChat
的具體實作。
建立 AgentGroupChat
若要建立 AgentGroupChat
,您可以指定參與的代理,或建立空白聊天,然後新增代理參與者。 設定 聊天設定 和 策略 也會在 AgentGroupChat
初始化期間執行。 這些設定會定義交談動態在群組內運作的方式。
注意:預設 Chat-Settings 會造成交談受限於單一回應。 如需設定_聊天設定的詳細資訊,請參閱
AgentChat
Behavior。
使用 AgentGroupChat
建立 Agent
:
// Define agents
ChatCompletionAgent agent1 = ...;
OpenAIAssistantAgent agent2 = ...;
// Create chat with participating agents.
AgentGroupChat chat = new(agent1, agent2);
# Define agents
agent1 = ChatCompletionAgent(...)
agent2 = OpenAIAssistantAgent(...)
# Create chat with participating agents
chat = AgentGroupChat(agents=[agent1, agent2])
代理程式目前無法在Java中使用。
將 Agent
新增至 AgentGroupChat
:
// Define agents
ChatCompletionAgent agent1 = ...;
OpenAIAssistantAgent agent2 = ...;
// Create an empty chat.
AgentGroupChat chat = new();
// Add agents to an existing chat.
chat.AddAgent(agent1);
chat.AddAgent(agent2);
# Define agents
agent1 = ChatCompletionAgent(...)
agent2 = OpenAIAssistantAgent(...)
# Create an empty chat
chat = AgentGroupChat()
# Add agents to an existing chat
chat.add_agent(agent=agent1)
chat.add_agent(agent=agent2)
代理程式目前無法在Java中使用。
使用 AgentGroupChat
AgentChat
支援兩種作業模式:Single-Turn
和 Multi-Turn
。 在 single-turn
中,會指定特定代理程式以提供回應。 在 multi-turn
中,交談中的所有代理程式都會輪流回應,直到符合終止準則為止。 在這兩種模式中,代理程式可以透過彼此回應來達成定義的目標來共同作業。
提供輸入
將輸入訊息新增至 AgentChat
遵循與 ChatHistory
物件相同的模式。
AgentGroupChat chat = new();
chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, "<message content>"));
chat = AgentGroupChat()
await chat.add_chat_message(message="<message content>")
代理程式目前無法在Java中使用。
單回合代理程式呼叫
在多回合調用中,系統必須決定下一個回應的代理程式,以及對話應該結束的時機。 相反地,單回合呼叫只會從指定的代理傳回回應,讓呼叫者能直接管理代理的參與。
在代理透過單回合調用參與 AgentChat
之後,它會被新增至有資格進行多回合調用的代理集合中。
// Define an agent
ChatCompletionAgent agent = ...;
// Create an empty chat.
AgentGroupChat chat = new();
// Invoke an agent for its response
ChatMessageContent[] messages = await chat.InvokeAsync(agent).ToArrayAsync();
# Define an agent
agent = ChatCompletionAgent(...)
# Create an empty chat
chat = AgentGroupChat()
# Invoke an agent for its response(s)
async for message in chat.invoke(agent)
# process message response(s)
代理程式目前無法在Java中使用。
多回合代理程序調用
雖然代理程式共同作業要求系統必須就緒,不僅會決定哪些代理程式應該在每個回合期間回應,而且會評估交談何時達到其預期目標,但起始多回合共同作業仍然相當簡單。
代理程式回應會在產生時以異步方式傳回,讓交談能夠實時展開。
注意:在下列各節中, 代理程式選取 和 聊天終止將詳細探討 執行設定 。 默認的 執行設定 會採用循序或循環選取,並將代理的參與限制在單一回合。
.NET 執行設定 API: AgentGroupChatSettings
// Define agents
ChatCompletionAgent agent1 = ...;
OpenAIAssistantAgent agent2 = ...;
// Create chat with participating agents.
AgentGroupChat chat =
new(agent1, agent2)
{
// Override default execution settings
ExecutionSettings =
{
TerminationStrategy = { MaximumIterations = 10 }
}
};
// Invoke agents
await foreach (ChatMessageContent response in chat.InvokeAsync())
{
// Process agent response(s)...
}
# Define agents
agent1 = ChatCompletionAgent(...)
agent2 = OpenAIAssistantAgent(...)
# Create chat with participating agents
chat = AgentGroupChat(
agents=[agent1, agent2],
termination_strategy=DefaultTerminationStrategy(maximum_iterations=10),
)
async for response in chat.invoke():
# process agent response(s)
代理程式目前無法在Java中使用。
存取聊天記錄
AgentChat
交談歷程記錄一律可供存取,即使訊息是透過調用模式傳遞。 這可確保過去交換在整個交談中仍可供使用。
注意:會先提供最新的訊息(遞減順序:最新到最舊)。
// Define and use a chat
AgentGroupChat chat = ...;
// Access history for a previously utilized AgentGroupChat
ChatMessageContent[] history = await chat.GetChatMessagesAsync().ToArrayAsync();
# Define a group chat
chat = AgentGroupChat(...)
# Access history for a previously utilized AgentGroupChat
history = await chat.get_chat_messages()
代理程式目前無法在Java中使用。
由於不同的代理程式類型或組態可能會維護自己的交談歷程記錄版本,因此代理程式特定歷程記錄也可藉由指定代理程式來使用。 (例如:OpenAIAssistant
與 ChatCompletionAgent
。
// Agents to participate in chat
ChatCompletionAgent agent1 = ...;
OpenAIAssistantAgent agent2 = ...;
// Define a group chat
AgentGroupChat chat = ...;
// Access history for a previously utilized AgentGroupChat
ChatMessageContent[] history1 = await chat.GetChatMessagesAsync(agent1).ToArrayAsync();
ChatMessageContent[] history2 = await chat.GetChatMessagesAsync(agent2).ToArrayAsync();
# Agents to participate in a chat
agent1 = ChatCompletionAgent(...)
agent2 = OpenAIAssistantAgent(...)
# Define a group chat
chat = AgentGroupChat(...)
# Access history for a previously utilized AgentGroupChat
history1 = await chat.get_chat_messages(agent=agent1)
history2 = await chat.get_chat_messages(agent=agent2)
代理程式目前無法在Java中使用。
定義 AgentGroupChat
行為
代理程式之間的共同作業來解決複雜的工作是核心代理模式。 若要有效地使用此模式,系統必須就緒,不僅會決定哪些代理程式應該在每個回合期間回應,而且會評估交談何時達到其預期目標。 這需要管理代理選擇,並建立交談終止的明確準則,以確保代理之間的順暢合作,達成解決方案。 這兩個層面都是由 [執行設定 ] 屬性所控管。
下列各節「 代理程式選取 」和 「聊天終止」將詳細探討這些考慮。
代理選擇
在多回合調用中,代理程式選取是由 選取策略引導。 此策略是由基類所定義,可擴充以實作針對特定需求量身打造的自定義行為。 為了方便起見,也提供兩個預先定義的具體 選取策略 ,提供在交談期間處理代理程式選取的現成使用方法。
如果已知,可能會指定起始代理以總是先執行第一個回合。 在使用以 KernelFunction
為基礎的策略時,可能會使用歷史縮減器來限制令牌的使用量。
.NET 選取策略 API:
SelectionStrategy
SequentialSelectionStrategy
KernelFunctionSelectionStrategy
Microsoft.SemanticKernel.Agents.History
// Define the agent names for use in the function template
const string WriterName = "Writer";
const string ReviewerName = "Reviewer";
// Initialize a Kernel with a chat-completion service
Kernel kernel = ...;
// Create the agents
ChatCompletionAgent writerAgent =
new()
{
Name = WriterName,
Instructions = "<writer instructions>",
Kernel = kernel
};
ChatCompletionAgent reviewerAgent =
new()
{
Name = ReviewerName,
Instructions = "<reviewer instructions>",
Kernel = kernel
};
// Define a kernel function for the selection strategy
KernelFunction selectionFunction =
AgentGroupChat.CreatePromptFunctionForStrategy(
$$$"""
Determine which participant takes the next turn in a conversation based on the the most recent participant.
State only the name of the participant to take the next turn.
No participant should take more than one turn in a row.
Choose only from these participants:
- {{{ReviewerName}}}
- {{{WriterName}}}
Always follow these rules when selecting the next participant:
- After {{{WriterName}}}, it is {{{ReviewerName}}}'s turn.
- After {{{ReviewerName}}}, it is {{{WriterName}}}'s turn.
History:
{{$history}}
""",
safeParameterNames: "history");
// Define the selection strategy
KernelFunctionSelectionStrategy selectionStrategy =
new(selectionFunction, kernel)
{
// Always start with the writer agent.
InitialAgent = writerAgent,
// Parse the function response.
ResultParser = (result) => result.GetValue<string>() ?? WriterName,
// The prompt variable name for the history argument.
HistoryVariableName = "history",
// Save tokens by not including the entire history in the prompt
HistoryReducer = new ChatHistoryTruncationReducer(3),
};
// Create a chat using the defined selection strategy.
AgentGroupChat chat =
new(writerAgent, reviewerAgent)
{
ExecutionSettings = new() { SelectionStrategy = selectionStrategy }
};
REVIEWER_NAME = "Reviewer"
WRITER_NAME = "Writer"
agent_reviewer = ChatCompletionAgent(
kernel=kernel,
name=REVIEWER_NAME,
instructions="<instructions>",
)
agent_writer = ChatCompletionAgent(
kernel=kernel,
name=WRITER_NAME,
instructions="<instructions>",
)
selection_function = KernelFunctionFromPrompt(
function_name="selection",
prompt=f"""
Determine which participant takes the next turn in a conversation based on the the most recent participant.
State only the name of the participant to take the next turn.
No participant should take more than one turn in a row.
Choose only from these participants:
- {REVIEWER_NAME}
- {WRITER_NAME}
Always follow these rules when selecting the next participant:
- After user input, it is {WRITER_NAME}'s turn.
- After {WRITER_NAME} replies, it is {REVIEWER_NAME}'s turn.
- After {REVIEWER_NAME} provides feedback, it is {WRITER_NAME}'s turn.
History:
{{{{$history}}}}
""",
)
chat = AgentGroupChat(
agents=[agent_writer, agent_reviewer],
selection_strategy=KernelFunctionSelectionStrategy(
function=selection_function,
kernel=_create_kernel_with_chat_completion("selection"),
result_parser=lambda result: str(result.value[0]) if result.value is not None else COPYWRITER_NAME,
agent_variable_name="agents",
history_variable_name="history",
),
)
代理程式目前無法在Java中使用。
聊天終止
在 多回合 調用中,終止 策略 會決定何時進行最終回合。 此策略可確保對話會在適當的時間點結束。
此策略是由基類所定義,可擴充以實作針對特定需求量身打造的自定義行為。 為了方便起見,也提供數個預先定義的具體 選擇策略,提供現成的方法來定義 AgentChat
交談的終止準則。
.NET 選取策略 API:
TerminationStrategy
RegexTerminationStrategy
KernelFunctionSelectionStrategy
KernelFunctionTerminationStrategy
AggregatorTerminationStrategy
Microsoft.SemanticKernel.Agents.History
// Initialize a Kernel with a chat-completion service
Kernel kernel = ...;
// Create the agents
ChatCompletionAgent writerAgent =
new()
{
Name = "Writer",
Instructions = "<writer instructions>",
Kernel = kernel
};
ChatCompletionAgent reviewerAgent =
new()
{
Name = "Reviewer",
Instructions = "<reviewer instructions>",
Kernel = kernel
};
// Define a kernel function for the selection strategy
KernelFunction terminationFunction =
AgentGroupChat.CreatePromptFunctionForStrategy(
$$$"""
Determine if the reviewer has approved. If so, respond with a single word: yes
History:
{{$history}}
""",
safeParameterNames: "history");
// Define the termination strategy
KernelFunctionTerminationStrategy terminationStrategy =
new(selectionFunction, kernel)
{
// Only the reviewer may give approval.
Agents = [reviewerAgent],
// Parse the function response.
ResultParser = (result) =>
result.GetValue<string>()?.Contains("yes", StringComparison.OrdinalIgnoreCase) ?? false,
// The prompt variable name for the history argument.
HistoryVariableName = "history",
// Save tokens by not including the entire history in the prompt
HistoryReducer = new ChatHistoryTruncationReducer(1),
// Limit total number of turns no matter what
MaximumIterations = 10,
};
// Create a chat using the defined termination strategy.
AgentGroupChat chat =
new(writerAgent, reviewerAgent)
{
ExecutionSettings = new() { TerminationStrategy = terminationStrategy }
};
REVIEWER_NAME = "Reviewer"
WRITER_NAME = "Writer"
agent_reviewer = ChatCompletionAgent(
kernel=kernel,
name=REVIEWER_NAME,
instructions="<instructions>",
)
agent_writer = ChatCompletionAgent(
kernel=kernel,
name=WRITER_NAME,
instructions="<instructions>",
)
termination_function = KernelFunctionFromPrompt(
function_name="termination",
prompt="""
Determine if the copy has been approved. If so, respond with a single word: yes
History:
{{$history}}
""",
)
chat = AgentGroupChat(
agents=[agent_writer, agent_reviewer],
termination_strategy=KernelFunctionTerminationStrategy(
agents=[agent_reviewer],
function=termination_function,
kernel=_create_kernel_with_chat_completion("termination"),
result_parser=lambda result: str(result.value[0]).lower() == "yes",
history_variable_name="history",
maximum_iterations=10,
),
)
代理程式目前無法在Java中使用。
重設聊天完成狀態
不論使用單回合或多回合方法叫用 AgentGroupChat
,AgentGroupChat
的狀態都會更新,表示在符合終止準則之後,完成。 這可確保系統會在對話完全結束時辨識。 若要在 AgentGroupChat
狀態之後繼續使用 實例,必須重設此狀態,才能允許進一步的互動。 若未重設,將無法進行其他互動或代理程序回應。
在達到最大回合限制的多回合調用的情況下,系統會停止代理程序調用,但不會將實例標示為 已完成。 這可讓您擴充交談的可能性,而不需要重設 完成 狀態。
// Define an use chat
AgentGroupChat chat = ...;
// Evaluate if completion is met and reset.
if (chat.IsComplete)
{
// Opt to take action on the chat result...
// Reset completion state to continue use
chat.IsComplete = false;
}
# Define a group chat
chat = AgentGroupChat()
# Evaluate if completion is met and reset
if chat.is_complete:
# Reset completion state to continue use
chat.is_complete = False
代理程式目前無法在Java中使用。
清除整個對話狀態
完成使用 AgentChat
並有 OpenAIAssistant
參與後,可能需要刪除與 助理相關聯的遠端 線程。
AgentChat
支援重設或清除整個交談狀態,包括刪除任何遠端 線程 定義。 這可確保聊天結束后,沒有任何剩餘的交談數據會與助理連結。
完整重設不會移除已加入 的 AgentChat
,並將 AgentChat
保留在可以重複使用的狀態。 這可讓您接續與相同代理程序的互動,而不需要重新初始化它們,讓未來的交談更有效率。
// Define an use chat
AgentGroupChat chat = ...;
// Clear the all conversation state
await chat.ResetAsync();
# Define a group chat
chat = AgentGroupChat()
# Clear the conversation state
await chat.reset()
代理程式目前無法在Java中使用。
使用指南
如需使用 AgentGroupChat
進行 Agent
共同作業的端對端範例,請參閱:
-
如何使用
AgentGroupChat
協調代理程式共同作業