SDKガイド
C# / .NET
公式 OpenAI .NET ライブラリで api14 を使う手順です。OpenAIClientOptions.Endpoint の設定から、チャット、ストリーミング、ツール呼び出し、構造化出力、画像入力、埋め込み、再試行までを C# で示します。
公式の OpenAI .NET ライブラリを api14 で使います。OpenAIClientOptions.Endpoint を api14 に設定し、クライアントの作成時に openai/gpt-5-mini などのモデル ID を渡します。
インストール
dotnet add package OpenAI
export API14_API_KEY="sk-api14-..."
設定
using System.ClientModel;
using OpenAI;
using OpenAI.Chat;
var credential = new ApiKeyCredential(Environment.GetEnvironmentVariable("API14_API_KEY")!);
var options = new OpenAIClientOptions { Endpoint = new Uri("https://api14.com/api/v1") };
var client = new ChatClient(model: "openai/gpt-5-mini", credential: credential, options: options);
各 ChatClient は 1 つのモデルに紐付けられます。使用するモデル ID ごとに 1 つ作成してください。
キーは、環境、ユーザーシークレット、またはシークレットストアから読み取り、ソース管理にコミットされる appsettings.json からは読み取らないでください。ASP.NET Core では、クライアントを 1 つシングルトンとして登録します。スレッドセーフです。
チャット
ChatCompletion completion = await client.CompleteChatAsync("Explain vector databases in two sentences.");
Console.WriteLine(completion.Content[0].Text);
システムプロンプトを使う場合は次のとおりです。
ChatCompletion completion = await client.CompleteChatAsync(
[
new SystemChatMessage("You are terse."),
new UserChatMessage("What is RAG?"),
]);
ストリーミング
var claude = new ChatClient("anthropic/claude-sonnet-4.5", credential, options);
await foreach (StreamingChatCompletionUpdate update in claude.CompleteChatStreamingAsync("Write a haiku about APIs."))
{
foreach (ChatMessageContentPart part in update.ContentUpdate)
Console.Write(part.Text);
}
ストリーミングを参照してください。
ツール呼び出し
using System.Text.Json;
ChatTool getWeather = ChatTool.CreateFunctionTool(
functionName: "get_weather",
functionDescription: "Current weather for a city",
functionParameters: BinaryData.FromString("""
{ "type": "object", "properties": { "city": { "type": "string" } }, "required": ["city"] }
"""));
var toolOptions = new ChatCompletionOptions { Tools = { getWeather } };
List<ChatMessage> messages = [new UserChatMessage("What's the weather in Istanbul?")];
ChatCompletion completion = await client.CompleteChatAsync(messages, toolOptions);
while (completion.FinishReason == ChatFinishReason.ToolCalls)
{
messages.Add(new AssistantChatMessage(completion));
foreach (ChatToolCall call in completion.ToolCalls)
{
using JsonDocument args = JsonDocument.Parse(call.FunctionArguments);
string city = args.RootElement.GetProperty("city").GetString()!;
messages.Add(new ToolChatMessage(call.Id, GetWeather(city))); // 自分の関数
}
completion = await client.CompleteChatAsync(messages, toolOptions);
}
Console.WriteLine(completion.Content[0].Text);
ツール呼び出しを参照してください。
構造化出力
var jsonOptions = new ChatCompletionOptions
{
ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
jsonSchemaFormatName: "person",
jsonSchema: BinaryData.FromString("""
{
"type": "object",
"properties": { "name": { "type": "string" }, "born": { "type": "integer" } },
"required": ["name", "born"],
"additionalProperties": false
}
"""),
jsonSchemaIsStrict: true),
};
ChatCompletion result = await client.CompleteChatAsync(
[new UserChatMessage("Extract: Ada Lovelace, born 1815.")], jsonOptions);
using JsonDocument person = JsonDocument.Parse(result.Content[0].Text);
Console.WriteLine(person.RootElement.GetProperty("born").GetInt32());
構造化出力を参照してください。
画像入力
var vision = new ChatClient("google/gemini-2.5-flash", credential, options);
ChatCompletion described = await vision.CompleteChatAsync(
[
new UserChatMessage(
ChatMessageContentPart.CreateTextPart("What is in this picture?"),
ChatMessageContentPart.CreateImagePart(new Uri("https://example.com/photo.jpg"))),
]);
ローカルファイルの場合は、ChatMessageContentPart.CreateImagePart(BinaryData.FromBytes(File.ReadAllBytes("photo.png")), "image/png") を使います。画像とファイル入力を参照してください。
埋め込み
using OpenAI.Embeddings;
var embeddings = new EmbeddingClient("openai/text-embedding-3-small", credential, options);
OpenAIEmbedding embedding = await embeddings.GenerateEmbeddingAsync("The quick brown fox");
Console.WriteLine(embedding.ToFloats().Length);
エラー
失敗した呼び出しは ClientResultException をスローします。生のレスポンスにステータスとヘッダーが含まれます。
try
{
await client.CompleteChatAsync("Hi");
}
catch (ClientResultException ex) when (ex.Status == 402)
{
Console.Error.WriteLine("Balance too low, add funds (insufficient_balance).");
}
catch (ClientResultException ex) when (ex.Status == 429)
{
string? retryAfter = null;
ex.GetRawResponse()?.Headers.TryGetValue("Retry-After", out retryAfter);
Console.Error.WriteLine($"Rate limited, retry after {retryAfter ?? "60"}s.");
}
エラーを参照してください。
タイムアウトと再試行
ライブラリは、429 と 5xx を指数バックオフで自動的に再試行します。すべてのクライアントに渡すオプションで、再試行回数とネットワークのタイムアウトを調整できます。
using System.ClientModel.Primitives;
var options = new OpenAIClientOptions
{
Endpoint = new Uri("https://api14.com/api/v1"),
NetworkTimeout = TimeSpan.FromMinutes(2),
RetryPolicy = new ClientRetryPolicy(maxRetries: 4),
};
...Async の呼び出しに CancellationToken を渡すと、再試行を含む合計時間を制限できます。daily_limit_reached や insufficient_balance は、再試行しても解決しません。レート制限を参照してください。
すべての機能
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api14.com/api/v1",
apiKey: process.env.API14_API_KEY,
});
const result = await client.chat.completions.create({
"model": "openai/gpt-5-mini",
"messages": [
{
"role": "user",
"content": "Explain vector databases in two sentences."
}
]
});
console.log(result.choices[0].message.content);