チャット完了モデルを操作する

この記事では、チャット完了要求を送信し、複数ターンの会話を作成し、会話のトークン予算を管理します。

チャット モデルは、会話インターフェイス用に最適化された言語モデルです。 以前のテキスト入力およびテキストアウト完了モデルとは異なり、チャット モデルはメッセージのトランスクリプトを受け入れ、モデルによって生成されたメッセージを返します。 この形式では、複数ターンの会話と非チャットのシナリオがサポートされます。

古い補完モデルのようにチャットモデルにプロンプトを与えるのではなく、この記事で説明されているメッセージ形式を使用してください。 そうしないと、モデルが冗長な、またはあまり役に立たない応答を生成する可能性があります。

Tip

新しいアプリでは、Chat Completions ではなく Responses API を基盤に構築することを検討してください。 既存のアプリをアップグレードするには、「OpenAI to Responses Azure」を参照し、Azure OpenAI アプリをチャット入力候補から応答 API にアップグレードします

メモ

GPT-5 シリーズなどの推論モデルは、この API で動作が異なります。 max_completion_tokensではなくmax_tokensを使用し、temperaturetop_p、ペナルティ パラメーターはサポートしていません。 gpt-5.6 以降のモデルでは、reasoning_effortnone に設定しない限り、関数ツールを含むチャット完了要求は失敗します。 推論モデルを使用したツール呼び出しには Responses API を使用します。 詳細については、OpenAI 推論モデルAzureを参照してください。

前提 条件

  • OpenAI Python ライブラリ (pip install openai) をインストールします。
  • Microsoft Entra ID認証の場合は、Azure ID (pip install azure-identity) とAzure CLIをインストールします。 Cognitive Services User ロールをユーザー アカウントに割り当ててから、az login実行します。
  • トークンカウントの例では、tiktoken: pip install tiktokenをインストールします。
  • API キーを使用する場合は、 AZURE_OPENAI_API_KEY 環境変数を設定します。
  • .NET 8.0 SDK 以降。
  • Microsoft Entra ID認証の場合は、Azure CLIをインストールし、Cognitive Services User ロールをユーザー アカウントに割り当てます。
  • API キーを使用する場合は、 AZURE_OPENAI_API_KEY 環境変数を設定します。
  • Node.js 22 以降。
  • Microsoft Entra ID認証の場合は、Azure CLIをインストールし、Cognitive Services User ロールをユーザー アカウントに割り当ててから、az loginを実行します。
  • API キーを使用する場合は、 AZURE_OPENAI_API_KEY 環境変数を設定します。

コード サンプルでは、YOUR-RESOURCE-NAMEを Azure OpenAI リソース名に置き換え、YOUR-DEPLOYMENT-NAMEをモデル デプロイ名に置き換えます。

セットアップ

各完全な例を chat.pyとして保存し、 python chat.pyで実行します。

チャット完了モデルを操作する

次のコード スニペットは、Chat Completions API を使用するモデルを操作する最も基本的な方法を示しています。

メモ

Responses API は同じチャット スタイルの対話を使用しますが、以前のチャット入力候補 API では使用できない最新の機能をサポートしています。

from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://ai.azure.com/.default"
)

client = OpenAI(
    base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
    api_key=token_provider,
)

