使用 openai-dotnet 在 C# 中发出第一个请求:端点、密钥、回复
从 C# 控制台应用发送你的第一个聊天补全:在官方 OpenAI .NET 库中设置 Endpoint,从环境变量读取密钥,打印回复和结束原因。

要从 C# 向 CheapTokens 发送请求,请保留官方的 OpenAI .NET 库,并将 OpenAIClientOptions. 设置为 https:/。传入完整的模型 id,例如 deepseek-,并从环境变量中读取密钥。ChatClient 和 CompleteChat 调用与 OpenAI 示例中完全一致。
假设你已有一个与 OpenAI 通信的 ASP.NET 服务,想在不改动其余代码的情况下尝试另一个端点和模型。在将其接入之前,先在一个小型控制台应用中检查通常出错的三个方面(密钥、端点、模型 id)。这就是我们在这里构建的内容。以下细节来自该库在 GitHub 上的 README(openai/openai-dotnet,查阅于 2026 年 11 月 5 日)以及 CheapTokens 文档:文档页面 中有相同的基础 URL。
你需要准备什么#
该包在 NuGet 上名为 OpenAI。2026 年 11 月 5 日的最新稳定版本是 2.15.0(其变更日志条目日期为 11 月 4 日)。它面向 .NET 8 和 .NET Standard 2.0,README 称其适用于所有 .NET Standard 2.0 应用程序,因此较旧的项目也没问题。
应用需要三个值:
- 基础 URL:
https:/(兼容 OpenAI Chat Completions);/ api. cheaptokens. dev/ v1 - 模型 id:
deepseek-。请使用完整 id,价格表中的短名称不被接受。DeepSeek-V4-Flash 具有 380K 上下文窗口,每次回答最多 32,768 个输出 token,全天统一价格;ai/ DeepSeek- V4- Flash- 0731 - 来自你的 CheapTokens 账户的 API 密钥,保存在环境变量中。如果不确定如何存储,请阅读如何安全存储 API 密钥。
构建控制台应用#
分步操作
创建项目并运行
创建控制台项目
dotnet new console -o FirstRequest
cd FirstRequest添加包
dotnet add package OpenAI将密钥放入环境变量
在 bash 或 zsh 中:
export CHEAPTOKENS_API_KEY=your-key在 Windows PowerShell 中:
$env:CHEAPTOKENS_API_KEY = "your-key"粘贴代码并运行
将 Program.cs 的内容替换为下一节的代码,然后运行 dotnet run。

逐行解读代码#
using System.ClientModel;
using OpenAI;
using OpenAI.Chat;
string? apiKey = Environment.GetEnvironmentVariable("CHEAPTOKENS_API_KEY");
if (string.IsNullOrEmpty(apiKey))
{
Console.WriteLine("Set CHEAPTOKENS_API_KEY first.");
return;
}
ChatClient client = new(
model: "deepseek-ai/DeepSeek-V4-Flash-0731",
credential: new ApiKeyCredential(apiKey),
options: new OpenAIClientOptions
{
Endpoint = new Uri("https://api.cheaptokens.dev/v1")
});
ChatCompletion completion = client.CompleteChat("Explain in two sentences what a token is.");
Console.WriteLine(completion.Content[0].Text);
Console.WriteLine($"finish_reason: {completion.FinishReason}");README 针对“代理或自托管的 OpenAI 兼容 LLM”展示了此模式:端点放入 OpenAIClientOptions,密钥放入 ApiKeyCredential(它存在于 System. 中,因此第一个 using)。顶部的检查是我们添加的:如果变量未设置,它会给出清晰的提示。
CompleteChat 使用普通字符串发送一条用户消息并等待完整回答。回复文本在 completion. 中。结束原因在 completion. 中。

你应该看到什么#
你应该会得到一段关于 token 的简短解释,以及一行包含结束原因的内容;正常结束后为 Stop(README 将 FinishReason 与 ChatFinishReason. 进行比较)。回复的措辞每次运行都会变化。
第二行值得一读。README 将 FinishReason 与 ChatFinishReason.(模型自行结束)和 ChatFinishReason.(模型想要调用工具)进行比较。在普通聊天中,任何不是 Stop 的值都意味着回答因其他原因结束,最常见的嫌疑是长度限制。如果你看到回复在句子中间停止,这篇文章解释了 finish_reason 和 max_tokens。
切换现有服务#
如果你的服务已经为 OpenAI 创建了 ChatClient,你需要更改两处:模型字符串和选项。其余调用继续正常工作。
比较
同一个客户端,两行改动
之前
ChatClient client = new(
model: "your-current-model",
credential: new ApiKeyCredential(apiKey));之后
ChatClient client = new(
model: "deepseek-ai/DeepSeek-V4-Flash-0731",
credential: new ApiKeyCredential(apiKey),
options: new OpenAIClientOptions
{
Endpoint = new Uri("https://api.cheaptokens.dev/v1")
});对于短请求还有第二个选项:zai-(390K 上下文,最多 8,192 个输出 token)。你只需更改 model 字符串。你的密钥可用的 id 列表只需一个请求即可获取,参见使用 GET /v1/models 列出模型。
一次请求的成本#
假设一个服务每天处理 1,000 个请求,每个请求约 300 个输入 token 和 400 个输出 token。在 DeepSeek-V4-Flash 上,这样一个请求的成本为 $0.000045。下表展示了全部三个模型上同样的 1,000 个请求与 OpenRouter 的对比。总计(输入和输出合计),DeepSeek-V4-Flash 比 OpenRouter 更便宜。当前价格见定价页面,DeepSeek 页面列出了该模型提供的内容。
| 模型 | 输入 $/1M | 输出 $/1M | 每次请求 | 1,000 次请求 | OpenRouter,1,000 次请求 |
|---|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.000022 | $0.022 | $0.0433 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.000045 | $0.0445 | $0.077 |
| MiniMax-M2.7 | $0.05 | $0.15 | $0.000075 | $0.075 | $0.90 |
每次请求 300 个输入 token 和 400 个输出 token。每 100 万 token 的价格为当前价格,会随我们的资费一同变动;OpenRouter 列显示相同工作负载的参考价格。
如果不起作用#
- 401。 密钥缺失或错误。打印变量是否已设置(代码中的检查会执行此操作),并确保
dotnet run与运行export(或$env:)的终端相同:变量仅存在于该会话中。 - 404。 最常见的是模型 id:使用了短名称而非完整的
deepseek-,或者端点缺少ai/ DeepSeek- V4- Flash- 0731 /v1(还要检查OpenAIClientOptions是否确实传给了ChatClient)。详情见 API 401 或 404:密钥、基础 URL 或模型 id 错误。 - error CS0246: 找不到类型或命名空间名 'ApiKeyCredential'。
Program.cs顶部缺少using System.行。ClientModel;
另一种语言的相同思路:使用 openai-go 的 Go 版本。



