对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

将MongoDB与 OpenAI Agents SDK 集成

您可以将MongoDB用作通过 OpenAI Agents SDK构建的代理的后端数据库。 Agents SDK 是一个Python框架,用于从一设立基元集构建代理应用程序:

  • 代理,是配置了指令和工具的大型语言模型 (LLM)。

  • 交接,允许一个代理将任务委托给另一个代理。

  • 护栏,用于验证代理的输入和输出。

  • 会话,存储代理运行期间的对话历史记录。

该 SDK 遵循两个设计原则。它包含足够多的功能来构建真实的应用程序,但基元却很少,无法在短时间内学习;了解。它的默认设置也会产生良好的结果,您可以自定义代理运行的每个步骤。

助手 SDK 提供 MongoDBSession,这是一种会话实施,可在MongoDB中保留对话历史记录。将该历史记录存储在MongoDB中可为您的代理带来以下优势:

  • 可水平可扩展的多进程会话存储。会话状态存在于集群中,而不是在单个进程的内存中,因此连接到同一集群的任何工作线程、容器或无服务器函数都可以继续对话。每条消息都带有一个单调递增的 seq计数器,该计数器在并发写入之间保留消息顺序。

  • 用于存储对话和应用程序数据的一个数据库。如果您的应用程序已使用MongoDB ,则您的代理将通过相同的连接和相同的驾驶员读取操作数据并写入会话历史记录,而无需部署和保护单独的内存服务。

  • 适用于代理状态的灵活文档。文档模型将会话轮次、工具调用和结构化输出一起存储,因此您可以扩展记录内容,而无需模式迁移。

  • 可查询代理历史记录。会话历史记录存储在普通集合中,因此您可以对其查询、聚合和索引以Atlas 审核代理行为或构建分析。

  • 检索路径。由于您的代理已连接到MongoDB,因此您可以将MongoDB Vector Search 添加到同一集群,以便对您的数据进行语义检索。要学习;了解更多信息,请参阅 Agentic RAG。

在本教程中,您构建一个多代理旅行助手。分流代理通过调用两个专家助手作为工具来回答问题,这两个专家从存储对话会话的同一集群中读取参考数据。

如要完成本教程,您必须具备以下条件:

  • Python 3.10 或更高版本。

  • 以下MongoDB 集群类型之一:

    • 一个 Atlas 集群,运行 MongoDB 6.0.11、7.0.2 或更高版本。请确保您的 IP 地址包含在 Atlas 项目的访问列表中。

    • 使用Python和Docker创建的本地Atlas部署。安装atlas-local-lib-py pip install atlas-local-lib-py(),以编程方式创建和管理本地部署。要学习;了解更多信息,请参阅 atlas-local-lib-py存储库。

    • 安装了 Search 和 Vector Search 的MongoDB Community集群。

  • 一个 OpenAI API 密钥。您必须拥有一个 OpenAI 帐户,该帐户具有可用于 API 请求的信用额度。要了解有关注册 OpenAI 账号的更多信息,请参阅 OpenAI API 网站

1

本教程使用 uv 来管理环境:

uv venv
source .venv/bin/activate
2

安装带有 mongodb 额外的助手 SDK。用引号括起包名称,这样Shell就不会解释括号:

uv pip install "openai-agents[mongodb]"

额外的安装 pymongo 版本 4.14 或更高版本,其中提供会话和代理工具使用的 AsyncMongoClient 类。

3

应用程序会从 ATLAS_URI 读取您的Atlas连接字符串,而 Agents SDK 会从 OPENAI_API_KEY 读取您的密钥:

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

<connection-string> 占位符值替换为集群的 SRV连接字符串

连接字符串应使用以下格式:

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集合中的第二问题。由于会话将第一个行程存储在MongoDB中,因此助手将“那个行程”解析为在第二个问题中,您无需自己传递历史记录。

您的输出可能会有所不同,因为模型会为每次运行生成新的响应。

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.

应用程序会创建一个 AsyncMongoClient 并在代理和会话之间共享:

  • 专业代理通过其工具功能查询destinationspolicies 集合,因此它们会根据您的数据回答。

  • MongoDBSession 将每个对话回合写入同一数据库中的 agent_sessionsagent_messages 集合。两个集合名称都是可配置的,会话会在首次使用时创建所需的索引。

由于应用程序自行构建客户端,因此客户端生命周期属于应用程序,session.close() 不执行任何操作。要让会话拥有客户端端,请使用 MongoDBSession.from_uri() 创建会话。

要学习;了解有关使用 Agents SDK 协调多个智能体的更多信息,请参阅 OpenAI 文档中的以下页面:

  • 编排多个代理,以便在通过代码编排和通过 LLM 编排之间进行权衡。

  • 切换用于将对话委托给另一个代理,而不是将其作为工具来调用。

  • 用于验证代理输入和输出的防护栏。

  • 完整的MongoDBSession 参考文档。