
당신의 코딩 에이전트가 완료했다고 말합니다. 누가 그것을 검증했나요?
요약
코딩 에이전트가 작업 완료를 보고할 때 발생하는 신뢰성 문제를 다룹니다. 에이전트가 스스로를 검증하는 한계를 지적하며, 독립적인 검증 게이트를 통해 신뢰 경계를 구축해야 함을 강조합니다.
핵심 포인트
- 에이전트의 자연어 응답은 작업 완료의 객관적 증거가 될 수 없음
- 프롬프팅만으로는 에이전트의 검증 오류를 완전히 해결하기 어려움
- CI 시스템처럼 독립적인 권위자를 통한 검증 프로세스가 필수적임
- VichuFlow 아키텍처를 통해 작업자와 검증자를 분리하는 구조 제안
코딩 에이전트와의 익숙한 상호작용은 다음과 같습니다:
"기능을 구현했고, 테스트를 업데이트했으며, 모든 것이 통과되었습니다."
안심이 되는 말입니다.
하지만 _모든 것이 통과되었다_는 것은 정확히 무엇을 의미할까요?
- 에이전트가 실제로 테스트를 실행했나요?
- 올바른 명령어를 사용했나요?
- 전체 테스트 스위트 (test suite)를 실행했나요, 아니면 편리한 테스트 하나만 실행했나요?
- 린팅 (linting)과 타입 체크 (type checking)도 실행되었나요?
- 검증 명령어가 워크스페이스 (workspace)를 수정했나요?
- 에이전트가 작업 도중 충돌(crash)이 발생하면 어떻게 되나요?
- 작업이 실제로 완료되었다고 결정하는 사람은 누구인가요?
코드를 작성한 에이전트가 코드가 올바른지 보고하는 에이전트인 경우가 많습니다.
다시 말해, 작업자가 자신의 작업에 점수를 매기고 있는 것입니다.
이것이 제가 VichuFlow를 구축하면서 고민해 온 아키텍처적 문제입니다.
에이전트는 훌륭한 작업자이지만, 신뢰할 수 없는 권위자입니다
현대의 코딩 에이전트는 저장소 (repositories)를 탐색하고, 기능을 구현하며, 코드를 리팩터링 (refactor)하고, 테스트를 작성하며, 변경 사항을 검토할 수 있습니다.
그들은 놀라울 정도로 유능한 작업자가 되어가고 있습니다.
하지만, 그들의 자연어 (natural-language) 응답은 작업이 완료되었다는 신뢰할 수 있는 증거가 아닙니다.
이것이 에이전트가 의도적으로 거짓말을 한다는 것을 반드시 의미하지는 않습니다. 다음과 같은 상황이 발생할 수 있습니다:
- 테스트 출력을 잘못 읽음.
- 불완전한 검증 명령어를 사용함.
- 이전 단계의 컨텍스트 (context)를 놓침.
- 명령어가 성공했다고 가정함.
- 그럴듯해 보이는 결과에 도달한 후 중단함.
- 모든 필수 체크가 끝나기 전에 성공을 보고함.
프롬프팅 (Prompting)을 통해 이러한 실패를 줄일 수 있지만, 프롬프팅만으로는 신뢰할 수 있는 신뢰 경계 (trust boundary)를 만들 수 없습니다.
"항상 테스트를 실행하라"는 프롬프트는 우리가 검증하려는 바로 그 시스템에 의해 해석되는 명령일 뿐입니다.
검증자 (verifier)는 별도의 권위자여야 합니다.
"완료"는 무엇을 의미해야 하는가?
소프트웨어 작업의 경우, 완료는 관찰 가능한 증거를 기반으로 해야 합니다.
흐름은 다음과 같습니다:

