
こんにちは、Lena Nadir Blog 管理人です。
前回のロードマップ記事でお伝えした通り、このシリーズでは AI-103 の中でも配点比率が最も高い Generative AI/Agent 領域に絞って、実機を動かしながら学んでいきます。
第1回では、Microsoft Foundry Portal 上で最初の AI Agent をノーコードで定義し、Python SDK 経由で同じ Agent を呼び出すところまでを一気通貫でやってみます。
2026年8月更新: Microsoft Foundryの最新名称に合わせて表記を見直しました。
今回作るもの
今回作成するのは、LLM / AI Agent 関連の論文を Web Search で収集し、要点をまとめてくれる Agent です。
具体的には、ユーザーがトピックを1つ伝えるだけで、Agent が以下の2ステップを自律的に実行します。
- STEP 1 - Search and List: Web Search で直近の関連論文・記事を検索し、タイトル・出典・要約・URLをリスト化
- STEP 2 - Synthesize: リストアップした内容を横断的に見て、共通するトレンドをSummaryとしてまとめる
「検索して終わり」ではなく「検索した内容を統合して考察する」という、Agentらしい自律的な振る舞いが体感できるテーマです。
事前準備
- Microsoft Foundry プロジェクトの作成
- Python 環境のセットアップ
pip install azure-ai-projects azure-identity
az login
- 認証用の環境変数(プロジェクトエンドポイント)
PROJECT_ENDPOINT=https://<your-resource>.services.ai.azure.com/api/projects/<your-project>
Foundry Portal で Agent をノーコードで作成する
Foundry Portal 上で、新しい Agent を作成します。手順は以下の通りです。
- Microsoft Foundry Portal にサインインし、対象のプロジェクト(今回は
proj-default)を開きます - 左側メニューの Create セクションから Agents を選択します
- 上部ナビゲーションの Build タブが選択されていることを確認します(Agentの作成・編集は Build 配下の機能です)
- 画面右上の New agent ボタン(プルダウン)をクリックします
- 表示される3つの選択肢から Build an agent を選びます
- Build an agent: コードを書かず、GUI上でInstructions・Tools・Modelを設定する方式(今回はこちら)
- Code an agent: SDK/コードベースで一から実装する方式
- Link external agent: 外部で構築済みのAgentをFoundryに接続する方式

Build an agent を選ぶと、Agentの Playground 画面に遷移します。ここで、以下の設定を行います。
- Agent名:
llm-paper-research-agent - Model:
gpt-4o - Tools: Web search を有効化
Agent名の命名規則
Agent名は以下のルールに従う必要があります。
- 英数字とハイフンのみ使用可能
- 先頭と末尾は英数字(ハイフン不可)
- 63文字以内
大文字の使用も技術的には可能ですが、Azureリソース全般の命名慣習に合わせて、小文字+ハイフン区切りにしています。
Instructions の検索テンプレートを定義する
Agentの「振る舞いの一貫性」を担保するのは Instructions です。Playground画面上で、以下の手順で設定します。
- Instructions 欄をクリックし、Agentに実行させたい振る舞いをテキストで入力します(今回のテンプレートは後述)
- Tools セクションにある Web search を有効化します(トグルをONにするか、未追加の場合は
Addから追加します) - 画面右上の Save をクリックして変更を保存します

今回、Instructionsには以下のテンプレートを設定しました。「検索して結果を並べるだけ」で終わらせず、毎回同じ2段階の振る舞いを取らせるのがポイントです。
You are a research assistant specialized in LLM (Large Language Model) and AI Agent topics.
When the user provides a topic, follow these two steps:
STEP 1 - Search and List:
Use web search to find recent, relevant papers or articles on the given topic.
For each result, present:
- Title
- Source (e.g., arXiv, conference name, publisher)
- A 1-2 sentence summary of the key contribution
- The source URL (always cite it)
Prioritize results from the last 12 months. Aim for 5-8 relevant results.
STEP 2 - Synthesize:
After listing all results, write a "Summary" section that identifies
3-5 common trends, themes, or notable points of discussion across the
papers you found. This should go beyond restating individual items —
highlight what they collectively suggest about the current state of
the field.
Always keep the two steps clearly separated and labeled in your response.
Portal の Prompt でテストしてみる
Playgroundの「Message the agent…」欄に、実際にプロンプトを入力し、送信ボタンを押します。
Summarize the latest research on AI agent memory architectures.
Instructionsで想定している「LLM/AI Agent関連のトピック」の範囲に収まりつつ、“AI agent memory architectures”はここ1〜2年で論文・記事が増えている具体的なテーマなので、STEP 1のWeb検索で十分な数の結果が集まるか、STEP 2で複数論文を横断したSummaryを生成できるか、テストします。
STEP 1: 検索結果のリスト化
タイトル・出典(arXiv/ACL/EMNLPなど)・要約1〜2文の形式で、直近1年程度の論文が6件リストアップされました。番号付きの引用マーカーもついており、URL引用の仕組みが機能していることが確認できます。

