Files
ImportAssist/tools/ImportAssist.Analyze/Program.cs
T

131 lines
3.4 KiB
C#

using System.ClientModel;
using Azure.AI.OpenAI;
using Microsoft.Extensions.Configuration;
using OpenAI.Chat;
if (args.Length != 1)
{
Console.Error.WriteLine(
"Aufruf aus dem Repository-Hauptverzeichnis: " +
"dotnet run --project tools/ImportAssist.Analyze -- <Prüfbericht.json>");
return 1;
}
var configuration = new ConfigurationBuilder()
.AddUserSecrets<Program>()
.Build();
var endpoint = configuration["AzureOpenAI:Endpoint"];
var deployment = configuration["AzureOpenAI:Deployment"];
var apiKey = configuration["AzureOpenAI:ApiKey"];
if (string.IsNullOrWhiteSpace(endpoint) ||
string.IsNullOrWhiteSpace(deployment) ||
string.IsNullOrWhiteSpace(apiKey))
{
Console.Error.WriteLine(
"Konfiguration fehlt: Endpoint, Deployment und ApiKey " +
"müssen in den User Secrets gesetzt sein.");
return 1;
}
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out var endpointUri) ||
endpointUri.Scheme != Uri.UriSchemeHttps)
{
Console.Error.WriteLine("Endpoint muss eine gültige HTTPS-Adresse sein.");
return 1;
}
try
{
var instructions = await File.ReadAllTextAsync(
"docs/ai-analysis-prompt.md");
var specification = await File.ReadAllTextAsync(
"docs/invoice-interface-v1.md");
var report = await File.ReadAllTextAsync(args[0]);
if (string.IsNullOrWhiteSpace(instructions) ||
string.IsNullOrWhiteSpace(specification) ||
string.IsNullOrWhiteSpace(report))
{
Console.Error.WriteLine("Eine der Eingabedateien ist leer.");
return 1;
}
var azureClient = new AzureOpenAIClient(
endpointUri, new ApiKeyCredential(apiKey));
var chatClient = azureClient.GetChatClient(deployment);
ChatMessage[] messages =
[
new SystemChatMessage(instructions),
new UserChatMessage($"""
Schnittstellenbeschreibung:
{specification}
Prüfbericht:
{report}
Analysiere diesen Prüfbericht gemäß deinen Anweisungen
und der beigefügten Schnittstellenbeschreibung.
""")
];
var options = new ChatCompletionOptions
{
MaxOutputTokenCount = 2000
};
Console.Error.WriteLine($"Analyse mit {deployment} läuft ...");
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(90));
ChatCompletion completion = await chatClient.CompleteChatAsync(
messages, options, timeout.Token);
foreach (var part in completion.Content)
{
Console.Write(part.Text);
}
Console.WriteLine();
Console.Error.WriteLine(
$"Tokens: Eingabe {completion.Usage.InputTokenCount}, " +
$"Ausgabe {completion.Usage.OutputTokenCount}");
if (completion.FinishReason != ChatFinishReason.Stop)
{
Console.Error.WriteLine(
$"Antwort nicht regulär abgeschlossen: {completion.FinishReason}");
return 2;
}
return 0;
}
catch (ClientResultException ex)
{
Console.Error.WriteLine(
$"Azure-Modellaufruf fehlgeschlagen. HTTP-Status: {ex.Status}");
return 1;
}
catch (OperationCanceledException)
{
Console.Error.WriteLine("Die Analyse hat das Zeitlimit überschritten.");
return 1;
}
catch (IOException ex)
{
Console.Error.WriteLine($"Dateifehler: {ex.Message}");
return 1;
}
catch (UnauthorizedAccessException)
{
Console.Error.WriteLine("Keine Leseberechtigung für eine Eingabedatei.");
return 1;
}