AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

MongoDB を OpenAI エージェント SDK と統合する

MongoDB は、 OpenAI Agents SDK で構築するエージェントのバッキングデータベースとして使用できます。エージェント SDK は、少数のプリミティブ セットからエージェント アプリケーションを構築するためのPythonフレームワークです。

  • エージェントは、指示とツールが設定された大規模言語モデル(LLM)です。

  • ハンドオフ。あるエージェントがタスクを別のエージェントに委任することを可能にするもの。

  • ガードレール。エージェントの入力と出力を検証します。

  • セッション。エージェントの実行全体で会話履歴を保存します。

SDK は 2 つのデザイン原則に従っています。実際のアプリケーションをビルドするのに十分な機能が含まれていますが、短時間で学ぶのに十分なほど少ないプリミティブです。そのデフォルト設定でも良い結果が得られます。また、エージェントの実行する各ステップをカスタマイズできます。

エージェント SDK は、MongoDB に会話履歴を持続化するセッション実装である MongoDBSession を提供します。MongoDB にその履歴を保存することで、エージェントは以下の利点を得られます。

  • 水平スケーラブルなマルチプロセスセッションストレージ。セッション状態は単一プロセスのメモリではなく、クラスター内に保存されます。そのため、同じクラスターに接続するワーカー、コンテナ、またはサーバーレス関数は会話を続行できます。各メッセージには単調増加の seq カウンターが含まれており、これによって複数の同時書き込みでのメッセージの順序が維持されます。

  • 1 つのデータベースで会話データとアプリケーションデータを取り扱います。アプリケーションで既に MongoDB を使用している場合、エージェントは同じ接続と同じドライバーを介して操作データを読み取り、セッション履歴を書き込みます。このため、メモリサービスの配置することとセキュリティのための別個のサービスは不要です。

  • エージェントの状態向けの柔軟なドキュメント。document model は、会話のターン、ツールの呼び出し、構造化された出力を、それらが進化するにつれてまとめて保存します。これにより、スキーマ移行を行わずにレコードする内容を拡張することができます。

  • クエリ可能なエージェント履歴。セッション履歴は通常のコレクションに保存されます。そのため、エージェントの動作を監査したり、分析をビルドするために、クエリ、集計、インデックスを行うことができます。

  • 検索するパス。エージェントはすでにMongoDBに接続されているため、同じクラスターにMongoDB ベクトル検索 を追加して、データのセマンティック検索を提供できます。詳細については、「 エージェント RG 」を参照してください。

このチュートリアルでは、マルチエージェントの旅行アシスタントをビルドする。トリアージ エージェントは、2 人の専門エージェントをツールとして呼び出し、質問に答えます。そして、両方の専門エージェントは、会話セッションを保存する同じクラスターから参照データを読み取ります。

Atlas の サンプル データ セット からの映画データを含むコレクションを使用します。

1

このチュートリアルでは、v を使用して環境を管理します。

uv venv
source .venv/bin/activate
2

`mongodb` 余計を使用してエージェント SDK をインストールします。shell がブラケットを解釈しないように、パッケージ名をクォートしてください。

uv pip install "openai-agents[mongodb]"

余計 は、セッション ツールとエージェント ツールの両方が使用する AsyncMongoClient クラスを提供する pymongo バージョン 4.14 以降をインストールします。

3

アプリケーションは Atlas 接続文字列を ATLAS_URI から読み取ります。また、エージェント SDK は OPENAI_API_KEY からキーを読み取ります。

export ATLAS_URI="<connection-string>"
export OPENAI_API_KEY="<api-key>"

<connection-string>プレースホルダー値をクラスターの SRV接続文字列に置き換えます。

接続stringには、次の形式を使用する必要があります。

mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
1

multi_agent_app.py というファイルを作成し、次のコードを貼り付けます。インライン コメントには、アプリケーションの各パートがどのように MongoDB を使用しているかが説明されています。