STEP 2: 横断的なSummary
関連論文をリストアップした後、続く「STEP 2 – Synthesize」では、Agentが個々の論文を言い換えるのではなく、複数の論文を横断した考察(トレンド)を6点にまとめてくれました。最後には全体を総括する一文も添えられており、末尾の引用元にはfaviconアイコンも表示されています。

これで、Instructionsで意図した「論文検索→リスト化→統合的な考察」という一連の流れが、Portal上のテストチャットだけで実現できることが確認できました。
Python SDK から同じ Agent を呼び出す
ここからは、Portalで作成済みのAgentを、Python SDK経由で呼び出します。
補足: このAgentサービスは Responses API ベースのアーキテクチャを採用しています。Assistants API(Thread/Run方式)とは異なり、「Thread」ではなく「conversation」、「Runのポーリング」ではなく「ストリーミングイベントの処理」という流れになります。
1. クライアントの初期化
import os
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
PROJECT_ENDPOINT = os.environ["PROJECT_ENDPOINT"]
AGENT_NAME = "llm-paper-research-agent" # Portalで作成済みのAgent名
project = AIProjectClient(
endpoint=PROJECT_ENDPOINT,
credential=DefaultAzureCredential(),
)
openai = project.get_openai_client()
ポイントは、APIキーを一切使わずDefaultAzureCredential()によるキーレス認証だけでAgentを呼び出せることです。Portalで作成済みのAgent名をAGENT_NAMEとして参照するだけで、Azure ADの資格情報経由で安全にアクセスできます。
2. conversationの作成
Responses APIは毎回の呼び出しが基本的にステートレスなので、responses.create()を単発で呼ぶだけでは、Agentは前の発言内容を覚えていません。複数ターンにわたって文脈を保持させるには、会話のまとまりを表すconversationを明示的に作成し、そのidを以降のリクエストに渡してAgentに引き継ぐ必要があります。Assistants APIにおける「Thread」に相当する役割です。
conversation = openai.conversations.create()
print(f"Conversation created (id: {conversation.id})")
3. メッセージ送信とストリーミング処理
stream_response = openai.responses.create(
stream=True,
conversation=conversation.id,
input="Summarize the latest research on AI agent memory architectures.",
extra_body={
"agent_reference": {"name": AGENT_NAME, "type": "agent_reference"}
},
)
full_text = ""
citations = []
for event in stream_response:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
full_text += event.delta
elif event.type == "response.output_item.done":
if event.item.type == "message":
content = event.item.content[-1]
if content.type == "output_text":
for ann in content.annotations:
if ann.type == "url_citation":
citations.append(ann.url)
elif event.type == "response.completed":
print("\n\n--- Response completed ---")
このコードでは、以下の2つの処理を行っています。
openai.responses.create(...): 作成済みのconversationに対して、extra_bodyのagent_referenceで今回のAgent(llm-paper-research-agent)を指定してメッセージを送信します。stream=Trueにより、応答を一括で待たずにイベント単位で逐次受信します。for event in stream_response: ストリームで届くイベントを種類ごとに処理します。response.output_text.delta: Agentの応答テキストが生成されるたびに届く差分(トークン単位の断片)です。届くたびにprintしてターミナルに逐次表示しつつ、full_textに連結して全文を保持します。response.output_item.done: メッセージなど1つの出力アイテムが完成したタイミングで発火します。ここでは、最後のcontentからWeb Searchの引用URL(url_citation)を取り出し、citationsに集めています。response.completed: ストリーム全体が完了したことを示すイベントで、完了メッセージを表示します。
4. 結果の確認
STEP 3のループ処理中、response.output_item.doneイベントの中からWeb Searchの引用URL(url_citation)をcitationsリストに集めていました。最後に、このcitationsを重複除去して出力し、Agentが実際にどのソースを参照して回答を生成したかを確認します。

💡 このコードはNotebook形式でも公開しています。GitHubリポジトリはページ末尾からどうぞ。
内部の処理を覗く:Tracesタブ
Assistants API(Thread/Run方式)であれば「Run Steps」を確認するところですが、このResponses APIアーキテクチャでは、Portal上の Traces タブ が同等の役割を果たします。ここで、Agentが「いつWeb Searchツールを呼び出したか」「どんな検索クエリを生成したか」を確認できます。
Agent画面上部の Traces タブを開くと、Responses 一覧に先ほどSDK経由で送信したリクエストが Completed ステータスで記録されています。なお、ツール呼び出しの詳細まで追うにはApp Insightsリソースとの連携が必要ですが、この一覧自体は連携なしでも確認できます。

