AI 에이전트가 보고서를 작성할 수 없게 되어, 모델 제어와 쓰기 권한의 경계를 재검토했습니다
요약
멀티 에이전트 시스템에서 보고서 작성 시 공통 제어 메커니즘의 오류가 발생했습니다. 이 문제를 해결하기 위해, 모델 전송 및 파일 쓰기 처리를 개선하고 각 통신마다 입력 예산(input budget)을 조사하도록 아키텍처를 수정했습니다. 이는 외부 호출이라도 내부적으로는 모든 전송 대상 모델에 대한 개별적인 제어를 보장합니다.
핵심 포인트
- Job과 이를 실행하는 Runner 개념으로 시스템 구조화가 이루어짐.
- 모델에게 전달되는 입력의 토큰 양을 관리하는 '입력 예산(input budget)' 조사가 핵심임.
- 공통 제어가 아닌, 실제 전송 대상 모델별로 개별적인 통신 경계 검사를 수행함.
- 업무 모델과 내부 심사 모델 등 모든 통신 과정이 측정 및 판정의 대상이 됨.
멀티 에이전트 시스템을 구축하다 보면, 에이전트의 지시나 역할뿐만 아니라 그것을 구동하는 측면의 메커니즘도 점차 늘어나게 됩니다.
제 환경에서도 입력 자료의 양을 조사하는 처리나 결과물을 저장하는 처리를 공통화하고 있습니다. 그 과정에서 에이전트가 필요한 보고서를 작성하려고 했을 때, 공통 제어에 의해 멈추는 문제가 발생했습니다.
이번 글에서는 이 문제를 분석하여 모델 전송과 파일 쓰기를 다루는 부분을 수정한 내용입니다. 샌드박스(sandbox)를 비활성화하는 것이 아니라, 처리에 필요한 범위를 구체적으로 처리할 수 있도록 했습니다.
제가 만든 시스템에서는 정보 수집이나 Podcast 제작 등을 여러 단계로 나누어 실행하고 있습니다.
이 글에서 하나의 작업을 Job이라 부르고, Job을 시작하여 결과를 받는 공통의 실행 주체를 Runner라고 칭합니다.
에이전트는 결과물 외에도 '주어진 필수 입력을 어떻게 처리했는지'에 대한 이용 보고서(utilization report)를 반환받습니다. Runner는 이 보고서와 결과물을 확인한 후, 공식적인 저장 처리를 진행합니다.
또한, 모델에 전달되는 입력이 너무 커지지 않도록 전송 전에 입력 예산(input budget)을 조사하고 있습니다. 여기서의 예산은 금액이 아니라, 모델에 전달할 입력의 토큰 양과 출력용으로 확보해 둘 여유분을 의미합니다.
이처럼 에이전트 앞뒤에는 업무 자체와는 별개의 제어가 존재합니다. 이번 오류가 바로 그 부분에서 발생했습니다.
2026년 10월 9일 실행 과정에서, 웹 자료를 준비하는 단계가 이용 보고서를 작성하려고 할 때 중단되었습니다. 기록된 오류는 model_changed_budget_required였습니다.
조사 결과, 업무를 담당하는 모델과는 별도로 자동 승인 심사를 수행하는 모델로의 통신이 발생하고 있었습니다. 공통 입력 제어가 이 통신을 '모델이 변경되었다'고 간주하여 거부했던 것입니다.
즉, 외부적으로는 하나의 Job으로 호출하더라도 내부적으로는 다른 역할을 하는 모델과 통신하는 경우가 있었습니다. 그런데 공통 제어는 업무 측에서 예상한 모델과 다른 통신을 제대로 처리하지 못하고 있었습니다.
에이전트에게 지시를 바꿔도 이 전제상의 불일치는 남아있습니다. 수정해야 할 부분은 모델이 보고서의 의미를 이해할 수 있는지 여부가 아니라, 공통 실행 처리였습니다.
수정 후에는 모델 식별자(identifier)가 변경되었다는 이유만으로 중단시키는 것을 멈췄습니다. 대신, 실제로 전송할 때마다 해당 전송 대상 모델에 대한 입력 예산을 조사하도록 했습니다.
예를 들어, 다음과 같은 통신이 있는 경우입니다.
- 업무 모델에게 작업을 요청한다
- 내부 심사 모델에게 확인을 요청한다
- 업무 모델로 돌아와서 작업을 계속한다

