도구 호출 계약·승인·운영 가시성 3일 변화 | AI Agent Execution Contracts and Controls

도구 호출 계약·승인·운영 가시성 3일 변화 | AI Agent Execution Contracts and Controls

핵심 답변: 2026년 10월 20일~23일(KST) AI/LLM·에이전트 개발 도구의 공통 변화는 모델 호출 자체보다 도구 호출의 계약·승인·비용·중단 상태를 애플리케이션이 명시적으로 다뤄야 한다는 것입니다. OpenAI Python SDK는 실시간 Decisions 입력을 더 구조화된 형태로 넓혔고, LangChain은 스트리밍 도구 인수를 증분 이벤트로 바꿨으며, Vercel AI SDK는 거부된 도구 호출과 중복 승인의 실행 경계를 강화했습니다. 에이전트를 제품이나 CI에 붙인 팀은 이번 주에 스트림 파서, 도구 실행의 멱등성, 승인 로그와 비용 계측을 함께 점검하는 것이 우선입니다.

요약: 이 3일 리포트는 SDK의 작은 버전 변화들을 단순 업데이트 목록이 아니라, 에이전트가 실제 외부 도구를 호출하는 서비스에서 반복적으로 나타나는 세 흐름—구조화된 상호작용, 실행 통제, 운영 가시성—으로 묶어 설명합니다. 아래의 사실은 각 공식 릴리스 노트에 근거하며, 실무 제안은 별도로 구분했습니다.

3일 결론

새 모델을 붙이는 속도보다 중요한 것은 “부분 응답·거부·재시도·승인”을 상태 전이로 관리하는 능력입니다. 실시간 스트림에서 도구 인수가 조각으로 도착할 수 있고, 스트림이 정상 종료 신호 없이 끊길 수 있으며, 승인 메시지가 중복될 수 있습니다. 이 상태들을 단순 텍스트 이벤트로 취급하면 중복 실행, 잘못된 재시도, 누락된 비용 기록으로 이어질 수 있습니다. 반대로 서버 측 도구 프록시와 이벤트 로그를 상태 기계로 설계하면 공급자·프레임워크가 바뀌어도 실행 경계를 유지할 수 있습니다.

72시간 동안 확인된 6개 신호

  • OpenAI Python 3.36.0: Responses API의 Vertex AI 지원, 30분 cache-write 사용량, compaction trigger ID가 추가됐습니다.
  • OpenAI Python 3.37.0: Live response의 Decisions 질문 instructions가 문자열 또는 구조화된 text/image/JSON 파트가 될 수 있어 타입 처리 변경이 필요합니다.
  • Anthropic Python 2.0.0: 2026-10-21 API 버전 지원과 workspace 기반 지출 한도 조회 범위가 추가됐습니다.
  • Anthropic Python 2.1.0: 사용자 프로필의 enforcement status·actions·filter가 추가됐습니다.
  • LangChain Core 1.7.0: 스트리밍 도구 인수가 누적 스냅샷이 아니라 tool-call-delta 조각으로 전달됩니다.
  • Vercel AI SDK 7.0.149: 하나의 도구 호출에서 첫 승인 응답만 처리하고, toolChoice: 'none'일 때 로컬 실행 전에 호출을 거부하도록 보강했습니다. 또한 불완전한 스트림을 위한 interrupted 종료 사유가 추가됐습니다.

흐름 1: 도구 호출은 이제 ‘완성된 JSON 한 번’이라는 가정에서 벗어납니다

사실: 입력과 스트림 이벤트가 더 세분화되고 있습니다

OpenAI Python 3.37.0은 Live response 모델에서 Decisions 질문의 instructions가 문자열뿐 아니라 구조화된 텍스트·이미지·JSON 파트가 될 수 있다고 명시했습니다. 기존 코드가 문자열 메서드를 무조건 호출하거나, 입력 메시지 역할과 tool-history 항목을 열거형으로 완전 처리한다고 가정했다면 이번 마이너 릴리스에서 깨질 수 있습니다.

