OpenAI Agents SDK 파이썬 판이 2026년 10월 15일에 0.24.0으로 올라왔어요. 눈여겨볼 변경은 두 가지예요. 함수 도구가 예외를 던졌을 때 모델에게 돌려줄 문장을 실행 단위로 한 번에 정할 수 있게 됐고, MCP 도구에 붙은 주석 정보를 훅에서 읽을 수 있게 됐어요. 중단된 실행을 저장해 이어 쓰는 팀은 저장 형식이 바뀐 점도 확인해야 해요.

도구가 터졌을 때 모델이 읽는 문장
지금까지는 함수 도구마다 실패 처리 방법을 따로 달아야 했어요. 이번에 RunConfig.tool_error_formatter 콜백이 새로운 종류의 오류를 받아요. ToolErrorFormatterArgs.kind에 ""tool_exception""이 추가됐고, 원래 예외는 error 필드로 넘어와요. 기존에 있던 ""approval_rejected"", ""tool_not_found""와 같은 콜백에서 분기하면 돼요.
from agents import Runner, RunConfig, ToolErrorFormatterArgs
def format_tool_error(args: ToolErrorFormatterArgs) -> str | None:
if args.kind == ""tool_exception"":
return f""{args.tool_name} 실행에 실패했어요. 입력값을 확인한 뒤 다른 방법을 시도하세요.""
return None
config = RunConfig(tool_error_formatter=format_tool_error)
result = await Runner.run(agent, ""주문 상태를 확인해 줘"", run_config=config)
None을 돌려주면 SDK 기본 문구가 그대로 나가요. 비동기 함수도 쓸 수 있어요.
주의할 점은 error에 민감한 정보가 들어 있을 수 있다는 거예요. 데이터베이스 주소나 내부 경로가 예외 메시지에 섞여 있다면 str(args.error)를 그대로 모델에 보여주면 안 돼요. 소스의 설명도 애플리케이션이 승인한 내용만 돌려주라고 해요. 위 예시처럼 도구 이름과 일반 안내만 담는 편이 안전해요.
적용되는 도구와 안 되는 도구
모든 도구에 이 콜백이 먼저 걸리는 것은 아니에요. 적용 대상은 기본 실패 처리를 쓰는 @function_tool 도구예요. 도구에 failure_error_function을 직접 지정했다면 그쪽이 우선하고, 명시적으로 None을 줬을 때도 마찬가지예요. Agent.as_tool()로 만든 도구와 로컬 MCP 서버 쪽 도구는 기존 정책을 유지해요.
도구가 열 개 붙어 있어도 문구가 모두 같다고 기대하지 마세요. 개별 핸들러를 단 도구는 failure_error_function을 검색해 먼저 세어 보세요.
이미 포매터를 쓰고 있다면 한 가지를 고쳐야 해요. 릴리스 검토 기록은 ""승인 거부가 아니면 도구를 못 찾은 것""처럼 가정한 콜백이 이제 잘못된 문구를 낼 수 있다고 경고해요. 도구가 실제로 예외를 던진 경우에도 ""그런 도구가 없어요""라는 답이 나갈 수 있다는 뜻이에요. kind를 세 가지 모두 명시적으로 분기하거나, 모르는 종류에는 None을 돌려주세요.

MCP 도구의 주석을 훅에서 읽기
MCP 서버는 도구마다 readOnlyHint, destructiveHint 같은 힌트를 줄 수 있어요. 0.24.0에서는 MCP 도구가 FunctionTool로 변환될 때 이 값을 복사해 두고, mcp_annotations 속성으로 읽을 수 있게 했어요. 주석이 없거나 MCP 도구가 아니면 None이에요. 그래서 RunHooks의 on_tool_start에서 별도 조회 없이 감사 로그를 남길 수 있어요.
from agents import RunHooks
class AnnotationAudit(RunHooks):
async def on_tool_start(self, context, agent, tool):
hints = getattr(tool, ""mcp_annotations"", None)
if hints is not None:
print(tool.name, hints.readOnlyHint, hints.destructiveHint)
이 값으로 승인 여부가 바뀌지는 않아요. 구현 기록에도 승인과 실행 동작, 직렬화된 도구 정보는 그대로라고 적혀 있어요. 서버가 보낸 힌트는 안전하다는 증명이 아니라 참고 정보예요. 빠진 힌트는 빠진 채로 오니, 값이 None일 때 읽기 전용으로 볼지 쓰기 작업으로 볼지는 MCP 사양의 기본값을 보고 직접 정해야 해요. 이 값만 믿고 자동 승인하는 규칙은 만들지 않는 편이 좋아요.
저장해 둔 실행을 쓴다면
승인 대기 중에 상태를 저장하는 앱이라면 이 절을 먼저 읽으세요. 새 RunState 스냅숏은 스키마 1.21로 저장돼요. 이전 SDK는 이 형식을 읽지 못하니, 롤백 계획에도 넣어 두세요. 같은 이름을 가진 하위 에이전트를 여러 개 쓰는 구성에서는 예전 스냅숏이 읽히지 않을 수 있다고 릴리스 검토가 안내해요. 해당 작업은 저장할 때 쓰던 SDK 버전으로 끝내고, 새 실행부터는 에이전트 이름을 서로 다르게 짓는 것을 권해요.
대화 기록을 OpenAI Conversations 세션에 쓴다면 쓰기가 최대 20개 항목 단위로 나뉘어 들어가요. 중간 요청에서 실패하면 일부만 저장된 상태가 될 수 있으니, 재시도하기 전에 원격 기록을 확인하세요. 전체 목록을 다시 보내면 앞부분이 중복될 수 있어요.
올리기 전에 해 볼 순서
PyPI에는 0.23.0 파일이 없고 0.22.3 다음이 0.23.1이에요. 0.22.3에서 올리면 0.23.0의 변경도 함께 받아요. 파이썬 3.10 이상이라는 요건은 그대로예요.
개발 환경에서 pip install -U openai-agents로 올린 뒤 두 가지를 돌려 보세요. 실패하는 도구를 일부러 하나 만들어 새 포매터 문구가 모델에 전달되는지 보세요. 그다음 승인 대기 중인 실행을 저장하고 다시 읽는 테스트를 한 번 실행해요. 운영 배포는 그 뒤예요.
참고한 자료
- openai-agents-python v0.24.0 릴리스 노트 https://github.com/openai/openai-agents-python/releases/tag/v0.24.0 (확인일 2026-10-25)
- openai-agents-python v0.23.1 릴리스 노트 https://github.com/openai/openai-agents-python/releases/tag/v0.23.1 (확인일 2026-10-25)
- PR 5326 run-wide tool exception formatting https://github.com/openai/openai-agents-python/pull/5326 (확인일 2026-10-25)
- PR 5356 expose MCP annotations on converted tools https://github.com/openai/openai-agents-python/pull/5356 (확인일 2026-10-25)
- PyPI openai-agents 릴리스 이력 https://pypi.org/project/openai-agents/#history (확인일 2026-10-25)