microsoft / semantic-kernel

Integrate cutting-edge LLM technology quickly and easily into your apps
https://aka.ms/semantic-kernel
MIT License
21.15k stars 3.1k forks source link

.Net: how to post ChatHistory to kernel CreateFunctionFromPrompt in different way? #5283

Open kill136 opened 5 months ago

kill136 commented 5 months ago

app. MapPost(Constants.HttpSKAskEndpoint, async Task ( HttpContext context, SearchQuery query, IKernelMemory service, ILogger log, CancellationToken cancellationToken) => { string apiKey = context. Request.Query["apiKey"]; log. LogTrace("New skAsk request"); IKernelBuilder builder = Kernel.CreateBuilder(); builder. AddOpenAIChatCompletion( modelId: "gpt-3.5-turbo", apiKey: apiKey, null, serviceId: "chatgpt", new HttpClient() { BaseAddress = new Uri("https://www.barcodecloud.club/proxy/api.openai.com") }); builder. Plugins.AddFromType(); //var bingConnector = new BingConnector("4a6ae95875844abaa19d5576e38bbb68"); //var bing = new WebSearchEnginePlugin(bingConnector); //builder. Plugins.AddFromObject(bing); //OpenAIClient? openAIClient = new OpenAIClient(apiKey,new OpenAIClientOptions() { Transport= }), //builder. Services.AddOpenAIChatCompletion("gpt-3.5-turbo", apiKey);

         var kernel = builder. Build();
         var chatCompletionService = kernel. GetRequiredService<IChatCompletionService>( "chatgpt");

         // Handler which is called before a function is invoked
         void MyInvokingHandler(object? sender, FunctionInvokingEventArgs e)
         {
             Console.WriteLine($"Invoking {e.Function.Name}");
         }

         // Handler which is called before a prompt is rendered
         void MyRenderingHandler(object? sender, PromptRenderingEventArgs e)
         {
             Console.WriteLine($"Rendering prompt for {e.Function.Name}");
         }

         // Handler which is called after a prompt is rendered
         void MyRenderedHandler(object? sender, PromptRenderedEventArgs e)
         {
             Console.WriteLine($"Rendered prompt: {e.RenderedPrompt}");
         }

         // Handler which is called after a function is invoked
         void MyInvokedHandler(object? sender, FunctionInvokedEventArgs e)
         {
             if (e.Result.Metadata is not null && e.Result.Metadata.ContainsKey("Usage"))
             {
                 Console.WriteLine($"Token usage: {e.Result.Metadata?[" Usage"]?. AsJson()}");
             }
         }

         // Add the handlers to the kernel
         kernel. FunctionInvoking += MyInvokingHandler;
         kernel. PromptRendering += MyRenderingHandler;
         kernel. PromptRendered += MyRenderedHandler;
         kernel. FunctionInvoked += MyInvokedHandler;
         var skPrompt = """
                客户提问: {{$input}}

                知识库回答: {{memory.search $query}}

                根据上面的信息,有感情的回答用户的提问,如果遇到你无法确认的信息,请自由调用插件功能,比如搜索引擎插件,时间插件
                """;
         OpenAIPromptExecutionSettings settings = new() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };
         var myFunction = kernel. CreateFunctionFromPrompt(skPrompt, settings);
         var memoryConnector = new MemoryWebClient("http://127.0.0.1:9001/", Environment.GetEnvironmentVariable("MEMORY_API_KEY"));
         var memoryPlugin = kernel. ImportPluginFromObject(new MemoryPlugin(memoryConnector, waitForIngestionToComplete: true), "memory");
         TagCollectionWrapper tags = new TagCollectionWrapper();

         foreach (var memoryFilter in query. Filters)
         {
             foreach (var filter in memoryFilter.GetFilters())
             {
                 tags. Add(filter. Key, filter. Value);
             }
         }
         ChatHistory chatMessages = query. Messages;

         var answer = await myFunction.InvokeAsync(kernel, new KernelArguments()
         {
             { "input", query. Query },
             { "index", query. Index },
             { "query", query. Query },
             { "tags",tags },
             { "minRelevance", query. MinRelevance },
             { "limit", query. Limit }
         });
         Console.WriteLine("Answer: " + answer);
         return Results.Ok(answer. GetValue<string>());
     })
 . AddEndpointFilter(authFilter)
 . Produces<MemoryAnswer>(StatusCodes.Status200OK)
 . Produces<ProblemDetails>(StatusCodes.Status401Unauthorized)
 . Produces<ProblemDetails>(StatusCodes.Status403Forbidden);

####################################### above is my code, i dont want using {{$chatMessages }} para in a Prompt ,who knows other way?

github-actions[bot] commented 2 months ago

This issue is stale because it has been open for 90 days with no activity.