Files
agent-framework/dotnet/samples/02-agents/AgentsWithFoundry/Agent_Step16_FileSearch/Program.cs
T
Ben Thomas c79f886dc3 .NET: Align Foundry sample environment variables and credentials. (#6422)
* dotnet: refresh Foundry sample guidance

Carry forward the still-relevant sample guidance and Foundry-specific documentation fixes from the old stacked sample migration work, adapted to the current repo layout and policy.

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

* dotnet: rename Foundry sample env vars

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

* dotnet: remove persistent provider sample

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

* dotnet: drop SAMPLE_GUIDELINES.md from this PR

Defer the guidelines doc and its cross-link to a follow-on PR to avoid broken-link failures in CI.

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

* dotnet: add DefaultAzureCredential warning to remaining samples

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

* dotnet: address PR review feedback

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-11 17:26:00 +00:00

83 lines
3.7 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
// This sample shows how to use File Search Tool with a ChatClientAgent.
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI.Assistants;
using OpenAI.Files;
string endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("FOUNDRY_MODEL") ?? "gpt-5.4-mini";
const string AgentInstructions = "You are a helpful assistant that can search through uploaded files to answer questions.";
// We need the AIProjectClient to upload files and create vector stores.
// 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.
AIProjectClient aiProjectClient = new(new Uri(endpoint), new DefaultAzureCredential());
var projectOpenAIClient = aiProjectClient.GetProjectOpenAIClient();
var filesClient = projectOpenAIClient.GetProjectFilesClient();
var vectorStoresClient = projectOpenAIClient.GetProjectVectorStoresClient();
// 1. Create a temp file with test content and upload it.
string searchFilePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + "_lookup.txt");
File.WriteAllText(
path: searchFilePath,
contents: """
Employee Directory:
- Alice Johnson, 28 years old, Software Engineer, Engineering Department
- Bob Smith, 35 years old, Sales Manager, Sales Department
- Carol Williams, 42 years old, HR Director, Human Resources Department
- David Brown, 31 years old, Customer Support Lead, Support Department
"""
);
Console.WriteLine($"Uploading file: {searchFilePath}");
OpenAIFile uploadedFile = filesClient.UploadFile(
filePath: searchFilePath,
purpose: FileUploadPurpose.Assistants
);
Console.WriteLine($"Uploaded file, file ID: {uploadedFile.Id}");
// 2. Create a vector store with the uploaded file.
var vectorStoreResult = await vectorStoresClient.CreateVectorStoreAsync(
options: new() { FileIds = { uploadedFile.Id }, Name = "EmployeeDirectory_VectorStore" }
);
string vectorStoreId = vectorStoreResult.Value.Id;
Console.WriteLine($"Created vector store, vector store ID: {vectorStoreId}");
// Create a AIAgent with HostedFileSearchTool.
AIAgent agent = aiProjectClient.AsAIAgent(deploymentName,
instructions: AgentInstructions,
name: "FileSearchAgent-RAPI",
tools: [new HostedFileSearchTool() { Inputs = [new HostedVectorStoreContent(vectorStoreId)] }]);
// Run the agent
Console.WriteLine("\n--- Running File Search Agent ---");
AgentResponse response = await agent.RunAsync("Who is the youngest employee?");
Console.WriteLine($"Response: {response}");
// Getting any file citation annotations generated by the tool
foreach (AIAnnotation annotation in response.Messages.SelectMany(m => m.Contents).SelectMany(c => c.Annotations ?? []))
{
if (annotation.RawRepresentation is TextAnnotationUpdate citationAnnotation)
{
Console.WriteLine($$"""
File Citation:
File Id: {{citationAnnotation.OutputFileId}}
Text to Replace: {{citationAnnotation.TextToReplace}}
""");
}
}
// Cleanup file resources.
Console.WriteLine("\n--- Cleanup ---");
await vectorStoresClient.DeleteVectorStoreAsync(vectorStoreId);
await filesClient.DeleteFileAsync(uploadedFile.Id);
File.Delete(searchFilePath);
Console.WriteLine("Cleanup completed successfully.");