修改后的 Semantic Kernel 之 Examples.Plugin 代码

// Copyright (c) Microsoft. All rights reserved.

using System;
using System.ComponentModel;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Xunit;
using Xunit.Abstractions;

namespace Examples;

/// <summary>
/// This example shows how to create a plugin class and interact with as described at
/// https://learn.microsoft.com/semantic-kernel/overview/
/// This sample uses function calling, so it only works on models newer than 0613.
/// </summary>
public class Plugin : BaseTest
{
    [Fact]
    public async Task RunAsync()
    {
        WriteLine("======== Plugin ========");

        // Create kernel
        // <KernelCreation>
        var builder = Kernel.CreateBuilder();
        builder.Services.AddOpenAIChatCompletion("qwen-max", "sk-one-api-token");
        builder.Services.ConfigureHttpClientDefaults(b =>
            b.ConfigurePrimaryHttpMessageHandler(() => new OneApiRedirectingHandler()));
        builder.Plugins.AddFromType<LightPlugin>();
        Kernel kernel = builder.Build();
        // </KernelCreation>

        // <Chat>

        // Create chat history
        var history = new ChatHistory();

        // Get chat completion service
        var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

        // Start the conversation
        Write("User > ");
        string? userInput;
        while ((userInput = ReadLine()) != null)
        {
            // Add user input
            history.AddUserMessage(userInput);

            // Enable auto function calling
            OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
            {
                ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
            };

            // Get the response from the AI
            var result = await chatCompletionService.GetChatMessageContentAsync(
                history,
                executionSettings: openAIPromptExecutionSettings,
                kernel: kernel);

            // Print the results
            WriteLine("Assistant > " + result);

            // Add the message from the agent to the chat history
            history.AddMessage(result.Role, result.Content ?? string.Empty);

            // Get user input again
            Write("User > ");
        }
        // </Chat>
    }

    public Plugin(ITestOutputHelper output) : base(output)
    {
        SimulatedInputText = [
            "Hello",
            "Can you turn on the lights"];
    }
}

// <LightPlugin>
public class LightPlugin
{
    public bool IsOn { get; set; } = false;

#pragma warning disable CA1024 // Use properties where appropriate
    [KernelFunction]
    [Description("Gets the state of the light.")]
    public string GetState() => IsOn ? "on" : "off";
#pragma warning restore CA1024 // Use properties where appropriate

    [KernelFunction]
    [Description("Changes the state of the light.'")]
    public string ChangeState(bool newState)
    {
        this.IsOn = newState;
        var state = GetState();

        // Print the state to the console
        Console.WriteLine($"[Light is now {state}]");

        return state;
    }
}
// </LightPlugin>

public class OneApiRedirectingHandler() : DelegatingHandler(new HttpClientHandler())
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.RequestUri = new UriBuilder(request.RequestUri!) { Scheme = "http", Host = "one-api", Port = 3000 }.Uri;
        return base.SendAsync(request, cancellationToken);
    }
}
posted @ 2024-02-16 20:12  dudu  阅读(28)  评论(0编辑  收藏  举报