mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
d3f0c33180
* Checkpoint * Checkpoint * Stable * Strategies * Updated * Encoding * Formatting * Cleanup * Formatting * Tests * Tuning * Update tests * Test update * Remove working solution * Add sample to solution * Sample readyme * Experimental * Format * Formatting * Encoding * Support IChatReducer * Sample output formatting * Initial plan * Replace CompactingChatClient with MessageCompactionContextProvider Co-authored-by: crickman <66376200+crickman@users.noreply.github.com> * Boundary condition * Fix encoding * Fix cast * Test coverage * Namespace * Improvements * Efficiency * Cleanup * Detect service managed conversation * Fix namespace * Fix merge * Fix test expectation * Update dotnet/src/Microsoft.Agents.AI.Abstractions/InMemoryChatHistoryProvider.cs Co-authored-by: westey <164392973+westey-m@users.noreply.github.com> * Address PR comments (x1) * Update comment * Update comments * Clean-up * Format output * Sync sample comment * Fix condition * Adjust data-flow * Address comments (x2) * Direct compaction * Fix summarization content * Argument check / fix count calculation * Minor follow-up * Diagnostics * Minor updates * Fix state test * Fix sliding window perf * Stable state keys * Increase size computation * Formatting * Add README.md for Agent_Step18_CompactionPipeline sample (#4574) * Sample comments * Updated * Update dotnet/src/Microsoft.Agents.AI/Compaction/MessageIndex.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/tests/Microsoft.Agents.AI.UnitTests/Compaction/CompactionProviderTests.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/src/Microsoft.Agents.AI/Compaction/MessageIndex.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Address copilot comments * Fix namespace * Comments / convensions * Prefix `MessageGroup` and `MessageIndex` * Fix sliding window * Update dotnet/src/Microsoft.Agents.AI/Compaction/SummarizationCompactionStrategy.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/src/Microsoft.Agents.AI.Abstractions/InMemoryChatHistoryProvider.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Python alignment * Fix merge * Fix equality, readme, and sample * Readme update and ToolResult fix * Update dotnet/src/Microsoft.Agents.AI/Compaction/SummarizationCompactionStrategy.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/samples/02-agents/Agents/Agent_Step18_CompactionPipeline/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Simplify readme * Update dotnet/samples/02-agents/Agents/Agent_Step18_CompactionPipeline/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Remove example * Remove unused --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: westey <164392973+westey-m@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
121 lines
5.5 KiB
C#
121 lines
5.5 KiB
C#
// Copyright (c) Microsoft. All rights reserved.
|
|
|
|
// This sample demonstrates how to use a CompactionProvider with a compaction pipeline
|
|
// as an AIContextProvider for an agent's in-run context management. The pipeline chains multiple
|
|
// compaction strategies from gentle to aggressive:
|
|
// 1. ToolResultCompactionStrategy - Collapses old tool-call groups into concise summaries
|
|
// 2. SummarizationCompactionStrategy - LLM-compresses older conversation spans
|
|
// 3. SlidingWindowCompactionStrategy - Keeps only the most recent N user turns
|
|
// 4. TruncationCompactionStrategy - Emergency token-budget backstop
|
|
|
|
using System.ComponentModel;
|
|
using Azure.AI.OpenAI;
|
|
using Azure.Identity;
|
|
using Microsoft.Agents.AI;
|
|
using Microsoft.Agents.AI.Compaction;
|
|
using Microsoft.Extensions.AI;
|
|
|
|
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
|
|
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
|
|
|
// WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production.
|
|
// In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid
|
|
// latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
|
|
AzureOpenAIClient openAIClient = new(new Uri(endpoint), new DefaultAzureCredential());
|
|
|
|
// Create a chat client for the agent and a separate one for the summarization strategy.
|
|
// Using the same model for simplicity; in production, use a smaller/cheaper model for summarization.
|
|
IChatClient agentChatClient = openAIClient.GetChatClient(deploymentName).AsIChatClient();
|
|
IChatClient summarizerChatClient = openAIClient.GetChatClient(deploymentName).AsIChatClient();
|
|
|
|
// Define a tool the agent can use, so we can see tool-result compaction in action.
|
|
[Description("Look up the current price of a product by name.")]
|
|
static string LookupPrice([Description("The product name to look up.")] string productName) =>
|
|
productName.ToUpperInvariant() switch
|
|
{
|
|
"LAPTOP" => "The laptop costs $999.99.",
|
|
"KEYBOARD" => "The keyboard costs $79.99.",
|
|
"MOUSE" => "The mouse costs $29.99.",
|
|
_ => $"Sorry, I don't have pricing for '{productName}'."
|
|
};
|
|
|
|
// Configure the compaction pipeline with one of each strategy, ordered least to most aggressive.
|
|
PipelineCompactionStrategy compactionPipeline =
|
|
new(// 1. Gentle: collapse old tool-call groups into short summaries
|
|
new ToolResultCompactionStrategy(CompactionTriggers.MessagesExceed(7)),
|
|
|
|
// 2. Moderate: use an LLM to summarize older conversation spans into a concise message
|
|
new SummarizationCompactionStrategy(summarizerChatClient, CompactionTriggers.TokensExceed(0x500)),
|
|
|
|
// 3. Aggressive: keep only the last N user turns and their responses
|
|
new SlidingWindowCompactionStrategy(CompactionTriggers.TurnsExceed(4)),
|
|
|
|
// 4. Emergency: drop oldest groups until under the token budget
|
|
new TruncationCompactionStrategy(CompactionTriggers.TokensExceed(0x8000)));
|
|
|
|
// Create the agent with a CompactionProvider that uses the compaction pipeline.
|
|
AIAgent agent =
|
|
agentChatClient
|
|
.AsBuilder()
|
|
// Note: Adding the CompactionProvider at the builder level means it will be applied to all agents
|
|
// built from this builder and will manage context for both agent messages and tool calls.
|
|
.UseAIContextProviders(new CompactionProvider(compactionPipeline))
|
|
.BuildAIAgent(
|
|
new ChatClientAgentOptions
|
|
{
|
|
Name = "ShoppingAssistant",
|
|
ChatOptions = new()
|
|
{
|
|
Instructions =
|
|
"""
|
|
You are a helpful, but long winded, shopping assistant.
|
|
Help the user look up prices and compare products.
|
|
When responding, Be sure to be extra descriptive and use as
|
|
many words as possible without sounding ridiculous.
|
|
""",
|
|
Tools = [AIFunctionFactory.Create(LookupPrice)]
|
|
},
|
|
// Note: AIContextProviders may be specified here instead of ChatClientBuilder.UseAIContextProviders.
|
|
// Specifying compaction at the agent level skips compaction in the function calling loop.
|
|
//AIContextProviders = [new CompactionProvider(compactionPipeline)]
|
|
});
|
|
|
|
AgentSession session = await agent.CreateSessionAsync();
|
|
|
|
// Helper to print chat history size
|
|
void PrintChatHistory()
|
|
{
|
|
if (session.TryGetInMemoryChatHistory(out var history))
|
|
{
|
|
Console.ForegroundColor = ConsoleColor.Cyan;
|
|
Console.WriteLine($"\n[Messages: #{history.Count}]\n");
|
|
Console.ResetColor();
|
|
}
|
|
}
|
|
|
|
// Run a multi-turn conversation with tool calls to exercise the pipeline.
|
|
string[] prompts =
|
|
[
|
|
"What's the price of a laptop?",
|
|
"How about a keyboard?",
|
|
"And a mouse?",
|
|
"Which product is the cheapest?",
|
|
"Can you compare the laptop and the keyboard for me?",
|
|
"What was the first product I asked about?",
|
|
"Thank you!",
|
|
];
|
|
|
|
foreach (string prompt in prompts)
|
|
{
|
|
Console.ForegroundColor = ConsoleColor.Cyan;
|
|
Console.Write("\n[User] ");
|
|
Console.ResetColor();
|
|
Console.WriteLine(prompt);
|
|
Console.ForegroundColor = ConsoleColor.Cyan;
|
|
Console.Write("\n[Agent] ");
|
|
Console.ResetColor();
|
|
Console.WriteLine(await agent.RunAsync(prompt, session));
|
|
|
|
PrintChatHistory();
|
|
}
|