-
Notifications
You must be signed in to change notification settings - Fork 133
Expand file tree
/
Copy pathProgram.cs
More file actions
117 lines (99 loc) · 4.1 KB
/
Copy pathProgram.cs
File metadata and controls
117 lines (99 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using System.ClientModel;
using System.ClientModel.Primitives;
using System.IO;
using System.Reflection;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;
using OpenAI.Files;
using OpenAI.VectorStores;
using DotNetEnv;
Env.Load("../../../../.env");
var endpoint = Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_AI_PROJECT_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
// Create an AI Project client and get an OpenAI client that works with the foundry service.
AIProjectClient aiProjectClient = new(
new Uri(endpoint),
new AzureCliCredential());
OpenAIClient openAIClient = aiProjectClient.GetProjectOpenAIClient();
// Upload the file that contains the data to be used for RAG to the Foundry service.
OpenAIFileClient fileClient = openAIClient.GetOpenAIFileClient();
ClientResult<OpenAIFile> uploadResult;
try
{
uploadResult = await fileClient.UploadFileAsync(
filePath: "../document.md",
purpose: FileUploadPurpose.Assistants);
}
catch (ClientResultException ex)
{
LogDetailedClientError("File upload failed", ex);
throw;
}
#pragma warning disable OPENAI001
VectorStoreClient vectorStoreClient = openAIClient.GetVectorStoreClient();
ClientResult<VectorStore> vectorStoreCreate = await vectorStoreClient.CreateVectorStoreAsync(options: new VectorStoreCreationOptions()
{
Name = "document-knowledge-base",
FileIds = { uploadResult.Value.Id }
});
#pragma warning restore OPENAI001
var fileSearchTool = new HostedFileSearchTool() { Inputs = [new HostedVectorStoreContent(vectorStoreCreate.Value.Id)] };
AIAgent agent = await aiProjectClient
.CreateAIAgentAsync(
model: deploymentName,
name: "dotNETRAGAgent",
instructions: @"You are an AI assistant designed to answer user questions using only the information retrieved from the provided document(s).
If a user's question cannot be answered using the retrieved context, you must clearly respond:
'I'm sorry, but the uploaded document does not contain the necessary information to answer that question.'
Do not answer from general knowledge or reasoning. Do not make assumptions or generate hypothetical explanations.
For questions that do have relevant content in the document, respond accurately and cite the document explicitly.",
tools: [fileSearchTool]);
AgentSession session = await agent.CreateSessionAsync();
//Console.WriteLine(await agent.RunAsync("Can you explain Contoso's travel insurance coverage?", session));
Console.WriteLine(await agent.RunAsync("What is the weather in Ohio today?", session));
static void LogDetailedClientError(string context, ClientResultException ex)
{
Console.Error.WriteLine($"[Client Error] {context}");
Console.Error.WriteLine($"Status: {ex.Status}");
Console.Error.WriteLine($"Message: {ex.Message}");
var responseBody = TryExtractResponseBody(ex);
if (!string.IsNullOrWhiteSpace(responseBody))
{
Console.Error.WriteLine("Server response body:");
Console.Error.WriteLine(responseBody);
}
}
static string? TryExtractResponseBody(ClientResultException ex)
{
try
{
var responseField = typeof(ClientResultException).GetField("_response", BindingFlags.NonPublic | BindingFlags.Instance);
if (responseField?.GetValue(ex) is PipelineResponse response)
{
var stream = response.ContentStream;
if (stream == null)
{
return null;
}
if (stream.CanSeek)
{
stream.Position = 0;
}
using var reader = new StreamReader(stream, leaveOpen: true);
var body = reader.ReadToEnd();
if (stream.CanSeek)
{
stream.Position = 0;
}
return body;
}
}
catch
{
// Ignore reflection or IO errors when extracting diagnostics.
}
return null;
}