그림 1: 내부 심사 모델로의 통신도 실제 전송마다 측정 및 판정
최초의 업무 모델만 조사하고 끝내는 것이 아니라, 각 전송을 검사합니다. 추가로 읽어 들인 자료나 여러 턴에 걸친 통신도 검사 대상에서 제외하지 않습니다.
여기서 다른 모델이라면 무엇이든 보내도 좋다는 취급은 하지 않습니다. 공통 상한선과 모델별 상한선이 있는 경우, 더 작은 값을 사용합니다. 명시된 출력용 예약량(reserved output amount)은 더 큰 값을 채택합니다. 호출 중에 모델별 상한선이 변하지 않도록 처리했습니다.
입력 측정은 토큰 수 추정을 포함하므로, 모델의 내부 처리를 엄격하게 재현한 숫자는 아닙니다. 그 전제 하에 여유분을 두고, 예산을 초과하는 전송은 계속해서 중단시킵니다.
수정한 부분은 '모델명이 같지 않으면 중단한다'는 판정입니다. 입력량 검사나 전송 기록까지 제외한 것은 아닙니다.
또 하나 정리한 것이 이용 보고서를 작성할 권한입니다.
보고서의 경로를 지시문에 적더라도, 그것만으로는 실제로 쓰기가 가능하다고 할 수 없습니다. 특히 작업 디렉터리와는 별개의 임시 영역에 보고처를 두는 경우, 실행 시점의 권한과 충돌할 가능성이 있습니다.
그래서 Runner가 해당 Job 전용의 임시 영역을 실행 측에 전달하도록 했습니다. 여기서는 이 영역을 private staging이라고 부릅니다. 에이전트가 보고서를 놓는 장소와 그 후에 공식적으로 저장하는 장소를 분리했습니다.
추가로 쓰기를 허가하는 범위는 이 Job의 staging 내부만입니다. 다음 장소들은 추가 허가 대상에 포함하지 않습니다.
- 입력 자료나 설정 파일 디렉터리
- 다른 Job 영역이나 유사한 이름의 형제 디렉터리
- Run 관리 기록
- 공식적인 결과물 저장소
- Temp 디렉터리 전체
보고서 경로가 전용 staging 내부에 있는지 확인하고, 절대 경로로 추가 영역만 CLI에 전달합니다. 상대 경로로 모호하게 지정하는 것도 피했습니다.
또한, 일반적인 결과물을 생성하지 않는 Job이라도 이용 보고서만은 필요한 경우가 있습니다. 그러한 Job에도 보고서를 작성할 수 있는 전용 영역을 전달하도록 했습니다.
공식 저장(Formal saving)은 기존과 같이 Runner와 저장 담당 메커니즘이 수행합니다. 에이전트가 공식 저장소까지 광범위하게 쓸 수 있도록 구성하는 것은 변경하지 않았습니다.

그림 2: 추가 쓰기 권한은 Job 전용 staging으로 제한하고, 공식 저장은 Runner 측에서 실행
이는 추가 허가 범위만 한정하는 변경일 뿐입니다. 기존 작업 디렉터리에 대한 모든 권한을 읽기 전용(read-only)으로 변경했다는 의미가 아닙니다. 기존의 workspace-write 기능, 통신 제한, 자동 승인 심사도 유지하고 있습니다.
이번에 수정한 부분은 하나의 Workflow만을 위한 전용 처리가 아닙니다. 고정된 Workflow나 동적인 실행이 사용하는 공통 래퍼(wrapper)입니다. 따라서, 실패한 프로세스가 한 번 통과되었다고 끝내지 않고, 확인 내용을 분리했습니다.
공통 래퍼를 로컬 HTTP 프록시(proxy)에 연결하여, “업무 모델 → 심사 모델 → 업무 모델”의 세 번 통신을 거쳤습니다. 모델별 명시 예산(explicit budget)을 추가하지 않아도 각 전송을 측정할 수 있다는 점과, 여전히 예산 초과 등을 거부한다는 것을 확인했습니다. 이것은 전송 경계를 조사하는 통합 테스트(integration test)입니다.
또 다른 독립적인 테스트에서는, 실제 운영 환경과 동일한 작업 디렉터리와 임시 영역 측의 staging 배치를 사용하여 실 모델을 구동했습니다. 필수 입력 2건에 대한 이용 보고서가 작성되었고, Runner가 2종류의 결과물을 생성하며 스키마(Schema) 검증을 통과하는 지점까지 확인했습니다.
다만, 이 성공 사례에서 관찰된 모델 통신은 업무 모델에 한정됩니다. 심사 모델로 전환되는 과정까지 실 모델을 통해 통과했다는 증거로는 취급하지 않습니다. 모델이 전환되는 경로는 앞서 언급한 통합 테스트에서 별도로 확인했습니다.
새로 실행 가능한 16개의 고정 Workflow에 대해, 격리된 테스트용 정상 경로가 완료되는 것도 확인했습니다. 다만, 취득(取得), GPU, 음성, 공개처 등에 모의(mock)를 사용하고 있습니다. "16종류 전체를 운영 환경에서 구동하여 실제 공개까지 성공했다"는 결과는 아닙니다. 공통 부분 변경으로 인해 다른 경로가 손상되지 않았는지 알아보기 위한 시험입니다.
실 모델 테스트 역시, 짧은 기사 2건과 취득 모의를 사용하고 있습니다. 운영 환경 전체 분량에 대한 재시도, 음성 합성, 실제 공개는 이번 검증에 포함하지 않았습니다.
이번 문제에서는 에이전트에게 "이용 보고서를 반환하는" 작업을 부여했습니다. 한편, 이를 실행하는 측에는 내부 심사 모델로의 통신을 처리할 수 없거나, 필요한 보고처에 쓰기 권한을 전달할 수 없는 경로가 있었습니다.
역할만 정의한다고 해서 그 역할을 실행할 수 있는 상태가 되는 것은 아닙니다. 무엇을 입력으로 받고, 어디에 쓰고, 도중에 어떤 모델과 통신하는지까지, 실행 측의 전제 조건을 갖출 필요가 있었습니다.
마찬가지로 에이전트가 도중에 멈출 때는, 저는 다음 사항들을 나누어 살펴보는 것이 좋다고 생각합니다.
- 모델에 요청한 내용 자체에 문제가 있는지
- 주변의 래퍼(wrapper)가 올바른 처리를 거부하고 있지는 않은지
- 필요한 출력처에 실제 쓰기 권한이 있는지
- 성공한 테스트가 어느 경로까지 확인되었는지
권한을 광범위하게 부여하면, 당장의 쓰기 작업만 통과할 수도 있습니다. 하지만 그렇게 되면 입력 자료나 공식 결과물까지 덮어쓸 수 있는 범위가 넓어져 버립니다.
이번에는, 추가로 필요한 장소를 Job 전용 staging으로 한정하고, 모델 통신은 전송(send)마다 검사하는 형태로 수정했습니다. 이처럼 실행 경계의 전제 조건을 재검토한 것 역시, 멀티 에이전트 메커니즘을 계속 사용하기 위한 개선이었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기