Skip to content

Instantly share code, notes, and snippets.

@pavlovmilen
Created September 2, 2024 15:26
Show Gist options
  • Save pavlovmilen/5e22d7d000eaf8225effc436fc725457 to your computer and use it in GitHub Desktop.
Save pavlovmilen/5e22d7d000eaf8225effc436fc725457 to your computer and use it in GitHub Desktop.
public async Task<ApiResponse<string>> ChatWithChatGPTAsync(string context, string myQuestion)
{
var result = new ApiResponse<string>();
try
{
var url = _configuration.GetValue<string>("AzureOpenAiApi:Endpoint");
var key = _configuration.GetValue<string>("AzureOpenAiApi:SubscriptionKey");
var openAIClient = new AzureOpenAIClient(new Uri(url), new AzureKeyCredential(key));
var chatClient = openAIClient.GetChatClient(_configuration.GetValue<string>("AzureOpenAiApi:DeploymentName"));
var inputMessages = new List<ChatMessage>
{
new SystemChatMessage(Consts.RagPrompt),
new UserChatMessage($"Given this context: {context} my question is {myQuestion}, can you provide me with an answer"),
};
var chatCompletionOptions = new ChatCompletionOptions
{
Temperature = _configuration.GetValue<float>("AzureOpenAiApi:Temperature"),
MaxTokens = 1200,
FrequencyPenalty = 0,
PresencePenalty = 0,
};
chatCompletionOptions.Tools.Add(ChatToolGenerator.CreateCrimeContextTool());
ChatCompletion completion = await chatClient.CompleteChatAsync(inputMessages, chatCompletionOptions);
if (completion.FinishReason == ChatFinishReason.ToolCalls)
{
try
{
var toolResult = string.Empty;
foreach (var toolCall in completion.ToolCalls)
{
switch (toolCall.FunctionName)
{
case "CrimeAtLocationForPostcode":
var arguments = JsonSerializer.Deserialize<GetPostcodeArguments>(toolCall.FunctionArguments);
var crimeContext = await _functions.CrimeAtLocationForPostcode(arguments.postcode);
if (crimeContext == "No data found")
{
toolResult = "No data found";
}
else
{
// Add the crimeContext as a new input message
inputMessages.Add(new SystemChatMessage(Consts.MyCrimeSummarySystemPromt));
inputMessages.Add(new SystemChatMessage($"Crime data for {arguments.postcode} is: {crimeContext}"));
// Now, make a final call with the updated input messages
ChatCompletion finalCompletion = await chatClient.CompleteChatAsync(inputMessages, chatCompletionOptions);
// Process the final response
toolResult = finalCompletion.Content[0].Text;
var properties = new Dictionary<string, string>
{
{ "TotalTokens", finalCompletion.Usage?.TotalTokens.ToString() },
{ "PromptTokens", finalCompletion.Usage?.InputTokens.ToString() },
{ "CompletionTokens", finalCompletion.Usage?.OutputTokens.ToString() },
};
_telemetryClient.TrackMetric("AzureOpenAIApiResponseTotalTokens", finalCompletion?.Usage?.TotalTokens ?? 0, properties);
}
break;
}
}
result.IsSuccess = true;
result.Data = toolResult;
return result;
}
catch (Exception exept)
{
_logger.LogError(exept, "Error while processing tool calls");
throw;
}
}
else
{
if (completion == null)
{
var message = "No value from Azure response api";
_logger.LogError(message);
result.Message = message;
result.IsSuccess = false;
return result;
}
if (completion.Content.Count == 0)
{
var message = "No response from Azure Open AI API";
_logger.LogError(message);
result.Message = message;
result.IsSuccess = false;
return result;
}
var properties = new Dictionary<string, string>
{
{ "TotalTokens", completion.Usage?.TotalTokens.ToString() },
{ "PromptTokens", completion.Usage?.InputTokens.ToString() },
{ "CompletionTokens", completion.Usage?.OutputTokens.ToString() },
};
_telemetryClient.TrackMetric("AzureOpenAIApiResponseTotalTokens", completion?.Usage?.TotalTokens ?? 0, properties);
result.Data = completion.Content[0].Text;
result.IsSuccess = true;
return result;
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment