XiHan Framework 处于预览阶段

查看获取方式
跳转到内容

XiHan.Framework.AI.OpenAI ​

AI 的 OpenAI 兼容 Provider:Kind = openai 的 Provider 都由本包按配置创建聊天客户端与嵌入生成器,覆盖 OpenAI 官方端点与 Ollama、vLLM、LM Studio 等 OpenAI 兼容端点。提供 ai.chat@1 与 ai.embedding@1。

项内容
包 IDXiHan.Framework.AI.OpenAI
环层Ring 3(实现)
能力提供 ai.chat@1、ai.embedding@1(role: provider);依赖 kernel.hosting@1
特性入口OpenAIFeature(清单 xihan.ai.openai)
配置节XiHan:AI
依赖XiHan.Framework.AI.Abstractions;Microsoft.Extensions.AI、Microsoft.Extensions.AI.OpenAI、Microsoft.Extensions.Http
AOT不兼容(OpenAI SDK 未声明 AOT 兼容,csproj 设 IsAotCompatible=false)
稳定性Preview

概述 ​

OpenAIFeature 调用 AddAI(configuration) 登记 AI 核心服务,再登记两个工厂:

  • OpenAIChatClientFactory:OpenAIClient → GetChatClient(ChatModel).AsIChatClient(),再套上 Microsoft.Extensions.AI 的函数调用循环(UseFunctionInvocation),模型发起的工具调用在客户端里自动执行。
  • OpenAIEmbeddingGeneratorFactory:GetEmbeddingClient(EmbeddingModel).AsIEmbeddingGenerator(EmbeddingDimensions)。

OpenAIClient 的网络超时只取 Provider 的 TimeoutSeconds(缺省 100 秒);Endpoint 为空时连官方端点;ApiKey 为空时用占位凭据,供不校验密钥的本地端点使用。装配与启动不访问网络,客户端在第一次解析时创建并按 Provider 名缓存。启动时构建工具目录:操作派生或 XiHan:AI:Tools:<操作 ID> 覆盖的工具名不合法、与别的工具重名(AI_VALIDATION_001)即启动失败。再解析提示增强器:XiHan:AI:Knowledge:PromptName 指向的模板不存在(AI_NOTFOUND_002)或用了 {context}、{question} 以外的占位符(AI_VALIDATION_001)即启动失败,只装本特性(不装 AIToolsFeature 与知识库 Provider)时也一样。

何时使用 ​

接 OpenAI 官方 API,或任何提供 OpenAI 兼容接口的模型服务(本地推理服务、兼容网关)。本包不进 Profiles.Full,因为它需要外部端点。

安装与启用 ​

bash
dotnet add package XiHan.Framework.AI.OpenAI --prerelease

当前是预览版,安装要带 --prerelease;从源码或本地包源引用见快速上手。

csharp
using XiHan.Framework.AI.Abstractions;
using XiHan.Framework.AI.OpenAI;
using XiHan.Framework.Hosting.AspNetCore;
using XiHan.Framework.Profiles.Standard;

var builder = WebApplication.CreateBuilder(args);
builder.AddXiHan(xihan => xihan
    .UseStandardProfile()
    .UseFeature<AIToolsFeature>()
    .UseFeature<OpenAIFeature>());

var app = builder.Build();
app.UseXiHan();
app.Run();

配置 ​

Provider 写在 XiHan:AI:Providers:<name> 下,Kind 为 openai(必填,不写时启动失败)。配置在装配时读一次、不热更新,改了要重启应用:

json
{
  "XiHan": {
    "AI": {
      "DefaultProvider": "cloud",
      "Providers": {
        "cloud": {
          "Kind": "openai",
          "ApiKey": "dev-openai-key",
          "ChatModel": "gpt-4o-mini",
          "EmbeddingModel": "text-embedding-3-small",
          "EmbeddingDimensions": 1536
        },
        "local": {
          "Kind": "openai",
          "Endpoint": "http://localhost:11434/v1",
          "ChatModel": "qwen2.5",
          "TimeoutSeconds": 90
        }
      }
    }
  }
}
键说明
Endpoint绝对的 http(s) 地址;空表示官方端点,写错时启动失败
ApiKey空时用占位凭据 no-key
ChatModel解析聊天客户端时必填,缺失返回 AI_VALIDATION_001
EmbeddingModel解析嵌入生成器时必填,缺失返回 AI_VALIDATION_001
EmbeddingDimensions请求的嵌入维度,空用模型缺省
TimeoutSecondsOpenAIClientOptions.NetworkTimeout,缺省 100

其余键(DefaultProvider、提示词、护栏、知识库)见 AI.Abstractions。

主要类型 ​

类型说明
OpenAIFeature能力包入口
OpenAIChatClientFactoryKind 为 openai(KindName)的聊天客户端工厂
OpenAIEmbeddingGeneratorFactory同种类的嵌入生成器工厂

两个工厂都可以接收可选的 IHttpClientFactory;聊天工厂还接收可选的 ILoggerFactory,交给函数调用循环写日志。

使用示例 ​

经代理或在测试里替换传输时,在 Program.cs 里给名为 xihan.ai.openai 的 HttpClient 配置处理器,本包从 IHttpClientFactory 取它发请求:

csharp
var builder = WebApplication.CreateBuilder(args);

// 经公司代理访问模型端点;超时不在这里设,由 Provider 的 TimeoutSeconds 决定
builder.Services.AddHttpClient("xihan.ai.openai")
    .ConfigurePrimaryHttpMessageHandler(static () => new SocketsHttpHandler { Proxy = new WebProxy("http://proxy.internal:8080") });

WebProxy 在 System.Net 命名空间。

AddHttpClient 来自 Microsoft.Extensions.Http。这个名字也是公开常量 OpenAIFeature.HttpClientName。

框架的端点来自 XiHan:AI:Providers,是运维配的,不过出站地址策略。应用替换提供商目录、让用户填端点时,给这个名字接上策略,写法见那一章。

聊天、工具与护栏的用法见 AI。

行为与限制 ​

  • 容器里有 IHttpClientFactory 时(应用在任何地方调用过 AddHttpClient),本包就从它取名为 xihan.ai.openai 的客户端发请求,没有专门配置这个名字时取到的是工厂的缺省客户端,应用用 ConfigureHttpClientDefaults 给全部客户端加的处理器(如弹性处理器)同样作用于它。
  • 超时只以 TimeoutSeconds 为准:取到的客户端的 HttpClient.Timeout 由本包置为不限,与 SDK 自己的传输一样,不会被缺省的 100 秒截断;在 AddHttpClient 里设的 Timeout 不生效。
  • 端点返回错误或不可达记 AI_UNAVAILABLE_001(reason 只写异常类型,完整异常进日志),超时记 AI_TIMEOUT_001;这两项在 IAIChat 与知识库流水线里映射,直接从目录取客户端的调用拿到的是 SDK 的原始异常。
  • 经 IAIChat 与知识库流水线的调用另有框架的超时令牌(同取 TimeoutSeconds,按容器的 TimeProvider 计时),覆盖整次调用,含函数调用循环;SDK 的 NetworkTimeout 照常作用于每次网络请求。两者同时触发、或超时与调用方取消同时发生时,SDK 报的是调用方的取消,框架按自己的令牌报 AI_TIMEOUT_001(超时与取消)。
  • 缓存、遥测等横切逻辑可以叠加在目录解析出的客户端上,用 Microsoft.Extensions.AI 自己的中间件。
  • 通过 AI.Conformance 的 AIProviderConformance。

相关 ​

Released under The MIT License