오늘도 공부
ProofShot: 완료되었는지 정말 확인하는 에이전트 본문
AI 에이전트가 UI를 만들고 나서 “완료했습니다”라고 말하는 순간이 있다. 그런데 정작 개발자가 받는 건 코드 diff와 말뿐이다. 화면이 진짜 떴는지, 버튼이 눌리는지, 콘솔 에러가 없는지, 데모 영상 하나 없이 끝나는 경우가 많다. ProofShot은 바로 그 지점을 찌른다. 이 프로젝트는 AI 코딩 에이전트가 기능을 만든 뒤 실제 브라우저 세션을 녹화하고, 스크린샷과 로그까지 묶어서 사람이 검토할 수 있는 “시각적 증거”를 남기는 CLI다. (GitHub)
핵심은 “에이전트가 UI를 만들 수 있느냐”가 아니라 “에이전트가 만든 결과를 사람이 빠르게 믿을 수 있느냐”다. ProofShot은 Claude Code, Cursor, Codex, Gemini CLI, Windsurf처럼 셸 명령을 실행할 수 있는 에이전트에 붙일 수 있게 설계됐고, 로컬 브라우저에서 실제로 동작을 재현한 뒤 영상, 스크린샷, 콘솔 로그, 서버 로그, 요약 리포트까지 아티팩트로 남긴다. 그래서 이 도구는 테스트 프레임워크라기보다, 에이전트 개발 워크플로에 “검증 레이어”를 추가하는 도구에 가깝다. (GitHub)
GitHub - AmElmo/proofshot: Give AI coding agents eyes. Records browser sessions, captures screenshots, collects errors, and bund
Give AI coding agents eyes. Records browser sessions, captures screenshots, collects errors, and bundles proof artifacts — so humans can verify what the agent built. - AmElmo/proofshot
github.com
프로젝트 소개
ProofShot은 오픈소스, 에이전트-불문(agent-agnostic) CLI다. 리포지토리 설명 그대로 “AI coding agents eyes”를 주는 도구를 지향한다. 개발자가 에이전트에게 기능 구현을 맡기면, ProofShot이 브라우저 세션을 열고 녹화를 시작하고, 에이전트가 브라우저를 조작하는 동안 액션 로그를 수집한 뒤, 마지막에 이를 하나의 검토 가능한 결과물로 패키징한다. 아티팩트 폴더에는 session.webm, viewer.html, SUMMARY.md, step-*.png, session-log.json, server.log, console-output.log 같은 파일이 남는다. (GitHub)
이 프로젝트는 GitHub 사용자 AmElmo가 공개한 리포지토리이며, 구현은 TypeScript ESM 기반이다. CLI는 commander로 구성되어 있고, 출력과 사용자 피드백에는 chalk를 쓰며, 포트 확인에는 detect-port를 사용한다. 빌드는 tsup, 테스트는 vitest를 사용하고, 브라우저 자동화 계층은 Vercel의 agent-browser에 의존한다. agent-browser는 peer dependency로 선언되어 있고, 설치 후에는 agent-browser install을 통해 Chromium 환경까지 셋업하도록 유도한다. (GitHub)
즉, 이 프로젝트를 한 줄로 요약하면 이렇다. **“에이전트가 만든 UI 결과를 사람이 눈으로 검토할 수 있게 증거를 남겨주는 브라우저 검증 파이프라인”**이다. 테스트 코드를 직접 작성하지 않아도 되고, SaaS 대시보드·칸반 보드·채팅 UI 같은 샘플 앱을 포함해 바로 실험해볼 수 있게 준비되어 있다. (GitHub)
왜 이 프로젝트가 등장했을까
최근 AI 에이전트는 코드 생성 자체는 꽤 잘한다. 문제는 마지막 10%다. UI는 눈으로 봐야 아는 문제가 많다. 버튼 정렬이 깨졌는지, 로딩 스피너가 영원히 도는지, 다크모드에서 텍스트가 안 보이는지, 클릭 후 콘솔 에러가 터지는지는 코드만으로 판단하기 어렵다. README에서도 같은 문제를 짚는다. 에이전트는 UI 기능을 “blind”하게 만들고, 결과가 제대로 보이는지, 작동하는지, 에러가 없는지 직접 확인하기 어렵다는 것이다. (GitHub)
기존 접근은 대체로 세 가지였다. 첫째, 사람이 직접 로컬 서버를 띄우고 화면을 클릭해본다. 둘째, Playwright 같은 도구로 E2E 테스트를 별도로 짠다. 셋째, 스크린샷만 몇 장 받아서 확인한다. 하지만 첫 번째는 너무 수작업이고, 두 번째는 작성 비용이 높고, 세 번째는 동적인 흐름을 놓치기 쉽다. ProofShot은 이 사이를 노린다. 에이전트가 이미 셸 명령을 실행할 수 있다는 전제를 활용해서, 별도 벤더 종속 없이 브라우저 검증 흐름을 자동 삽입한다. (GitHub)
이 프로젝트가 흥미로운 이유는 “테스트 자동화”보다 “검토 자동화”에 더 가깝기 때문이다. 성공/실패 한 줄이 아니라, 왜 성공했다고 볼 수 있는지를 영상과 로그로 보여준다. PR에 올릴 때도 그 증거를 코멘트로 붙일 수 있어, 팀 협업에서 “진짜 해봤어?”라는 질문을 줄이는 방향으로 설계되어 있다. (GitHub)
핵심 기능
1. 에이전트용 검증 세션 시작과 종료
ProofShot의 워크플로는 매우 단순하다. start, exec, stop 세 단계다. proofshot start는 브라우저를 열고 녹화를 시작하며, 필요하면 --run "npm run dev" 형태로 개발 서버도 같이 띄운다. proofshot stop은 녹화를 종료하고 콘솔/서버 에러를 수집한 뒤 결과물을 만든다. 이 단순함이 중요하다. 에이전트는 복잡한 SDK 대신 셸 명령 몇 개만 알면 된다. (GitHub)
proofshot start --run "npm run dev" --port 3000 --description "로그인 폼 검증"
proofshot exec snapshot -i
proofshot exec open http://localhost:3000/login
proofshot exec fill @e2 "test@example.com"
proofshot exec click @e5
proofshot exec screenshot step-login.png
proofshot stop
2. agent-browser를 통한 에이전트-불문 브라우저 제어
ProofShot의 가장 중요한 결정은 브라우저 자동화 엔진으로 agent-browser를 선택한 것이다. 아키텍처 문서에 따르면, ProofShot은 브라우저 자체를 구현하지 않고 agent-browser CLI를 감싸는 얇은 오케스트레이션 레이어다. 그래서 Claude Code든 Cursor든 Codex든, “셸 명령을 실행할 수 있느냐”만 충족하면 같은 방식으로 붙일 수 있다. (GitHub)
또한 agent-browser는 지속적인 데몬 프로세스로 브라우저 상태를 유지한다. 이 덕분에 proofshot exec click @e3 다음에 proofshot exec screenshot step.png를 실행해도 같은 탭, 같은 페이지 상태가 이어진다. CLI 명령이 stateless하지 않고 같은 세션 문맥을 유지한다는 점이, 에이전트와의 궁합을 크게 높인다. (GitHub)
3. 액션 타임라인과 상호작용 로그 수집
proofshot exec는 단순한 pass-through가 아니다. 세션이 활성화되어 있으면 액션 시점, 명령 문자열, 상대 시간, 경우에 따라 대상 요소의 바운딩 박스와 라벨까지 session-log.json에 기록한다. 특히 @eN 참조를 쓰는 클릭·입력 액션에서는 실행 전에 요소 정보를 최대한 수집해 두는데, 이는 나중에 비디오 위에 클릭 리플이나 액션 토스트 같은 오버레이를 렌더링하기 위해서다. (GitHub)
이 부분이 꽤 영리하다. agent-browser의 get box가 ref를 직접 받지 못하므로, ProofShot은 먼저 id를 찾고 #id로 좌표를 구해보고, 실패하면 텍스트나 placeholder, aria-label 같은 속성으로 fallback한다. 완벽한 DOM 추적 시스템은 아니지만, 에이전트 워크플로에서 필요한 수준의 “행동 설명 가능성”을 확보하려는 설계다. (GitHub)
4. 콘솔 에러와 서버 에러 동시 수집
UI가 얼핏 정상처럼 보여도 브라우저 콘솔이나 서버 로그에는 빨간 줄이 가득할 수 있다. ProofShot은 stop 시점에 브라우저 콘솔 출력과 에러를 가져오고, 서버 로그도 읽어서 다국어 런타임 패턴으로 스캔한다. JavaScript/Node.js, Python, Ruby/Rails, Go, Java/Kotlin, Rust, PHP, C#/.NET, Elixir/Phoenix 등 여러 생태계의 에러 패턴이 미리 정의돼 있다. (GitHub)
이건 “바이브 코딩” 환경에 특히 중요하다. 에이전트가 화면만 얼추 맞춰놓고 내부적으로는 경고와 예외를 남기고 있을 수 있기 때문이다. ProofShot은 적어도 “화면이 나왔다”와 “운영에 가까운 기준으로 봐도 문제 없었다” 사이의 간극을 조금 줄여준다. (GitHub)
5. PR에 붙일 수 있는 검증 결과물 생성
로컬에서만 끝나는 도구였다면 활용 범위가 제한적이었을 것이다. ProofShot은 proofshot pr 명령으로 현재 브랜치와 연결된 세션들을 찾아 PR 코멘트로 업로드할 수 있다. 스크린샷들을 모으고, 가장 최근 세션의 비디오를 선택하며, SUMMARY.md를 바탕으로 에러 개수도 합산한다. gh가 설치되어 있어야 하고, ffmpeg가 있으면 .webm을 .mp4로 변환하는 후처리도 지원한다. (GitHub)
이 기능은 팀 단위에서 특히 유용하다. 리뷰어는 로컬에서 직접 앱을 띄워보지 않아도, PR 안에서 에이전트가 어떤 흐름을 검증했는지 바로 볼 수 있다. 말하자면 “AI가 만든 기능”을 “인간이 검토 가능한 증거 패키지”로 바꾸는 마지막 단계다. (GitHub)
프로젝트 아키텍처 분석
ProofShot의 구조를 보면, 무거운 테스트 플랫폼이 아니라 오케스트레이터라는 표현이 가장 정확하다. 실제 브라우저 조작은 agent-browser가 담당하고, ProofShot은 세션 상태, 로그, 녹화, 리포트 생성, PR 업로드를 책임진다. 소스 트리도 commands, browser, server, session, artifacts, utils로 나뉘어 있어 역할 분리가 명확하다. cli.ts는 각 커맨드를 등록하고, start.ts, exec.ts, stop.ts, pr.ts가 라이프사이클을 이끈다. (GitHub)

