Completion을 추론하기 전에 AI 코딩 JSONL을 안전하게 파싱하는 방법
요약
AI 코딩 에이전트의 트랜스크립트(JSONL)를 안전하게 파싱하기 위한 방어적 설계 전략을 다룹니다. 스트리밍 리더를 통한 I/O 제한, 프로바이더별 필드 투영, 세션 상태 변화를 고려한 의미론적 검증의 중요성을 설명합니다.
핵심 포인트
- 메모리 보호를 위해 스트리밍 리더와 라인별 I/O 제한 적용 필요
- 불필요한 의존성을 줄이기 위해 프로바이더별 필수 필드만 투영하여 역직렬화
- 이전 completion 마커가 이후 활동에 의해 무효화될 수 있음을 고려한 설계
- API 오류나 속도 제한 등 의미론적으로 유효하지 않은 엔벨로프 거부
JSONL은 과소평가하기 쉽습니다. 한 줄당 하나의 객체라는 점은 짧은 루프로 파싱할 수 있는 형식처럼 들립니다. 하지만 라이브 코딩 에이전트(coding-agent)의 트랜스크립트(transcript)는 그 루프를 안전하지 않게 만드는 사례들을 추가합니다: 불완전한 마지막 추가(append), 비정상적으로 큰 레코드, 중복된 이벤트, 프로바이더(provider)별 특화된 엔벨로프(envelopes), 그리고 이후의 활동으로 인해 무효화된 오래된 completion 마커(completion markers) 등이 그것입니다.
다음은 세션 상태(session state)를 추론하기 전에 우리가 사용하는 방어적 설계입니다.
JSON 파싱 전 I/O 제한
제한이 없는 트랜스크립트를 하나의 문자열로 읽지 마십시오. 스트리밍 리더(streaming reader)와 문서화된 라인 정책(line policy)을 사용하십시오. Agent Island v1.7.1은 현재 각 플랫폼에서 서로 다른 출시된 안전 장치를 사용합니다: macOS Claude 리더는 64 MiB의 백스톱(backstop)을 가지고 있으며, Windows 리더는 파싱하기 전에 1,000,000자를 초과하는 라인을 건너뜁니다.
이것들은 하나의 공유된 제한이 아닙니다. 이는 동일한 목표를 가진 플랫폼별 정책입니다: 하나의 잘못된 형식(malformed)이나 병리적인(pathological) 레코드가 나머지 스캔 작업을 중단시켜서는 안 된다는 것입니다.
상태를 변경할 수 있는 필드만 투영(Project)
광범위한 역직렬화(deserialization)는 관련 없는 페이로드(payload)에 대한 의도치 않은 의존성을 생성합니다. 모니터에는 더 작은 프로바이더 인식 투영(provider-aware projection)이 필요합니다.
Claude의 경우, 유용한 필드에는 type, uuid, timestamp, message.stop_reason, isSidechain, isApiErrorMessage, 그리고 toolEndsTurn이 포함됩니다. Codex의 경우, 출시된 리더들은 type, payload.type, payload.turn_id, role, timestamp, completed_at, 그리고 started_at과 같은 필드들을 검사합니다.
제한된 라인 읽기
-> JSON 파싱
-> 프로바이더별 필드 투영
...
Completion은 후보일 뿐입니다
completion 형태의 이벤트는 하나의 턴(turn)에 속합니다. 이후의 사용자 메시지나 시작(start) 이벤트는 세션이 다음으로 넘어갔음을 의미합니다. 리듀서(reducer)는 의미론적 순서(semantic order)를 비교해야 하며, 이후의 활동이 이전의 completion을 대체할 수 있도록 허용해야 합니다.
이것이 파일 수정 시간만으로는 충분하지 않은 이유이기도 합니다. 하나의 파일에는 여러 턴이 포함될 수 있으며, 가장 최신 이벤트가 이전의 stop 마커와 모순될 수 있습니다.
잘못된 completion 엔벨로프 거부
구문적으로 유효한(syntactically valid) 라인이라도 전방 경고(foreground alert) 관점에서는 의미론적으로 틀릴 수 있습니다.
- Rate-limit(속도 제한) 및 API-error(API 오류) 엔벨로프(envelopes)는 성공적인 completion(완성)이 아닙니다.
- 사이드체인(sidechain) 또는 서브에이전트(subagent)의 종료가 자동으로 메인 스레드(main-thread)의 핸드오프(handoff)를 의미하지는 않습니다.
- 모델의 stop 마커(stop marker) 이후에도 도구(tool) 활동이 계속될 수 있습니다.
일반적인 completion 리듀서(reducer)를 실행하기 전에 제공자별 가드(provider-specific guards)를 실행하십시오.
파일 변경이 새로운 reduction을 트리거하도록 하기
Agent Island는 JSONL 파일의 변경 사항을 감시(watch)하며, 폴백(fallback)으로서 지속적인 폴링(polling)을 유지합니다. 이벤트 기반 관찰(event-driven observation)은 지연을 줄여주며, 폴링은 감시자(watcher) 알림을 놓쳤을 때 이를 복구합니다. 현재 건너뛴 불완전한 라인은 다음 추가(append) 작업 이후에 다시 고려될 수 있습니다.
경로, 크기, 수정 시간을 기준으로 변경되지 않은 파일을 캐싱(caching)하는 것은 유용하지만, 소스가 변경되면 반드시 캐시를 무효화(invalidate)해야 합니다. 캐싱은 최적화 도구일 뿐, 오래된 상태를 고정(freeze)해도 된다는 허가증이 아닙니다.
유지할 가치가 있는 8가지 테스트
- 잘못된 형식의 라인이 이후의 유효한 레코드들을 중단시키지 않는가.
- 불완전한 마지막 라인이 추가(append) 작업 이후에 읽기 가능한 상태가 되는가.
- 크기가 초과된 라인이 문서화된 플랫폼 정책을 따르는가.
- 중복된 이벤트가 두 번째 경고를 생성하지 않는가.
- 이후의 사용자 활동이 이전의 completion을 대체하는가.
- API-error 엔벨로프가 completion 상태가 되지 않는가.
- 사이드체인의 종료가 부모 세션(parent session)에 대해 사용자에게 페이지(page)를 호출하지 않는가.
- 폴링이 놓친 감시자(watcher) 이벤트를 복구하는가.
안전한 JSONL 파싱은 제한된 I/O와 더불어 제공자 인지적 의미론(provider-aware semantics), 순서 지정(ordering), 중복 제거(deduplication), 그리고 새로고침 동작(refresh behavior)의 결합입니다. 전체 구현 노트와 현재 범위는 canonical guide에서 확인할 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기