openai/openai-dotnet

Public

mirrored from https://github.com/openai/openai-dotnetAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.1.0-beta.2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

examples/Chat/Example03_FunctionCallingAsync.cs

141lines · modeblame

9f9f2936Jose Arriaga Maldonado2 years ago1using NUnit.Framework;
2using OpenAI.Chat;
3using System;
4using System.Collections.Generic;
5using System.Text.Json;
6using System.Threading.Tasks;
7
8cc6643fJose Arriaga Maldonado2 years ago8namespace OpenAI.Examples;
9f9f2936Jose Arriaga Maldonado2 years ago9
8cc6643fJose Arriaga Maldonado2 years ago10public partial class ChatExamples
9f9f2936Jose Arriaga Maldonado2 years ago11{
8cc6643fJose Arriaga Maldonado2 years ago12// See Example03_FunctionCalling.cs for the tool and function definitions.
9f9f2936Jose Arriaga Maldonado2 years ago13
14[Test]
8cc6643fJose Arriaga Maldonado2 years ago15public async Task Example03_FunctionCallingAsync()
9f9f2936Jose Arriaga Maldonado2 years ago16{
8cc6643fJose Arriaga Maldonado2 years ago17ChatClient client = new("gpt-4-turbo", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
9f9f2936Jose Arriaga Maldonado2 years ago18
19#region
31c2ba63Jose Arriaga Maldonado1 years ago20List<ChatMessage> messages =
21[
9f9f2936Jose Arriaga Maldonado2 years ago22new UserChatMessage("What's the weather like today?"),
23];
24
25ChatCompletionOptions options = new()
26{
27Tools = { getCurrentLocationTool, getCurrentWeatherTool },
28};
29#endregion
30
31#region
32bool requiresAction;
33
34do
35{
36requiresAction = false;
31c2ba63Jose Arriaga Maldonado1 years ago37ChatCompletion completion = await client.CompleteChatAsync(messages, options);
9f9f2936Jose Arriaga Maldonado2 years ago38
31c2ba63Jose Arriaga Maldonado1 years ago39switch (completion.FinishReason)
9f9f2936Jose Arriaga Maldonado2 years ago40{
41case ChatFinishReason.Stop:
42{
43// Add the assistant message to the conversation history.
31c2ba63Jose Arriaga Maldonado1 years ago44messages.Add(new AssistantChatMessage(completion));
9f9f2936Jose Arriaga Maldonado2 years ago45break;
46}
47
48case ChatFinishReason.ToolCalls:
49{
50// First, add the assistant message with tool calls to the conversation history.
31c2ba63Jose Arriaga Maldonado1 years ago51messages.Add(new AssistantChatMessage(completion));
9f9f2936Jose Arriaga Maldonado2 years ago52
53// Then, add a new tool message for each tool call that is resolved.
31c2ba63Jose Arriaga Maldonado1 years ago54foreach (ChatToolCall toolCall in completion.ToolCalls)
9f9f2936Jose Arriaga Maldonado2 years ago55{
56switch (toolCall.FunctionName)
57{
58case nameof(GetCurrentLocation):
59{
60string toolResult = GetCurrentLocation();
61messages.Add(new ToolChatMessage(toolCall.Id, toolResult));
62break;
63}
64
65case nameof(GetCurrentWeather):
66{
67// The arguments that the model wants to use to call the function are specified as a
68// stringified JSON object based on the schema defined in the tool definition. Note that
69// the model may hallucinate arguments too. Consequently, it is important to do the
70// appropriate parsing and validation before calling the function.
71using JsonDocument argumentsJson = JsonDocument.Parse(toolCall.FunctionArguments);
72bool hasLocation = argumentsJson.RootElement.TryGetProperty("location", out JsonElement location);
73bool hasUnit = argumentsJson.RootElement.TryGetProperty("unit", out JsonElement unit);
74
75if (!hasLocation)
76{
77throw new ArgumentNullException(nameof(location), "The location argument is required.");
78}
79
80string toolResult = hasUnit
81? GetCurrentWeather(location.GetString(), unit.GetString())
82: GetCurrentWeather(location.GetString());
83messages.Add(new ToolChatMessage(toolCall.Id, toolResult));
84break;
85}
86
87default:
88{
89// Handle other unexpected calls.
90throw new NotImplementedException();
91}
92}
93}
94
95requiresAction = true;
96break;
97}
98
99case ChatFinishReason.Length:
100throw new NotImplementedException("Incomplete model output due to MaxTokens parameter or token limit exceeded.");
101
102case ChatFinishReason.ContentFilter:
103throw new NotImplementedException("Omitted content due to a content filter flag.");
104
105case ChatFinishReason.FunctionCall:
106throw new NotImplementedException("Deprecated in favor of tool calls.");
107
108default:
31c2ba63Jose Arriaga Maldonado1 years ago109throw new NotImplementedException(completion.FinishReason.ToString());
9f9f2936Jose Arriaga Maldonado2 years ago110}
111} while (requiresAction);
112#endregion
113
114#region
7a8bc8beJose Arriaga Maldonado1 years ago115foreach (ChatMessage message in messages)
9f9f2936Jose Arriaga Maldonado2 years ago116{
7a8bc8beJose Arriaga Maldonado1 years ago117switch (message)
9f9f2936Jose Arriaga Maldonado2 years ago118{
119case UserChatMessage userMessage:
120Console.WriteLine($"[USER]:");
121Console.WriteLine($"{userMessage.Content[0].Text}");
122Console.WriteLine();
123break;
124
125case AssistantChatMessage assistantMessage when assistantMessage.Content.Count > 0:
126Console.WriteLine($"[ASSISTANT]:");
127Console.WriteLine($"{assistantMessage.Content[0].Text}");
128Console.WriteLine();
129break;
130
131case ToolChatMessage:
132// Do not print any tool messages; let the assistant summarize the tool results instead.
133break;
134
135default:
136break;
137}
138}
139#endregion
140}
141}