response = client.chat.completions.create(
    model="YOUR-DEPLOYMENT-NAME",  # Replace with your model deployment name.
    messages=[
        {"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
        {"role": "user", "content": "Who were the founders of Microsoft?"}
    ]
)

#print(response)
print(response.model_dump_json(indent=2))
print(response.choices[0].message.content)
{
    "id": "chatcmpl-8GHoQAJ3zN2DJYqOFiVysrMQJfe1P",
    "choices": [
        {
            "finish_reason": "stop",
            "index": 0,
            "message": {
                "content": "Microsoft was founded by Bill Gates and Paul Allen. They established the company on April 4, 1975. Bill Gates served as the CEO of Microsoft until 2000 and later as Chairman and Chief Software Architect until his retirement in 2008, while Paul Allen left the company in 1983 but remained on the board of directors until 2000.",
                "role": "assistant"
            },
            "content_filter_results": {
                "hate": {
                    "filtered": false,
                    "severity": "safe"
                },
                "self_harm": {
                    "filtered": false,
                    "severity": "safe"
                },
                "sexual": {
                    "filtered": false,
                    "severity": "safe"
                },
                "violence": {
                    "filtered": false,
                    "severity": "safe"
                }
            }
        }
    ],
    "created": 1698892410,
    "model": "gpt-4o",
    "object": "chat.completion",
    "usage": {
        "completion_tokens": 73,
        "prompt_tokens": 29,
        "total_tokens": 102
    },
    "prompt_filter_results": [
        {
            "prompt_index": 0,
            "content_filter_results": {
                "hate": {
                    "filtered": false,
                    "severity": "safe"
                },
                "self_harm": {
                    "filtered": false,
                    "severity": "safe"
                },
                "sexual": {
                    "filtered": false,
                    "severity": "safe"
                },
                "violence": {
                    "filtered": false,
                    "severity": "safe"
                }
            }
        }
    ]
}
Microsoft was founded by Bill Gates and Paul Allen. They established the company on April 4, 1975. Bill Gates served as the CEO of Microsoft until 2000 and later as Chairman and Chief Software Architect until his retirement in 2008, while Paul Allen left the company in 1983 but remained on the board of directors until 2000.

すべての応答には finish_reasonが含まれます。 finish_reasonに使用できる値は次のとおりです。

  • stop: API は完全なモデル出力を返しました。
  • length: max_completion_tokens パラメーターまたはトークンの制限により、不完全なモデル出力。
  • content_filter: コンテンツ フィルター フラグのためにコンテンツを省略しました。
  • tool_calls: ツールと呼ばれるモデル。
  • function_call: 関数と呼ばれるモデル。 この値は非推奨です。

ストリーミング応答では、最後のチャンクで応答が完了するまで、finish_reasonnull です。

想定される応答に対して十分高くなるように、max_completion_tokens を設定します。 値を大きくすると、モデルがメッセージの末尾に到達する前に停止するのを防ぐことができます。

Chat Completions API を使う

会話として書式設定された入力を受け入れるための OpenAI トレーニング済みチャット完了モデル。 messages パラメーターは、ロール別に編成された会話を持つメッセージ オブジェクトの配列を受け取ります。 Python API を使用すると、ディクショナリの一覧が使用されます。

基本的なチャット完了の形式は次のとおりです。

messages = [
    {"role": "system", "content": "Provide context or instructions to the model."},
    {"role": "user", "content": "The user's message goes here."},
]

1 つの例の回答とその後に質問が続く会話は、次のようになります。

messages = [
    {"role": "system", "content": "Provide context or instructions to the model."},
    {"role": "user", "content": "Example question goes here."},
    {"role": "assistant", "content": "Example answer goes here."},
    {"role": "user", "content": "First question for the model to answer."},
]

システム ロール

システム の役割 (システム メッセージとも呼ばれます) は、配列の先頭に含まれます。 このメッセージは、モデルに最初の指示を提供します。 システム ロールには、次のようなさまざまな情報を指定できます。

  • アシスタントの簡単な説明。
  • アシスタントの性格特性。
  • アシスタントが従う手順またはルール。
  • FAQ からの関連する質問など、モデルに必要なデータまたは情報。

ユース ケースのシステム ロールをカスタマイズするか、基本的な手順を含めます。 システム メッセージは省略可能ですが、最適な結果を得るための基本的なメッセージを少なくとも含めます。

メッセージ

システム ロールの後に、 userassistantの間に一連のメッセージを含めることができます。

message = {"role": "user", "content": "What is thermodynamics?"}

モデルからの応答をトリガーするには、応答するアシスタントの番であることを示すユーザー メッセージで終了します。 また、少数ショット学習を行う方法として、ユーザーとアシスタントの間の一連のサンプル メッセージを含めることもできます。

メッセージ プロンプトの例

次のセクションでは、チャット入力候補モデルで使用できるさまざまなスタイルのプロンプトの例を示します。 これらの例は開始点にすぎません。 さまざまなプロンプトを試して、独自のユース ケースの動作をカスタマイズできます。

基本的な例

チャット入力候補モデルを chatgpt.com と同様に動作させる場合は、次のような基本的なシステム メッセージを使用できます。 Assistant is a large language model trained by OpenAI.

messages = [
    {"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
    {"role": "user", "content": "Who were the founders of Microsoft?"},
]

手順を含む例

一部のシナリオでは、モデルに対して実行できる操作のガードレールを定義するための指示をモデルに追加することが必要になる場合があります。

messages = [
    {"role": "system", "content": """Assistant is an intelligent chatbot designed to help users answer tax-related questions.
Instructions: 
- Only answer questions related to taxes. 
- If you're unsure of an answer, say "I don't know" or "I'm not sure" and recommend the IRS website."""},
    {"role": "user", "content": "When are my taxes due?"},
]

データを基礎として使用する

また、関連するデータや情報をシステム メッセージに含めて、モデルに会話のコンテキストを追加することもできます。 少量の情報のみを含める必要がある場合は、システム メッセージにハード コーディングできます。 モデルが認識する必要がある大量のデータがある場合は、embeddings または Azure AI 検索クエリ時に最も関連性の高い情報を取得できます。

messages = [
    {"role": "system", "content": """Assistant helps users answer technical questions about Azure OpenAI in Microsoft Foundry Models. Only answer questions using the following context. If the context doesn't contain the answer, say 'I don't know.'

Context:
- Azure OpenAI provides REST API access to OpenAI models, including GPT-5, GPT-4.1, and Embeddings model series.
- Azure OpenAI gives customers advanced language AI with GPT-5, GPT-image, and Embeddings models with the security and enterprise capabilities of Azure. Azure OpenAI co-develops the APIs with OpenAI, ensuring compatibility and a smooth transition between the services.
- At Microsoft, we're committed to advancing AI according to principles that put people first."""},
    {"role": "user", "content": "What is Azure OpenAI?"},
]

チャット完了機能を用いた少数ショット学習

また、モデルに少数の例を提供することもできます。 新しいプロンプト形式により、少数のショット学習のアプローチが若干変更されました。 少数の例として、ユーザーとアシスタントの間の一連のメッセージをプロンプトに含めることができるようになりました。 これらの例を使用すると、一般的な質問に対する回答をシード処理して、モデルを準備したり、特定の動作をモデルに教えたりすることができます。

この例では、 gpt-5-minigpt-5などの現在のチャット完了モデルで少数のショット学習を使用する方法を示します。 さまざまな方法を試して、ユース ケースに最適なものを見つけてください。

messages = [
    {"role": "system", "content": "Assistant helps users answer tax-related questions."},
    {"role": "user", "content": "When do I need to file my taxes by?"},
    {"role": "assistant", "content": "Check the current individual filing deadline at https://www.irs.gov/filing/individuals/when-to-file."},
    {"role": "user", "content": "How can I check the status of my tax refund?"},
    {"role": "assistant", "content": "Check your refund status at https://www.irs.gov/refunds."},
]

チャットの完了を非チャット シナリオに使用する

Chat Completions API は、複数ターンの会話を操作するように設計されていますが、非チャット シナリオにも適しています。

たとえば、エンティティ抽出シナリオでは、次のプロンプトを使用できます。

messages = [
    {"role": "system", "content": """You extract entities from text and return them as a JSON object with this format:
{
   "name": "",
   "company": "",
   "phone_number": ""
}"""},
    {"role": "user", "content": "Hello. My name is Robert Smith. I'm calling from Contoso Insurance, Delaware. My colleague mentioned that you are interested in learning about our comprehensive benefits policy. Could you give me a call back at (555) 346-9322 when you get a chance so we can go over the benefits?"},
]

基本的な会話ループを作成する

前の例は、チャット補完 API との対話の基本的な仕組みを示しています。 この例では、次のアクションを実行する会話ループを作成する方法を示します。

  • コンソール入力を継続的に受け取り、メッセージ リストの一部としてユーザー ロールコンテンツとして適切に書式設定します。
  • コンソールに出力され、書式設定され、アシスタントロールコンテンツとしてメッセージリストに追加された応答を出力します。

新しい質問をするたびに、実行中の会話トランスクリプトが最新の質問と共に送信されます。 モデルにはメモリがないため、各質問で更新されたトランスクリプトを送信するか、モデルは以前の質問と回答のコンテキストを失います。

from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://ai.azure.com/.default"
)

client = OpenAI(
    base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
    api_key=token_provider,
)

conversation = [{"role": "system", "content": "You are a helpful assistant."}]

while True:
    user_input = input("Q:")
    conversation.append({"role": "user", "content": user_input})

    response = client.chat.completions.create(
        model="YOUR-DEPLOYMENT-NAME",  # Replace with your model deployment name.
        messages=conversation
    )

    conversation.append({"role": "assistant", "content": response.choices[0].message.content})
    print("\n" + response.choices[0].message.content + "\n")

上記のコードを実行すると、空白のコンソール ウィンドウが表示されます。 ウィンドウに最初の質問を入力し、 Enter キーを選択します。 応答が返されたら、プロセスを繰り返し、質問を続けることができます。

会話を管理する

前の例は、モデルのトークン制限 (コンテキスト ウィンドウ) に達するまで実行されます。 質問と回答を受け取るごとに、 messages リストのサイズが大きくなります。 messagesの結合されたトークン数と要求された出力トークンは、モデルの制限内に留まる必要があります。または、要求が失敗します。 現在のトークン制限については、 モデル ページ を参照してください。

プロンプトと完了がトークンの制限内に収まるようにするのは、ユーザーの責任です。 長い会話の場合は、トークン数を追跡し、制限内のプロンプトのみをモデルに送信する必要があります。 または、応答 APIを使用して、APIが会話履歴を切り捨てまたは管理するように処理を行うことができます。

次のコード サンプルでは、OpenAI の tiktoken ライブラリを使用して、4,096 トークンのデモンストレーションしきい値で会話をトリミングします。 token_limitを、運用環境で使用するためにデプロイされたモデルのコンテキスト ウィンドウに設定します。

pip install --upgrade tiktokenを実行して tiktoken をアップグレードする必要がある場合があります。

import tiktoken
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://ai.azure.com/.default"
)