필수 게이트 (gate)가 실패한다면, 에이전트가 마지막 메시지에서 무엇이라고 말하든 상관없이 워크플로 (workflow)는 진행되어서는 안 됩니다.
이는 CI (지속적 통합)와 유사합니다.
풀 리퀘스트 (pull request) 작성자가 CI를 통과했다고 선언할 수 없는 것과 같습니다. CI 시스템이 독립적으로 체크를 실행하고 결과를 기록합니다.
저는 코딩 에이전트 워크플로 (coding-agent workflows)에도 동일한 책임의 분리 (separation of responsibilities)가 필요하다고 믿습니다.
런타임 (runtime)이 워크플로를 소유해야 한다
이러한 생각은 몇 가지 설계 원칙으로 이어졌습니다.
1. 상태 (State)는 에이전트 대화 외부에 존재해야 한다
에이전트 대화는 유용한 인터페이스이지만, 워크플로 데이터베이스 (workflow databases)로서는 부적합합니다.
장시간 실행되는 작업은 다음과 같은 상황에서도 유지되는 내구성이 있는 상태 (durable state)를 가져야 합니다:
- 컨텍스트 윈도우 (Context-window)의 변화
- 터미널 (Terminal) 재시작
- 에이전트 충돌 (Agent crashes)
- 머신 (Machine) 재부팅
- 중단된 작업
현재 단계, 이전 시도, 검증 결과, 그리고 변이 기록 (mutation records)은 대화와 독립적으로 존재해야 합니다.
2. 단계 전환 (Stage transitions)에는 증거가 필요하다
에이전트가 "구현 완료"라고 말한다고 해서 워크플로가 자동으로 검증 (verification) 단계로 넘어가서는 안 됩니다.
전환 시에는 워크플로에 의해 정의된 증거가 필요해야 합니다:
- 기록된 아티팩트 (artifact)
- 변이 보고서 (mutation report)
- 구조화된 리뷰 판결 (structured review verdict)
- 성공적인 테스트 (test), 린트 (lint), 또는 타입 체크 (typecheck) 명령
그 증거가 충분한지 결정하는 것은 에이전트가 아니라 상태 머신 (state machine)입니다.
3. 검증 명령은 런타임에 속한다
워크플로에서 다음과 같은 명령을 요구한다면:
go test ./...
런타임이 직접 해당 명령을 실행하고 종료 코드 (exit code)와 출력을 캡처해야 합니다.
에이전트는 명령을 추천할 수는 있지만, 해당 명령이 통과되었는지에 대한 최종 권한을 가져서는 안 됩니다.
4. 예산 (Budgets)은 외부에서 강제되어야 한다
자율 루프 (Autonomous loops)는 예상보다 훨씬 더 많은 시간이나 토큰 (tokens)을 소비할 수 있습니다.
호출 제한 (Invocation limits), 실제 시간 제한 (wall-clock limits), 그리고 사용 가능한 토큰 (token) 또는 비용 제한 (cost limits)은 에이전트 스스로 멈추는 것에 의존하기보다 런타임 (runtime)에 의해 추적되어야 합니다.
5. 워크플로 (workflow)는 단일 벤더 (vendor)에 의존해서는 안 됩니다
구현이 Claude Code, Codex, 다른 코딩 에이전트 (coding agent), 또는 심지어 셸 스크립트 (shell script)에 의해 작성되었더라도 검증 모델 (verification model)은 동일하게 유지되어야 합니다.
에이전트 (Agents)는 작업자 (workers)입니다. 워크플로 계약 (workflow contract)은 작업자와 독립적이어야 합니다.
내가 만들고 있는 것
VichuFlow는 이러한 아키텍처 (architecture)를 탐구하기 위한 나의 시도입니다.
이것은 아직 초기 프로젝트입니다. 현재 릴리스는 더 큰 런타임 아키텍처 (runtime architecture)의 첫 번째 완전한 조각이며, 그 비전의 모든 부분을 한꺼번에 출시하려는 시도가 아닙니다.
이는 저장소 (repository) 상에서 코딩 워크플로 (coding workflows)를 지속적인 상태 머신 (persistent state machines)으로 실행하는 오픈 소스 Go 런타임 (runtime)입니다.
런타임 (runtime)은 스스로 코드를 작성하지 않습니다. 대신 코딩 에이전트 (coding agents)를 조정하고 다음 단계로 진행할 수 있는지 여부를 결정합니다.
단순화된 워크플로 (workflow)는 다음과 같이 보일 수 있습니다:
explore
↓
propose
...
모든 실행 결과는 .vichu/ 아래에 일반 파일로 영구 저장됩니다. 저장소 소유자는 별도의 서버나 데이터베이스 (database) 없이도 상태 (state)와 이벤트 기록 (event history)을 검사할 수 있습니다.
검증 게이트 (Verification gates)는 프로젝트의 기존 툴체인 (toolchain)을 사용합니다:
commands:
test: go test ./...
lint: go vet ./...
...
Node 프로젝트의 경우 해당 명령어가 node --test를 사용할 수 있고, Python의 경우 unittest, Rust의 경우 cargo test를 사용할 수 있습니다.
VichuFlow 자체는 단일 바이너리 (single binary)입니다. Go 프로젝트에 국한되지 않습니다.
현재 릴리스에는 네이티브 Claude Code 호스트 팩 (host pack), Claude Code 및 Codex를 위한 헤드리스 어댑터 (headless adapters), 그리고 셸 (shell) 및 결정론적 테스트 (deterministic test) 어댑터가 포함되어 있습니다.
작은 예시
VichuFlow를 설치한 후, 프로젝트는 Claude Code 호스트 통합 (host integration)을 초기화할 수 있습니다:
vichu init --host claude-code
그 다음, Claude Code에서 다음과 같이 실행합니다:
/vichu implement password reset using sdd
호스트 (host)는 코딩 작업을 위임하고, VichuFlow 런타임 (runtime)은 지속적인 상태 (persistent state)와 검증 게이트 (verification gates)를 관리합니다.
헤드리스 워크플로 (headless workflow)는 터미널에서도 시작할 수 있습니다:
vichu exec "fix the failing login test"
필요한 검증 게이트 (verification gate)가 실패하면, 실행 (run)은 completed 상태가 되지 않습니다.
에이전트는 워크플로 (workflow)와 설정된 제한 사항 (limits)에 따라 문제를 해결할 수 있는 또 다른 기회를 얻습니다.
VichuFlow가 아직 해결하지 못한 것들
VichuFlow는 1.0 이전 버전이며, 검증 (verification)을 실행 (execution)으로부터 분리한다고 해서 자동으로 완벽한 보안 경계 (security boundary)가 생성되는 것은 아닙니다.
현재 런타임 (runtime)과 코딩 에이전트 (coding agent)는 여전히 동일한 작업 환경 (working environment)에서 작동합니다. 파일 시스템 (filesystem)에 직접 접근할 수 있는 에이전트는 VichuFlow의 로컬 상태 파일 (local state files)을 수정하려고 시도할 수 있습니다.
또한 동시 실행 (concurrent runs), 특정 검증 작업 중의 충돌 복구 (crash recovery), 그리고 무시된 디렉토리에 대한 파일 시스템 감사 (filesystem auditing)와 관련된 현재의 제한 사항들도 존재합니다.
이러한 제한 사항들은 "런타임을 신뢰하라"는 말이 또 다른 근거 없는 주장이 되어서는 안 되기 때문에 공개적으로 문서화되어 있습니다.
현재의 보증은 더 좁은 범위입니다:
VichuFlow는 에이전트가 보고한 테스트 결과 (test results)를 증거로 수락하지 않습니다. 일반적인 워크플로를 완료하기 전에 설정된 검증 게이트 (verification gates)를 직접 실행합니다.
지속적으로 저장된 판결 (persisted verdict)을 변조 탐지 가능 (tamper-evident)하게 만드는 것이 다음의 중요한 단계 중 하나입니다.
향후 방향
현재 버전은 가장 작으면서도 유용한 신뢰 경계 (trust boundary)를 구축하는 데 집중하고 있습니다:
- 에이전트 대화 (agent conversation) 외부의 지속적인 실행 상태 (persistent run state).
- 증거 기반의 단계 전환 (evidence-based stage transitions).
- 커널 (kernel)에 의해 실행되는 검증 게이트 (verification gates).
- 변이 감사 (mutation auditing) 및 제한된 에이전트 루프 (bounded agent loops).
- 네이티브 Claude Code 워크플로, 그리고 여러 어댑터 (adapters)를 통한 헤드리스 실행 (headless execution).
저에게는 수많은 통합 (integrations) 기능을 빠르게 추가하는 것보다 이러한 기반을 다지는 것이 더 중요합니다. 워크플로 계약 (workflow contract)이 신뢰할 수 있게 되면, 동일한 런타임 (runtime)은 몇 가지 유용한 방향으로 확장될 수 있습니다:
- 추가적인 네이티브 호스트 (native hosts): 실행 규칙을 변경하거나 증거 (evidence)를 잃지 않고도 코딩 도구 간에 실행을 이동할 수 있습니다.
- 게이트 (gate) 결과, 아티팩트 출처 (artifact provenance), 그리고 검토 판결 (review verdicts)으로부터 구축된 검증된 메모리 (verified memory): 신뢰할 수 없는 에이전트의 노트 대신 이를 활용합니다.
- 더 풍부한 관측성 (observability): 활성 실행 (active runs), 결정 (decisions), 실패 (failures), 그리고 예산 (budgets)을 이해하기 위함입니다.
- 더 표현력이 풍부한 소프트웨어 개발 워크플로 (software-development workflows) 및 사양 제공자 (specification providers): 결정론적 검증 (deterministic verification)을 최종 권위로 유지하면서도 가능합니다.
이것들은 로드맵 방향이며, 제가 오늘 바로 사용할 수 있다고 주장하는 기능은 아닙니다.
프로젝트가 성장하더라도 핵심 아이디어는 동일하게 유지되어야 합니다: 에이전트는 변할 수 있지만, 워크플로를 진행시키는 데 필요한 증거 (evidence)는 변해서는 안 됩니다.
이 레이어가 중요한 이유
코딩 모델은 계속해서 개선될 것입니다.
더 나은 코드를 작성하고, 도구를 더 정확하게 사용하며, 점점 더 복잡한 작업을 완료할 것입니다.
하지만 지능이 향상된다고 해서 독립적인 검증 (independent verification)의 필요성이 사라지는 것은 아닙니다.
개발자가 더 숙련된다고 해서 CI (지속적 통합)를 없애지는 않습니다. 데이터베이스 클라이언트가 트랜잭션이 커밋되었는지 여부를 결정하게 두지도 않습니다. 백그라운드 작업 (background job)에게 그 자체의 완료 여부에 대한 유일한 기록이 되라고 요구하지도 않습니다.
코딩 에이전트에게 더 많은 자율성을 부여할수록, 외부 상태 (external state), 관측 가능한 증거 (observable evidence), 그리고 결정론적 게이트 (deterministic gates)는 더욱 중요해집니다.
흥미로운 질문은 단지 다음과 같은 것이 아닙니다:
에이전트가 얼마나 유능한가?
또한 다음과 같습니다:
주변 시스템이 에이전트를 신뢰하기 전에 어떤 증거를 요구하는가?
저는 여전히 VichuFlow를 통해 그 질문을 탐구하고 있으며, 특히 실제 리포지토리 (repositories)에서 코딩 에이전트를 이미 사용 중인 개발자분들의 피드백을 받고 싶습니다.
현재 여러분은 자율적인 코딩 작업이 실제로 완료되었다는 것을 어떻게 판단하고 계신가요?
VichuFlow는 MIT 라이선스이며 GitHub에서 확인할 수 있습니다.
고지 사항 (Disclosure): 저는 이 글의 구조를 잡고 편집하는 데 AI 어시스턴트 (AI assistant)를 사용했습니다. 저는 VichuFlow의 현재 구현 및 문서(documentation)를 바탕으로 기술적 주장들을 검토하였으며, 여기에 표현된 의견은 저의 개인적인 견해입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기