第9章 会話の文脈と状態を扱う
本章は初稿です。
9.1 この章で学ぶこと
「Windows です」「その手順でも直りませんでした」という発言だけでは、何の相談か分かりません。前のやり取りを引き継いで初めて、追加情報として意味を持ちます。
本章では、同じ Agent で会話を続ける場合と、新しい会話を始める場合を比較します。履歴、モデルへ渡す文脈、長期記憶、業務の記録を区別できるようになることを目指します。
9.2 一つの振る舞いと、複数の会話
Conversation は入出力の履歴を保持し、Response はその履歴と新しい入力を使って実行されます。Agent は複数の会話で再利用できます。[^runtime]
図9-1 共通にするのは振る舞いであり、全員の相談履歴ではない。 枠は相談ごとの履歴の区切り、矢印は振る舞いの参照と履歴の引き継ぎを表します。図の分離を実現するには、アプリケーション側でも利用者と会話の対応を確認します。会話 ID が認可の代わりになるわけではありません。
たとえば「VPN の相談」と「経費システムの相談」を別の会話へ分ければ、話題の混同を減らせます。話題を引き継ぐ設計にする場合も、どの情報を持ち越すかを明示します。
9.3 会話を続けるコードを読む
次のコードは、第7章の client を利用できる with ブロックの内側で試す断片です。単独の実行ファイルではありません。Agent の名前や指示を変えず、会話だけを変えて比較します。SDK と Azure の接続部分は実環境未検証です。
conversation_a = client.conversations.create()
for message in [
"VPN に接続できません。",
"OS は Windows です。",
"ここまでに伝えた情報と、まだ足りない情報を整理してください。",
]:
response = client.responses.create(
conversation=conversation_a.id,
input=message,
)
if response.status != "completed" or not response.output_text:
raise RuntimeError(f"Unexpected response state: {response.status}")
print(response.output_text)
conversation_b = client.conversations.create()
response_b = client.responses.create(
conversation=conversation_b.id,
input="その手順でも直りませんでした。",
)
if response_b.status != "completed" or not response_b.output_text:
raise RuntimeError(f"Unexpected response state: {response_b.status}")
print(response_b.output_text)
Conversation A では、VPN と Windows が既に伝えられています。Conversation B には、その履歴を渡していません。同じ Agent でも、前者の具体的な相談を当然には知っていません。公式の会話例も、同じ Conversation を指定して複数の応答を生成します。[^quickstart]
モデルが偶然「VPN ですか」と推測した場合も、履歴の継承を証明したことにはなりません。渡した会話 ID と入力項目を確認してください。
9.4 保存してある履歴と、今回使う文脈は違う
モデルは、今回の入力として与えられた情報を使って応答します。サービスに保存された履歴の全体と、今回モデルが扱う文脈を同一視しないようにします。実際に引き継ぐ項目や長い履歴の扱いは、利用する API とモデルの仕様で確認します。
モデルが文章などを処理する単位をトークンと呼びます。トークン数は文字数と同じではなく、一度に扱える文脈にはモデルごとの上限があります。履歴や資料を無制限に渡すことはできません。入力が増えれば費用や処理時間にも影響します。
長くなった相談では、必要な履歴を選ぶ、確認済み事項を要約する、古い話題を別の会話へ分ける、といった設計を考えます。ただし、要約にも誤りが入り得ます。「OS は Windows」と「Windows かもしれない」を同じ確定情報へ変えないことが重要です。
9.5 会話、長期記憶、業務記録を分ける
| 情報 | 目的 | 今回の例 |
|---|---|---|
| 会話の履歴 | 相談の流れを引き継ぐ | 質問、追加情報、過去の回答 |
| 今回の文脈 | 今の応答に必要な材料を渡す | 関係する履歴と検索結果 |
| 長期記憶 | 別の場面でも使う情報を保持・取得する | 許可された利用者の設定など |
| 業務記録 | 操作や許可の成立を確認する | 承認、登録先の ID、処理結果 |
最初の試作品に長期記憶を必須とする必要はありません。一つの相談を適切に継続するところから始めます。
また、会話に「承認をいただきました」と出力されたことは、利用者の承認の証拠ではありません。チケット登録へ発展させる場合、承認と登録結果は別の業務記録として扱います。この違いは付録で学びます。
9.6 小さな実習と確認課題
Conversation A と B の比較表を作り、「実際に渡した情報」「回答で使われた情報」「推測された情報」を分けてください。Azure を使わない場合も、同じ入力項目の一覧を作れます。
追加課題として、A の履歴から次の要約を作ります。
VPN に接続できない。OS は Windows。エラーの内容と、既に試した手順は未確認。
この要約に「再インストール済み」を勝手に足したら、次の回答にどのような影響が出るでしょうか。履歴を短くするだけでなく、事実と未確認事項を保つことが理解のポイントです。
9.7 まとめ
Agent の振る舞いは再利用できますが、相談の履歴は適切に分けます。保存、入力、記憶、業務の証拠も別です。次章では、この会話へ検索関数の要求と結果を加えます。
9.8 参考情報
- Build with runtime components in Foundry Agent Service — 会話、応答、履歴を引き継ぐ方式
- Quickstart: Create a prompt agent — 複数ターンの会話の基本例
[^runtime]: Build with runtime components in Foundry Agent Service — Microsoft
[^quickstart]: Quickstart: Create a prompt agent — Microsoft
前章:第8章 指示でエージェントの振る舞いを整える · 教材の目次へ戻る · 次章:第10章 Function calling で外部の処理を呼び出す