client = OpenAI(
    base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
    api_key=token_provider,
)

system_message = {"role": "system", "content": "You are a helpful assistant."}
max_response_tokens = 250
token_limit = 4096
conversation = []
conversation.append(system_message)

def num_tokens_from_messages(messages, model="gpt-4o"):
    """Return the number of tokens used by a list of messages."""
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        print("Warning: model not found. Using o200k_base encoding.")
        encoding = tiktoken.get_encoding("o200k_base")

    if model in {
        "gpt-4o",
        "gpt-4o-mini",
        "gpt-5",
        "gpt-4.1",
        "o1",
        "o1-mini",
        "o3",
        "o3-mini",
        "o4-mini",
    }:
        tokens_per_message = 3
        tokens_per_name = 1

    elif any(model.startswith(prefix) for prefix in [
        "gpt-4o-",
        "gpt-5-",
        "gpt-4.1-",
        "o1-",
        "o3-",
        "o4-mini-",
    ]):
        tokens_per_message = 3
        tokens_per_name = 1
    else:
        raise NotImplementedError(
            f"""num_tokens_from_messages() is not implemented for model {model}. """
        )

    num_tokens = 0
    for message in messages:
        num_tokens += tokens_per_message
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))
            if key == "name":
                num_tokens += tokens_per_name
    num_tokens += 3
    return num_tokens