LangChain Core 1.7.0도 같은 방향을 보여줍니다. raw stream에서 도구 인수는 지금까지의 전체 스냅샷이 아니라 새로 들어온 조각인 tool-call-delta로 나옵니다. 공식 노트는 기존 스냅샷이 필요하면 langchain-core<1.7을 고정하라고 안내합니다. 이는 단순 명명 변경이 아니라, UI·감사 로그·도구 실행기에서 ‘언제 인수가 완성되었는가’를 다시 정의해야 하는 계약 변경입니다.

실무 시사점: 스트림 파서와 실행기를 분리합니다

프론트엔드에서 보이는 부분 인수와 서버에서 실행 가능한 정규화 인수를 같은 객체로 쓰지 마십시오. 스트림 소비자는 델타를 요청별 버퍼에 합치고, 서버의 검증 단계는 JSON 스키마·도구 allowlist·조직 권한을 모두 통과한 완결 이벤트만 실행 큐로 넘겨야 합니다. 실행이 시작된 뒤 들어오는 늦은 델타는 표시용 로그로만 남기거나 폐기하는 규칙이 필요합니다.

  • 각 toolCallId에 collecting → validated → approved → executing → completed/failed/cancelled 상태를 둡니다.
  • 부분 인수는 절대 외부 API·셸·배포 훅으로 전달하지 않습니다.
  • SDK 업그레이드 테스트에는 문자열·멀티파트 instructions와 분할된 tool argument 스트림을 모두 넣습니다.

흐름 2: 승인·거부·중단은 UX가 아니라 서버 측 실행 정책입니다

사실: 도구 실행의 ‘한 번만’과 ‘실행하지 않음’이 라이브러리 수준에서 강화됐습니다

Vercel AI SDK 7.0.149는 한 도구 호출에 대해 반복되거나 충돌하는 승인 응답이 들어와도 첫 번째 응답만 처리하도록 바꿨습니다. 또한 toolChoice: 'none'를 전달하고, 거부된 도구 호출을 generateText·streamText·WorkflowAgent의 로컬 실행 전에 차단합니다. 같은 릴리스는 완료 신호 없이 끝나는 provider stream에 interrupted 종료 사유를 더하고, 이런 경우 자동 도구 실행·agent continuation·자동 UI 후속 처리를 멈추도록 했습니다.

이 변경은 라이브러리 하나의 버그 수정에 그치지 않습니다. 도구 호출이 브라우저 승인, 백엔드 큐, 외부 SaaS 웹훅을 가로지를 때 중복 승인과 연결 단절은 흔한 분산 시스템 문제입니다. “사용자가 승인 버튼을 한 번 눌렀다”는 사실만으로 실행의 유일성을 보장할 수 없습니다.

실무 시사점: 승인 키와 멱등 키를 분리합니다

승인 토큰은 사람의 의사를 증명하고, 멱등 키는 동일 작업의 중복 실행을 막는 용도입니다. 두 역할을 같은 값에 기대지 말고 approval_id, tool_call_id, idempotency_key, 정책 판정 결과를 별도 컬럼으로 기록하십시오. interrupted 상태에서는 ‘계속 실행’ 대신 도구 실행을 보류하고, 사용자가 새 승인으로 재개하도록 설계하는 편이 안전합니다.

  • 쓰기 작업에는 서버가 발급한 멱등 키를 외부 API까지 전달합니다.
  • 승인 API는 같은 approval_id의 두 번째 요청을 성공 처리하되 재실행하지 않게 만듭니다.
  • 스트림 종료 사유가 성공 이외이면 후속 도구 호출을 기본 거부하고, 재개 경로를 명시합니다.

흐름 3: 에이전트 운영은 모델 비용·컨텍스트·조직 정책을 함께 계측하는 단계로 이동합니다

사실: 사용량·컨텍스트 수명·조직 단위 통제가 SDK 표면으로 올라왔습니다

OpenAI Python 3.36.0은 Responses API의 Vertex AI 지원과 함께 30분 단위 cache-write 사용량, compaction trigger ID를 추가했습니다. 이는 여러 모델 경로를 쓰는 팀이 비용과 컨텍스트 압축의 흔적을 요청 단위로 연결할 수 있는 신호입니다. 다만 릴리스 노트가 자동 비용 최적화를 보장하는 것은 아니므로, 실제 비용 절감 효과는 각 팀의 트래픽과 프롬프트 구조에서 측정해야 합니다.

