Skip to content

Commit 724ccd7

Browse files
committed
complete the code example with the execution loop
1 parent 7525b1a commit 724ccd7

File tree

1 file changed

+151
-34
lines changed

1 file changed

+151
-34
lines changed

Basic_Samples/Functions/dotnet/csharp/Function_calling_finding_nearby_places.ipynb

Lines changed: 151 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
{
6363
"data": {
6464
"text/html": [
65-
"<div><div></div><div></div><div><strong>Installed Packages</strong><ul><li><span>Azure.AI.OpenAI, 1.0.0-beta.12</span></li></ul></div></div>"
65+
"<div><div></div><div></div><div><strong>Installed Packages</strong><ul><li><span>Azure.AI.OpenAI, 1.0.0-beta.14</span></li></ul></div></div>"
6666
]
6767
},
6868
"metadata": {},
@@ -75,7 +75,7 @@
7575
},
7676
{
7777
"cell_type": "code",
78-
"execution_count": 2,
78+
"execution_count": null,
7979
"metadata": {
8080
"dotnet_interactive": {
8181
"language": "csharp"
@@ -87,26 +87,7 @@
8787
"languageId": "polyglot-notebook"
8888
}
8989
},
90-
"outputs": [
91-
{
92-
"data": {
93-
"text/html": [
94-
"<div><div></div><div></div><div><strong>Installed Packages</strong><ul><li><span>Microsoft.DotNet.Interactive.AIUtilities, 1.0.0-beta.24129.1</span></li></ul></div></div>"
95-
]
96-
},
97-
"metadata": {},
98-
"output_type": "display_data"
99-
},
100-
{
101-
"data": {
102-
"text/plain": [
103-
"Loading extension script from `C:\\Users\\dicolomb\\.nuget\\packages\\microsoft.dotnet.interactive.aiutilities\\1.0.0-beta.24054.2\\interactive-extensions\\dotnet\\extension.dib`"
104-
]
105-
},
106-
"metadata": {},
107-
"output_type": "display_data"
108-
}
109-
],
90+
"outputs": [],
11091
"source": [
11192
"#r \"nuget:Microsoft.DotNet.Interactive.AIUtilities, 1.0.0-beta.24129.1\"\n",
11293
"\n",
@@ -123,7 +104,7 @@
123104
},
124105
{
125106
"cell_type": "code",
126-
"execution_count": 4,
107+
"execution_count": 3,
127108
"metadata": {
128109
"dotnet_interactive": {
129110
"language": "csharp"
@@ -157,7 +138,7 @@
157138
},
158139
{
159140
"cell_type": "code",
160-
"execution_count": 5,
141+
"execution_count": 4,
161142
"metadata": {
162143
"dotnet_interactive": {
163144
"language": "csharp"
@@ -177,7 +158,7 @@
177158
},
178159
{
179160
"cell_type": "code",
180-
"execution_count": 6,
161+
"execution_count": 5,
181162
"metadata": {
182163
"dotnet_interactive": {
183164
"language": "csharp"
@@ -196,7 +177,7 @@
196177
},
197178
{
198179
"cell_type": "code",
199-
"execution_count": 7,
180+
"execution_count": 6,
200181
"metadata": {
201182
"dotnet_interactive": {
202183
"language": "csharp"
@@ -316,7 +297,7 @@
316297
},
317298
{
318299
"cell_type": "code",
319-
"execution_count": 23,
300+
"execution_count": 7,
320301
"metadata": {
321302
"dotnet_interactive": {
322303
"language": "csharp"
@@ -356,7 +337,7 @@
356337
},
357338
{
358339
"cell_type": "code",
359-
"execution_count": 24,
340+
"execution_count": 8,
360341
"metadata": {
361342
"dotnet_interactive": {
362343
"language": "csharp"
@@ -391,7 +372,7 @@
391372
},
392373
{
393374
"cell_type": "code",
394-
"execution_count": 27,
375+
"execution_count": 9,
395376
"metadata": {
396377
"dotnet_interactive": {
397378
"language": "csharp"
@@ -426,7 +407,7 @@
426407
},
427408
{
428409
"cell_type": "code",
429-
"execution_count": 29,
410+
"execution_count": 11,
430411
"metadata": {
431412
"dotnet_interactive": {
432413
"language": "csharp"
@@ -443,8 +424,8 @@
443424
"data": {
444425
"text/plain": [
445426
"{\n",
446-
" \"currentLocation\": \"Capitol Hill\",\n",
447-
" \"placeType\": \"Bars\"\n",
427+
" \"currentLocation\": \"Capitol Hill, Seattle\",\n",
428+
" \"placeType\": \"BarsGrillsAndPubs\"\n",
448429
"}"
449430
]
450431
},
@@ -457,9 +438,16 @@
457438
"\n"
458439
]
459440
},
441+
{
442+
"cell_type": "markdown",
443+
"metadata": {},
444+
"source": [
445+
"Now the full loop"
446+
]
447+
},
460448
{
461449
"cell_type": "code",
462-
"execution_count": null,
450+
"execution_count": 16,
463451
"metadata": {
464452
"dotnet_interactive": {
465453
"language": "csharp"
@@ -473,7 +461,136 @@
473461
},
474462
"outputs": [],
475463
"source": [
476-
"response.Display();"
464+
"// setup the call exposing the tool to llm\n",
465+
"public async Task<string> Ask(string userQuestion){\n",
466+
" var messages = new List<ChatRequestMessage>{\n",
467+
" new ChatRequestSystemMessage(\"You are a sophisticated AI assistant, a specialist in user intent detection and interpretation. Your task is to perceive and respond to the user's needs, even when they're expressed in an indirect or direct manner. You excel in recognizing subtle cues: for example, if a user states they are 'hungry', you should assume they are seeking nearby dining options such as a restaurant or a cafe. If they indicate feeling 'tired', 'weary', or mention a long journey, interpret this as a request for accommodation options like hotels or guest houses. However, remember to navigate the fine line of interpretation and assumption: if a user's intent is unclear or can be interpreted in multiple ways, do not hesitate to politely ask for additional clarification. Use only values from the nums in the functions.\"),\n",
468+
" new ChatRequestUserMessage(userQuestion)\n",
469+
" };\n",
470+
"\n",
471+
" // create the initial request\n",
472+
" var request = new ChatCompletionsOptions{\n",
473+
" \n",
474+
" Tools = { CreateToolDefinition(findFunction) },\n",
475+
" DeploymentName = gptDeployment,\n",
476+
" };\n",
477+
"\n",
478+
" foreach (var chatRequestMessage in messages)\n",
479+
" {\n",
480+
" request.Messages.Add(chatRequestMessage);\n",
481+
" }\n",
482+
"\n",
483+
" var response = await client.GetChatCompletionsAsync(request);\n",
484+
"\n",
485+
" // we need to track the messages and tool calls to re-evaluate the response\n",
486+
" while (response.Value.Choices.Any(c => c.FinishReason == CompletionsFinishReason.ToolCalls))\n",
487+
" {\n",
488+
" var needToEval = false;\n",
489+
" \n",
490+
" \n",
491+
" foreach (var choice in response.Value.Choices)\n",
492+
" {\n",
493+
"\n",
494+
" // proceed with the llm tool calls\n",
495+
" if (choice?.Message?.ToolCalls is { } toolCalls)\n",
496+
" {\n",
497+
" // there are tool calls in the response, build assistant message and execute the tool\n",
498+
" var assistantMessage = new ChatRequestAssistantMessage(choice.Message.Content);\n",
499+
" foreach (var messageToolCall in choice.Message.ToolCalls)\n",
500+
" {\n",
501+
" assistantMessage.ToolCalls.Add(messageToolCall);\n",
502+
" }\n",
503+
"\n",
504+
" assistantMessage.FunctionCall = choice.Message.FunctionCall;\n",
505+
"\n",
506+
" // add the assistant message to the messages, this one contains the tool calls that the llm wants to execute\n",
507+
" messages.Add(assistantMessage);\n",
508+
"\n",
509+
" // execute the tool calls \n",
510+
" foreach (var toolCall in toolCalls)\n",
511+
" {\n",
512+
" if (toolCall is ChatCompletionsFunctionToolCall functionToolCall)\n",
513+
" {\n",
514+
" // make sure we are executing the right tool!!\n",
515+
" if (functionToolCall.Name == findFunction.Name)\n",
516+
" {\n",
517+
" var id = functionToolCall.Id;\n",
518+
" var toolResult = await ((Task<string>) findFunction.Execute(functionToolCall.Arguments));\n",
519+
" \n",
520+
" messages.Add(new ChatRequestToolMessage(\n",
521+
" toolResult as string ?? JsonSerializer.Serialize(toolResult), functionToolCall.Id));\n",
522+
"\n",
523+
" // we need to re-evaluate the response with the new messages, this will enable the llm to continue\n",
524+
" needToEval = true;\n",
525+
" }\n",
526+
" }\n",
527+
" }\n",
528+
" }\n",
529+
" }\n",
530+
"\n",
531+
" if (needToEval)\n",
532+
" {\n",
533+
" // we can now re-evaluate the response with the new messages and get final response\n",
534+
" new ChatCompletionsOptions{\n",
535+
" Tools = { CreateToolDefinition(findFunction) },\n",
536+
" DeploymentName = gptDeployment,\n",
537+
" };\n",
538+
"\n",
539+
" foreach (var chatRequestMessage in messages)\n",
540+
" {\n",
541+
" request.Messages.Add(chatRequestMessage);\n",
542+
" }\n",
543+
"\n",
544+
" response = await client.GetChatCompletionsAsync(request);\n",
545+
" }\n",
546+
" }\n",
547+
"\n",
548+
" // no more tool call to handle, we can now display the final response\n",
549+
" var message = response.Value.Choices[0].Message.Content;\n",
550+
" Console.WriteLine(message);\n",
551+
"\n",
552+
" return message;\n",
553+
"}"
554+
]
555+
},
556+
{
557+
"cell_type": "code",
558+
"execution_count": 17,
559+
"metadata": {
560+
"dotnet_interactive": {
561+
"language": "csharp"
562+
},
563+
"polyglot_notebook": {
564+
"kernelName": "csharp"
565+
},
566+
"vscode": {
567+
"languageId": "polyglot-notebook"
568+
}
569+
},
570+
"outputs": [
571+
{
572+
"name": "stdout",
573+
"output_type": "stream",
574+
"text": [
575+
"Here are some local and affordable pubs in Capitol Hill, Seattle that you might like:\n",
576+
"\n",
577+
"1. [Capitol Hill Comedy / Bar](https://comedyslashbar.com/): 210 Broadway E, Seattle, WA, 98125. Contact: (206) 390-9152\n",
578+
"\n",
579+
"2. [Barrio Mexican Kitchen & Bar](https://www.barriorestaurant.com/): 1420 12th Ave, Seattle, WA, 98122. Contact: (206) 588-8105\n",
580+
"\n",
581+
"3. [Mezcaleria Oaxaca Capitol Hill](https://mercadoluna.com/mezcaleria-oaxaca/): 422 E Pine St, Seattle, WA, 98122. Contact: (206) 324-0506\n",
582+
"\n",
583+
"4. [Capitol Cider](https://www.capitolcider.com/): 818 E Pike St, Seattle, WA, 98122. Contact: (206) 397-3564\n",
584+
"\n",
585+
"5. [GOLD BAR](https://goldbarseattle.com/Info): 1418 E OLIVE Way, Seattle, WA, 98122. Contact: (206) 402-3473\n",
586+
"\n",
587+
"Please note that prices and availability may vary. Make sure to check their websites or contact them for more information. Enjoy your meal!\n",
588+
"\r\n"
589+
]
590+
}
591+
],
592+
"source": [
593+
"await Ask(\"I am hungry in Seattle, actually Capitol Hill. At the moment I would appreaciate something local and cheap. Maybe a pub? Don't know what is the best to go for. I am open to any idea, What do you suggest?\");"
477594
]
478595
}
479596
],

0 commit comments

Comments
 (0)