while True:
    user_input = input("Q:")
    conversation.append({"role": "user", "content": user_input})
    conv_history_tokens = num_tokens_from_messages(conversation, model="gpt-4o")

    while conv_history_tokens + max_response_tokens >= token_limit:
        del conversation[1]
        conv_history_tokens = num_tokens_from_messages(conversation, model="gpt-4o")

    response = client.chat.completions.create(
        model="YOUR-DEPLOYMENT-NAME",
        messages=conversation,
        temperature=0.7,
        max_completion_tokens=max_response_tokens
    )

    conversation.append({"role": "assistant", "content": response.choices[0].message.content})
    print("\n" + response.choices[0].message.content + "\n")

この例では、トークン数に達すると、会話トランスクリプト内の最も古いメッセージが削除されます。 効率のために、delの代わりにpop()が使用されます。 インデックス 1 から始めて、常にシステム メッセージを保持し、ユーザーまたはアシスタント メッセージのみを削除します。 時間が経つにつれて、この方法で会話を管理すると、モデルが会話の以前の部分のコンテキストを徐々に失うため、会話の品質が低下する可能性があります。

別の方法として、会話の期間を最大トークン長または特定のターン数に制限します。 トークンの上限に達すると、会話の続行を許可すると、モデルはコンテキストを失います。 新しい会話を開始し、メッセージの一覧をクリアして、使用可能な完全なトークン制限を使用して新しい会話を開始するようにユーザーに求めることができます。

前に示したコードのトークンカウント部分は、 OpenAI のクックブックの例の 1 つの簡略化されたバージョンです。

トラブルシューティング

モデルで無効な Unicode 出力が生成されたので、完了を作成できませんでした

  • エラー コード: 500
  • エラーメッセージ:500 - InternalServerError: Error code: 500 - {"error": {"message": "Failed to create completion as the model generated invalid Unicode output"}}
  • 回避 策: プロンプトの温度を 1 未満に減らし、再試行ロジックでクライアントを使用します。 要求の再試行は、多くの場合成功します。

一般的なエラー

  • 401/403 (認証): API キーを確認するか、Azure OpenAI リソースにMicrosoft Entra IDアクセス権があることを確認します。
  • 400/404 (デプロイが見つかりません):modelがデプロイ名と一致することを確認します。
  • 無効な URL: base_url/openai/v1/で終わることを確認します。

セットアップ

  1. 新しい.NETコンソール アプリケーションを作成します。

    dotnet new console -n chat-completions
    cd chat-completions
    
  2. 必要な NuGet パッケージをインストールします。

    dotnet add package OpenAI
    dotnet add package Azure.Identity
    

    OpenAI パッケージは安定しています。 Microsoft Entra IDの例では、試験段階のカスタム認証コンストラクターを使用し、OPENAI001警告を抑制します。

  3. Microsoft Entra IDによるキーレス認証の場合は、Azureにサインインします。

    az login
    

チャット完了モデルを操作する

次のコード スニペットは、Chat Completions API を使用するモデルを操作する最も基本的な方法を示しています。

メモ

応答 API は同じチャット スタイルの対話を使用しますが、以前のチャット入力候補 API ではサポートされていない最新の機能をサポートします。

using Azure.Identity;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel.Primitives;

#pragma warning disable OPENAI001

BearerTokenPolicy tokenPolicy = new(
    new DefaultAzureCredential(),
    "https://ai.azure.com/.default");

ChatClient client = new(
    model: "YOUR-DEPLOYMENT-NAME",
    authenticationPolicy: tokenPolicy,
    options: new OpenAIClientOptions()
    {
        Endpoint = new Uri("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/")
    }
);

ChatCompletion completion = await client.CompleteChatAsync(
[
    new SystemChatMessage("Assistant is a large language model trained by OpenAI."),
    new UserChatMessage("Who were the founders of Microsoft?"),
]);

Console.WriteLine(completion.Content[0].Text);
Microsoft was founded by Bill Gates and Paul Allen. They established the company on April 4, 1975. Bill Gates served as the CEO of Microsoft until 2000 and later as Chairman and Chief Software Architect until his retirement in 2008, while Paul Allen left the company in 1983 but remained on the board of directors until 2000.

すべての応答に FinishReasonが含まれます。 FinishReasonに使用できる値は次のとおりです。

  • 停止: API から完全なモデル出力が返されました。
  • 長さ: MaxOutputTokenCount パラメーターまたはトークンの制限により、モデルの出力が不完全です。
  • ContentFilter: コンテンツ フィルター フラグのためにコンテンツを省略しました。
  • ToolCalls: ツールと呼ばれるモデル。
  • FunctionCall: 関数と呼ばれるモデル。 この値は非推奨です。

想定される応答に対して十分高くなるように、MaxOutputTokenCount を設定します。 値を大きくすると、モデルがメッセージの末尾に到達する前に停止するのを防ぐことができます。

Chat Completions API を使う

会話として書式設定された入力を受け入れるための OpenAI トレーニング済みチャット完了モデル。 messages パラメーターは、ロール別に編成された会話を持つメッセージ オブジェクトの配列を受け取ります。 .NET SDK を使用する場合は、各ロールに厳密に型指定されたメッセージ クラスを使用します。

基本的なチャット完了の形式は次のとおりです。

