この記事を読んでわかること
- Azure AI Foundry Agent Serviceの大体の仕組みがわかる!
- ユースケースごとの実装方針がわかる!
- 1分で読めません(釣りサムネです...)
目次
- Azure AI Foundry Agent Serviceって何?
- Agent Serviceに登場する概念の整理
- ユースケース別の方針
Azure AI Foudry Agent Service って何?
一言で言うと、AIエージェントをカスタムできるAzure AI Foundryのサービスです。
公式はこちら
Azure Open AIでAssistants APIを使ったことがある人にとっては、「Assistants APIの後継」と言う方が最もイメージしやすいかもしれません。
このAgent ServiceでAIエージェントを構築することで、人間の指示によって、RAGやWeb検索、コードインタプリタに至るまで通常のモデルのみではできない操作を実現することができます。
Microsoftは既存のAIサービスをAzure AI Foundry ブランド に移行する流れを見せており、Assistants APIからの移行もこの流れを汲んだものと言えるでしょう。
Agent Serviceに登場する概念の整理
登場する概念は、全部でたったの7個!!( 多いな... )
概念の大きい順に並べると、以下のようになります。
- Project
- Agent
- Tool
- Thread
- Message
- Run
- RunStep
一つずつ順を追って説明していきます。
Project
一番大きい概念です。Azure AI Foundy における、リソース管理の単位です。
Projectにエージェントを配置したり、モデルをデプロイしたりしていきます。
「エージェントを配置するための箱」 と理解するのがスムーズかと思います。
Agent
人間による指示を遂行するAIエージェントです。
Agent は Project にデプロイしたモデル(gpt-4oなど)をもとに構築します。
選択したモデルによって、Agentの基本的な性能や性質は決まってしまいます。
2025年11月時点では、gpt-4oかgpt-5系を指定しておけば、無難かなと思います。
Agentはのちに説明する Tool を使用することで、自律的な思考の末、外部のリソースにアクセスし、回答を生成することができます。
Toolの使用によって、社内文書などのナレッジを持った Agent を構築することができます。
Tool
Agentに対して与える「道具」のようなものです。
Toolを与えない Agent はただの丸裸の 基本モデルにすぎないので、基本的には1つ以上の Tool を Agentには与えることになります。
Toolは大きく分けて以下の3種類
| Toolの種類 | 説明 |
|---|---|
| ナレッジ | モデルの持っていない「知識」を外部のリソースから取得する |
| アクション | モデルが通常行うことのできない「操作」を行う |
| エージェントの呼び出し | 最も画期的。エージェントがさらにエージェントを呼び出すことができる。 |
ナレッジ
ナレッジで代表的なのは、以下の4つかと思います
- Azure AI Search
- 社内文書などを検索する際に使用する
- Bing Search
- Web検索の際に使用する
- FileSearch
- ユーザーからのファイルのインプットを受け、その内容に対しての質問を行う時に使用する
- SharePoint
- SharePoint内のものを参照させたいときに使用する
- 個人的にはGoogle Driveに接続したいと思ったりしますが、Microsoft製なので、ご愛嬌
アクション
アクションでよく使うのは、コードインタープリタでしょう。
- Code Interpreter
- エージェントが何かプログラムを実行するのに必要です。ファイルの生成には必要です
その他にも、任意の関数であったり、自前のAzureFunctions を呼び出すこともできます。
エージェントの呼び出し
これが一番画期的です。
エージェントが処理中に、別のエージェントを呼び出すことができます。
子のエージェントに処理を委譲することで、自身はユーザーの指示の遂行に集中します。
汎用的に色々実現できる Agent になぜこんなエージェント呼び出しがついているのかという話ですが、基本的には、現在のLLMは、多くの役目を任せすぎると精度が著しく落ちる という性質を持っています。これを防ぐために、役割ごとに Agent を定義して必要な時に呼び出すというのが有効であるから、というのがエージェント呼び出しの存在意義だと思います。
Thread
文字通り、スレッドという会話の単位です。
ChatGPTでいうチャットという概念に相当します。
スレッドの中に複数のMessageが連なり、コンテクストもスレッド内に閉じたものになっています。
したがって、同じスレッドに対してAgentの呼び出しを行うと、Agentはちゃんと数分前に話したことを覚えています。
逆に全く違うスレッドに対して質問しても、コンテクストを保持していないので、エージェントは何も記憶していません。
Message
Threadに連なる、実際の会話の内容です。
Messageには、アタッチメントという形で、ファイルがくっついていることもしばしば
Message は user / assistans の二つのtype で分けられており、ユーザーとエージェントのどちらが送信したものかわかるようになっています。
Run / RunStep
Message は Agentの処理の結果として生成されるものですが、Run こそがMessageの生成過程です。
Run はさらに RunStepに分けられます。RunStep は具体的にどんな処理をしたかというのを、格納しています。
以下の例は、RunStepでToolの呼び出しが行われたRunの中身です。
このようにして、どのような処理過程のもとにMessageが生成されたかというのを確認できます。
ユースケースごとの実装方針
ユーザーの入力ファイルをそのスレッドのみで参照させたい
何も考えずベクトルストアを定義すると、すべてのスレッドから参照されるベクトルストアを定義してしまい、スレッド同士のファイルが混線してしまいます。
以下のような実装にすれば、スレッドごとにベクトルストアを定義できます。
userからのmessageを定義する際にattachmentとしてファイルを入れ込むことで、このベクトルストアに格納してくれます。
import os
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
class AgentService:
"""
Agentにアクセスするクラス
"""
def __init__(self):
self.project = AIProjectClient(
endpoint=os.getenv("AZURE_AI_FOUNDRY_PROJECT_ENDPOINT", ""),
credential=DefaultAzureCredential(),
)
def ensure_thread_vector_store(self, agent_thread_id: str) -> str:
"""
スレッド専用の Vector Store を1つだけ確保してIDを返す。
既に付いていれば再利用(=混線しない)。
"""
thread = self.project.agents.threads.get(agent_thread_id)
current = thread.tool_resources.get("file_search", {})
vs_ids = current.get("vector_store_ids", [])
if vs_ids:
return vs_ids[0]
vs = self.project.agents.vector_stores.create(
name=f"vs_thread_{agent_thread_id}"
)
self.project.agents.threads.update(
thread_id=agent_thread_id,
tool_resources=ToolResources(
file_search=FileSearchToolResource(
vector_store_ids=[vs.id],
)
),
)
return vs.id
Agentの回答の中のファイル引用部分をダウンロードリンクにする
エージェントの回答の中には、引用(Citation)がついていることがあります。
特にRAGやWeb検索をした部分は、引用がついていることが多くあります。
RAGの原理的には、実はドキュメントの実体を参照してるわけではなく、ドキュメントをチャンキングした一部の部分を参照しているため、ダウンロードリンクが直接提供されることはありません。
よって、ドキュメントにメタデータとして元となるドキュメントのurlを登録する必要があります。
Blob Storage をもとにAzure の Indexer を 使用してベクトルストアを作る場合は、カスタムフィールドマッピングの機能を使用することで定義できます。



