OpenEnv 실전: 실제 환경에서 도구 사용 에이전트 평가
Source: Hugging Face Blog
목차
AI 에이전트는 통제된 연구 환경에서는 인상적인 성과를 보이지만, 실제 시스템에 배치될 때는 여러 단계에 걸친 추론, 실제 도구 및 API와의 상호작용, 부분적인 정보 하에서의 작동, 그리고 상태가 유지되는 권한이 부여된 환경에서 오류 복구 등을 수행해야 하므로 어려움을 겪습니다. 이는 연구 성공과 프로덕션 신뢰성 사이에 지속적인 격차가 존재함을 보여줍니다.
OpenEnv는 Meta와 Hugging Face가 공동으로 만든 오픈소스 프레임워크로, 에이전트가 실제 환경과 상호작용하는 방식을 표준화하여 이 문제를 해결하고자 합니다. 이번 협업의 일환으로 Turing은 접근 제어, 시간 추론, 다중 에이전트 협업과 같은 현실적인 제약 조건 하에서 도구를 사용하는 에이전트를 연구하기 위해 프로덕션 수준의 캘린더 관리 환경(README)을 제공했습니다.
이 글에서는 OpenEnv가 실제로 어떻게 작동하는지, 캘린더가 왜 현실 세계 에이전트 평가에 강력한 벤치마크가 되는지, 그리고 우리의 연구 결과가 도구를 사용하는 에이전트의 현재 한계에 대해 무엇을 보여주는지를 살펴봅니다.
OpenEnv란?
OpenEnv는 시뮬레이션이 아닌 실제 시스템에 대해 AI 에이전트를 평가하기 위한 프레임워크입니다. 실제 도구와 워크플로에 에이전트를 연결하는 표준화된 방식을 제공하면서, 일관되고 신뢰할 수 있는 평가에 필요한 구조를 유지합니다.
- OpenEnv는 OpenAI의 Gymnasium과 유사한 gym‑지향 API(
reset,step,action,observations)를 사용합니다. - 환경에 연결하기 위해 표준 MCP 툴‑콜 인터페이스를 채택하여, 도메인 간 및 시뮬레이션과 프로덕션 환경 간에 일관된 인터페이스를 제공합니다.
- 환경은 여러 행동에 걸쳐 상태를 유지합니다—이를 통해 장기적인 추론이 가능하며, 브라우저, 코드 저장소, 캘린더 등 실제 API와 도구에 직접 연결할 수 있습니다.
이것은 평가 방식을 *“제어된 데모에서 작동할 수 있나요?”*에서 *“실제 세계에서 신뢰성 있게 작동할 수 있나요?”*로 전환시킵니다.
Source:
Calendar Gym: 프로덕션 수준 벤치마크
캘린더 시스템은 겉보기와 달리 매우 복잡합니다. 회의를 잡는 일은 간단해 보이지만, 실제 캘린더 관리에서는 에이전트가 시간, 권한, 다수 사용자, 불완전한 정보 등을 고려해야 하며—종종 여러 단계에 걸쳐 의존 관계가 존재합니다. 이러한 특성 때문에 캘린더는 제어된 시뮬레이션 밖에서 툴을 사용하는 에이전트를 평가하기 위한 강력한 테스트베드가 됩니다.
OpenEnv를 현실적이고 까다로운 사용 사례에 적용하기 위해, Turing은 Calendar Gym이라는 프로덕션 수준 캘린더 관리 환경을 구축했습니다. 추상적인 일정 시뮬레이션을 하는 대신, 실제 캘린더 시스템에서 마주하게 될 제약들을 에이전트에게 그대로 제공합니다:
- 사용자와 캘린더 전반에 걸친 액세스 제어 목록(ACL).
- 다른 사용자의 상태에 대한 제한된 가시성.
- 올바른 순서로 연결되어야 하는 다단계 워크플로.
에이전트는 캘린더 목록 조회, 이벤트 및 권한 수정 등 다양한 캘린더 작업을 수행해야 하며, 실패한 액션, 잘못된 가정, 권한 부족 상황을 처리해야 합니다. 각 세션은 격리된 환경에서 실행되어 실행 간 신뢰할 수 있는 비교가 가능합니다.
아래는 Calendar Gym을 사용하는 최소 코드 예시입니다. 스크립트는 환경을 초기화하고, 사용 가능한 도구를 탐색하며, 캘린더를 목록화하고, 이벤트를 생성한 뒤 결과를 출력합니다.
from openenv_wrapper.client import MCPEnvClient
from openenv_wrapper.data_models import MCPAction
with MCPEnvClient.from_hub(base_url="TuringEnterprises/calendar-gym") as client:
# Connect and reset the environment
result = client.reset()
print("Reset successful:", result.observation.success)
# Discover available tools
result = client.step(MCPAction(action_type="ListToolsAction"))
print("Available tools:", len(result.observation.tools_list))
# List calendars
result = client.step(MCPAction(
action_type="ToolCallAction",
tool_name="calendars_list",
arguments={}
))
calendars = result.observation.tool_result["items"]
print("Calendars:", calendars)
# Create an event
result = client.step(MCPAction(
action_type="ToolCallAction",
tool_name="events_insert",
arguments={
"calendarId": "primary",
"summary": "Team Sync",
"start": {"dateTime": "2026-01-15T14:00:00Z"},
"end": {"dateTime": "2026-01-15T15:00:00Z"}
}
))
print("Event created:", result.observation.success)
아래는 ListToolsAction을 호출했을 때 Calendar Gym이 반환하는 결과의 일부(간략히 표시)입니다:
{
"observation": {
"success": true,
"tools_list": [
{"name": "calendars_list", "description": "List calendars visible to the user"},
{"name": "events_insert", "description": "Create a new event"},
{"name": "events_update", "description": "Update an existing event"},
{"name": "events_delete", "description": "Delete an event"},
{"name": "acl_get", "description": "Retrieve ACL for a calendar"},
{"name": "acl_insert", "description": "Add a new ACL entry"},
{"name": "acl_delete", "description": "Remove an ACL entry"}
]
}
}
우리가 배운 것
(내용 추가 예정 – 이 섹션에서는 다양한 에이전트를 Calendar Gym에 적용한 실험 결과를 논의하며, 강점, 실패 모드 및 개선 영역을 강조합니다.)
앞으로의 전망
(추가될 내용 – 이 섹션에서는 OpenEnv의 향후 방향, 잠재적인 새로운 환경, 그리고 연구 기회에 대해 개요를 제시할 예정입니다.)
부록: 도구 사용 시 일반적인 오류 사례
실제 환경에서 발견된 구체적인 오류 사례
(내용 추가 예정 – 에이전트가 도구와 상호작용할 때 관찰된 실제 오류 패턴을 정리한 목록이며, 완화 방안을 제시합니다.)
{
"tools_list": [
{
"name": "calendars_list",
"description": "List calendars visible to the current user.",
"input_schema": {
"type": "object",
"properties": {},
"additionalProperties": false
}
},
{
"name": "events_insert",
"description": "Create an event in a calendar.",
"input_schema": {
"type": "object",
"properties": {
"calendarId": { "type": "string" },
"summary": { "type": "string" },
"start": {
"type": "object",
"properties": { "dateTime": { "type": "string" } },
"required": ["dateTime"]
},
"end": {
"type": "object",
"properties": { "dateTime": { "type": "string" } },
"required": ["dateTime"]
}
},
"required": ["calendarId", "summary", "start", "end"]
}
}
]
}
우리가 배운 점
-
다단계 추론이 주요 병목 현상입니다.
에이전트는 더 긴 워크플로우에서 행동을 올바르게 연결하는 데 어려움을 겪으며, 벤치마크는 단일 도구 호출이 아니라 여러 종속 단계에 걸친 지속적인 추론을 테스트해야 함을 시사합니다. -
모호성이 성능을 크게 저하시킵니다.
에이전트는 명시적인 캘린더 식별자가 있는 작업에서 **90 %**에 가까운 성공률을 달성했지만, 동일한 작업을 자연어 설명으로 표현했을 때 성공률은 대략 **40 %**로 떨어졌습니다. 에이전트 루프에 더 강력한 조회 및 검증을 구축하는 것이—LLM이 참조를 스스로 해결하도록 의존하는 대신—필수적인 것으로 보입니다. -
올바른 도구 선택만으로는 충분하지 않습니다.
실패한 상호작용을 살펴보면, 오류의 절반 이상이 올바른 도구를 선택했음에도 불구하고 잘못된 도구 인수나 순서 오류에서 비롯되었습니다. 신뢰할 수 있는 에이전트 행동은 도구 선택만큼 실행 품질과 구조화된 피드백에 의존하며, 환경 설계가 중요합니다.
이러한 과제는 일정 및 캘린더에만 국한되지 않습니다. 에이전트가 장기간에 걸쳐 변화하는 시스템에서 작동할 때 나타나는 보다 넓은 제한을 반영하며, 권한, 부분 관찰 가능성 및 다단계 워크플로우를 함께 테스트하는 평가 프레임워크가 필요함을 시사합니다.
앞으로
OpenEnv는 현실적인 조건에서 에이전트를 테스트하기 위한 기반을 제공하고, Calendar Gym은 겉보기에 단순한 도메인이 어떻게 추론, 모호성 해결, 도구 사용에 대한 깊은 과제를 드러낼 수 있는지를 보여줍니다. 실패가 측정 가능하고 제약이 실제인 상황에서 에이전트를 평가함으로써, 생산 환경에서 신뢰성 있게 작동하는 에이전트를 구축하기 위해 필요한 것이 무엇인지에 대한 보다 명확한 통찰을 얻을 수 있습니다.
Calendar Gym의 설계, 벤치마킹 방법론 및 정량적 결과에 대해 더 깊이 살펴보려면, Turing의 site에 있는 전체 기술 기사를 확인하세요. Calendar Gym의 클론을 탐색하려면, Calendar Gym space를 방문하세요.
Source: …
부록: 도구 사용 시 흔히 발생하는 오류 사례
실제로 도구 통합은 극적인 방식으로 실패하기보다는 작고 예측 가능한 방식으로 실패합니다. MCP 도구를 실제 API(예: 캘린더 작업)에 연결할 때 몇 가지 반복되는 문제를 발견했습니다.
실제 환경에서 발견된 구체적인 오류 사례
아래는 운영 중에 자주 나타난 세 가지 실패 유형과 대표적인 오류 페이로드, 완화 전략을 정리한 것입니다. 이 예시들은 무엇이 잘못될 수 있는지뿐 아니라 구조화된 오류가 에이전트가 우아하게 복구하도록 어떻게 도움이 되는지를 보여줍니다.
-
스키마 검증 오류 (누락되었거나 형식이 잘못된 인수)
에이전트가 유효한 도구(예:
events_insert)를 호출했지만, 인수가 선언된 JSON 스키마와 일치하지 않습니다.calendarId와 같은 필수 필드 누락start/end의 잘못된 중첩- 객체가 기대되는 곳에 문자열 전달
예시 오류 페이로드
{ "ok": false, "error_type": "validation_error", "tool_name": "events_insert", "message": "Invalid arguments for tool 'events_insert'.", "details": { "missing_required_fields": ["calendarId", "end"], "invalid_fields": [ { "field": "start", "expected_type": "object", "received_type": "string" } ] } }완화: 프롬프트에 올바른
events_insert호출의 정형 예시를 제공하십시오. 모델이 조용히 실패하지 않고 복구·재시도할 수 있도록 구조화된 검증 오류를 반환합니다. -
권한 / 인증 오류 (401/403)
도구 호출 자체는 구문적으로 올바르지만, API가 권한 부족으로 거부합니다.
- OAuth 스코프 누락
- 액세스 토큰 만료
- 사용자가 대상 캘린더에 대한 쓰기 권한이 없음
예시 오류 페이로드
{ "ok": false, "error_type": "permission_error", "tool_name": "events_insert", "http_status": 403, "message": "The authenticated user does not have write access to calendar 'primary'.", "remediation": [ "Ensure the OAuth token includes calendar write scope.", "Verify the user has edit access to the target calendar.", "Reconnect the integration if the token has expired." ] }완화: 필요한 OAuth 스코프를 명확히 문서화하십시오. 구조화된 실행 가능한 조치 항목을 반환해 에이전트가 사용자를 안내하도록 하고, 동일한 실패 호출을 반복하지 않게 합니다.
-
날짜·시간 관련 오류 (RFC3339 및 타임존 문제)
이벤트가 API에 의해 거부되거나, 예상과 다른 시간에 생성됩니다.
흔히 발생하는 문제
- 타임존 오프셋 누락
- RFC3339가 아닌 날짜·시간 형식
start.dateTime또는end.dateTime의 잘못된 중첩- 오프셋을 지정하지 않은 로컬 시간과 UTC 혼용
예시 오류 페이로드
{ "ok": false, "error_type": "format_error", "tool_name": "events_insert", "message": "Invalid datetime format for field 'start.dateTime'.", "details": { "received": "02/11/2026 9:30 AM", "expected_format": "RFC3339 (e.g. 2026-02-11T09:30:00-05:00)" } }완화: RFC3339 형식에 명시적 타임존 오프셋을 반드시 포함하도록 표준화하십시오(예:
2026-02-11T09:30:00-05:00). 문서에 최소 하나의 올바른 날짜·시간 예시를 포함해 모델 동작을 고정하고, 복구 재시도를 줄입니다.
