Files
agent-framework/dotnet/samples/05-end-to-end/HostedAgents/AgentWithTextSearchRag/Program.cs
Copilot 7e98b0cd29 .NET: Update HostedAgents samples to Azure.AI.AgentServer.AgentFramework 1.0.0-beta.9 and MEAI 10.3.0 (#4477)
* Initial plan

* Update HostedAgents samples to Azure.AI.AgentServer.AgentFramework 1.0.0-beta.9 and MEAI 10.3.0

Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>

* Fix HostedAgents samples for Microsoft.Agents.AI 1.0.0-rc2 API changes

- Rename CreateAIAgent -> AsAIAgent (AgentThreadAndHITL, AgentWithHostedMCP, AgentWithTextSearchRag)
- Rename AsAgent -> AsAIAgent (AgentsInWorkflows)
- Replace AIContextProviderFactory with AIContextProviders and simplified TextSearchProvider ctor (AgentWithTextSearchRag)
- Update Microsoft.Agents.AI.OpenAI to 1.0.0-rc2 (AgentThreadAndHITL, AgentWithTextSearchRag, AgentWithTools)
- Update Microsoft.Agents.AI.Workflows to 1.0.0-rc2 (AgentsInWorkflows)
- Add Microsoft.Agents.AI 1.0.0-rc2 reference (AgentWithHostedMCP)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update HostedAgents samples for beta.9 API changes and add missing projects to slnx

- Use DefaultAzureCredential consistently across all samples
- Add AgentThreadAndHITL, AgentWithLocalTools, AgentWithTools to slnx
- Apply dotnet format

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove unnecessary Microsoft.Agents.AI.* package references (transitive from AgentFramework)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add DefaultAzureCredential production warning comments to all HostedAgents samples

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update HostedAgents READMEs to reflect DefaultAzureCredential usage

Replace AzureCliCredential references with DefaultAzureCredential in all
HostedAgents README files to match the actual sample code.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Replace Microsoft.Extensions.AI.OpenAI with Microsoft.Agents.AI.OpenAI and remove AsIChatClient()

Swap package references from Microsoft.Extensions.AI.OpenAI to
Microsoft.Agents.AI.OpenAI across all 6 HostedAgents samples. This enables
using the AsAIAgent() extension directly on ChatClient/ResponsesClient
(from OpenAI.Chat/OpenAI.Responses namespaces), removing the intermediate
AsIChatClient() call in 3 samples where it was unnecessary.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Use explicit types and AsAIAgent() extensions across all HostedAgents samples

Replace var with explicit types for clarity in all 6 samples. Replace
new ChatClientAgent() constructor calls with chatClient.AsAIAgent()
extension method in AgentWithLocalTools and AgentsInWorkflows.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-06 12:15:10 +00:00

80 lines
3.8 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
// This sample shows how to use TextSearchProvider to add retrieval augmented generation (RAG)
// capabilities to an AI agent. The provider runs a search against an external knowledge base
// before each model invocation and injects the results into the model context.
using Azure.AI.AgentServer.AgentFramework.Extensions;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI.Chat;
string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
TextSearchProviderOptions textSearchOptions = new()
{
// Run the search prior to every model invocation and keep a short rolling window of conversation context.
SearchTime = TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke,
RecentMessageMemoryLimit = 6,
};
// 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.
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetChatClient(deploymentName)
.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new ChatOptions
{
Instructions = "You are a helpful support specialist for Contoso Outdoors. Answer questions using the provided context and cite the source document when available.",
},
AIContextProviders = [new TextSearchProvider(MockSearchAsync, textSearchOptions)]
});
await agent.RunAIAgentAsync();
static Task<IEnumerable<TextSearchProvider.TextSearchResult>> MockSearchAsync(string query, CancellationToken cancellationToken)
{
// The mock search inspects the user's question and returns pre-defined snippets
// that resemble documents stored in an external knowledge source.
List<TextSearchProvider.TextSearchResult> results = [];
if (query.Contains("return", StringComparison.OrdinalIgnoreCase) || query.Contains("refund", StringComparison.OrdinalIgnoreCase))
{
results.Add(new()
{
SourceName = "Contoso Outdoors Return Policy",
SourceLink = "https://contoso.com/policies/returns",
Text = "Customers may return any item within 30 days of delivery. Items should be unused and include original packaging. Refunds are issued to the original payment method within 5 business days of inspection."
});
}
if (query.Contains("shipping", StringComparison.OrdinalIgnoreCase))
{
results.Add(new()
{
SourceName = "Contoso Outdoors Shipping Guide",
SourceLink = "https://contoso.com/help/shipping",
Text = "Standard shipping is free on orders over $50 and typically arrives in 3-5 business days within the continental United States. Expedited options are available at checkout."
});
}
if (query.Contains("tent", StringComparison.OrdinalIgnoreCase) || query.Contains("fabric", StringComparison.OrdinalIgnoreCase))
{
results.Add(new()
{
SourceName = "TrailRunner Tent Care Instructions",
SourceLink = "https://contoso.com/manuals/trailrunner-tent",
Text = "Clean the tent fabric with lukewarm water and a non-detergent soap. Allow it to air dry completely before storage and avoid prolonged UV exposure to extend the lifespan of the waterproof coating."
});
}
return Task.FromResult<IEnumerable<TextSearchProvider.TextSearchResult>>(results);
}