You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

SemanticKernelHostingExtensions.cs 5.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright (c) Microsoft. All rights reserved.
  2. using System.Text.Json;
  3. using Azure.AI.OpenAI;
  4. using DevTeam.Options;
  5. using Microsoft.Extensions.Configuration;
  6. using Microsoft.Extensions.DependencyInjection;
  7. using Microsoft.Extensions.Hosting;
  8. using Microsoft.Extensions.Logging;
  9. using Microsoft.Extensions.Options;
  10. using Microsoft.SemanticKernel;
  11. using Microsoft.SemanticKernel.Connectors.OpenAI;
  12. using Microsoft.SemanticKernel.Connectors.Qdrant;
  13. using Microsoft.SemanticKernel.Memory;
  14. namespace DevTeam;
  15. public static class SemanticKernelHostingExtensions
  16. {
  17. public static IHostApplicationBuilder ConfigureSemanticKernel(this IHostApplicationBuilder builder)
  18. {
  19. builder.Services.Configure<OpenAIOptions>(o =>
  20. {
  21. o.EmbeddingsEndpoint = o.ImageEndpoint = o.ChatEndpoint = builder.Configuration["OpenAI:Endpoint"] ?? throw new InvalidOperationException("Ensure that OpenAI:Endpoint is set in configuration");
  22. o.EmbeddingsApiKey = o.ImageApiKey = o.ChatApiKey = builder.Configuration["OpenAI:Key"]!;
  23. o.EmbeddingsDeploymentOrModelId = "text-embedding-3-large";
  24. o.ImageDeploymentOrModelId = "dall-e-3";
  25. o.ChatDeploymentOrModelId = "gpt-4o";
  26. });
  27. builder.Services.Configure<OpenAIClientOptions>(o =>
  28. {
  29. o.Retry.NetworkTimeout = TimeSpan.FromMinutes(5);
  30. });
  31. builder.Services.AddOptions<QdrantOptions>().Bind(builder.Configuration.GetSection("Qdrant"))
  32. .ValidateDataAnnotations()
  33. .ValidateOnStart();
  34. builder.Services.Configure<JsonSerializerOptions>(options =>
  35. {
  36. options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
  37. });
  38. builder.Services.AddTransient(CreateKernel);
  39. builder.Services.AddTransient(CreateMemory);
  40. return builder;
  41. }
  42. static ISemanticTextMemory CreateMemory(IServiceProvider provider)
  43. {
  44. var qdrantConfig = provider.GetRequiredService<IOptions<QdrantOptions>>().Value;
  45. var openAiConfig = provider.GetRequiredService<IOptions<OpenAIOptions>>().Value;
  46. var qdrantHttpClient = new HttpClient();
  47. if (!string.IsNullOrEmpty(qdrantConfig.ApiKey)) {
  48. qdrantHttpClient.DefaultRequestHeaders.Add("api-key", qdrantConfig.ApiKey);
  49. }
  50. var loggerFactory = provider.GetRequiredService<ILoggerFactory>();
  51. var memoryBuilder = new MemoryBuilder();
  52. return memoryBuilder.WithLoggerFactory(loggerFactory)
  53. .WithQdrantMemoryStore(qdrantHttpClient, qdrantConfig.VectorSize, qdrantConfig.Endpoint)
  54. .WithAzureOpenAITextEmbeddingGeneration(openAiConfig.EmbeddingsDeploymentOrModelId, openAiConfig.EmbeddingsEndpoint, openAiConfig.EmbeddingsApiKey)
  55. .Build();
  56. }
  57. static Kernel CreateKernel(IServiceProvider provider)
  58. {
  59. OpenAIOptions openAiConfig = provider.GetRequiredService<IOptions<OpenAIOptions>>().Value;
  60. var builder = Kernel.CreateBuilder();
  61. // Chat
  62. if (openAiConfig.ChatEndpoint.Contains(".azure", StringComparison.OrdinalIgnoreCase))
  63. {
  64. var openAIClient = new OpenAIClient(new Uri(openAiConfig.ChatEndpoint), new Azure.AzureKeyCredential(openAiConfig.ChatApiKey));
  65. builder.Services.AddAzureOpenAIChatCompletion(openAiConfig.ChatDeploymentOrModelId, openAIClient);
  66. }
  67. else
  68. {
  69. var openAIClient = new OpenAIClient(openAiConfig.ChatApiKey);
  70. builder.Services.AddOpenAIChatCompletion(openAiConfig.ChatDeploymentOrModelId, openAIClient);
  71. }
  72. // Text to Image
  73. if (openAiConfig.ImageEndpoint.Contains(".azure", StringComparison.OrdinalIgnoreCase))
  74. {
  75. ArgumentException.ThrowIfNullOrEmpty(openAiConfig.ImageDeploymentOrModelId);
  76. var openAIClient = new OpenAIClient(new Uri(openAiConfig.ImageEndpoint), new Azure.AzureKeyCredential(openAiConfig.ImageApiKey));
  77. builder.Services.AddAzureOpenAITextToImage(openAiConfig.ImageDeploymentOrModelId, openAIClient);
  78. }
  79. else
  80. {
  81. builder.Services.AddOpenAITextToImage(openAiConfig.ImageApiKey, modelId: openAiConfig.ImageDeploymentOrModelId);
  82. }
  83. // Embeddings
  84. if (openAiConfig.EmbeddingsEndpoint.Contains(".azure", StringComparison.OrdinalIgnoreCase))
  85. {
  86. var openAIClient = new OpenAIClient(new Uri(openAiConfig.EmbeddingsEndpoint), new Azure.AzureKeyCredential(openAiConfig.EmbeddingsApiKey));
  87. builder.Services.AddAzureOpenAITextEmbeddingGeneration(openAiConfig.EmbeddingsDeploymentOrModelId, openAIClient);
  88. }
  89. else
  90. {
  91. var openAIClient = new OpenAIClient(openAiConfig.EmbeddingsApiKey);
  92. builder.Services.AddOpenAITextEmbeddingGeneration(openAiConfig.EmbeddingsDeploymentOrModelId, openAIClient);
  93. }
  94. return builder.Build();
  95. }
  96. }