multi_agent_app.py
"""Multi-agent travel assistant backed by MongoDB Atlas.
A triage agent answers travel questions by calling two specialist
agents as tools. Both specialists read reference data from the same
Atlas cluster that stores the conversation session, so every agent in
the application shares one database.
"""
import asyncio
import os
from agents import Agent, Runner, function_tool
from agents.extensions.memory import MongoDBSession
from pymongo import AsyncMongoClient
# The script reads your credentials from the environment so that you
# don't commit them to source control.
REQUIRED_ENV_VARS = ("ATLAS_URI", "OPENAI_API_KEY")
DATABASE_NAME = "travel_assistant"
# One client serves both the agent tools and the session store. Because
# you create the client yourself, your application owns its lifecycle.
# main() assigns both of these after it validates the environment.
client: AsyncMongoClient | None = None
database = None
@function_tool
async def lookup_destination(city: str) -> str:
"""Look up travel guidance for a destination city."""
# Sub-agent tools query the shared database directly, so the agents
# answer from your data instead of from model training data.
document = await database.destinations.find_one({"city": city})
if document is None:
return f"No destination guide found for {city}."
return (
f"{document['city']}: best months are {document['best_months']}. "
f"{document['summary']}"
)
@function_tool
async def lookup_policy(topic: str) -> str:
"""Look up the company travel policy for a topic."""
document = await database.policies.find_one({"topic": topic})
if document is None:
return f"No policy found for {topic}."
return f"{document['topic']}: {document['rule']}"
# Each specialist is a full agent with its own instructions and tools.
destination_agent = Agent(
name="Destination expert",
instructions=(
"You advise travelers on destinations. Always call "
"lookup_destination and answer only from what it returns."
),
tools=[lookup_destination],
)
policy_agent = Agent(
name="Policy expert",
instructions=(
"You answer questions about the company travel policy. Always "
"call lookup_policy and answer only from what it returns."
),
tools=[lookup_policy],
)
# The as_tool() pattern turns each specialist into a tool that the
# triage agent can call. Unlike a handoff, control returns to the
# triage agent after each call, so it can combine both answers in one
# reply.
triage_agent = Agent(
name="Travel assistant",
instructions=(
"You are a travel assistant. Use the destination and policy "
"tools to gather facts before you answer, and call both when "
"the question needs both. Remember details the traveler shared "
"earlier in the conversation."
),
tools=[
destination_agent.as_tool(
tool_name="ask_destination_expert",
tool_description="Get travel guidance about a city.",
),
policy_agent.as_tool(
tool_name="ask_policy_expert",
tool_description="Get the company travel policy for a topic.",
),
],
)
async def seed_reference_data() -> None:
"""Load the sample data that the specialist agents read."""
await database.destinations.delete_many({})
await database.policies.delete_many({})
await database.destinations.insert_many(
[
{
"city": "Lisbon",
"best_months": "March through May",
"summary": "Mild spring weather and low hotel rates.",
},
{
"city": "Reykjavik",
"best_months": "June through August",
"summary": "Long daylight hours and open highland roads.",
},
]
)
await database.policies.insert_many(
[
{"topic": "flights", "rule": "Book economy for flights under six hours."},
{"topic": "hotels", "rule": "Nightly rates must stay under 250 USD."},
]
)
async def main() -> None:
global client, database
# Fail fast with a clear message instead of surfacing a connection
# error or an authentication error later in the run.
missing = [name for name in REQUIRED_ENV_VARS if not os.environ.get(name)]
if missing:
raise SystemExit(
"Set these environment variables before you run this script: "
+ ", ".join(missing)
)
client = AsyncMongoClient(os.environ["ATLAS_URI"])
database = client[DATABASE_NAME]
await seed_reference_data()
# The session stores conversation history in Atlas. Pass the
# existing client so the session and the agent tools share one
# connection pool.
session = MongoDBSession(
session_id="traveler-123",
client=client,
database=DATABASE_NAME,
)
# Confirm connectivity before the first run.
await session.ping()
# The Runner loads prior turns from the session and writes the new
# turn back, so the second question resolves "there" without you
# passing the history yourself.
first = await Runner.run(
triage_agent,
"I'm planning a trip to Lisbon. When should I go?",
session=session,
)
print(first.final_output)
second = await Runner.run(
triage_agent,
"What's our hotel budget for that trip?",
session=session,
)
print(second.final_output)
# session.close() is a no-op when you supply the client, so close
# the client yourself.
await client.close()
if __name__ == "__main__":
asyncio.run(main())
2
python multi_agent_app.py

エージェントは、destinations コレクションからの最初の質問と policies コレクションからの 2 番目の質問に答えます。セッションは最初のターンをMongoDBに保存するため、アシスタントは履歴を自分で渡す必要なく、2回目の質問で "その旅" を解決します。

モデルは実行するごとに新しい応答を生成するため、出力が異なる可能性があります。

For Lisbon, the best time to go is **March through May**.
That's the sweet spot for **mild weather**, comfortable sightseeing, **fewer crowds**, and generally **better hotel rates** than peak summer. If you want the best single month, I'd pick **May** for warmer days while still avoiding the biggest summer crowds.
I still don't see a company policy entry for a **Lisbon hotel budget/nightly cap**.
Best next step: check the company booking tool or ask your travel/admin team to confirm the approved lodging allowance for Lisbon.

アプリケーションは 1 つの AsyncMongoClient を作成し、それをエージェントとセッション間で共有します。

  • 専門エージェントは、ツール機能から destinations と policies のコレクションをクエリします。そのため、ユーザーのデータから答えます。

  • MongoDBSession 各会話のターンを、同じデータベース内の agent_sessions コレクションと agent_messages コレクションに書き込みます。両方のコレクション名は設定可能です。また、セッションは初回使用時に必要なインデックスを作成します。

アプリケーションがクライアント自体を構築するため、クライアントのライフサイクルはアプリケーションに属し、session.close() は何も行いません。セッションにクライアントを所有させるには、MongoDBSession.from_uri() を使用して作成します。

Agents SDK を使用した複数のエージェントの連携について学ぶには、OpenAI ドキュメントの以下のページを参照してください。

  • コードによるオーケストレーションと LM によるオーケストレーションのトレードオフを行うために、複数のエージェントをオーケストレーションする。

  • 対話をツールとして呼び出す代わりに、別のエージェントに対話を委任するためのハンドオフ。

  • エージェントの入力と出力を検証するための文字列。

  • 完全なMongoDBSession 参照のセッション。