該当のConversation IDをクリックすると、Conversation → Response → Output item というツリー構造で内訳が展開されます。
- Response 行を選択すると、右側にResponse ID・ユーザーの入力・Agentの出力(STEP 1の検索結果)が表示されます
- その下にはさらに2つのOutput itemが並んでおり、それぞれ以下に対応しています
web_search_call: Web Searchツールの呼び出しmessage: Agentが生成した最終的な応答メッセージ

さらに web_search_call のOutput itemをクリックすると、そのツール呼び出し単体のMetadata(JSON)が確認できます。type: "web_search_call"や、どのAgent(agent_reference)のどのバージョンから呼ばれたかといった情報に加えて、下にスクロールするとWeb Searchに実際に渡された検索クエリも確認できます。

まとめ
今回は、以下を実機で確認しました。
- Foundry Portal上で、Web Search ToolとInstructionsを組み合わせたAgentをノーコードで作成
- Instructionsに「検索→リスト化→統合的なSummary」という2段階のテンプレートを定義し、一貫した振る舞いを実現
- Python SDK(Responses API)から同じAgentを呼び出し、ストリーミングでレスポンスと引用URLを取得
次回は、File Search機能を使って、Agentに独自のナレッジベースを組み込む基本的なRAG(検索拡張生成)の実装に進みます。
確認テスト(AI-103形式)
AI-103本番の出題形式(シナリオ設定+最適な選択肢を選ぶ形式)に寄せた4問です。今回の内容の理解度をチェックしてみましょう。
Q1. あなたは、社内の技術ブログ向けに、指定したトピックについて直近1年以内の外部の論文・記事を検索し、要約とURLを提示するAgentを構築しています。この要件を満たすために、Agentに追加すべきツールはどれですか。
解答を見る
正解: B. Web Search
Web Searchは、Bing Grounding等を介して外部の最新Web情報を検索するツールで、直近の論文・記事のような、社内に存在しない外部情報を取得する要件に合致します。File Searchは自組織がアップロードした既存ドキュメントを検索対象にするツールのため、この要件(直近の外部情報の取得)には適しません。
Q2. あなたはAgentに、複数ターンにわたる会話の文脈(それまでのやり取りの内容)を保持させたいと考えています。Foundry Agent ServiceのResponses APIを使用する場合、この目的のために作成・参照すべきオブジェクトはどれですか。
解答を見る
正解: C. Conversation
Responses APIアーキテクチャでは、openai.conversations.create()で作成するConversationオブジェクトが、複数ターンの会話の文脈を保持する役割を持ちます。ThreadやRun、RunStepは、Assistants API(旧アーキテクチャ)で使われていた概念であり、Responses APIには存在しません。
Q3. あなたが構築しているAgentは、ユーザーからの1つの依頼に対して、「情報を検索する」→「検索結果を横断的に要約する」という2段階の処理を、指示しなくても毎回自律的に実行する必要があります。この要件を満たすために、最も適切な設定はどれですか。
解答を見る
正解: B
Agentの振る舞いの一貫性を担保するのはInstructionsです。「STEP 1→STEP 2」のように、実行させたい手順を明示的にテキストで指示することで、ユーザーが都度指示しなくても、Agentが自律的に一連の処理を実行するようになります。ツールの追加やモデルの変更だけでは、手順(ステップ)の遵守は保証されません。
Q4. 開発者が、Agentが「いつ、どのようなクエリでWeb Searchツールを呼び出したか」を確認したいと考えています。Foundry Portal上で、この情報を確認できる場所はどこですか。
解答を見る
正解: C. Traces タブ
Traces タブでは、Conversation → Response → Output item というツリー構造でAgentの内部処理を確認できます。web_search_callというOutput itemを選択すると、実際に生成された検索クエリなどのMetadataを確認できます。なお、より詳細なspan情報を得るにはApplication Insightsリソースとの連携が必要になる場合があります。
コード一式
この記事で使用したコードは、GitHubリポジトリの azure/ai-103/episode-01-agent-basics/ に公開しています。
💡 本番前に、実力を確認したい方へ
一通り手を動かした後、自分の理解度が試験レベルに達しているかを確認したい方向けに、Udemyで『【2026年版】AI-103 模擬試験集|良問厳選・Azure AI アプリ&エージェント開発 試験対策』を公開しています。
🎟 期間限定クーポン: AI103BLOG1000YENOFF(1,000円オフ、2026/09/08まで) → クーポン適用リンクはこちら
© 2026 Lena Nadir. All rights reserved.