openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.0.0-beta.10

Branches

Tags

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

Clone

HTTPS

Download ZIP

examples/Chat/Example03_FunctionCallingAsync.cs

146lines · 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
20List<ChatMessage> messages = [
21new UserChatMessage("What's the weather like today?"),
22];
23
24ChatCompletionOptions options = new()
25{
26Tools = { getCurrentLocationTool, getCurrentWeatherTool },
27};
28#endregion
29
30#region
31bool requiresAction;
32
33do
34{
35requiresAction = false;
36ChatCompletion chatCompletion = await client.CompleteChatAsync(messages, options);
37
38switch (chatCompletion.FinishReason)
39{
40case ChatFinishReason.Stop:
41{
42// Add the assistant message to the conversation history.
43messages.Add(new AssistantChatMessage(chatCompletion));
44break;
45}
46
47case ChatFinishReason.ToolCalls:
48{
49// First, add the assistant message with tool calls to the conversation history.
50messages.Add(new AssistantChatMessage(chatCompletion));
51
52// Then, add a new tool message for each tool call that is resolved.
53foreach (ChatToolCall toolCall in chatCompletion.ToolCalls)
54{
55switch (toolCall.FunctionName)
56{
57case nameof(GetCurrentLocation):
58{
59string toolResult = GetCurrentLocation();
60messages.Add(new ToolChatMessage(toolCall.Id, toolResult));
61break;
62}
63
64case nameof(GetCurrentWeather):
65{
66// The arguments that the model wants to use to call the function are specified as a
67// stringified JSON object based on the schema defined in the tool definition. Note that
68// the model may hallucinate arguments too. Consequently, it is important to do the
69// appropriate parsing and validation before calling the function.
70using JsonDocument argumentsJson = JsonDocument.Parse(toolCall.FunctionArguments);
71bool hasLocation = argumentsJson.RootElement.TryGetProperty("location", out JsonElement location);
72bool hasUnit = argumentsJson.RootElement.TryGetProperty("unit", out JsonElement unit);
73
74if (!hasLocation)
75{
76throw new ArgumentNullException(nameof(location), "The location argument is required.");
77}
78
79string toolResult = hasUnit
80? GetCurrentWeather(location.GetString(), unit.GetString())
81: GetCurrentWeather(location.GetString());
82messages.Add(new ToolChatMessage(toolCall.Id, toolResult));
83break;
84}
85
86default:
87{
88// Handle other unexpected calls.
89throw new NotImplementedException();
90}
91}
92}
93
94requiresAction = true;
95break;
96}
97
98case ChatFinishReason.Length:
99throw new NotImplementedException("Incomplete model output due to MaxTokens parameter or token limit exceeded.");
100
101case ChatFinishReason.ContentFilter:
102throw new NotImplementedException("Omitted content due to a content filter flag.");
103
104case ChatFinishReason.FunctionCall:
105throw new NotImplementedException("Deprecated in favor of tool calls.");
106
107default:
108throw new NotImplementedException(chatCompletion.FinishReason.ToString());
109}
110} while (requiresAction);
111#endregion
112
113#region
114foreach (ChatMessage requestMessage in messages)
115{
116switch (requestMessage)
117{
118case SystemChatMessage systemMessage:
119Console.WriteLine($"[SYSTEM]:");
120Console.WriteLine($"{systemMessage.Content[0].Text}");
121Console.WriteLine();
122break;
123
124case UserChatMessage userMessage:
125Console.WriteLine($"[USER]:");
126Console.WriteLine($"{userMessage.Content[0].Text}");
127Console.WriteLine();
128break;
129
130case AssistantChatMessage assistantMessage when assistantMessage.Content.Count > 0:
131Console.WriteLine($"[ASSISTANT]:");
132Console.WriteLine($"{assistantMessage.Content[0].Text}");
133Console.WriteLine();
134break;
135
136case ToolChatMessage:
137// Do not print any tool messages; let the assistant summarize the tool results instead.
138break;
139
140default:
141break;
142}
143}
144#endregion
145}
146}