0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Azure OpenAIのSystemChatMessageとUserChatMessageは何が違うのか調べてみた

0
Last updated at Posted at 2026-03-01

はじめに

C#でAzure OpenAI連携の機能を実装していたところ、SystemChatMessageUserChatMessageというクラスが出てきました。

new SystemChatMessage("あなたは親切なアシスタントです。"),
new UserChatMessage("こんにちは!"),

「どっちもメッセージを送ってるだけじゃないの?何が違うの?」と思って調べたので、学んだことをまとめます。

環境

  • .NET 10.0
  • Azure.AI.OpenAI(安定版)
  • Visual Studio 2026

そもそもChat Completion APIの仕組み

まず前提として、Azure OpenAIのChat Completion APIは会話形式でやりとりする仕組みになっています。

APIにメッセージを送るとき、1つの文字列を投げるのではなく、ロール(役割)付きのメッセージの配列を渡します。ロールには主に以下の3つがあります。

ロール C#のクラス 役割
system SystemChatMessage AIの振る舞いや前提条件を定義する
user UserChatMessage ユーザーからの入力(質問や依頼)
assistant AssistantChatMessage AIからの応答(会話履歴として使う)

コードで見るとこんなイメージです。

var completion = chatClient.CompleteChat(
    [
        new SystemChatMessage("..."),    // system: AIへの指示
        new UserChatMessage("..."),      // user: ユーザーの発言
        new AssistantChatMessage("..."), // assistant: AIの過去の応答
        new UserChatMessage("..."),      // user: ユーザーの次の発言
    ]);

この配列全体が「会話の文脈」としてモデルに渡されます。モデル自体は会話を記憶しないため、毎回この配列に会話履歴を含めて送る必要があります。

SystemChatMessage(systemロール)とは

SystemChatMessageは、AIの振る舞いを定義するための指示です。Microsoftのドキュメントでは「system message」「metaprompt」「system prompt」とも呼ばれています。

README.mdにもこう書かれていました。

System messages represent instructions or other guidance about how the assistant should behave

つまり「あなたはこういう存在で、こういうルールで応答してね」という設定を伝えるためのメッセージです。

何を書くのか

Microsoftのドキュメントによると、system messageには主に以下の要素を含められます。

  • 役割とタスク: アシスタントが何者で、何をするのか
  • トーンと対象: 誰に向けて、どんな口調で話すのか
  • スコープと境界: やってはいけないこと、対応できない場合の振る舞い
  • 安全ガイドライン: 有害な出力を減らすためのルール
  • ツールとデータ(任意): 利用可能なツールやデータソース

具体例

簡単なものから複雑なものまで、いくつか例を見てみます。

シンプルな例

new SystemChatMessage("あなたは親切なアシスタントです。")

業務に特化した例

new SystemChatMessage(
    """
    あなたはContoso社のカスタマサポト担当です。
    製品の保証、返品、注文状況に関する質問に回答してください。

    ## 
    - Contoso社の製品とポリシに関する質問のみ回答する
    - わからない場合は「その情報は持ち合わせていません。support@contoso.com にお問い合わせください」と回答する
    - 法的、医療、金融に関するアドバイスは行わない
    - 競合他社について言及しない

    ## 回答形式
    - 簡潔かつフレンドリ
    - 最後に「他にお手伝いできることはありますか?」と添える
    """)

参考データを含める例

new SystemChatMessage(
    """
    あなたはAzure OpenAIに関する技術的な質問に回答するチャットボットです。
    以下のコンテキストの範囲内でのみ回答してください。
    わからない場合は「わかりません」と回答してください。

    コンテキスト:
    - Azure OpenAIOpenAIの言語モデルへのREST APIアクセスを提供します
    - GPT-4oGPT-4o-miniなどのモデルが利用可能です
    - Azureのセキュリティとエンタプライズ機能を備えています
    """)

system messageの特徴

  • メッセージ配列の先頭に配置する
  • 省略可能だが、含めた方がよい結果が得られる(Microsoftのドキュメントでも推奨)
  • 会話全体を通じてモデルの振る舞いに影響を与える
  • 短い方がレイテンシーが少なく、コンテキストウィンドウを節約できる

注意点としては、system messageに指示を書いたからといって、モデルが100%その通りに動くとは限りません。Microsoftのドキュメントにも、system messageで「わからない場合は『わかりません』と答えて」と指示しても、それが必ず守られる保証はないと明記されています。あくまで「そうなりやすくなる」ものです。

UserChatMessage(userロール)とは

UserChatMessageは、ユーザーからの入力を表します。質問、依頼、処理してほしいテキストなど、ユーザーが実際にAIに投げるメッセージです。

new UserChatMessage("Azure OpenAIとは何ですか?")

