MongoDB は、 OpenAI Agents SDK で構築するエージェントのバッキングデータベースとして使用できます。エージェント SDK は、少数のプリミティブ セットからエージェント アプリケーションを構築するためのPythonフレームワークです。
指示とツールを使用して構成された大規模言語モデル(llm)である エージェント 。
ハンドオフ 。1 つのエージェントが別のエージェントにタスクを委任できます 。
エージェントの入力と出力を検証する 文字列 。
セッション :エージェントの実行全体で交流履歴を保存します。
SDKは 2 つの設計原則に従います。実際のアプリケーションを構築するのに十分な機能が含まれていますが、短期間に学習できるプリミティブは少ないです。デフォルトも優れた結果を生成し、エージェントを実行するすべてのステップをカスタマイズできます。
エージェント SDK でMongoDBを使用する理由
エージェント SDK は、 MongoDBで対話履歴を永続化するセッション実装である MongoDBSession を提供します。その履歴をMongoDBに保存すると、エージェントに次のメリットが得られます。
水平スケーリング可能なマルチプロセス セッションストレージ。セッション状態は、単一のプロセスのメモリではなくクラスターに存在するため、同じクラスターに接続する任意のワーカー、コンテナ、またはサーバーレス関数は通信を継続できます。各メッセージには単調に増加する
seqカウンターが含まれるため、同時書込み内でのメッセージ順序が維持されます。通信とアプリケーションデータ用の 1 つのデータベース。アプリケーションがすでにMongoDBを使用している場合、エージェントは同じ接続と同じドライバーを介して運用データを読み取り、セッション履歴を書込みます。配置および保護するための別のメモリ サービスはありません。
エージェント状態に合わせて柔軟なドキュメント。ドキュメントモデルは、やり取りの展開、ツール呼び出し、構造化された出力を展開時にまとめて保存するため、スキーマを移行せずにレコード内容を拡張できます。
クエリ可能なエージェントの履歴。セッション履歴は通常のコレクションに保存されるため、クエリ、集計、インデックスを作成して、エージェントの動作を監査するたり、分析を構築したりできます。
検索するパス。エージェントはすでにMongoDBに接続されているため、同じクラスターにMongoDB ベクトル検索 を追加して、データのセマンティック検索を提供できます。詳細については、「 エージェント RG 」を参照してください。
Tutorial
このチュートリアルでは、マルチエージェントの移動支援を構築します。トリガーエージェントは、ツールとして 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-py(pip install atlas-local-lib-py)をインストールします。詳細については、 atlas-local-lib-pyリポジトリを参照してください。Search とベクトル検索がインストールされたMongoDB Community クラスター。
OpenAI APIキー。API リクエストに使用できるクレジットがある OpenAI アカウントが必要です。OpenAI のアカウント登録の詳細については、OpenAI API のウェブサイトをご覧ください。
環境を設定する
環境変数を設定します。
アプリケーションは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
エージェントをビルドする
アプリケーションファイルを作成します。
multi_agent_app.py という名前のファイルを作成し、次のコードをそのファイルに貼り付けます。インライン コメントは、アプリケーションの各部分でMongoDBがどのように使用されているかを説明します。
"""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 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']}" ) 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())
アプリケーションを実行します。
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.
アプリケーションでのMongoDBの使用方法
アプリケーションは1 つの AsyncMongoClient を作成し、それをエージェントとセッション全体で共有します。
スペシャリスト エージェントは、ツール関数から
destinationsコレクションとpoliciesコレクションをクエリするため、データから応答します。MongoDBSessionは、各セッションを同じデータベース内のagent_sessionsコレクションとagent_messagesコレクションに書き込みます。どちらのコレクション名も構成可能で、セッションは最初に使用するときに必要なインデックスを作成します。
アプリケーションはクライアント自体を構築するため、クライアントのライフサイクルはアプリケーションに属し、session.close() は何も行いません。代わりに、セッションでクライアントを所有するには、MongoDBSession.from_uri() を使用してクライアントを作成します。
次のステップ
エージェント SDK で複数のエージェントを調整する方法の詳細については、 OpenAI ドキュメントの次のページを参照してください。