아키텍처 문서에 나온 흐름을 개발자 시선으로 다시 풀어보면 이렇다. start는 포트를 확인하고, 필요시 개발 서버를 detached process로 띄우고, 포트가 열릴 때까지 기다린 뒤, 브라우저를 열고 녹화를 시작하고, .session.json과 metadata.json을 기록한다. exec는 액션을 agent-browser에 전달하면서 같은 타임라인에 로그를 남긴다. stop은 콘솔과 서버 로그를 수집하고, 녹화를 종료하고, 액션 없는 dead time을 ffmpeg로 잘라내고, SUMMARY.md와 viewer.html을 만든 뒤 세션 상태를 정리한다. (GitHub)
이 구조의 장점은 세 가지다. 첫째, 브라우저 제어를 외부 도구에 위임해 유지보수 범위를 줄인다. 둘째, 세션 상태를 명시적으로 저장해 멀티 커맨드 워크플로를 안정적으로 유지한다. 셋째, 최종 산출물이 단순 로그가 아니라 사람이 볼 수 있는 viewer와 markdown report라는 점에서, 자동화와 인간 리뷰를 자연스럽게 연결한다. (GitHub)
내부 동작을 코드 관점에서 보면
CLI 진입점은 아주 직관적이다. install, start, stop, diff, clean, pr, exec 명령을 등록한다. 즉, ProofShot의 제품 표면적은 거의 이 7개 명령으로 끝난다. 복잡한 SDK나 API 객체 대신, “에이전트가 기억하기 쉬운 CLI”에 집중한 설계라고 볼 수 있다. (GitHub)
program.command('start')
.description('Start a verification session: browser, recording, error capture')
program.command('stop')
.description('Stop session: stop recording, collect errors, bundle proof artifacts')
program.command('exec')
.description('Run an agent-browser command with logging')
start 커맨드는 세션 충돌도 다룬다. 이미 활성 세션이 있으면 --force 없이 진행하지 않고, --run이 주어졌을 때만 개발 서버를 띄운다. 그리고 Git 브랜치와 commit SHA도 함께 메타데이터로 남긴다. 이 정보는 나중에 pr 명령이 현재 브랜치와 연결된 세션 폴더를 찾는 데 사용된다. (GitHub)
writeMetadata(sessionDir, {
branch,
commitSha,
startedAt: new Date().toISOString(),
description: options.description || null,
});
exec는 ProofShot의 감초 같은 부분이다. 세션이 살아 있으면 스크린샷 경로를 세션 폴더 기준으로 재작성하고, 요소 참조가 포함된 액션은 실행 전에 요소 위치와 라벨을 최대한 캐치한다. 그리고 그 시점의 상대 시간을 계산해 session-log.json에 누적 저장한다. 이 덕분에 최종 viewer에서 “몇 초 시점에 어떤 액션을 했는지”를 영상과 함께 맞춰볼 수 있다. (GitHub)
const entry: SessionLogEntry = {
action,
relativeTimeSec,
timestamp: now.toISOString(),
};
if (elementData) {
entry.element = elementData;
}
stop은 결과물을 만드는 핵심 단계다. 여기서 콘솔 출력, 타임스탬프된 서버 로그, 스크린샷 목록, 세션 로그를 조합해 최종 보고서를 만든다. 그리고 비디오 앞뒤의 무의미한 구간을 잘라내면서 타임라인 오프셋까지 보정한다. 이 디테일은 꽤 중요하다. 영상이 길어질수록 검토 경험이 나빠지는데, ProofShot은 단순히 “녹화했다”에서 멈추지 않고 “검토 가능한 형태로 정리했다”까지 간다. (GitHub)
왜 Playwright 직접 사용 대신 이 접근이 먹히는가
이 프로젝트를 보면서 자연스럽게 드는 질문은 “그냥 Playwright 쓰면 되지 않나?”다. 그런데 ProofShot의 문제 정의는 Playwright와 조금 다르다. Playwright는 강력한 자동화 프레임워크지만, 여기서 원하는 것은 에이전트가 쉽게 호출하고, 세션을 이어가고, 사람 검토용 증거를 패키징하는 작업이다. 아키텍처 문서에서도 agent-browser의 CLI 인터페이스, persistent daemon, stable element refs, 그리고 context-efficient snapshot 출력이 핵심 장점으로 설명된다. (GitHub)
특히 @eN 형태의 안정적인 요소 참조는 AI 에이전트에 맞는 UX다. CSS selector나 XPath를 직접 만들게 하는 방식보다, 스냅샷에서 @e3: Submit button 같은 형태를 보고 액션을 수행하는 편이 훨씬 에이전트 친화적이다. 이건 단순한 구현 디테일이 아니라, “사람용 테스트 도구”가 아니라 “에이전트용 검증 도구”를 만든다는 의도가 코드에 반영된 사례다. (GitHub)
실제로 언제 쓰면 좋은가
가장 잘 맞는 순간은 바이브 코딩 이후 마지막 확인이 너무 귀찮을 때다. 랜딩 페이지 수정, 로그인/회원가입 플로우, 대시보드 카드 레이아웃, 설정 화면 입력 폼, 채팅 UI 같은 작업은 에이전트가 만들 수는 있어도 사람이 결국 한 번은 눌러봐야 마음이 놓인다. 이런 경우 ProofShot은 “직접 확인”을 없애기보다, 그 확인을 자동으로 기록해 재사용 가능하게 만든다. (GitHub)
또 하나는 PR 리뷰 직전이다. 에이전트가 기능을 만들고 스스로 ProofShot으로 검증까지 수행하면, 리뷰어는 구현 코드와 함께 실제 동작 영상까지 바로 볼 수 있다. UI 변경이 잦고, 리뷰어가 매번 브랜치를 당겨서 로컬 실행하기 어려운 팀에서 특히 효율이 좋다. (GitHub)
반대로 이 도구가 만능은 아니다. 픽셀 단위 시각 회귀 테스트를 엄밀하게 관리하거나, CI에서 대규모 E2E 테스트 스위트를 안정적으로 돌리고 싶은 경우에는 여전히 Playwright/Cypress 같은 체계적인 테스트 계층이 필요하다. ProofShot의 강점은 “완전한 테스트 대체”가 아니라 “에이전트 결과 검증의 마지막 1마일”에 있다. 이 점을 이해하고 쓰면 기대치가 정확히 맞는다. 이 평가는 프로젝트 문서와 구현 흐름을 바탕으로 한 해석이다. (GitHub)
바로 써보는 흐름
설치는 꽤 간단하다. 전역으로 proofshot을 설치하고, proofshot install을 한 번 실행하면 로컬 머신에서 감지된 AI 도구별로 사용자 레벨 skill/rule 파일을 설치한다. Claude Code는 ~/.claude/skills/proofshot/SKILL.md, Cursor는 ~/.cursor/rules/proofshot.mdc, Codex는 ~/.codex/skills/proofshot/SKILL.md처럼 각 도구별 경로에 들어간다. 즉, 프로젝트마다 반복 설정할 필요 없이 머신 단위로 붙는다. (GitHub)
npm install -g proofshot
proofshot install
프로젝트 루트에 별도 설정이 없어도 기본값으로 동작한다. 기본 포트는 3000, 출력 경로는 ./proofshot-artifacts, 기본 뷰포트는 1280x720, headless 모드가 기본이다. 필요하면 proofshot.config.json으로 덮어쓸 수 있다. (GitHub)
{
"devServer": {
"port": 3000,
"startupTimeout": 30000
},
"output": "./proofshot-artifacts",
"viewport": {
"width": 1280,
"height": 720
},
"headless": true
}
에이전트에게는 이렇게 지시하면 된다.
로그인 폼 기능을 proofshot으로 검증해.
개발 서버를 띄우고, 로그인 페이지로 이동해서 입력/제출까지 확인하고,
중간 단계마다 스크린샷을 남겨.
마지막에 proofshot stop으로 결과물을 정리해.
이 프롬프트가 좋은 이유는 ProofShot이 단순 CLI이기 때문이다. 에이전트가 이해해야 할 것은 “시작하고, 조작하고, 멈춘다”는 구조뿐이다. 여기에 스크린샷 포인트만 추가하면 된다. (GitHub)
아쉬운 점도 있다
ProofShot은 현재 구조상 agent-browser 생태계에 강하게 기대고 있다. 즉, 브라우저 레이어의 안정성과 기능 폭은 결국 하부 도구의 역량에 영향을 받는다. 또 에러 수집도 stop 시점의 point-in-time 스냅샷 성격이 있어, 장시간 세션에서 모든 상태 변화를 완벽히 추적하는 관측 시스템과는 다르다. 이건 한계이면서도, 동시에 도구를 가볍게 유지하는 선택이기도 하다. (GitHub)
그럼에도 설계 방향은 상당히 명확하다. 이 프로젝트는 브라우저 자동화의 모든 문제를 해결하려 하지 않는다. 대신 에이전트가 만든 UI를 인간이 신뢰할 수 있게 만드는 증거 수집기 역할에 집중한다. 그래서 기능 범위가 오히려 선명하다. (GitHub)
마무리
ProofShot은 “AI가 코드를 짰다” 다음 단계에 필요한 도구다. 이제 팀이 필요한 건 생성 자체보다 검증의 신뢰도다. 이 프로젝트는 테스트 프레임워크처럼 모든 걸 판정하려 하지 않고, 에이전트가 한 일을 영상·스크린샷·로그로 남겨 사람의 검토 속도를 올린다. 그래서 바이브 코더, AI 페어 프로그래밍 사용자, PR 리뷰어가 모두 이득을 본다. (GitHub)
한마디로 정리하면, ProofShot은 에이전트의 “됐음”을 믿지 말고, 증거를 남기게 만드는 도구다. UI 작업을 에이전트에게 많이 맡기고 있다면, 이 프로젝트는 꽤 빠르게 체감될 종류의 오픈소스다. (GitHub)
'AI' 카테고리의 다른 글
| Insanely Fast Whisper: Whisper를 빠르게 동작하는 wrapper cli (0) | 2026.03.27 |
|---|---|
| PostHog: 분석 도구를 넘어 제품 운영 플랫폼이 된 오픈소스의 현재 (0) | 2026.03.27 |
| AgentScope: 멀티 에이전트 실험을 넘어 운영 환경까지 가져가는 Python 에이전트 프레임워크 (0) | 2026.03.27 |
| Dexter: 금융 리서치를 위해 태어난 자율형 에이전트, 범용 코드 에이전트와 뭐가 다를까 (0) | 2026.03.27 |
| Claude Skills에 Karpathy의 autoresearch 적용하면? (0) | 2026.03.26 |
