com.openai.unity
com.openai.unity 是一款专为 Unity 游戏引擎设计的非官方 OpenAI REST API 客户端插件。它旨在帮助开发者在 Unity 项目中轻松集成 OpenAI 的强大能力,如智能对话、文本生成、语音交互及函数调用等功能,无需从零开始编写复杂的网络请求代码。
该工具主要解决了 Unity 开发者在对接 OpenAI 服务时面临的接口适配难、异步处理复杂以及依赖管理繁琐等痛点。通过封装标准的 RESTful 接口,它让游戏或应用能够流畅地调用大模型能力,实现更智能化的 NPC 互动、动态内容生成或实时语音助手。
com.openai.unity 非常适合 Unity 游戏开发者、技术美术以及希望在交互式应用中融入 AI 功能的软件工程师使用。其独特的技术亮点在于基于成熟的 OpenAI-DotNet 库构建,原生支持 Unity 的异步编程模式,并提供了对 Azure OpenAI、流式响应(Streaming)以及实时会话(Realtime)的深度支持。安装方面,它完美兼容 Unity 包管理器(UPM)和 OpenUPM 注册表,一键即可配置好所有必要的依赖项,大幅降低了接入门槛,让创作者能更专注于创意实现而非底层技术细节。
使用场景
一家独立游戏工作室正在开发一款支持语音互动的 NPC 系统,希望让玩家能通过麦克风直接与角色进行实时对话。
没有 com.openai.unity 时
- 开发者需手动封装复杂的 HTTP 请求代码来处理 OpenAI REST API,导致大量样板代码堆积,维护困难。
- 实现流式响应(Streaming)和功能调用(Function Calling)时,需自行处理异步数据解析,极易出现卡顿或数据丢失。
- 缺乏对 Unity 生命周期和异步任务的原生支持,多线程处理不当常引发主线程阻塞,造成游戏画面冻结。
- 集成音频输入输出功能时,需额外寻找第三方库进行 WAV 编码转换,增加了项目依赖管理的复杂度。
- 调试过程繁琐,任何 API 参数变更都需要修改底层网络逻辑,严重拖慢原型验证速度。
使用 com.openai.unity 后
- 通过 OpenUPM 一键安装即可直接调用封装好的 API 接口,无需编写底层网络请求,代码量减少 70%。
- 原生支持流式文本生成与函数调用回调,开发者只需订阅事件即可平滑展示 NPC 回复,交互体验流畅自然。
- 内置专为 Unity 优化的异步处理机制,自动适配主线程更新,彻底消除因网络请求导致的帧率波动。
- 集成了音频编码与 WebSocket 实时会话模块,可直接对接麦克风输入并处理实时语音流转,简化了音频管线。
- 提供清晰的文档与标准化错误处理,快速切换不同模型或调整参数,让团队能在数小时内完成新功能迭代。
com.openai.unity 将复杂的 AI 接口调用转化为 Unity 原生的开发体验,让游戏开发者能专注于创意逻辑而非底层通信细节。
运行环境要求
- Windows
- macOS
- Linux
未说明
未说明
快速开始
OpenAI
一个用于 Unity 的 OpenAI 包,可通过其 RESTful API 使用。 本项目为独立开发,并非官方库,本人与 OpenAI 无任何关联。使用前需拥有 OpenAI API 账号。
所有版权、商标、标识及资产均属于其各自所有者。
安装
需要 Unity 2021.3 LTS 或更高版本。
推荐通过 Unity 包管理器和 OpenUPM 进行安装。
通过 Unity 包管理器和 OpenUPM
终端
openupm add com.openai.unity
手动操作
- 打开您的 Unity 项目设置。
- 添加 OpenUPM 包注册表:
- 名称:
OpenUPM - URL:
https://package.openupm.com - 作用域:
com.openaicom.utilities
- 名称:
![]()
- 打开 Unity 包管理器窗口。
- 将注册表从 Unity 切换到
My Registries。 - 添加
OpenAI包。
通过 Unity 包管理器和 Git URL
[!WARNING] 本仓库依赖其他仓库!您需要自行添加这些依赖。
- 打开您的 Unity 包管理器。
- 从 Git URL 添加包:
https://github.com/RageAgainstThePixel/com.openai.unity.git#upm
文档
欢迎查看我们的全新 API 文档!
https://rageagainstthepixel.github.io/OpenAI-DotNet
目录
身份验证
提供 API 密钥的方式有四种,按优先级顺序排列如下:
[!WARNING] 建议使用环境变量来加载 API 密钥,而不是将其硬编码在源代码中。不建议在生产环境中使用此方法,而仅适用于接收用户凭据、本地测试和快速入门场景。
- 通过构造函数直接传递密钥 :warning:
- Unity 可脚本化对象 :warning:
- 从配置文件加载密钥
- 使用系统环境变量
您可以在初始化 API 时使用 OpenAIAuthentication,如下所示:
通过构造函数直接传递密钥
[!WARNING] 建议使用环境变量来加载 API 密钥,而不是将其硬编码在源代码中。不建议在生产环境中使用此方法,而仅适用于接收用户凭据、本地测试和快速入门场景。
var api = new OpenAIClient("sk-apiKey");
或者手动创建一个 OpenAIAuthentication 对象:
var api = new OpenAIClient(new OpenAIAuthentication("sk-apiKey", "org-yourOrganizationId", "proj_yourProjectId"));
Unity 可脚本化对象
您可以将密钥直接保存到位于 Assets/Resources 文件夹中的可脚本化对象中。
可以通过项目面板的上下文菜单创建一个新的 OpenAIConfiguration 可脚本化对象。
[!WARNING] 请注意不要将此文件提交到版本控制系统中,因为其他人将能够看到您的 API 密钥。建议使用 OpenAI-DotNet-Proxy,并通过您首选的 OAuth 提供商对用户进行身份验证。
![]()
从配置文件加载密钥
尝试从配置文件中加载 API 密钥,默认情况下为当前目录下的 .openai 文件,也可以选择向上遍历目录树或在用户的主目录中查找。
要创建配置文件,可以新建一个名为 .openai 的文本文件,并在其中添加以下内容:
[!NOTE] 组织 ID 和项目 ID 是可选的。
JSON 格式
{
"apiKey": "sk-aaaabbbbbccccddddd",
"organizationId": "org-yourOrganizationId",
"projectId": "proj_yourProjectId"
}
已弃用的格式
OPENAI_API_KEY=sk-aaaabbbbbccccddddd
OPENAI_ORGANIZATION_ID=org-yourOrganizationId
OPENAI_PROJECT_ID=proj_yourProjectId
您还可以通过调用 OpenAIAuthentication 中的静态方法,直接从已知路径加载配置文件:
- 加载指定目录中的默认
.openai配置文件:
var api = new OpenAIClient(new OpenAIAuthentication().LoadFromDirectory("path/to/your/directory"));
- 从特定路径加载配置文件。文件不必命名为
.openai,只要符合 JSON 格式即可:
var api = new OpenAIClient(new OpenAIAuthentication().LoadFromPath("path/to/your/file.json"));
使用系统环境变量
使用系统的环境变量来指定要使用的 API 密钥和组织。
- 使用
OPENAI_API_KEY指定您的 API 密钥。 - 使用
OPENAI_ORGANIZATION_ID指定组织。 - 使用
OPENAI_PROJECT_ID指定项目。
var api = new OpenAIClient(new OpenAIAuthentication().LoadFromEnvironment());
Azure OpenAI
您也可以选择使用 Microsoft 的 Azure OpenAI 部署。
您可以在 Azure Playground 中找到所需的信息,点击 View Code 按钮,查看类似如下的 URL:
https://{your-resource-name}.openai.azure.com/openai/deployments/{deployment-id}/chat/completions?api-version={api-version}
your-resource-name您的 Azure OpenAI 资源名称。deployment-id您部署模型时选择的部署名称。api-version用于此操作的 API 版本,格式为 YYYY-MM-DD。
要将客户端设置为使用您的部署,您需要在客户端构造函数中传入 OpenAISettings。
var auth = new OpenAIAuthentication("sk-apiKey");
var settings = new OpenAISettings(resourceName: "your-resource-name", deploymentId: "deployment-id", apiVersion: "api-version");
var api = new OpenAIClient(auth, settings);
Azure Active Directory 身份验证
按照常规方式使用 MSAL(Microsoft 身份验证库 for .NET)获取访问令牌,然后在创建 OpenAIAuthentication 时使用该访问令牌。此外,在创建 OpenAISettings 时,请确保将 useAzureActiveDirectory 设置为 true。
// 使用任何 MSAL 方法获取访问令牌
var accessToken = result.AccessToken;
var auth = new OpenAIAuthentication(accessToken);
var settings = new OpenAISettings(resourceName: "your-resource", deploymentId: "deployment-id", apiVersion: "api-version", useActiveDirectoryAuthentication: true);
var api = new OpenAIClient(auth, settings);
OpenAI API 代理
在前端应用中直接使用 OpenAI-DotNet 或 com.openai.unity 包可能会暴露您的 API 密钥及其他敏感信息。为降低此风险,建议搭建一个中间 API,由该 API 代表您的前端应用向 OpenAI 发送请求。本库既可用于前端配置,也可用于中间层主机配置,从而确保与 OpenAI API 的安全通信。
前端示例
在前端示例中,您需要使用首选的 OAuth 提供商安全地验证用户身份。用户通过身份验证后,再将自定义的身份令牌与后端的 API 密钥进行交换。
请按照以下步骤操作:
- 使用 OpenAI-DotNet 或 com.openai.unity 包创建新项目。
- 使用您的 OAuth 提供商对用户进行身份验证。
- 身份验证成功后,创建一个新的
OpenAIAuthentication对象,并传入以sess-为前缀的自定义令牌。 - 创建一个新的
OpenAISettings对象,指定中间 API 所在的域名。 - 在创建客户端实例时,将新的
auth和settings对象传递给OpenAIClient构造函数。
以下是前端设置的示例:
var authToken = await LoginAsync();
var auth = new OpenAIAuthentication($"sess-{authToken}");
var settings = new OpenAISettings(domain: "api.your-custom-domain.com");
var api = new OpenAIClient(auth, settings);
通过这种设置,您的前端应用可以安全地与后端通信,而后端将使用 OpenAI-DotNet-Proxy 将请求转发至 OpenAI API。这样可以确保您的 OpenAI API 密钥及其他敏感信息在整个过程中始终保持安全。
后端示例
在此示例中,我们将演示如何在新的 ASP.NET Core Web 应用中设置并使用 OpenAIProxy。代理服务器将负责身份验证,并将请求转发至 OpenAI API,从而确保您的 API 密钥及其他敏感信息的安全。
- 创建一个新的 ASP.NET Core 极简 Web API 项目。
- 将 OpenAI-DotNet NuGet 包添加到您的项目中。
- PowerShell 安装:
Install-Package OpenAI-DotNet-Proxy - .NET CLI 安装:
dotnet add package OpenAI-DotNet-Proxy - 手动编辑 .csproj 文件:
<PackageReference Include="OpenAI-DotNet-Proxy" />
- PowerShell 安装:
- 创建一个继承自
AbstractAuthenticationFilter的新类,并重写ValidateAuthentication方法。这将实现IAuthenticationFilter接口,用于根据内部服务器验证用户会话令牌。 - 在
Program.cs中,调用OpenAIProxy.CreateWebApplication方法创建新的代理 Web 应用程序,并将自定义的AuthenticationFilter作为类型参数传递。 - 按照常规方式创建
OpenAIAuthentication和OpenAIClientSettings,使用您的 API 密钥、组织 ID 或 Azure 设置。
public partial class Program
{
private class AuthenticationFilter : AbstractAuthenticationFilter
{
public override async Task ValidateAuthenticationAsync(IHeaderDictionary request)
{
await Task.CompletedTask; // 调用远程资源验证令牌
// 您需要实现自己的类来正确测试为您终端用户颁发的自定义令牌。
if (!request.Authorization.ToString().Contains(TestUserToken))
{
throw new AuthenticationException("用户未授权");
}
}
}
public static void Main(string[] args)
{
var auth = OpenAIAuthentication.LoadFromEnv();
var settings = new OpenAIClientSettings(/* 如果使用 Azure OpenAI,请填写自定义设置 */);
using var openAIClient = new OpenAIClient(auth, settings);
OpenAIProxy.CreateWebApplication<AuthenticationFilter>(args, openAIClient).Run();
}
}
一旦您设置了代理服务器,终端用户就可以向您的代理 API 发送经过身份验证的请求,而无需直接访问 OpenAI API。代理服务器将处理身份验证并将请求转发至 OpenAI API,从而确保您的 API 密钥及其他敏感信息的安全。
模型
列出并描述 API 中可用的各种模型。您可以参考 模型文档,了解有哪些模型以及它们之间的区别。
此外,请查看 模型端点兼容性,以了解哪些模型适用于哪些端点。
要指定本库中未预定义的自定义模型:
var model = new Model("model-id");
可通过 OpenAIClient.ModelsEndpoint 访问模型 API。
列出模型
列出当前可用的模型,并提供每个模型的基本信息,例如所有者和可用性。
var api = new OpenAIClient();
var models = await api.ModelsEndpoint.GetModelsAsync();
foreach (var model in models)
{
Debug.Log(model.ToString());
}
获取模型
获取某个模型的详细信息,包括所有者和权限等基本信息。
var api = new OpenAIClient();
var model = await api.ModelsEndpoint.GetModelDetailsAsync("gpt-4o");
Debug.Log(model.ToString());
删除微调模型
删除一个微调过的模型。您必须在组织中拥有所有者角色。
var api = new OpenAIClient();
var isDeleted = await api.ModelsEndpoint.DeleteFineTuneModelAsync("your-fine-tuned-model");
Assert.IsTrue(isDeleted);
响应
OpenAI 最先进的模型响应生成接口。支持文本和图像输入,以及文本输出。利用先前响应的输出作为输入,与模型建立有状态的交互。通过内置的文件搜索、网页搜索、计算机操作等工具扩展模型的能力。使用函数调用功能让模型访问外部系统和数据。
响应 API 可通过 OpenAIClient.ResponsesEndpoint 访问。
创建响应
创建模型响应。提供文本或图像输入以生成文本或 JSON 输出。让模型调用您自定义的代码,或使用内置工具(如网页搜索、文件搜索)来将您自己的数据作为模型响应的输入。
简单文本响应
var api = new OpenAIClient();
var response = await api.ResponsesEndpoint.CreateModelResponseAsync("给我讲一个关于独角兽的三句话睡前故事。");
var responseItem = response.Output.LastOrDefault();
Debug.Log($"{responseItem.Role}: {responseItem}");
response.PrintUsage();
带函数调用的流式响应
var api = new OpenAIClient();
var conversation = new List<IResponseItem>
{
new Message(Role.System, "你是一个有用的助手。"),
new Message(Role.User, "现在几点了?"),
};
var tools = new List<Tool>
{
Tool.GetOrCreateTool(typeof(DateTimeUtility), nameof(DateTimeUtility.GetDateTime))
};
var request = new CreateResponseRequest(conversation, Model.GPT5_Nano, tools: tools);
async Task StreamCallback(string @event, IServerSentEvent sseEvent)
{
switch (sseEvent)
{
case Message messageItem:
conversation.Add(messageItem);
break;
case FunctionToolCall functionToolCall:
conversation.Add(functionToolCall);
var output = await functionToolCall.InvokeFunctionAsync();
conversation.Add(output);
await api.ResponsesEndpoint.CreateModelResponseAsync(new(conversation, Model.GPT5_Nano, tools: tools, toolChoice: "none"), StreamCallback);
break;
}
}
var response = await api.ResponsesEndpoint.CreateModelResponseAsync(request, StreamCallback);
var responseItem = response.Output.LastOrDefault();
Debug.Log($"{responseItem.Role}: {responseItem}");
response.PrintUsage();
获取响应
根据给定的 ID 获取模型响应。
var api = new OpenAIClient();
var response = await api.ResponsesEndpoint.GetModelResponseAsync("response-id");
Debug.Log(response.ToString());
列出输入项
返回指定响应的所有输入项列表。
var api = new OpenAIClient();
var responseInputItems = await api.ResponsesEndpoint.ListInputItemsAsync("response-id");
foreach (var item in responseInputItems)
{
Debug.Log(item.ToJsonString());
}
取消响应
根据给定的 ID 取消模型响应。
[!注意] 只有在创建时将 background 参数设置为 true 的响应才能被取消。
var api = new OpenAIClient();
var isCancelled = await api.ResponsesEndpoint.CancelModelResponseAsync("response-id");
Assert.IsTrue(isCancelled);
删除响应
根据给定的 ID 删除模型响应。
var api = new OpenAIClient();
var isDeleted = await api.ResponsesEndpoint.DeleteModelResponseAsync("response-id");
Assert.IsTrue(isDeleted);
对话
创建和管理对话,以便在多次响应 API 调用之间存储和检索对话状态。
对话 API 通过 OpenAIClient.ConversationsEndpoint 访问。
创建对话
创建一个对话。
var api = new OpenAIClient();
conversation = await api.ConversationsEndpoint.CreateConversationAsync(
new CreateConversationRequest(new Message(Role.Developer, systemPrompt)));
Debug.Log(conversation.ToString());
// 在创建响应时使用对话对象。
var request = await api.ResponsesEndpoint.CreateResponseAsync(
new CreateResponseRequest(textInput: "Hello!", conversationId: conversation, model: Model.GPT5_Nano));
var response = await openAI.ResponsesEndpoint.CreateModelResponseAsync(request);
var responseItem = response.Output.LastOrDefault();
Debug.Log($"{responseItem.Role}:{responseItem}");
response.PrintUsage();
获取对话
根据 ID 获取对话。
var api = new OpenAIClient();
var conversation = await api.ConversationsEndpoint.GetConversationAsync("conversation-id");
Debug.Log(conversation.ToString());
更新对话
使用自定义元数据更新对话。
var api = new OpenAIClient();
var metadata = new Dictionary<string, object>
{
{ "favorite_color", "blue" },
{ "favorite_food", "pizza" }
};
var updatedConversation = await api.ConversationsEndpoint.UpdateConversationAsync("conversation-id", metadata);
删除对话
根据 ID 删除对话。
var api = new OpenAIClient();
var isDeleted = await api.ConversationsEndpoint.DeleteConversationAsync("conversation-id");
Assert.IsTrue(isDeleted);
列出对话项
列出具有给定 ID 的对话的所有项。
var api = new OpenAIClient();
var query = new ListQuery(limit: 10);
var items = await api.ConversationsEndpoint.ListConversationItemsAsync("conversation-id", query);
foreach (var item in items)
{
Debug.Log(item.ToJsonString());
}
创建对话项
为具有给定 ID 的对话创建一个新的对话项。
var api = new OpenAIClient();
var items = new List<IResponseItem>
{
new Message(Role.User, "Hello!"),
new Message(Role.Assistant, "Hi! How can I help you?")
}
var addedItems = await api.ConversationsEndpoint.CreateConversationItemsAsync("conversation-id", items);
foreach (var item in addedItems)
{
Debug.Log(item.ToJsonString());
}
获取对话项
根据 ID 获取对话项。
var api = new OpenAIClient();
var item = await api.ConversationsEndpoint.GetConversationItemAsync("conversation-id", "item-id");
Debug.Log(item.ToJsonString());
删除对话项
根据 ID 删除对话项。
var api = new OpenAIClient();
var isDeleted = await api.ConversationsEndpoint.DeleteConversationItemAsync("conversation-id", "item-id");
Assert.IsTrue(isDeleted);
实时
[!WARNING] 测试功能。API 可能会发生重大变更。
实时 API 使您能够构建低延迟、多模态的对话体验。目前它支持文本和音频作为输入和输出,以及函数调用。
助手 API 通过 OpenAIClient.RealtimeEndpoint 访问。
创建实时会话
以下是一个简单的示例,说明如何创建实时会话,并向模型发送和接收消息。
var api = new OpenAIClient();
var cancellationTokenSource = new CancellationTokenSource();
var tools = new List<Tool>
{
Tool.FromFunc("goodbye", () =>
{
cancellationTokenSource.Cancel();
return "Goodbye!";
})
};
var configuration = new SessionConfiguration(Model.GPT4oRealtime, tools: tools);
using var session = await api.RealtimeEndpoint.CreateSessionAsync(configuration);
var responseTask = session.ReceiveUpdatesAsync<IServerEvent>(ServerEvents, cancellationTokenSource.Token);
await session.SendAsync(new ConversationItemCreateRequest("Hello!"));
await session.SendAsync(new CreateResponseRequest());
await session.SendAsync(new InputAudioBufferAppendRequest(new ReadOnlyMemory<byte>(new byte[1024 * 4])), cancellationTokenSource.Token);
await session.SendAsync(new ConversationItemCreateRequest("GoodBye!"));
await session.SendAsync(new CreateResponseRequest());
await responseTask;
void ServerEvents(IServerEvent @event)
{
switch (@event)
{
case ResponseAudioTranscriptResponse transcriptResponse:
Debug.Log(transcriptResponse.ToString());
break;
case ResponseFunctionCallArgumentsResponse functionCallResponse:
if (functionCallResponse.IsDone)
{
ToolCall toolCall = functionCallResponse;
toolCall.InvokeFunction();
}
break;
}
}
客户端事件
该库实现了用于发送客户端事件的 IClientEvent 接口。
UpdateSessionRequest:使用新的会话选项更新会话。InputAudioBufferAppendRequest:将音频追加到输入音频缓冲区。(与其他客户端事件不同,服务器不会对此事件发送确认响应)。InputAudioBufferCommitRequest:提交输入音频缓冲区。(在服务器 VAD 模式下,客户端无需发送此事件)。InputAudioBufferClearRequest:清空输入音频缓冲区。ConversationItemCreateRequest:创建一个新的对话项。这是向模型发送用户内容的主要方式。ConversationItemTruncateRequest:发送此事件以截断先前助手消息的音频。ConversationItemDeleteRequest:删除一个对话项。当您希望从对话历史中移除某条消息时,这非常有用。CreateResponseRequest:从模型生成回复。在创建新的对话项或调用工具函数后发送此事件。这将触发模型生成回复。ResponseCancelRequest:发送此事件以取消正在进行的回复。
发送客户端事件
您可以随时通过调用会话对象上的 RealtimeSession.SendAsync 方法向服务器发送客户端事件。发送调用将返回一个 IServerEvent 句柄,该句柄最能代表服务器对该事件的适当响应。如果您希望以更细粒度的方式处理服务器响应,这将非常有用。
不过,理想情况下,您可能希望使用 RealtimeSession.ReceiveUpdatesAsync 来处理所有服务器响应。
[!注意] 服务器不会对
InputAudioBufferAppendRequest事件发送确认响应。
[!重要提示] 您还需要发送
CreateResponseRequest以触发模型生成回复。
var serverEvent = await session.SendAsync(new ConversationItemCreateRequest("你好!"));
Debug.Log(serverEvent.ToJsonString());
serverEvent = await session.SendAsync(new CreateResponseRequest());
Debug.Log(serverEvent.ToJsonString());
服务器事件
该库为传入的服务器发送事件实现了 IServerEvent 接口。
RealtimeEventError:在发生错误时返回,可能是客户端问题或服务器问题。SessionResponse:用于session.created和session.updated事件。RealtimeConversationResponse:在创建新对话项时返回。ConversationItemCreatedResponse:在创建新对话项时返回。ConversationItemInputAudioTranscriptionResponse:在输入音频转录完成或失败时返回。ConversationItemTruncatedResponse:在对话项被截断时返回。ConversationItemDeletedResponse:在对话项被删除时返回。InputAudioBufferCommittedResponse:在输入音频缓冲区被提交时返回,无论是由客户端提交还是在服务器 VAD 模式下自动提交。InputAudioBufferClearedResponse:在输入音频缓冲区被清空时返回。InputAudioBufferStartedResponse:在服务器 VAD 模式下,当检测到音频缓冲区中有语音时,由服务器发送此事件。每当有音频添加到缓冲区时都可能发生(除非已检测到语音)。客户端可能会利用此事件来中断音频播放或向用户提供视觉反馈。InputAudioBufferStoppedResponse:在服务器 VAD 模式下,当服务器检测到音频缓冲区中的语音结束时返回。RealtimeResponse:在创建或完成回复时返回。ResponseOutputItemResponse:在添加或完成回复输出项时返回。ResponseContentPartResponse:在添加或完成回复内容部分时返回。ResponseTextResponse:在更新或完成回复文本时返回。ResponseAudioTranscriptResponse:在更新或完成回复音频转录时返回。ResponseAudioResponse:在更新或完成回复音频时返回。ResponseFunctionCallArgumentsResponse:在更新或完成回复函数调用参数时返回。RateLimitsResponse:在速率限制更新时返回。
接收服务器事件
要接收服务器事件,您需要在会话对象上调用 RealtimeSession.ReceiveUpdatesAsync 方法。该方法将返回一个 Task,当会话关闭或取消令牌触发时,此任务将完成。理想情况下,此方法只需调用一次,并在整个会话期间持续运行。
[!NOTE] 您也可以通过使用
IRealtimeEvent接口而不是IServerEvent来获取IClientEvent回调。
await session.ReceiveUpdatesAsync<IServerEvent>(ServerEvents, cancellationTokenSource.Token);
void ServerEvents(IServerEvent @event)
{
switch (@event)
{
case RealtimeEventError error:
// 任何错误发生时都会触发
break;
case SessionResponse sessionResponse:
// 当会话创建或更新时触发
break;
case RealtimeConversationResponse conversationResponse:
// 当新对话创建时触发
break;
case ConversationItemCreatedResponse conversationItemCreated:
// 当新对话项创建时触发
break;
case ConversationItemInputAudioTranscriptionResponse conversationItemTranscription:
// 当输入音频转录完成或失败时触发
break;
case ConversationItemTruncatedResponse conversationItemTruncated:
// 当对话项被截断时触发
break;
case ConversationItemDeletedResponse conversationItemDeleted:
// 当对话项删除时触发
break;
case InputAudioBufferCommittedResponse committedResponse:
// 当输入音频缓冲区提交时触发
break;
case InputAudioBufferClearedResponse clearedResponse:
// 当输入音频缓冲区清空时触发
break;
case InputAudioBufferStartedResponse startedResponse:
// 当音频缓冲区中检测到语音时触发
break;
case InputAudioBufferStoppedResponse stoppedResponse:
// 当音频缓冲区中的语音停止时触发
break;
case RealtimeResponse realtimeResponse:
// 当响应创建或完成时触发
break;
case ResponseOutputItemResponse outputItemResponse:
// 当响应输出项添加或完成时触发
break;
case ResponseContentPartResponse contentPartResponse:
// 当响应内容部分添加或完成时触发
break;
case ResponseTextResponse textResponse:
// 当响应文本更新或完成时触发
break;
case ResponseAudioTranscriptResponse transcriptResponse:
// 当响应音频转录更新或完成时触发
break;
case ResponseFunctionCallArgumentsResponse functionCallResponse:
// 当响应函数调用参数更新或完成时触发
break;
case RateLimitsResponse rateLimitsResponse:
// 当速率限制更新时触发
break;
}
}
助手
[!WARNING] 测试功能。API 可能会发生重大变更。
构建可以调用模型并使用工具来执行任务的助手。
助手 API 通过 OpenAIClient.AssistantsEndpoint 访问。
列出助手
返回助手列表。
var api = new OpenAIClient();
var assistantsList = await api.AssistantsEndpoint.ListAssistantsAsync();
foreach (var assistant in assistantsList.Items)
{
Debug.Log($"{assistant} -> {assistant.CreatedAt}");
}
创建助手
使用模型和指令创建助手。
var api = new OpenAIClient();
var request = new CreateAssistantRequest(Model.GPT4o);
var assistant = await api.AssistantsEndpoint.CreateAssistantAsync(request);
获取助手
获取助手信息。
var api = new OpenAIClient();
var assistant = await api.AssistantsEndpoint.RetrieveAssistantAsync("assistant-id");
Debug.Log($"{assistant} -> {assistant.CreatedAt}");
修改助手
修改助手信息。
var api = new OpenAIClient();
var createRequest = new CreateAssistantRequest(Model.GPT4_Turbo);
var assistant = await api.AssistantsEndpoint.CreateAssistantAsync(createRequest);
var modifyRequest = new CreateAssistantRequest(Model.GPT4o);
var modifiedAssistant = await api.AssistantsEndpoint.ModifyAssistantAsync(assistant.Id, modifyRequest);
// 或者使用 AssistantExtension 更方便!
var modifiedAssistantEx = await assistant.ModifyAsync(modifyRequest);
删除助手
删除助手。
var api = new OpenAIClient();
var isDeleted = await api.AssistantsEndpoint.DeleteAssistantAsync("assistant-id");
// 或者使用 AssistantExtension 更方便!
var isDeleted = await assistant.DeleteAsync();
Assert.IsTrue(isDeleted);
助手流式传输
[!NOTE] 通过将
Func<IServerSentEvent, Task> streamEventHandler回调传递给任何支持流式传输的方法,可以轻松地将助手流事件添加到现有的线程调用中。
线程
创建助手可以与之交互的线程。
线程 API 通过 OpenAIClient.ThreadsEndpoint 访问。
创建线程
创建线程。
var api = new OpenAIClient();
var thread = await api.ThreadsEndpoint.CreateThreadAsync();
Debug.Log($"创建线程 {thread.Id} -> {thread.CreatedAt}");
创建线程并运行
在一个请求中创建线程并运行。
另请参阅:线程运行
var api = new OpenAIClient();
var assistant = await api.AssistantsEndpoint.CreateAssistantAsync(
new CreateAssistantRequest(
name: "数学辅导老师",
instructions: "你是一位私人数学辅导老师。请用一句话或更短的回答来解答问题。",
model: Model.GPT4o));
var messages = new List<Message> { "我需要解方程 `3x + 11 = 14`。你能帮我吗?" };
var threadRequest = new CreateThreadRequest(messages);
var run = await assistant.CreateThreadAndRunAsync(threadRequest);
Debug.Log($"创建的线程和运行:{run.ThreadId} -> {run.Id} -> {run.CreatedAt}");
创建线程并流式执行
在一个请求中创建线程并执行,同时流式接收事件。
var api = new OpenAIClient();
var tools = new List<Tool>
{
Tool.GetOrCreateTool(typeof(WeatherService), nameof(WeatherService.GetCurrentWeatherAsync))
};
var assistantRequest = new CreateAssistantRequest(tools: tools, instructions: "你是一位有用的天气助手。请根据地理位置使用合适的单位。");
var assistant = await api.AssistantsEndpoint.CreateAssistantAsync(assistantRequest);
ThreadResponse thread = null;
async Task StreamEventHandler(IServerSentEvent streamEvent)
{
switch (streamEvent)
{
case ThreadResponse threadResponse:
thread = threadResponse;
break;
case RunResponse runResponse:
if (runResponse.Status == RunStatus.RequiresAction)
{
var toolOutputs = await assistant.GetToolOutputsAsync(runResponse);
foreach (var toolOutput in toolOutputs)
{
Debug.Log($"工具输出:{toolOutput}");
}
await runResponse.SubmitToolOutputsAsync(toolOutputs, StreamEventHandler);
}
break;
default:
Debug.Log(streamEvent.ToJsonString());
break;
}
}
var run = await assistant.CreateThreadAndRunAsync("我在吉隆坡,请告诉我现在温度是多少?", StreamEventHandler);
run = await run.WaitForStatusChangeAsync();
var messages = await thread.ListMessagesAsync();
foreach (var response in messages.Items.Reverse())
{
Debug.Log($"{response.Role}: {response.PrintContent()}");
}
检索线程
检索一个线程。
var api = new OpenAIClient();
var thread = await api.ThreadsEndpoint.RetrieveThreadAsync("thread-id");
// 或者,如果你只想获取线程的最新状态
thread = await thread.UpdateAsync();
Debug.Log($"检索线程 {thread.Id} -> {thread.CreatedAt}");
修改线程
修改一个线程。
[!注意] 只能修改元数据。
var api = new OpenAIClient();
var thread = await api.ThreadsEndpoint.CreateThreadAsync();
var metadata = new Dictionary<string, string>
{
{ "key", "自定义线程元数据" }
};
thread = await api.ThreadsEndpoint.ModifyThreadAsync(thread.Id, metadata);
// 或者使用扩展方法以方便操作!
thread = await thread.ModifyAsync(metadata);
Debug.Log($"修改线程 {thread.Id} -> {thread.Metadata["key"]}");
删除线程
删除一个线程。
var api = new OpenAIClient();
var isDeleted = await api.ThreadsEndpoint.DeleteThreadAsync("thread-id");
// 或者使用扩展方法以方便操作!
var isDeleted = await thread.DeleteAsync();
Assert.IsTrue(isDeleted);
线程消息
在线程中创建消息。
列出线程消息
返回给定线程的消息列表。
var api = new OpenAIClient();
var messageList = await api.ThreadsEndpoint.ListMessagesAsync("thread-id");
// 或者使用扩展方法以方便操作!
var messageList = await thread.ListMessagesAsync();
foreach (var message in messageList.Items)
{
Debug.Log($"{message.Id}: {message.Role}: {message.PrintContent()}");
}
创建线程消息
创建一条消息。
var api = new OpenAIClient();
var thread = await api.ThreadsEndpoint.CreateThreadAsync();
var request = new CreateMessageRequest("你好,世界!");
var message = await api.ThreadsEndpoint.CreateMessageAsync(thread.Id, request);
// 或者使用扩展方法以方便操作!
var message = await thread.CreateMessageAsync("你好,世界!");
Debug.Log($"{message.Id}: {message.Role}: {message.PrintContent()}");
检索线程消息
检索一条消息。
var api = new OpenAIClient();
var message = await api.ThreadsEndpoint.RetrieveMessageAsync("thread-id", "message-id");
// 或者使用扩展方法以方便操作!
var message = await thread.RetrieveMessageAsync("message-id");
var message = await message.UpdateAsync();
Debug.Log($"{message.Id}: {message.Role}: {message.PrintContent()}");
修改线程消息
修改一条消息。
[!注意] 只能修改消息的元数据。
var api = new OpenAIClient();
var metadata = new Dictionary<string, string>
{
{ "key", "自定义消息元数据" }
};
var message = await api.ThreadsEndpoint.ModifyMessageAsync("thread-id", "message-id", metadata);
// 或者使用扩展方法以方便操作!
var message = await message.ModifyAsync(metadata);
Debug.Log($"修改消息元数据:{message.Id} -> {message.Metadata["key"]}");
线程运行
表示在线程上执行的一次运行。
列出线程运行
返回属于某个线程的所有运行列表。
var api = new OpenAIClient();
var runList = await api.ThreadsEndpoint.ListRunsAsync("thread-id");
// 或者使用扩展方法以方便操作!
var runList = await thread.ListRunsAsync();
foreach (var run in runList.Items)
{
Debug.Log($"[{run.Id}] {run.Status} | {run.CreatedAt}");
}
创建线程运行
创建一次运行。
var api = new OpenAIClient();
var assistant = await api.AssistantsEndpoint.CreateAssistantAsync(
new CreateAssistantRequest(
name: "数学家教",
instructions: "你是一位私人数学家教。请用一句话或更短的篇幅简要回答问题。",
model: Model.GPT4o));
var thread = await api.ThreadsEndpoint.CreateThreadAsync();
var message = await thread.CreateMessageAsync("我需要解方程 `3x + 11 = 14`。你能帮我吗?");
var run = await thread.CreateRunAsync(assistant);
Debug.Log($"[{run.Id}] {run.Status} | {run.CreatedAt}");
创建线程并流式处理运行
创建一个运行,并流式传输事件。
var api = new OpenAIClient();
var assistant = await api.AssistantsEndpoint.CreateAssistantAsync(
new CreateAssistantRequest(
name: "数学家教",
instructions: "你是一位私人数学家教。请用一句话或更短的篇幅简要回答问题。你的回答应以 JSON 格式呈现。",
model: Model.GPT4o,
responseFormat: ChatResponseFormat.Json));
var thread = await api.ThreadsEndpoint.CreateThreadAsync();
var message = await thread.CreateMessageAsync("我需要解方程 `3x + 11 = 14`。你能帮我吗?");
var run = await thread.CreateRunAsync(assistant, async streamEvent =>
{
Debug.Log(streamEvent.ToJsonString());
await Task.CompletedTask;
});
var messages = await thread.ListMessagesAsync();
foreach (var response in messages.Items.Reverse())
{
Debug.Log($"{response.Role}: {response.PrintContent()}");
}
检索线程运行
检索一个运行。
var api = new OpenAIClient();
var run = await api.ThreadsEndpoint.RetrieveRunAsync("thread-id", "run-id");
// 或者使用扩展方法以方便操作!
var run = await thread.RetrieveRunAsync("run-id");
var run = await run.UpdateAsync();
Debug.Log($"[{run.Id}] {run.Status} | {run.CreatedAt}");
修改线程运行
修改一个运行。
[!注意] 只能修改元数据。
var api = new OpenAIClient();
var metadata = new Dictionary<string, string>
{
{ "key", "自定义运行元数据" }
};
var run = await api.ThreadsEndpoint.ModifyRunAsync("thread-id", "run-id", metadata);
// 或者使用扩展方法以方便操作!
var run = await run.ModifyAsync(metadata);
Debug.Log($"修改运行 {run.Id} -> {run.Metadata["key"]}");
向运行提交工具输出
当运行状态为 requires_action,且 required_action.type 为 submit_tool_outputs 时,可以使用此端点在所有工具调用完成后提交工具输出。所有输出必须在一次请求中提交。
[!注意] 请参阅“创建线程并流式处理运行”示例,了解如何流式传输工具输出事件。
var api = new OpenAIClient();
var tools = new List<Tool>
{
// 使用预定义工具
Tool.Retrieval, Tool.CodeInterpreter,
// 或者根据类型和您希望用于函数调用的方法名称创建工具
Tool.GetOrCreateTool(typeof(WeatherService), nameof(WeatherService.GetCurrentWeatherAsync)),
// 传入对象实例以在其上调用方法
Tool.GetOrCreateTool(api.ImagesEndPoint, nameof(ImagesEndpoint.GenerateImageAsync)),
// 定义 func<,> 回调函数
Tool.FromFunc("name_of_func", () => { /* 回调函数 */ }),
Tool.FromFunc<T1,T2,TResult>("func_with_multiple_params", (t1, t2) => { /* 计算返回值的逻辑 */ return tResult; })
};
var assistantRequest = new CreateAssistantRequest(tools: tools, instructions: "你是一位有用的天气助手。请根据地理位置使用适当的单位。");
var testAssistant = await api.AssistantsEndpoint.CreateAssistantAsync(assistantRequest);
var run = await testAssistant.CreateThreadAndRunAsync("我在吉隆坡,请告诉我现在的温度是多少?");
// 等待运行处于排队和进行中状态
run = await run.WaitForStatusChangeAsync();
// 调用所有工具调用函数并获取工具输出。
var toolOutputs = await testAssistant.GetToolOutputsAsync(run.RequiredAction.SubmitToolOutputs.ToolCalls);
foreach (var toolOutput in toolOutputs)
{
Debug.Log($"工具调用输出:{toolOutput.Output}");
}
// 提交工具输出
run = await run.SubmitToolOutputsAsync(toolOutputs);
// 等待运行再次进入排队和进行中状态
run = await run.WaitForStatusChangeAsync();
var messages = await run.ListMessagesAsync。
foreach (var message in messages.Items.OrderBy(response => response.CreatedAt))
{
Debug.Log($"{message.Role}: {message.PrintContent()}");
}
线程结构化输出
结构化输出是 JSON 模式的演进版本。虽然两者都能确保生成有效的 JSON,但只有结构化输出才能保证符合模式要求。
[!重要提示]
- 使用 JSON 模式时,务必通过对话中的某条消息(例如系统消息)指示模型生成 JSON。如果不明确指示生成 JSON,模型可能会生成无休止的空白内容,请求也可能持续进行,直到达到令牌限制。为了防止这种情况发生,API 会在上下文中未出现“JSON”字符串时抛出错误。
- 如果
finish_reason是 length,表示生成内容超过了 max_tokens 或对话的令牌限制,则模型返回的消息中的 JSON 可能是不完整的(即被截断)。为避免这种情况,在解析响应前请检查finish_reason。
首先定义您的响应结构。这些将用作您的模式。 这些是您将反序列化的目标对象,因此请务必使用标准的 Json 对象模型。
public class MathResponse
{
[JsonProperty("steps")]
public IReadOnlyList<MathStep> Steps { get; private set; }
[JsonProperty("final_answer")]
public string FinalAnswer { get; private set; }
}
public class MathStep
{
[JsonProperty("explanation")]
public string Explanation { get; private set; }
[JsonProperty("output")]
public string Output { get; private set; }
}
使用时,只需在 CreateAssistantAsync、CreateRunAsync 或 CreateThreadAndRunAsync 中将 MathResponse 类型指定为泛型约束即可。
var api = new OpenAIClient();
var assistant = await api.AssistantsEndpoint.CreateAssistantAsync<MathResponse>(
new CreateAssistantRequest(
name: "数学家教",
instructions: "你是一位有帮助的数学家教。请逐步引导用户完成解题过程。",
model: "gpt-4o-2024-08-06"));
ThreadResponse thread = null;
尝试
{
异步任务 StreamEventHandler(IServerSentEvent @event)
{
try
{
切换 (@event)
{
案例 MessageResponse message:
如果 (message.Status != MessageStatus.Completed)
{
Debug.Log(@event.ToJsonString());
中断;
}
var mathResponse = message.FromSchema<MathResponse>();
对于 (var i = 0; i < mathResponse.Steps.Count; i++)
{
var step = mathResponse.Steps[i];
Debug.Log($"步骤 {i}: {step.Explanation}");
Debug.Log($"结果: {step.Output}");
}
Debug.Log($"最终答案: {mathResponse.FinalAnswer}");
中断;
默认:
Debug.Log(@event.ToJsonString());
中断;
}
}
抓取 (Exception e)
{
Debug.Log(e);
抛出;
}
等待 Task.CompletedTask;
}
var run = await assistant.CreateThreadAndRunAsync("如何解方程 8x + 7 = -23", StreamEventHandler);
thread = await run.GetThreadAsync();
run = await run.WaitForStatusChangeAsync();
Debug.Log($"创建了线程和运行:{run.ThreadId} -> {run.Id} -> {run.CreatedAt}");
var messages = await thread.ListMessagesAsync();
对于 (var response 在 messages.Items 中按 CreatedAt 排序)
{
Debug.Log($"{response.Role}: {response.PrintContent()}");
}
}
最后
{
等待 assistant.DeleteAsync(deleteToolResources: thread == null);
如果 (thread != null)
{
var isDeleted = await thread.DeleteAsync(deleteToolResources: true);
}
}
你也可以手动创建 JSON 模式 JSON 字符串,但你需要负责反序列化你的响应数据:
var api = new OpenAIClient();
var mathSchema = new JsonSchema("math_response", @"
{
""type"": ""object"",
""properties"": {
""steps"": {
""type"": ""array"",
""items"": {
""type"": ""object"",
""properties"": {
""explanation"": {
""type"": ""string""
},
""output"": {
""type"": ""string""
}
},
""required"": [
""explanation"",
""output""
],
""additionalProperties"": false
}
},
""final_answer"": {
""type"": ""string""
}
},
""required"": [
""steps"",
""final_answer""
],
""additionalProperties"": false
}");
var assistant = await api.AssistantsEndpoint.CreateAssistantAsync(
新的 CreateAssistantRequest(
名称: "数学辅导老师",
指令: "你是一位乐于助人的数学辅导老师。请逐步引导用户解决问题。",
模型: "gpt-4o-2024-08-06",
jsonSchema: mathSchema));
ThreadResponse thread = null;
尝试
{
var run = await assistant.CreateThreadAndRunAsync("如何解方程 8x + 7 = -23",
异步 @event =>
{
Debug.Log(@event.ToJsonString());
等待 Task.CompletedTask;
});
thread = await run.GetThreadAsync();
run = await run.WaitForStatusChangeAsync();
Debug.Log($"创建了线程和运行:{run.ThreadId} -> {run.Id} -> {run.CreatedAt}");
var messages = await thread.ListMessagesAsync。
对于 (var response 在 messages.Items 中)
{
Debug.Log($"{response.Role}: {response.PrintContent()}");
}
}
最后
{
等待 assistant.DeleteAsync(deleteToolResources: thread == null);
如果 (thread != null)
{
var isDeleted = await thread.DeleteAsync(deleteToolResources: true);
Assert.IsTrue(isDeleted);
}
}
列出线程运行步骤
返回属于某个运行的运行步骤列表。
var api = new OpenAIClient();
var runStepList = await api.ThreadsEndpoint.ListRunStepsAsync("thread-id", "run-id");
// 或者使用扩展方法以方便操作!
var runStepList = await run.ListRunStepsAsync。
对于 (var runStep 在 runStepList.Items 中)
{
Debug.Log($"[{runStep.Id}] {runStep.Status} {runStep.CreatedAt} -> {runStep.ExpiresAt}");
}
获取线程运行步骤
获取一个运行步骤。
var api = new OpenAIClient();
var runStep = await api.ThreadsEndpoint.RetrieveRunStepAsync("thread-id", "run-id", "step-id");
// 或者使用扩展方法以方便操作!
var runStep = await run.RetrieveRunStepAsync("step-id");
var runStep = await runStep.UpdateAsync();
Debug.Log($"[{runStep.Id}] {runStep.Status} {runStep.CreatedAt} -> {runStep.ExpiresAt}");
取消线程运行
取消一个处于 in_progress 状态的运行。
var api = new OpenAIClient();
var isCancelled = await api.ThreadsEndpoint.CancelRunAsync("thread-id", "run-id");
// 或者使用扩展方法以方便操作!
var isCancelled = await run.CancelAsync();
Assert.IsTrue(isCancelled);
向量存储
向量存储用于存储文件,供 file_search 工具使用。
通过 OpenAIClient.VectorStoresEndpoint 访问向量存储 API。
列出向量存储
返回向量存储列表。
var api = new OpenAIClient();
var vectorStores = await api.VectorStoresEndpoint.ListVectorStoresAsync。
对于 (var vectorStore 在 vectorStores.Items 中)
{
Debug.Log(vectorStore);
}
创建向量存储
创建一个向量存储。
var api = new OpenAIClient();
var createVectorStoreRequest = 新的 CreateVectorStoreRequest("测试向量存储");
var vectorStore = await api.VectorStoresEndpoint.CreateVectorStoreAsync(createVectorStoreRequest);
Debug.Log(vectorStore);
获取向量存储
获取一个向量存储。
var api = new OpenAIClient();
var vectorStore = await api.VectorStoresEndpoint.GetVectorStoreAsync("向量存储ID");
Debug.Log(vectorStore);
修改向量存储
修改一个向量存储。
var api = new OpenAIClient();
var metadata = 新的 字典<string, object> { { "测试", 当前时间 } };
var vectorStore = await api.VectorStoresEndpoint.ModifyVectorStoreAsync("向量存储ID", metadata: metadata);
Debug.Log(vectorStore);
删除向量存储
删除向量存储。
var api = new OpenAIClient();
var isDeleted = await api.VectorStoresEndpoint.DeleteVectorStoreAsync("vector-store-id");
Assert.IsTrue(isDeleted);
向量存储文件
向量存储文件表示向量存储中的文件。
列出向量存储文件
返回向量存储文件的列表。
var api = new OpenAIClient();
var files = await api.VectorStoresEndpoint.ListVectorStoreFilesAsync("vector-store-id");
foreach (var file in vectorStoreFiles.Items)
{
Debug.Log(file);
}
创建向量存储文件
通过将文件附加到向量存储来创建向量存储文件。
var api = new OpenAIClient();
var file = await api.VectorStoresEndpoint.CreateVectorStoreFileAsync("vector-store-id", "file-id", new ChunkingStrategy(ChunkingStrategyType.Static));
Debug.Log(file);
获取向量存储文件
获取向量存储文件。
var api = new OpenAIClient();
var file = await api.VectorStoresEndpoint.GetVectorStoreFileAsync("vector-store-id", "vector-store-file-id");
Debug.Log(file);
删除向量存储文件
删除向量存储文件。这会从向量存储中移除文件,但文件本身不会被删除。要删除文件,请使用删除文件端点。
var api = new OpenAIClient();
var isDeleted = await api.VectorStoresEndpoint.DeleteVectorStoreFileAsync("vector-store-id", vectorStoreFile);
Assert.IsTrue(isDeleted);
向量存储文件批次
向量存储文件表示向量存储中的文件。
创建向量存储文件批次
创建向量存储文件批次。
var api = new OpenAIClient();
var files = new List<string> { "file_id_1","file_id_2" };
var vectorStoreFileBatch = await api.VectorStoresEndpoint.CreateVectorStoreFileBatchAsync("vector-store-id", files);
Debug.Log(vectorStoreFileBatch);
获取向量存储文件批次
获取向量存储文件批次。
var api = new OpenAIClient();
var vectorStoreFileBatch = await api.VectorStoresEndpoint.GetVectorStoreFileBatchAsync("vector-store-id", "vector-store-file-batch-id");
// 你也可以使用便捷方法!
vectorStoreFileBatch = await vectorStoreFileBatch.UpdateAsync();
vectorStoreFileBatch = await vectorStoreFileBatch.WaitForStatusChangeAsync();
列出向量存储批次中的文件
返回批次中向量存储文件的列表。
var api = new OpenAIClient();
var files = await api.VectorStoresEndpoint.ListVectorStoreBatchFilesAsync("vector-store-id", "vector-store-file-batch-id");
foreach (var file in files.Items)
{
Debug.Log(file);
}
取消向量存储文件批次
取消向量存储文件批次。这会尽快尝试取消该批次中文件的处理。
var api = new OpenAIClient();
var isCancelled = await api.VectorStoresEndpoint.CancelVectorStoreFileBatchAsync("vector-store-id", "vector-store-file-batch-id");
聊天
给定一次聊天对话,模型将返回一个聊天完成响应。
聊天 API 通过 OpenAIClient.ChatEndpoint 访问。
聊天完成
为聊天消息创建完成。
var api = new OpenAIClient();
var messages = new List<Message>
{
new Message(Role.System, "你是一个有用的助手。"),
new Message(Role.User, "2020年的世界大赛是谁赢的?"),
new Message(Role.Assistant, "洛杉矶道奇队在2020年赢得了世界大赛。"),
new Message(Role.User, "比赛是在哪里举行的?"),
};
var chatRequest = new ChatRequest(messages, Model.GPT4o);
var response = await api.ChatEndpoint.GetCompletionAsync(chatRequest);
var choice = response.FirstChoice;
Debug.Log($"[{choice.Index}] {choice.Message.Role}: {choice.Message} | 结束原因: {choice.FinishReason}");
聊天流式传输
var api = new OpenAIClient();
var messages = new List<Message>
{
new Message(Role.System, "你是一个有用的助手。"),
new Message(Role.User, "2020年的世界大赛是谁赢的?"),
new Message(Role.Assistant, "洛杉矶道奇队在2020年赢得了世界大赛。"),
new Message(Role.User, "比赛是在哪里举行的?"),
};
var chatRequest = new ChatRequest(messages);
var response = await api.ChatEndpoint.StreamCompletionAsync(chatRequest, async partialResponse =>
{
Debug.Log(partialResponse.FirstChoice.Delta.ToString());
await Task.CompletedTask;
});
var choice = response.FirstChoice;
Debug.Log($"[{choice.Index}] {choice.Message.Role}: {choice.Message} | 结束原因: {choice.FinishReason}");
聊天工具
var api = new OpenAIClient();
var messages = new List<Message>
{
new(Message.Role.System, "你是一个有用的天气助手。始终提示用户他们的位置。"),
new Message(Role.User, "今天天气怎么样?"),
};
foreach (var message in messages)
{
Debug.Log($"{message.Role}: {message}");
}
// 定义助手可以使用的工具:
// 1. 获取所有用 FunctionAttribute 装饰的静态方法列表
var tools = Tool.GetAllAvailableTools(includeDefaults: false, forceUpdate: true, clearCache: true);
// 2. 定义自定义工具列表:
var tools = new List<Tool>
{
Tool.GetOrCreateTool(objectInstance, "要调用的方法名称"),
Tool.FromFunc("你函数的自定义名称", ()=> { /* 某些逻辑要执行 */ })
};
var chatRequest = new ChatRequest(messages, 工具: tools, 工具选择: "auto");
var response = await api.ChatEndpoint.GetCompletionAsync(chatRequest);
messages.Add(response.FirstChoice.Message);
Debug.Log($"{response.FirstChoice.Message.Role}: {response.FirstChoice} | 结束原因: {response.FirstChoice.FinishReason}");
var locationMessage = new Message(Role.User, "我在苏格兰的格拉斯哥");
messages.Add(locationMessage);
Debug.Log($"{locationMessage.Role}: {locationMessage.Content}");
chatRequest = new ChatRequest(messages, tools: tools, toolChoice: "auto");
response = await api.ChatEndpoint.GetCompletionAsync(chatRequest);
messages.Add(response.FirstChoice.Message);
if (response.FirstChoice.FinishReason == "stop")
{
Debug.Log($"{response.FirstChoice.Message.Role}: {response.FirstChoice} | 结束原因: {response.FirstChoice.FinishReason}");
var unitMessage = new Message(Role.User, "华氏度");
messages.Add(unitMessage);
Debug.Log($"{unitMessage.Role}: {unitMessage.Content}");
chatRequest = new ChatRequest(messages, tools: tools, toolChoice: "auto");
response = await api.ChatEndpoint.GetCompletionAsync(chatRequest);
}
// 遍历所有工具调用并执行它们
foreach (var toolCall in response.FirstChoice.Message.ToolCalls)
{
Debug.Log($"{response.FirstChoice.Message.Role}: {toolCall.Function.Name} | 结束原因: {response.FirstChoice.FinishReason}");
Debug.Log($"{toolCall.Function.Arguments}");
// 调用函数以获取通用的 JSON 结果作为工具调用的返回值。
var functionResult = await toolCall.InvokeFunctionAsync();
// 如果你知道返回类型并需要进行额外处理,可以使用泛型重载版本。
var functionResult = await toolCall.InvokeFunctionAsync<string>();
messages.Add(new Message(toolCall, functionResult));
Debug.Log($"{Role.Tool}: {functionResult}");
}
// 系统:你是一个有用的天气助手。
// 用户:今天天气怎么样?
// 助手:当然,请问您目前的位置是哪里?| 结束原因:stop
// 用户:我在苏格兰的格拉斯哥
// 助手:GetCurrentWeather | 结束原因:tool_calls
// {
// "location": "Glasgow, Scotland",
// "unit": "celsius"
// }
// 工具:苏格兰格拉斯哥当前的气温为39°C。
视觉聊天
[!WARNING] 测试功能。API 可能会随时发生变化。
var api = new OpenAIClient();
var messages = new List<Message>
{
new Message(Role.System, "你是一个有用的助手。"),
new Message(Role.User, new List<Content>
{
"这张图片里有什么?",
new ImageUrl("https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg", ImageDetail.Low)
})
};
var chatRequest = new ChatRequest(messages, model: Model.GPT4o);
var response = await api.ChatEndpoint.GetCompletionAsync(chatRequest);
Debug.Log($"{response.FirstChoice.Message.Role}: {response.FirstChoice.Message.Content} | 结束原因: {response.FirstChoice.FinishDetails}");
你甚至可以直接传入一个 Texture2D!
var api = new OpenAIClient();
var messages = new List<Message>
{
new Message(Role.System, "你是一个有用的助手。"),
new Message(Role.User, new List<Content>
{
"这张图片里有什么?",
texture
})
};
var chatRequest = new ChatRequest(messages, model: Model.GPT4o);
var result = await api.ChatEndpoint.GetCompletionAsync(chatRequest);
Debug.Log($"{result.FirstChoice.Message.Role}: {result.FirstChoice} | 结束原因: {result.FirstChoice.FinishDetails}");
音频聊天
var api = new OpenAIClient();
var messages = new List<Message>
{
new Message(Role.System, "你是一个有用的助手。"),
new Message(Role.User, "金毛寻回犬适合作为家庭宠物吗?")
};
var chatRequest = new ChatRequest(messages, Model.GPT4oAudio, audioConfig: Voice.Alloy);
var response = await api.ChatEndpoint.GetCompletionAsync(chatRequest);
Debug.Log($"{response.FirstChoice.Message.Role}: {response.FirstChoice} | 结束原因: {response.FirstChoice.FinishDetails}");
audioSource.PlayOneShot(response.FirstChoice.Message.AudioOutput.AudioClip);
结构化输出聊天
这是 JSON 模式 的进一步发展。虽然两者都能确保生成有效的 JSON,但只有结构化输出才能保证符合预定义的模式。
[!IMPORTANT]
- 使用 JSON 模式时,务必在对话中通过某条消息明确指示模型生成 JSON,例如通过系统提示语。如果不包含明确的 JSON 生成指令,模型可能会持续输出空白字符,请求将一直运行直到达到令牌上限。为了防止这种情况发生,API 会在上下文中未出现“JSON”字样时抛出错误。
- 如果
finish_reason是 length,则模型返回的消息中的 JSON 可能是不完整的(即被截断),这表明生成内容超出了最大令牌数或对话已超过令牌限制。为避免此问题,在解析响应之前请检查finish_reason。
首先定义你的响应结构。这些将作为你的模式使用。 这些是你将反序列化的目标对象,因此请确保使用标准的 JSON 对象模型。
public class MathResponse
{
[JsonProperty("steps")]
public IReadOnlyList<MathStep> Steps { get; private set; }
[JsonProperty("final_answer")]
public string FinalAnswer { get; private set; }
}
public class MathStep
{
[JsonProperty("explanation")]
public string Explanation { get; private set; }
[JsonProperty("output")]
public string Output { get; private set; }
}
使用时,只需在请求完成时指定 MathResponse 类型作为泛型约束即可。
var api = new OpenAIClient();
var messages = new List<Message>
{
new(Message.Role.System, "你是一位有用的教学助理。请逐步引导用户解决问题。"),
new(Message.Role.User, "如何解方程 8x + 7 = -23")
};
var chatRequest = new ChatRequest(messages, model: "gpt-4o-2024-08-06");
var (mathResponse, chatResponse) = await api.ChatEndpoint.GetCompletionAsync<MathResponse>(chatRequest);
for (int i = 0; i < mathResponse.Steps.Count; i++)
{
var step = mathResponse.Steps[i];
Debug.Log($"第 {i} 步:{step.Explanation}");
Debug.Log($"结果:{step.Output}");
}
Debug.Log($"最终答案:{mathResponse.FinalAnswer}");
chatResponse.GetUsage();
JSON 模式聊天
[!IMPORTANT]
- 使用 JSON 模式时,务必通过对话中的某条消息(例如系统消息)指示模型生成 JSON。如果不包含明确的 JSON 生成指令,模型可能会生成无休止的空白字符流,请求将持续运行直到达到令牌限制。为避免这种情况,如果上下文中未出现字符串“JSON”,API 将抛出错误。
- 如果
finish_reason为length,则模型返回的消息中的 JSON 可能是不完整的(即被截断),这表示生成内容超出了max_tokens或对话的令牌限制。为防止这种情况,在解析响应之前,请检查finish_reason。- JSON 模式不会保证输出符合任何特定模式,仅保证其有效且可无错误地解析。
var messages = new List<Message>
{
new Message(Role.System, "你是一个旨在输出 JSON 的助手。"),
new Message(Role.User, "2020 年世界大赛是谁赢了?"),
};
var chatRequest = new ChatRequest(messages, Model.GPT4o, responseFormat: ChatResponseFormat.Json);
var response = await api.ChatEndpoint.GetCompletionAsync(chatRequest);
foreach (var choice in response.Choices)
{
Debug.Log($"[{choice.Index}] {choice.Message.Role}: {choice} | 结束原因: {choice.FinishReason}");
}
response.GetUsage();
音频
将音频转换为文本。
音频 API 通过 OpenAIClient.AudioEndpoint 访问。
创建语音
根据输入文本生成音频。
var api = new OpenAIClient();
var request = new SpeechRequest("你好,世界!");
var speechClip = await api.AudioEndpoint.GetSpeechAsync(request);
audioSource.PlayOneShot(speechClip);
Debug.Log(speechClip);
[流式语音]
根据输入文本生成流式音频。
var api = new OpenAIClient();
var request = new SpeechRequest("你好,世界!", responseFormat: SpeechResponseFormat.PCM);
var speechClip = await api.AudioEndpoint.GetSpeechAsync(request, partialClip =>
{
audioSource.PlayOneShot(partialClip);
});
Debug.Log(speechClip);
[!NOTE] 请查看任何演示场景,以了解如何使用
OnAudioFilterRead处理播放的最佳实践。
创建转录
将音频转录为输入语言。
var api = new OpenAIClient();
var request = new AudioTranscriptionRequest(audioClip, language: "en");
var result = await api.AudioEndpoint.CreateTranscriptionAsync(request);
Debug.Log(result);
您还可以使用 verbose_json 获取更详细的带时间戳信息:
var api = new OpenAIClient();
using var request = new AudioTranscriptionRequest(transcriptionAudio, responseFormat: AudioResponseFormat.Verbose_Json, timestampGranularity: TimestampGranularity.Word, temperature: 0.1f, language: "en");
var response = await api.AudioEndpoint.CreateTranscriptionTextAsync(request);
foreach (var word in response.Words)
{
Debug.Log($"[{word.Start}-{word.End}] \"{word.Word}\"");
}
创建翻译
将音频翻译成英语。
var api = new OpenAIClient();
var request = new AudioTranslationRequest(audioClip);
var result = await api.AudioEndpoint.CreateTranslationAsync(request);
Debug.Log(result);
图片
根据提示和/或输入图像,模型会生成一张新图像。
图片 API 通过 OpenAIClient.ImagesEndpoint 访问。
创建图像
根据提示创建图像。
var api = new OpenAIClient();
var request = new ImageGenerationRequest("一只骑着迅猛龙的房子", Models.Model.DallE_3);
var imageResults = await api.ImagesEndPoint.GenerateImageAsync(request);
foreach (var result in imageResults)
{
Debug.Log(result.ToString());
Assert.IsNotNull(result.Texture);
}
编辑图像
根据原始图像和提示创建编辑或扩展后的图像。
var api = new OpenAIClient();
var request = new ImageEditRequest(Path.GetFullPath(imageAssetPath), Path.GetFullPath(maskAssetPath), "一个阳光明媚的室内休息区,池塘里有一只火烈鸟", size: ImageSize.Small);
var imageResults = await api.ImagesEndPoint.CreateImageEditAsync(request);
foreach (var result in imageResults)
{
Debug.Log(result.ToString());
Assert.IsNotNull(result.Texture);
}
创建图像变体
根据给定图像创建变体。
var api = new OpenAIClient();
var request = new ImageVariationRequest(imageTexture, size: ImageSize.Small);
var imageResults = await api.ImagesEndPoint.CreateImageVariationAsync(request);
foreach (var result in imageResults)
{
Debug.Log(result.ToString());
Assert.IsNotNull(result.Texture);
}
或者,该端点可以直接接受启用了读写权限且压缩设置为“无”的 Texture2D。
var api = new OpenAIClient();
var request = new ImageVariationRequest(imageTexture, size: ImageSize.Small);
var imageResults = await api.ImagesEndPoint.CreateImageVariationAsync(request);
foreach (var result in imageResults)
{
Debug.Log(result.ToString());
Assert.IsNotNull(result.Texture);
}
文件
文件用于上传文档,这些文档可以与诸如微调等功能一起使用。
文件 API 通过 OpenAIClient.FilesEndpoint 访问。
列出文件
返回属于用户组织的文件列表。
var api = new OpenAIClient();
var fileList = await api.FilesEndpoint.ListFilesAsync();
foreach (var file in fileList)
{
Debug.Log($"{file.Id} -> {file.Object}: {file.FileName} | {file.Size} bytes");
}
上传文件
上传可在多个端点使用的文件。单个组织上传的所有文件大小上限为 100 GB。
单个文件的最大大小为 512 MB。有关支持的文件类型,请参阅助手工具指南。微调 API 仅支持 .jsonl 文件。
var api = new OpenAIClient();
var file = await api.FilesEndpoint.UploadFileAsync("path/to/your/file.jsonl", FilePurpose.FineTune);
Debug.Log(file.Id);
删除文件
删除文件。
var api = new OpenAIClient();
var isDeleted = await api.FilesEndpoint.DeleteFileAsync(fileId);
Assert.IsTrue(isDeleted);
获取文件信息
返回特定文件的信息。
var api = new OpenAIClient();
var file = await api.FilesEndpoint.GetFileInfoAsync(fileId);
Debug.Log($"{file.Id} -> {file.Object}: {file.FileName} | {file.Size} bytes");
下载文件内容
将文件内容下载到指定目录。
var api = new OpenAIClient();
var downloadedFilePath = await api.FilesEndpoint.DownloadFileAsync(fileId);
Debug.Log(downloadedFilePath);
Assert.IsTrue(File.Exists(downloadedFilePath));
微调
管理微调任务,以根据您的特定训练数据定制模型。
相关指南:微调模型
文件 API 通过 OpenAIClient.FineTuningEndpoint 访问。
创建微调任务
从给定数据集创建一个微调指定模型的任务。
响应包括已加入队列的任务详细信息,包括任务状态以及完成后的微调模型名称。
var api = new OpenAIClient();
var fileId = "file-abc123";
var request = new CreateFineTuneRequest(fileId);
var job = await api.FineTuningEndpoint.CreateJobAsync(Model.GPT3_5_Turbo, request);
Debug.Log($"已启动 {job.Id} | 状态: {job.Status}");
列出微调任务
列出您组织的微调任务。
var api = new OpenAIClient();
var jobList = await api.FineTuningEndpoint.ListJobsAsync();
foreach (var job in jobList.Items.OrderByDescending(job => job.CreatedAt))
{
Debug.Log($"{job.Id} -> {job.CreatedAt} | {job.Status}");
}
获取微调任务信息
获取微调任务的信息。
var api = new OpenAIClient();
var job = await api.FineTuningEndpoint.GetJobInfoAsync(fineTuneJob);
Debug.Log($"{job.Id} -> {job.CreatedAt} | {job.Status}");
取消微调任务
立即取消微调任务。
var api = new OpenAIClient();
var isCancelled = await api.FineTuningEndpoint.CancelFineTuneJobAsync(fineTuneJob);
Assert.IsTrue(isCancelled);
列出微调任务事件
获取微调任务的状态更新。
var api = new OpenAIClient();
var eventList = await api.FineTuningEndpoint.ListJobEventsAsync(fineTuneJob);
Debug.Log(`${fineTuneJob.Id} -> 状态: ${fineTuneJob.Status} | 事件数量: ${eventList.Events.Count}`);
foreach (var @event in eventList.Items.OrderByDescending(@event => @event.CreatedAt))
{
Debug.Log($" {@event.CreatedAt} [{@event.Level}] {@event.Message}");
}
批处理
创建大量异步处理的 API 请求批次。批处理 API 可在 24 小时内返回结果,并享受 50% 的折扣。
批处理 API 通过 OpenAIClient.BatchesEndpoint 访问。
列出批处理
列出您组织的批处理。
var api = new OpenAIClient();
var batches = await api.BatchEndpoint.ListBatchesAsync();
foreach (var batch in listResponse.Items)
{
Debug.Log(batch);
}
创建批处理
从上传的请求文件创建并执行批处理。
var api = new OpenAIClient();
var batchRequest = new CreateBatchRequest("file-id", Endpoint.ChatCompletions);
var batch = await api.BatchEndpoint.CreateBatchAsync(batchRequest);
获取批处理
获取批处理。
var api = new OpenAIClient();
var batch = await api.BatchEndpoint.RetrieveBatchAsync("batch-id");
// 您也可以使用便捷方法!
batch = await batch.UpdateAsync();
batch = await batch.WaitForStatusChangeAsync();
取消批处理
取消正在进行的批处理。批处理将在“取消中”状态持续最多 10 分钟,随后变为“已取消”,此时输出文件中将包含部分结果(如有)。
var api = new OpenAIClient();
var isCancelled = await api.BatchEndpoint.CancelBatchAsync(batch);
Assert.IsTrue(isCancelled);
嵌入
获取给定输入的向量表示,该表示可被机器学习模型和算法轻松使用。
相关指南:嵌入
嵌入 API 通过 OpenAIClient.EmbeddingsEndpoint 访问。
创建嵌入
创建表示输入文本的嵌入向量。
var api = new OpenAIClient();
var response = await api.EmbeddingsEndpoint.CreateEmbeddingAsync("食物非常美味,服务员……", Models.Embedding_Ada_002);
Debug.Log(response);
内容审核
给定一段输入文本,该模型会输出该文本是否违反 OpenAI 的内容政策。
相关指南:内容审核
可以通过 OpenAIClient.ModerationsEndpoint 访问内容审核 API。
创建内容审核
判断文本是否违反 OpenAI 的内容政策。
var api = new OpenAIClient();
var isViolation = await api.ModerationsEndpoint.GetModerationAsync("我想杀了他们。");
Assert.IsTrue(isViolation);
此外,你还可以获取给定输入的各项评分。
var api = new OpenAIClient();
var response = await api.ModerationsEndpoint.CreateModerationAsync(new ModerationsRequest("我爱你"));
Assert.IsNotNull(response);
Debug.Log(response.Results?[0]?.Scores?.ToString());
版本历史
8.8.92026/01/268.8.82025/12/138.8.72025/11/098.8.62025/11/058.8.52025/11/038.8.42025/10/238.8.32025/10/238.8.22025/10/038.8.12025/07/048.8.02025/07/028.7.42025/07/018.7.32025/06/258.7.22025/06/258.7.12025/06/198.7.02025/06/158.6.62025/04/278.6.52025/04/138.6.42025/03/218.6.32025/03/098.6.22025/03/08常见问题
相似工具推荐
stable-diffusion-webui
stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。
everything-claude-code
everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上
ComfyUI
ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。
NextChat
NextChat 是一款轻量且极速的 AI 助手,旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性,以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发,NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。 这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言,它也提供了便捷的自托管方案,支持一键部署到 Vercel 或 Zeabur 等平台。 NextChat 的核心亮点在于其广泛的模型兼容性,原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型,让用户在一个界面即可自由切换不同 AI 能力。此外,它还率先支持 MCP(Model Context Protocol)协议,增强了上下文处理能力。针对企业用户,NextChat 提供专业版解决方案,具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能,满足公司对数据隐私和个性化管理的高标准要求。
ML-For-Beginners
ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程,旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周,包含 26 节精炼课程和 52 道配套测验,内容涵盖从基础概念到实际应用的完整流程,有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。 无论是希望转型的开发者、需要补充算法背景的研究人员,还是对人工智能充满好奇的普通爱好者,都能从中受益。课程不仅提供了清晰的理论讲解,还强调动手实践,让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持,通过自动化机制提供了包括简体中文在内的 50 多种语言版本,极大地降低了全球不同背景用户的学习门槛。此外,项目采用开源协作模式,社区活跃且内容持续更新,确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路,ML-For-Beginners 将是理想的起点。
ragflow
RAGFlow 是一款领先的开源检索增强生成(RAG)引擎,旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体(Agent)能力相结合,不仅支持从各类文档中高效提取知识,还能让模型基于这些知识进行逻辑推理和任务执行。 在大模型应用中,幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构(如表格、图表及混合排版),显著提升了信息检索的准确度,从而有效减少模型“胡编乱造”的现象,确保回答既有据可依又具备时效性。其内置的智能体机制更进一步,使系统不仅能回答问题,还能自主规划步骤解决复杂问题。 这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统,还是致力于探索大模型在垂直领域落地的创新者,都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口,既降低了非算法背景用户的上手门槛,也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目,它正成为连接通用大模型与行业专有知识之间的重要桥梁。