Anthropic Python 2.0.0은 새 API 버전과 workspace 기반 지출 한도 조회 범위를 추가했고, 이어진 2.1.0은 사용자 프로필의 enforcement status·actions·filter를 추가했습니다. 두 버전만으로 특정 조직 통제 정책의 전체 동작을 단정할 수는 없지만, AI 기능을 공용 API 키 한 개로 운영하기보다 워크스페이스·사용자·정책 이벤트 기준으로 관찰하는 방향이 강화되고 있다는 근거입니다.

실무 시사점: 모델 로그와 도구 로그를 하나의 추적 ID로 묶습니다

토큰만 기록하면 “왜 비용이 늘었는지” 알기 어렵고, 도구 실행만 기록하면 “어떤 컨텍스트가 이 행동을 유발했는지” 추적하기 어렵습니다. 요청 시작 시 발급한 trace ID를 모델 호출, cache-write/compaction 메타데이터, tool call, 승인, 외부 API 결과에 공통으로 넣으십시오. 그 위에서 조직별 월 예산뿐 아니라 작업별 최대 도구 호출 수·재시도 횟수·컨텍스트 크기 상한을 둬야 합니다.

개발자 액션: 이번 주에 할 5가지

  1. 스트림 회귀 테스트: tool argument가 세 조각 이상으로 오고 중간에 연결이 끊기는 fixture를 추가합니다. UI가 부분 인수를 보여도 실행기가 호출되지 않는지 확인합니다.
  2. 상태 전이 표준화: provider별 finish reason을 내부의 completed, interrupted, failed, cancelled로 매핑하고, 새 값이 와도 조용히 성공 처리하지 않게 합니다.
  3. 중복 실행 방지: 승인·재시도·웹훅 재전송 각각에 대한 멱등 테스트를 CI에 넣고, 실제 쓰기 도구에 키를 전달합니다.
  4. 비용/컨텍스트 대시보드: trace ID별 모델, 토큰, cache-write, compaction, tool 수, 재시도 수, 최종 상태를 한 행으로 조회할 수 있게 만듭니다.
  5. 의존성 업그레이드 검토: OpenAI Python 3.37.0과 LangChain Core 1.7.0은 타입·스트림 계약 영향이 있으므로 lockfile만 올리지 말고 staging에서 consumer 테스트를 통과시킨 뒤 배포합니다.

체크리스트

  • 부분 tool argument가 도착해도 외부 쓰기 도구는 실행되지 않는가?
  • 동일 승인 또는 웹훅이 두 번 와도 한 번만 실행되는가?
  • interrupted·timeout·cancel 상태에서 자동 후속 실행이 멈추는가?
  • 모델·컨텍스트·도구·승인·비용이 하나의 trace ID로 연결되는가?
  • 새 SDK 타입과 종료 사유를 exhaustive switch 또는 스키마 검증에서 누락 없이 처리하는가?

FAQ

LangChain 1.7로 바로 올리면 모든 도구 호출이 깨지나요?

아닙니다. 공식 노트상 .tool_calls.get()과 .output은 유지됩니다. 다만 raw stream의 block-delta에서 누적 인수를 읽던 소비자는 tool-call-delta 처리로 바꾸거나 호환 버전을 고정해야 합니다. 업그레이드 전 실제 스트림 소비 지점을 검색해 확인하십시오.

도구 승인 UI가 있으니 중복 실행 방지는 필요 없나요?

필요합니다. 네트워크 재전송, 탭 중복, 워커 재시도, 웹훅 중복은 UI 밖에서 생깁니다. 서버와 외부 API에 멱등 키를 적용해야 합니다.

새 사용량 필드가 생겼으니 비용 최적화가 자동으로 되나요?

아닙니다. 사용량·cache-write·compaction 정보를 자체 trace와 연결하고, 작업별 예산 및 재시도 상한을 정책으로 강제할 때 운영 효과가 생깁니다.

출처

더 깊게 읽기: 실전 가이드

이 리포트는 최근 흐름을 빠르게 파악하기 위한 요약입니다. 실제 프로젝트에 적용할 때는 아래의 기준 글과 함께 확인하면 더 안전합니다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다