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

MongoDBと OpenAI Agents SDK の統合

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

  • 指示とツールを使用して構成された大規模言語モデル(llm)である エージェント 。

  • ハンドオフ 。1 つのエージェントが別のエージェントにタスクを委任できます 。

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

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

SDKは 2 つの設計原則に従います。実際のアプリケーションを構築するのに十分な機能が含まれていますが、短期間に学習できるプリミティブは少ないです。デフォルトも優れた結果を生成し、エージェントを実行するすべてのステップをカスタマイズできます。

エージェント SDK は、 MongoDBで対話履歴を永続化するセッション実装である MongoDBSession を提供します。その履歴をMongoDBに保存すると、エージェントに次のメリットが得られます。

  • 水平スケーリング可能なマルチプロセス セッションストレージ。セッション状態は、単一のプロセスのメモリではなくクラスターに存在するため、同じクラスターに接続する任意のワーカー、コンテナ、またはサーバーレス関数は通信を継続できます。各メッセージには単調に増加する seqカウンターが含まれるため、同時書込み内でのメッセージ順序が維持されます。

  • 通信とアプリケーションデータ用の 1 つのデータベース。アプリケーションがすでにMongoDBを使用している場合、エージェントは同じ接続と同じドライバーを介して運用データを読み取り、セッション履歴を書込みます。配置および保護するための別のメモリ サービスはありません。

  • エージェント状態に合わせて柔軟なドキュメント。ドキュメントモデルは、やり取りの展開、ツール呼び出し、構造化された出力を展開時にまとめて保存するため、スキーマを移行せずにレコード内容を拡張できます。

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

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

このチュートリアルでは、マルチエージェントの移動支援を構築します。トリガーエージェントは、ツールとして 2 つのスペシャリストエージェントを呼び出して質問に答えます。両方のスペシャリストは、対話セッションを保存する同じクラスターから参照データを読み取ります。

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

  • Python 3.10 以降。

  • 次のいずれかのMongoDBクラスター タイプ

    • An Atlas cluster running MongoDB version 6.0.11, 7.0.2, or later. Ensure that your IP address is included in your Atlas project's access list.

    • PythonとDockerを使用して作成されたローカル Atlas 配置。プログラムでローカル配置を作成および管理するには、atlas-local-lib-pypip install atlas-local-lib-py )をインストールします。詳細については、 atlas-local-lib-pyリポジトリを参照してください。

    • Search とベクトル検索がインストールされたMongoDB Community クラスター。

  • OpenAI APIキー。API リクエストに使用できるクレジットがある OpenAI アカウントが必要です。OpenAI のアカウント登録の詳細については、OpenAI API のウェブサイトをご覧ください。

1

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

uv venv
source .venv/bin/activate
2

mongodb の追加でエージェント SDK をインストールします。 シェルが括弧を解釈しないように、パッケージ名を引用符で囲みます。

uv pip install "openai-agents[mongodb]"

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

3

アプリケーションはATLAS_URI から Atlas接続文字列を読み取り、エージェント 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コレクションから、2 番目の質問には policiesコレクションから応答します。セッションは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() を使用してクライアントを作成します。

エージェント SDK で複数のエージェントを調整する方法の詳細については、 OpenAI ドキュメントの次のページを参照してください。

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

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

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

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