AI 에이전트의 경우: 문서 인덱스는 https://www.mongodb.com/ko-kr/docs/llms.txt에서 사용할 수 있으며, 모든 페이지의 마크다운 버전은 어떤 URL 경로에 .md를 추가하여 사용할 수 있습니다.
Docs Menu

MongoDB를 OpenAI 에이전트 SDK와 통합하기

OpenAI Agents SDK로 빌드 에이전트의 백업 데이터베이스 로 MongoDB 사용할 수 있습니다. Agents SDK는 다음과 같은 작은 기본 설정하다 로 에이전트 애플리케이션을 빌드하기 위한 Python 프레임워크 입니다.

  • 에이전트, 즉 명령과 도구로 구성된 대규모 언어 모델(LLM)

  • 핸드오프, 한 에이전트가 다른 에이전트에게 작업을 위임할 수 있도록 하는 기능입니다.

  • 가드레일, 에이전트의 입력과 출력을 검증합니다.

  • 세션: 에이전트 실행 전체에 걸쳐 대화 기록을 저장합니다.

SDK는 두 가지 디자인 원칙을 따릅니다. 실제 애플리케이션을 빌드할 수 있는 충분한 기능이 포함되어 있지만, 짧은 시간 내에 학습할 수 있을 만큼 기본 요소가 적습니다. 에이전트의 기본값은 또한 좋은 결과를 생성하며, 에이전트 실행의 모든 단계를 사용자 지정할 수 있습니다.

에이전트 SDK는 MongoDB에서 대화 기록을 유지하는 세션 구현인 MongoDBSession을 제공합니다. MongoDB에 해당 기록을 저장하면 에이전트에게 다음과 같은 장점을 제공합니다.

  • 수평적으로 확장 가능한 다중 프로세스 세션 저장. 세션 상태는 단일 프로세스의 메모리에 있지 않고 클러스터에 저장됩니다. 그러므로 동일한 클러스터에 연결하는 모든 워커, 컨테이너 또는 서버리스 함수는 대화를 계속할 수 있습니다. 각 메시지는 단조 증가하는 seq 카운터를 포함하고 있으며, 이는 동시 작성자 간에서 메시지 순서를 유지합니다.

  • 대화와 애플리케이션 데이터를 위한 단일 데이터베이스. 애플리케이션이 이미 MongoDB를 사용하고 있다면, 에이전트는 배포하고 보안할 필요가 없는 별도의 메모리 서비스 없이 동일한 연결과 동일한 드라이버를 통해 운영 데이터를 읽고 세션 기록을 쓰기 (write) 됩니다.

  • 에이전트 상태를 위한 유연한 문서. document model은 대화 턴, 도구 호출 및 구조화된 출력을 진화하면서 함께 저장합니다. 따라서 스키마 마이그레이션 없이 기록하는 내용을 확장할 수 있습니다.

  • 쿼리 가능한 에이전트 내역. 세션 기록은 일반 컬렉션에 저장되므로 쿼리, 집계 및 인덱싱하여 에이전트 동작을 감사하거나 분석을 빌드할 수 있습니다.

  • A path to retrieval. Because your agents already connect to MongoDB, you can add MongoDB Vector Search to the same cluster to give them semantic retrieval over your data. To learn more, see Agentic RAG.

이 튜토리얼에서 다중 에이전트 기반 여행 도우미를 빌드합니다. 트리아지 에이전트는 도구로 두 명의 전문 에이전트를 호출하여 질문에 답변합니다. 두 전문가 모두 대화 세션을 저장하는 동일한 클러스터에서 참조 데이터를 읽습니다.

이 튜토리얼을 완료하려면 다음 조건을 충족해야 합니다.

  • Python 3.10 이상.

  • 다음 MongoDB cluster 유형 중 하나입니다.

  • OpenAI API 키입니다. API 요청에 사용할 수 있는 크레딧이 있는 OpenAI 계정이 있어야 합니다. 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 연결 문자열을 읽습니다. 그리고 에이전트 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에 첫 번째 턴을 저장하기 때문에, 어시스턴트는 두 번째 질문에서 "그 여행"을 사용자가 기록을 직접 전달하지 않아도 해결합니다.

애플리케이션은 하나의 AsyncMongoClient을(를) 생성하고 에이전트와 세션 간에 공유합니다.

  • 전문 에이전트는 자신의 도구 기능에서 destinations 및 policies 컬렉션을 쿼리하여 사용자의 데이터에서 답변합니다.

  • MongoDBSession 각 대화 턴을 동일한 데이터베이스의 agent_sessions 및 agent_messages 컬렉션에 쓰기 (write)합니다. 두 컬렉션 이름 모두 설정 가능합니다. 그리고 세션은 첫 사용 시 필요한 인덱스를 생성합니다.

애플리케이션이 클라이언트를 직접 생성하므로 클라이언트 수명 주기는 애플리케이션에 속하며 session.close()은(는) 아무것도 하지 않습니다. 대신 세션이 클라이언트를 소유하도록 하려면 MongoDBSession.from_uri()로 만들어야 합니다.

Agents SDK를 사용하여 여러 에이전트를 조정하는 방법에 대해 자세히 알아보려면 OpenAI 설명서의 다음 페이지를 참조하세요.