こちらはシンプルで、「ユーザーが言ったこと」をそのまま渡すだけです。会話履歴として過去のユーザー発言を含める場合にも使います。

両者の違いを整理する

ここまで調べて理解した違いを整理します。

観点 SystemChatMessage UserChatMessage
誰の発言か 開発者(システム側) エンドユーザー
目的 AIの振る舞い・ルール・前提の定義 質問や依頼の入力
配置 通常は配列の先頭に1つ 会話の中で複数回登場
影響範囲 会話全体のトーンや制約 その場の質問・タスクに対する応答
省略 省略可能(非推奨) 最低1つは必要

イメージとしては、SystemChatMessage舞台の設定UserChatMessageセリフみたいなものだと思いました。

実際のコード例

Azure.AI.OpenAIを使った実際のコード例をいくつか紹介します。

基本的な使い方

using Azure.AI.OpenAI;
using Azure.Identity;
using OpenAI.Chat;

// クライアントの作成
var azureClient = new AzureOpenAIClient(
    new Uri("https://your-resource.openai.azure.com"),
    new DefaultAzureCredential());

var chatClient = azureClient.GetChatClient("my-gpt-4o-deployment");

// メッセージの組み立てと送信
var completion = chatClient.CompleteChat(
    [
        new SystemChatMessage("あなたは親切な日本語アシスタントです。簡潔に回答してください。"),
        new UserChatMessage("Azure OpenAIとは何ですか?"),
    ]);

Console.WriteLine(completion.Content[0].Text);

SystemChatMessageで「日本語で簡潔に」という方針を伝え、UserChatMessageで実際の質問を投げています。この2つを組み合わせることで、期待した形式の回答が返ってきやすくなります。

会話履歴を含める場合

マルチターンの会話では、過去のやりとりも配列に含めます。ここでAssistantChatMessageも登場します。

var completion = chatClient.CompleteChat(
    [
        new SystemChatMessage("あなたはC#の学習をサポートするアシスタントです。初心者にもわかりやすく説明してください。"),
        // 1ターン目
        new UserChatMessage("LINQって何ですか?"),
        new AssistantChatMessage("LINQは、C#のコレクション操作を簡潔に書ける機能です。SQLのような書き方でデータの抽出や変換ができます。"),
        // 2ターン目(これに対する応答が返る)
        new UserChatMessage("具体的なコード例を見せてください。"),
    ]);

モデルには会話の記憶がないため、2ターン目の質問だけ送ると「何の具体例?」となってしまいます。過去のやりとりを含めることで、「LINQの具体例」だと理解してくれます。

Few-shot学習(応答の例を示す)

system messageだけでは意図した形式で回答してくれない場合、UserとAssistantのやりとり例を入れて「こういう風に答えてね」と示すテクニックがあります。Few-shot学習と呼ばれます。

var completion = chatClient.CompleteChat(
    [
        new SystemChatMessage("ニュース記事の見出しからカテゴリを判定するアシスタントです。"),
        // 例1
        new UserChatMessage("見出し: 日経平均が年初来高値を更新"),
        new AssistantChatMessage("カテゴリ: 経済"),
        // 例2
        new UserChatMessage("見出し: 大谷翔平が今季30号ホームラン"),
        new AssistantChatMessage("カテゴリ: スポーツ"),
        // 実際に判定してほしい入力
        new UserChatMessage("見出し: 新型iPhoneが来月発売へ"),
    ]);

// → 「カテゴリ: テクノロジー」のような応答が期待される

例を示すことで、「見出しを受け取ったら『カテゴリ: ○○』の形式で返す」というパターンをモデルが汲み取ってくれます。

まとめ

  • SystemChatMessage(systemロール) はAIの振る舞い・ルール・前提条件を定義するもの
  • UserChatMessage(userロール) はユーザーからの質問や依頼を伝えるもの
  • 両者は役割が明確に異なるので、適切に使い分けることで意図した応答を得やすくなる
  • 会話履歴を含める場合はAssistantChatMessageも組み合わせる
  • system messageは省略可能だが、含めた方がよい結果が得られる

調べてみると、普段何気なく使っていた「ロール」の概念がちゃんと設計された仕組みだということがわかりました。特にsystem messageの設計次第でAIの応答品質がかなり変わるので、意識して書くようにしたいです。

参考になったら いいねストック をお願いします!
同じような経験をされた方のコメントもお待ちしています。

参考

関連リンク

技術ブログでも学びや検証内容をまとめています。

nakamuuublog

アウトプットで手当がもらえる会社 ONE WEDGE

株式会社ONE WEDGE では一緒に働く仲間を募集中!

技術記事を書くと手当がもらえる「IT系記事寄稿特別手当」という制度があります。

興味があればぜひカジュアルに話しましょう!

👉 採用サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?