new SystemChatMessage("Provide some context and/or instructions to the model"),
new UserChatMessage("The user's message goes here")

1 つの例の回答とその後に質問が続く会話は、次のようになります。

new SystemChatMessage("Provide some context and/or instructions to the model."),
new UserChatMessage("Example question goes here."),
new AssistantChatMessage("Example answer goes here."),
new UserChatMessage("First question/message for the model to actually respond to.")

システム ロール

システム の役割 (システム メッセージとも呼ばれます) は、配列の先頭に含まれます。 このメッセージは、モデルに最初の指示を提供します。 システム ロールには、次のようなさまざまな情報を指定できます。

  • アシスタントの簡単な説明。
  • アシスタントの性格特性。
  • アシスタントが従う手順またはルール。
  • FAQ からの関連する質問など、モデルに必要なデータまたは情報。

ユース ケースのシステム ロールをカスタマイズするか、基本的な手順を含めます。 システム メッセージは省略可能ですが、最適な結果を得るための基本的なメッセージを少なくとも含めます。

メッセージ

システム ロールの後に、 userassistantの間に一連のメッセージを含めることができます。

new UserChatMessage("What is thermodynamics?")

モデルからの応答をトリガーするには、応答するアシスタントの番であることを示すユーザー メッセージで終了します。 また、少数ショット学習を行う方法として、ユーザーとアシスタントの間の一連のサンプル メッセージを含めることもできます。

メッセージ プロンプトの例

次のセクションでは、チャット入力候補モデルで使用できるさまざまなスタイルのプロンプトの例を示します。 これらの例は開始点にすぎません。 さまざまなプロンプトを試して、独自のユース ケースの動作をカスタマイズできます。

基本的な例

チャット入力候補モデルを chatgpt.com と同様に動作させる場合は、次のような基本的なシステム メッセージを使用できます。 Assistant is a large language model trained by OpenAI.

new SystemChatMessage("Assistant is a large language model trained by OpenAI."),
new UserChatMessage("Who were the founders of Microsoft?")

手順を含む例

一部のシナリオでは、モデルに対して実行できる操作のガードレールを定義するための指示をモデルに追加することが必要になる場合があります。

new SystemChatMessage(@"Assistant is an intelligent chatbot designed to help users answer their tax related questions.
Instructions:
- Only answer questions related to taxes.
- If you're unsure of an answer, you can say ""I don't know"" or ""I'm not sure"" and recommend users go to the IRS website for more information."),
new UserChatMessage("When are my taxes due?")

データを基礎として使用する

また、関連するデータや情報をシステム メッセージに含めて、モデルに会話のコンテキストを追加することもできます。 少量の情報のみを含める必要がある場合は、システム メッセージにハード コーディングできます。 モデルが認識する必要がある大量のデータがある場合は、embeddings または Azure AI 検索クエリ時に最も関連性の高い情報を取得できます。

new SystemChatMessage(@"Assistant is an intelligent chatbot designed to help users answer technical questions about Azure OpenAI in Microsoft Foundry Models. Only answer questions using the context below and if you're not sure of an answer, you can say 'I don't know'.

Context:
- Azure OpenAI provides REST API access to OpenAI models, including GPT-5, GPT-4.1, and Embeddings model series.
- Azure OpenAI gives customers advanced language AI with GPT-5, GPT-image, and Embeddings models with the security and enterprise capabilities of Azure. Azure OpenAI co-develops the APIs with OpenAI, ensuring compatibility and a smooth transition between the services.
- At Microsoft, we're committed to the advancement of AI driven by principles that put people first. Microsoft has made significant investments to help guard against abuse and unintended harm, which includes requiring applicants to show well-defined use cases, incorporating Microsoft's principles for responsible AI use."),
new UserChatMessage("What is Azure OpenAI?")

チャット完了機能を用いた少数ショット学習

また、モデルに少数の例を提供することもできます。 少数の例として、ユーザーとアシスタントの間の一連のメッセージをプロンプトに含めることができます。 これらの例を使用すると、一般的な質問に対する回答をシード処理して、モデルを準備したり、特定の動作をモデルに教えたりすることができます。

この例では、 gpt-5-minigpt-5などの現在のチャット完了モデルを使用します。

new SystemChatMessage("Assistant is an intelligent chatbot designed to help users answer their tax related questions."),
new UserChatMessage("When do I need to file my taxes by?"),
new AssistantChatMessage("Check the current individual filing deadline at https://www.irs.gov/filing/individuals/when-to-file."),
new UserChatMessage("How can I check the status of my tax refund?"),
new AssistantChatMessage("Check your refund status at https://www.irs.gov/refunds.")

チャットの完了を非チャット シナリオに使用する

Chat Completions API は、複数ターンの会話を操作するように設計されていますが、非チャット シナリオにも適しています。

たとえば、エンティティ抽出シナリオでは、次のプロンプトを使用できます。

new SystemChatMessage(@"You are an assistant designed to extract entities from text. Users will paste in a string of text and you will respond with entities you've extracted from the text as a JSON object. Here's an example of your output format:
{
   ""name"": """",
   ""company"": """",
   ""phone_number"": """"
}"),
new UserChatMessage("Hello. My name is Robert Smith. I'm calling from Contoso Insurance, Delaware. My colleague mentioned that you are interested in learning about our comprehensive benefits policy. Could you give me a call back at (555) 346-9322 when you get a chance so we can go over the benefits?")

基本的な会話ループを作成する

前の例は、チャット補完 API との対話の基本的な仕組みを示しています。 この例では、次のアクションを実行する会話ループを作成する方法を示します。

  • コンソール入力を継続的に受け取り、メッセージ リストの一部としてユーザー ロールコンテンツとして適切に書式設定します。
  • コンソールに出力され、書式設定され、アシスタントロールコンテンツとしてメッセージリストに追加された応答を出力します。

新しい質問をするたびに、実行中の会話トランスクリプトが最新の質問と共に送信されます。 モデルにはメモリがないため、各質問で更新されたトランスクリプトを送信するか、モデルは以前の質問と回答のコンテキストを失います。

using Azure.Identity;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel.Primitives;

#pragma warning disable OPENAI001

BearerTokenPolicy tokenPolicy = new(
    new DefaultAzureCredential(),
    "https://ai.azure.com/.default");

ChatClient client = new(
    model: "YOUR-DEPLOYMENT-NAME",
    authenticationPolicy: tokenPolicy,
    options: new OpenAIClientOptions()
    {
        Endpoint = new Uri("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/")
    }
);

List<ChatMessage> conversation =
[
    new SystemChatMessage("You are a helpful assistant."),
];

while (true)
{
    Console.Write("Q: ");
    string? userInput = Console.ReadLine();
    if (string.IsNullOrWhiteSpace(userInput)) break;

    conversation.Add(new UserChatMessage(userInput));

    ChatCompletion response = await client.CompleteChatAsync(conversation);
    string assistantMessage = response.Content[0].Text;

    conversation.Add(new AssistantChatMessage(assistantMessage));
    Console.WriteLine($"\n{assistantMessage}\n");
}

上記のコードを実行すると、空白のコンソール ウィンドウが表示されます。 ウィンドウに最初の質問を入力し、 Enter キーを選択します。 応答が返されたら、プロセスを繰り返し、質問を続けることができます。

会話を管理する

前の例は、モデルのトークン制限 (コンテキスト ウィンドウ) に達するまで実行されます。 質問と回答を受け取るごとに、 conversation リストのサイズが大きくなります。 メッセージの結合されたトークン数と要求された出力トークンは、モデルの制限内に留まる必要があります。または、要求が失敗します。 現在のトークン制限については、 モデル ページ を参照してください。

プロンプトと完了がトークンの制限内に収まるようにするのは、ユーザーの責任です。 長い会話の場合は、トークン数を追跡し、制限内のプロンプトのみをモデルに送信する必要があります。 または、応答 API を使用して、会話履歴の切り捨てや管理を API に任せることができます。

次のコード サンプルでは、4,096 トークンのデモンストレーションしきい値で会話をトリミングします。 TokenLimitを、運用環境で使用するためにデプロイされたモデルのコンテキスト ウィンドウに設定します。 このサンプルでは、最も古いシステム以外のメッセージを削除して、会話を境界内に保持します。

正確なトークンカウントのために、Microsoft.ML.Tokenizers パッケージと Microsoft.ML.Tokenizers.Data.O200kBase パッケージをインストールします。

dotnet add package Microsoft.ML.Tokenizers
dotnet add package Microsoft.ML.Tokenizers.Data.O200kBase
using Azure.Identity;
using Microsoft.ML.Tokenizers;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel.Primitives;

#pragma warning disable OPENAI001

BearerTokenPolicy tokenPolicy = new(
    new DefaultAzureCredential(),
    "https://ai.azure.com/.default");

ChatClient client = new(
    model: "YOUR-DEPLOYMENT-NAME",
    authenticationPolicy: tokenPolicy,
    options: new OpenAIClientOptions()
    {
        Endpoint = new Uri("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/")
    }
);

const int MaxResponseTokens = 250;
const int TokenLimit = 4096;

var tokenizer = TiktokenTokenizer.CreateForModel("gpt-4o");

List<ChatMessage> conversation =
[
    new SystemChatMessage("You are a helpful assistant."),
];

static int CountTokens(TiktokenTokenizer tokenizer, IEnumerable<ChatMessage> messages)
{
    int count = 3; // base overhead for reply priming
    foreach (var message in messages)
    {
        count += 4; // per-message overhead
        string content = message switch
        {
            SystemChatMessage s => s.Content[0].Text ?? string.Empty,
            UserChatMessage u => u.Content[0].Text ?? string.Empty,
            AssistantChatMessage a => a.Content[0].Text ?? string.Empty,
            _ => string.Empty
        };
        count += tokenizer.CountTokens(content);
    }
    return count;
}

while (true)
{
    Console.Write("Q: ");
    string? userInput = Console.ReadLine();
    if (string.IsNullOrWhiteSpace(userInput)) break;

    conversation.Add(new UserChatMessage(userInput));

    int historyTokens = CountTokens(tokenizer, conversation);
    while (historyTokens + MaxResponseTokens >= TokenLimit && conversation.Count > 2)
    {
        conversation.RemoveAt(1); // remove oldest non-system message
        historyTokens = CountTokens(tokenizer, conversation);
    }

    ChatCompletionOptions options = new() { MaxOutputTokenCount = MaxResponseTokens };
    ChatCompletion response = await client.CompleteChatAsync(conversation, options);
    string assistantMessage = response.Content[0].Text;

    conversation.Add(new AssistantChatMessage(assistantMessage));
    Console.WriteLine($"\n{assistantMessage}\n");
}

この例では、トークン数に達すると、会話トランスクリプト内の最も古いメッセージが削除されます。 常にシステム メッセージを保持し、ユーザーまたはアシスタント メッセージのみを削除します。 時間が経つにつれて、この方法で会話を管理すると、モデルが会話の以前の部分のコンテキストを徐々に失うため、会話の品質が低下する可能性があります。

別の方法として、会話の期間を最大トークン長または特定のターン数に制限します。 トークンの上限に達すると、会話の続行を許可すると、モデルはコンテキストを失います。 新しい会話を開始し、メッセージの一覧をクリアして、使用可能な完全なトークン制限を使用して新しい会話を開始するようにユーザーに求めることができます。

トラブルシューティング

モデルで無効な Unicode 出力が生成されたので、完了を作成できませんでした

  • エラー コード: 500
  • エラーメッセージ:500 - InternalServerError: Error code: 500 - {"error": {"message": "Failed to create completion as the model generated invalid Unicode output"}}
  • 回避 策:TemperatureChatCompletionOptionsを 1 未満に設定し、再試行ロジックでクライアントを使用します。 要求の再試行は、多くの場合成功します。

一般的なエラー

  • 401/403 (認証): API キーを確認するか、Azure OpenAI リソースにMicrosoft Entra IDアクセス権があることを確認します。
  • 400/404 (デプロイが見つかりません):ChatClient コンストラクターに渡されたモデル名がデプロイ名と一致することを確認します。
  • 無効なエンドポイント: EndpointOpenAIClientOptions URI がhttps://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/を指していることを確認します。

セットアップ

  1. Node.js 22 以降をインストールします。

  2. TypeScript プロジェクトを作成し、必要なパッケージをインストールします。

    npm init --yes
    npm install openai @azure/identity
    npm install --save-dev typescript tsx @types/node
    
  3. 各完全な例を chat.tsとして保存し、実行します。

    npx tsx chat.ts
    

チャット完了モデルを操作する

次の例は、Chat Completions API を使用するモデルを操作する基本的な方法を示しています。

メモ

Responses API は同じチャット スタイルの対話を使用しますが、以前のチャット入力候補 API では使用できない最新の機能をサポートしています。

import {
  DefaultAzureCredential,
  getBearerTokenProvider,
} from "@azure/identity";
import OpenAI from "openai";

const tokenProvider = getBearerTokenProvider(
  new DefaultAzureCredential(),
  "https://ai.azure.com/.default",
);
const openai = new OpenAI({
  baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
  apiKey: tokenProvider,
});

const completion = await openai.chat.completions.create({
  model: "YOUR-DEPLOYMENT-NAME",
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    { role: "user", content: "Who were the founders of Microsoft?" },
  ],
});

console.log(completion.choices[0]?.message.content);
console.log(`Finish reason: ${completion.choices[0]?.finish_reason}`);

次の出力が代表的です。 正確な文言は異なる場合があります。

Microsoft was founded by Bill Gates and Paul Allen.
Finish reason: stop

Azure OpenAI v1 クライアント パターン全体については、OpenAI Node の Azure Chat Completions の例を参照してください。

すべての応答には finish_reasonが含まれます。 指定できる値は次のとおりです。

  • stop: API は完全なモデル出力を返しました。
  • length: max_completion_tokens またはトークンの制限により、モデルが停止しました。
  • content_filter: コンテンツ フィルターで省略されたコンテンツ。
  • tool_calls: ツールと呼ばれるモデル。
  • function_call: 関数と呼ばれるモデル。 この値は非推奨です。

ストリーミング応答では、最後のチャンクで応答が完了するまで、finish_reasonnull です。

想定される応答に対して十分高くなるように、max_completion_tokens を設定します。 値を大きくすると、モデルがメッセージの末尾に到達する前に停止するのを防ぐことができます。

Chat Completions API を使う

チャット補完モデルは、会話形式の入力を受け入れます。 messages パラメーターは、ロール別に編成された会話を含むメッセージ オブジェクトの配列を受け取ります。 要求の外部で定義するときに、配列を OpenAI.Chat.ChatCompletionMessageParam[] として入力します。

基本的なチャット完了の形式は次のとおりです。

const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
  { role: "system", content: "Provide context or instructions to the model." },
  { role: "user", content: "The user's message goes here." },
];

1 つの例の回答を含む会話の後に質問が続く場合は、次のようになります。

const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
  { role: "system", content: "Provide context or instructions to the model." },
  { role: "user", content: "Example question goes here." },
  { role: "assistant", content: "Example answer goes here." },
  { role: "user", content: "First question for the model to answer." },
];

システム ロール

配列の先頭にシステム ロール (システム メッセージとも呼ばれます) を含めます。 このメッセージは、モデルに最初の指示を提供します。 アシスタントの目的、動作、ルール、または接地データを定義できます。

システム メッセージは省略可能ですが、最適な結果を得るための基本的なメッセージを少なくとも含めます。

メッセージ

システムロールの後に、 userassistantの間に一連のメッセージを含めます。

const message: OpenAI.Chat.ChatCompletionUserMessageParam = {
  role: "user",
  content: "What is thermodynamics?",
};

アシスタントが応答する番であることを示すユーザー メッセージで終了します。 また、少数の学習のために、ユーザーとアシスタントの間にサンプル メッセージを含めることもできます。

メッセージ プロンプトの例

これらの例は、アプリケーションに適応できるプロンプトの開始点として使用します。

基本的な例

const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
  { role: "system", content: "You are a helpful assistant." },
  { role: "user", content: "Who were the founders of Microsoft?" },
];

手順を含む例

システム メッセージを使用して、モデルの応答の境界を定義します。

const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
  {
    role: "system",
    content: `You help users answer tax-related questions.
Only answer questions about taxes.
If you don't know an answer, recommend the IRS website.`,
  },
  { role: "user", content: "When are my taxes due?" },
];

データを基礎として使用する

モデルの回答を根拠として、システム メッセージに少量の関連データを含めます。

const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
  {
    role: "system",
    content: `Answer only from this context. If the answer isn't present,
say "I don't know."

Context: Azure OpenAI provides REST API access to OpenAI models.`,
  },
  { role: "user", content: "What does Azure OpenAI provide?" },
];

より大きなグラウンド データセットの場合は、埋め込みまたはAzure AI 検索を使用して、要求時に関連情報を取得します。

少数ショット学習を利用する

最後の質問の前に、ユーザーとアシスタントのメッセージの例を含めます。

const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
  { role: "system", content: "You help users answer tax questions." },
  { role: "user", content: "When do I need to file my taxes?" },
  { role: "assistant", content: "Check the current deadline at irs.gov." },
  { role: "user", content: "How can I check my refund status?" },
];

チャットの完了を非チャット シナリオに使用する

Chat Completions API は、エンティティ抽出などの非チャット タスクもサポートしています。

const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
  {
    role: "system",
    content: "Extract names and companies. Return a JSON object.",
  },
  {
    role: "user",
    content: "Robert Smith is calling from Contoso Insurance.",
  },
];

基本的な会話ループを作成する

次の例では、コンソールから質問を読み取り、完全な会話をモデルに送信し、各回答を会話履歴に追加します。 モデルにはメモリがないため、更新された履歴をすべての要求と共に送信します。

import { stdin, stdout } from "node:process";
import { createInterface } from "node:readline/promises";
import {
  DefaultAzureCredential,
  getBearerTokenProvider,
} from "@azure/identity";
import OpenAI from "openai";

const tokenProvider = getBearerTokenProvider(
  new DefaultAzureCredential(),
  "https://ai.azure.com/.default",
);
const openai = new OpenAI({
  baseURL: "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
  apiKey: tokenProvider,
});
const conversation: OpenAI.Chat.ChatCompletionMessageParam[] = [
  { role: "system", content: "You are a helpful assistant." },
];
const consoleInput = createInterface({ input: stdin, output: stdout });

while (true) {
  const question = await consoleInput.question("Q: ");
  if (!question.trim()) break;
  conversation.push({ role: "user", content: question });
  const response = await openai.chat.completions.create({
    model: "YOUR-DEPLOYMENT-NAME",
    messages: conversation,
  });
  const answer =
    response.choices[0]?.message.content ?? "No response returned.";
  conversation.push({ role: "assistant", content: answer });
  console.log(`\n${answer}\n`);
}
consoleInput.close();

コードを実行するときに、 Q: プロンプトに質問を入力します。 空の行を入力して、アプリケーションを閉じます。

会話を管理する

会話ループは、会話がモデルのコンテキスト ウィンドウに到達するまで実行されます。 messagesと要求された出力の組み合わせトークン数は、モデルの制限内に留まる必要があります。 現在のトークンの制限については、 モデルのページを参照してください。 OpenAI Node SDK は、 response.usageを介して各要求の後にトークンの使用状況を報告しますが、次の要求を推定するためのトークナイザーは含まれません。 要求の前にトークンの使用状況を見積もるために、モデルとエンコードをサポートするトークナイザーを選択し、導入前に評価します。

長い会話の場合は、次のいずれかの方法を使用します。

  • システム メッセージを保持したまま、最も古い完全なユーザーとアシスタントのターンを削除します。 文字またはターン数は正確なトークン数ではないので、保守的な安全マージンを維持してください。
  • 一定のターンの後に新しい会話を開始します。
  • サーバーで管理される会話の状態と切り捨てをサポートする Responses API を使用します。

トラブルシューティング

モデルで無効な Unicode 出力が生成されたので、完了を作成できませんでした

  • エラー コード: 500
  • エラーメッセージ:Failed to create completion as the model generated invalid Unicode output
  • 回避策: これをサポートするモデルの場合は、 temperature を 1 未満に設定します。 OpenAI Node SDK は、既定で接続エラーと選択された HTTP エラーを 2 回再試行します。 この動作を変更するには、maxRetries クライアントでOpenAIを設定します。

一般的なエラー

  • 401/403 (認証):API キーを確認するか、サインイン ID が Azure OpenAI リソースにアクセスできることを確認します。
  • 400/404 (展開が見つかりません):modelが展開名と一致することを確認します。
  • 無効な URL: baseURL/openai/v1/で終わることを確認します。