특강

바이브 코딩: 팩트체크 실습을 통해

이종혁 (경희대학교 미디어학과) · 2026년 10월

이 강의가 다루는 것은 웹 채팅창이 아님. ChatGPT·Claude·Gemini를 브라우저에서 대화창으로 쓰는 방식이 아니라, 같은 급의 모델을 내 컴퓨터에 설치해 파일과 명령을 직접 다루게 하는 방식을 씀. 둘의 차이는 모델 성능이 아니라 권한과 설계에 있음. 여는 장에서 용어부터 정리함.

이 강의의 진행 방식 ① 계획만 적은 프롬프트 한 장을 던짐 → ② 돌아온 실물을 읽음 → ③ 어긋난 곳만 조임. 결과물은 매번 다르게 나옴. 그래서 이 특강은 완성된 코드를 싣지 않고, 무엇이 나와야 하는지 예측하고 대조하는 법을 실었음.

코딩을 해 본 적이 없어도 됨. 필요한 준비는 8장에서 처음부터 짚어 줌. 모르는 낱말이 나오면 맨 아래 「용어 미니 사전」을 먼저 볼 것.


PART 1. 이론과 환경 구축#

여는 장. 왜 웹 채팅창이 아니라 코딩 에이전트인가#

용어부터 — 바이브코딩의 구분#

기준 — 내 컴퓨터에 손댈 권한이 있는가.

용어 영어 표기 무엇을 가리키나
A 웹 채팅형 어시스턴트
(줄여서 채팅형)
chat assistant
conversational assistant
브라우저로 chatgpt.com·claude.ai에 접속해 대화창으로 쓰는 방식
B 코딩 에이전트
(줄여서 에이전트)
coding agent
agentic coding tool
터미널이나 코드 편집기에 설치해 내 폴더의 파일을 직접 읽고 쓰고 실행하게 하는 방식

한 줄 정리 — 대비는 "대화형 대 에이전트형"이 아니라 "보여주기만 하는 채팅형" 대 "직접 해 주는 에이전트형"임. 둘 다 대화로 쓰고, 둘 다 같은 급의 모델을 씀. 갈리는 것은 권한임.

결정적 차이 — 성능이 아니라 권한#

웹 채팅형 어시스턴트 코딩 에이전트
대화로 쓰나 ○ ○ (여기서는 안 갈림)
하는 일 코드를 보여 줌 파일을 직접 만들고 고침
실행 내가 복사·저장·실행 터미널 명령까지 스스로 실행
오류 내가 붙여넣어 다시 질문 스스로 읽고 재시도
여러 파일 한 번에 하나씩 보여 줌 폴더 전체를 훑고 여러 파일을 함께 고침
설정이 남나 대화창을 닫으면 사라짐 규칙·절차가 파일로 폴더에 남음
대가 — 매번 "실행해도 될까요?" 승인 요청

그래서 채팅형은 1단계에 머무름#

단계 채팅형 코딩 에이전트
1. prompt ○ ○
2. context △ 파일 업로드·웹검색으로 일부 흉내 ○
3. agentic ✕ 구조적으로 불가능 ○
4. harness ✕ 통제할 대상이 없음 ○

오늘 두 실습이 이 차이를 그대로 보여줌#

실습 1 (웹) 실습 2 (에이전트)
실행 주체 사람이 매번 버튼을 누름 에이전트가 스스로 순서를 진행
처리 단위 주장 한 개 input/ 안의 주장 여러 개
재현 브라우저를 닫으면 끝 코드와 규칙이 폴더에 남음
해당 단계 1~2단계 3~4단계

1장. AI 활용 수준의 네 단계#

prompt engineering  →  context engineering  →  agentic engineering  →  harness engineering
   (무엇을 묻나)          (무엇을 보여주나)        (누가 어떻게 일하나)       (어떻게 통제하나)
단계 다루는 대상 한계 → 다음 단계로
1. prompt 지시문 하나 모델이 모르는 정보는 못 냄
2. context 문맥창에 넣을 내용 사람이 시켜야 한 번 움직임
3. agentic 작업의 구조 자율성이 커지면 폭주함
4. harness 권한·검증·중단 조건 —

문맥창(context window)이란 — AI가 한 번에 읽어 둘 수 있는 분량. 사람으로 치면 책상 위에 펼쳐 놓은 자료의 크기임. 책상을 벗어난 자료는 아무리 중요해도 AI 눈에 보이지 않음. 2단계는 이 책상 위에 무엇을 올릴지 고르는 기술임.

2장. 1단계 — prompt engineering#

(무엇을) + (어떤 형식으로) + (어떤 조건에서)
기법 예시
역할 부여 "너는 20년차 사회부 기자다. 담백한 단문으로 답한다."
퓨샷 입력·출력 쌍 2~3개를 먼저 보여줌
출력 형식 지정 "표로 답한다. 열은 주장·근거·출처 셋이다."
제약 명시 "모르면 모른다고 답한다. 지어내지 않는다."
분할 요청 "쇼핑몰 전체"가 아니라 "입력칸 하나"
계획 먼저 요구 "만들기 전에 무엇을 만들지 먼저 알려줘" — 이 강의 두 실습이 모두 이 줄로 끝남
아쉬움 좋음
"할 일 앱 만들어 줘" "할 일을 추가·삭제·완료체크하는 웹앱을 index.html 한 파일로, 새로고침해도 목록이 남도록"
"안 돼" "추가 버튼을 눌러도 목록에 안 나타나. 콘솔 오류를 확인하고 고쳐 줘"
"예쁘게 만들어 줘" "글자 크기를 키우고 버튼을 화면 가운데 두 개만 남겨 줘"

3장. 2단계 — context engineering#

손이 적게 가는 것부터 차례로 올라감. 아래 순서가 곧 구축 난이도 순서임.

순서 방법 원리 용도 · 예 드는 품
① 대용량 자료를 넣어 두고
필요한 대목만 참조
폴더에 자료를 그냥 놓아둠. 에이전트가 목록을 보고 그때그때 필요한 파일·구간만 열어 읽음 보고서 수백 장, 기사 수천 건, 회의록 — 가장 먼저 시도할 것 거의 없음
② API 연결 —
실시간 검색 · RSS
바깥 서비스를 호출해 최신 내용을 그때그때 끌어와 문맥창에 넣음 오늘의 사건·뉴스·주가 (이번 실습의 Tavily가 여기) · RSS로 언론사 새 기사 수집 키 발급 + 호출 코드
③ MCP
(Model Context Protocol)
외부 도구·데이터를 표준 규약으로 꽂음. 서비스마다 코드를 새로 짜지 않아도 됨 GitHub·노션·구글드라이브·데이터베이스를 도구처럼 연결 서버 설치·설정
④ RAG
(검색 증강 생성)
문서를 조각내 벡터로 저장 → 질문과 뜻이 가까운 조각만 골라 삽입 사내 문서·논문·판례처럼 양이 아주 많고 계속 되물을 자료 가장 큼 (임베딩·DB 구축·갱신)

왜 ①이 에이전트에서만 제대로 되나 — 채팅형은 파일을 업로드해야 읽음. 용량·개수 제한이 걸림. 코딩 에이전트는 폴더를 그냥 보고 필요한 파일만 스스로 열어 읽음. 여는 장의 권한 차이가 여기서 바로 드러남.

4장. 3단계 — agentic engineering#

먼저 짚을 것 — 누가 "에이전트"인가. 가장 헷갈리는 대목이므로 일하는 주체와 주체가 읽는 문서를 구분해 둠.

이름 정체 위치
일하는 주체
(에이전트)
메인 에이전트 내가 지금 대화하고 있는 그 세션. 모든 도구를 다 쓸 수 있고, 전체를 지휘하고 종합함 claude를 실행한 그 창 (별도 파일 없음)
서브에이전트 메인이 불러내는 별도의 일꾼. 자기만의 깨끗한 문맥창을 갖고 한 가지 일만 함. 결과 요약만 메인에게 돌려줌 .claude/agents/<이름>.md
주체가 읽는
문서
메모리 파일
CLAUDE.md
에이전트가 아님. 메인 에이전트가 세션을 열 때마다 자동으로 읽는 지시문. 사람이 써 두는 규칙 메모임 작업 폴더의 CLAUDE.md
스킬 역시 에이전트가 아님. 상황에 맞을 때만 꺼내 읽는 절차서 .claude/skills/<이름>/SKILL.md

비유로 — 메인 에이전트가 팀장, 서브에이전트가 팀원임. CLAUDE.md는 팀장이 출근할 때마다 먼저 읽는 업무 수칙 게시판이고, 스킬은 캐비닛에 꽂힌 업무 매뉴얼임 — 필요할 때만 꺼내 봄. 게시판과 매뉴얼은 사람이 아님. 그래서 CLAUDE.md는 "메인 에이전트"가 아니라 메인 에이전트가 읽는 문서임.

자동 발동은 두 가지로 결정됨

tools: 줄이 권한을 정함

패턴 예시 주의
순차 검색 → 판단 → 검토 앞 단계 실패가 전파됨
병렬 자료원 3곳 동시 조회 사용량이 빠르게 소모됨
반복 검토 통과까지 수정 종료 조건 필수

5장. 4단계 — harness engineering#

장치 Claude Code에서 무엇을 막나
승인 프롬프트 기본 동작 모르는 사이에 파일이 바뀌는 것
권한 모드 작업 폴더 한정 엉뚱한 폴더를 건드리는 것
훅(Hook) settings.json의 hooks 특정 명령을 기계적으로 차단·검사
검토 에이전트 .claude/agents/reviewer.md 자기가 만든 것을 자기가 통과시키는 것
규칙 파일 CLAUDE.md의 "하지 말 것" 반복해서 나는 사고
# 하지 말 것
- .env 파일을 절대 커밋하지 않는다.
- 자동 재시도 루프를 만들지 않는다. 실패하면 사용자에게 알리고 멈춘다.
- 한 번의 사용자 요청당 외부 API 호출은 최대 1회로 제한한다.
- 대규모 리팩터링은 먼저 계획을 보여주고 승인받는다.

6장. 연구·교육에서의 함의#

영역 채팅형 코딩 에이전트
빅데이터 입력 업로드 용량·개수 제한 폴더 단위로 수천 건
비정형 데이터 입력 PDF·이미지 몇 장이 한계.
표로 안 정리된 자료는 매번 손으로 붙여넣어야 함
PDF·이미지·음성·영상·HWP를
폴더째 두고 스크립트로 일괄 변환·처리
결과 표준화 매번 흔들림 규칙 파일로 고정
재현 가능성 대화가 사라지면 끝 코드가 남아 언제든 재실행
협업·버전 관리 대화창 공유 저장소 공유 + Git

비정형 데이터가 왜 따로 중요한가

7장. 도구 지형#

Claude Code OpenAI Codex Google Antigravity
만든 곳 Anthropic OpenAI Google
터미널 명령 claude codex agy
편집기 확장 VS Code · JetBrains 공식 확장 VS Code 확장 자체 편집기 + CLI
규칙 파일 CLAUDE.md AGENTS.md AGENTS.md (또는 GEMINI.md)
서브에이전트 .claude/agents/*.md .codex/agents/*.toml .agents/agents/*.md
스킬 .claude/skills/ .agents/skills/ .agents/skills/
내장 웹검색 있음 (WebSearch) 있음 (web_search) 있음
로그인 계정 Claude 유료 구독 ChatGPT 계정 (Plus 이상 권장) Google 계정
이 특강 기본 경로 대체 경로 — 13-8 전용 절차 대체 경로 — 13-9

8장. 환경 구축 (PART 1의 유일한 실습)#

이 장만 통과하면 나머지는 전부 대화로 진행됨. 가장 많이 막히는 구간이므로 네 가지 설치 방법을 모두 실었음. 하나가 안 되면 바로 다음 것으로 넘어갈 것. 상세 절차: 입문 가이드 1부

설치는 어느 인터넷에서 하나 — 학교·기관 Wi-Fi는 피할 것

학교·회사·공공기관 Wi-Fi는 보안 필터가 프로그램 내려받기를 막거나 느리게 하는 경우가 많음. 여럿이 같은 Wi-Fi로 수백 MB를 동시에 받으면 중간에 끊기기도 함. 이때 뜨는 오류는 명령이 틀린 것처럼 보여서 원인을 찾기 어려움.

순서어디서언제
1집 Wi-Fi수업 전에 설치·로그인까지 끝내 둠 (가장 권함)
2내 휴대폰 핫스폿수업 중 설치·로그인이 필요할 때. 기관 Wi-Fi에서 한 번이라도 아래 증상이 나오면 고민하지 말고 바로 전환
3학교·기관 Wi-Fi설치가 끝난 뒤 실습(대화·검색)에는 대개 문제없음
  • 망 문제의 증상 — ETIMEDOUT · ECONNRESET · ENOTFOUND · 403 · certificate·SSL이 들어간 오류, 설치 스크립트의 syntax error near unexpected token '<', 진행률이 몇 분째 멈춤, 로그인 브라우저 창이 "연결할 수 없음".
  • 핫스폿 데이터 사용량(대략) — Claude Code 약 110MB · Codex 약 160MB · VS Code 약 100MB · Node.js 약 30MB · 파이썬 약 30MB. 도구 하나만 고르면 300MB 안팎임.
  • 핫스폿은 각자 자기 휴대폰으로. 한 사람의 핫스폿에 여럿이 붙으면 기관 Wi-Fi와 똑같이 느려짐.
  • 핫스폿으로 바꾼 뒤에는 터미널을 새로 열고 실패했던 명령을 그대로 다시 실행하면 됨. 반쯤 설치된 것을 지울 필요 없음.

8-1. 바탕 도구 네 가지#

준비물 받는 곳 왜 필요한가 주의
VS Code code.visualstudio.com 파일을 보고 고치는 편집기. 터미널도 여기 안에 들어 있음 확장에서 Python 설치
터미널 VS Code → Terminal → New Terminal 명령을 글자로 입력하는 창. AI 도구가 여기서 돎 단축키 Ctrl + 백틱(`)
Node.js nodejs.org (LTS) 방법 4(npm)를 쓸 때만 필요. 방법 1~3은 없어도 됨 Windows는 "Add to PATH" 체크 유지 · 22 버전 이상 · "Automatically install the necessary tools..." (필요한 도구를 자동으로 설치) 체크하지 말 것
파이썬 python.org (3.11 이상) 실습 2의 검색 스크립트를 돌림 Windows는 "Add python.exe to PATH" 반드시 체크

Windows에서 권하는 것 하나 더 — Git for Windows. 필수는 아니지만 설치해 두면 Claude Code가 더 익숙한 방식(Bash)으로 명령을 실행함. 없으면 PowerShell로 돎.

터미널에서 확인 — 세 줄 모두 버전이 나와야 다음으로 감

node -v                 # 방법 4를 쓸 때만 필요. v22.x 이상
npm -v                  # 위와 같음
python --version        # macOS는 python3 --version

8-2. AI 코딩 도구 설치 — 네 가지 길#

결론부터 — 처음이면 방법 1을 쓸 것. 터미널 명령을 한 줄도 치지 않고 끝남.

Windows 사용자 — 터미널은 PowerShell 하나로 통일하고, 설치 전에 이 한 줄부터

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned -Force

VS Code 터미널의 기본값이 PowerShell이고, 이 교안의 Windows 명령도 모두 PowerShell 기준임. 새 Windows PC는 PowerShell이 npm으로 깐 claude·codex 명령과 가상환경 활성화(Activate.ps1)를 막아 둠. 위 한 줄은 내 계정에만 적용되고 관리자 권한도 필요 없음. 처음에 한 번 해 두면 이후 이 오류가 생기지 않음. CMD(명령 프롬프트)는 쓰지 말 것 — 교안의 PowerShell 명령과 섞이면 오히려 실패가 늘어남.

방법 Node.js 자동 업데이트 이럴 때
1 VS Code 확장 불필요 ○ 초보자 · 터미널이 낯선 경우 ← 권장
2 공식 설치 스크립트 불필요 ○ 터미널에서 claude 명령을 직접 쓰고 싶을 때
3 패키지 관리자
(winget · Homebrew)
불필요 ✕ (수동) 회사 PC 등 스크립트 실행이 막힌 환경
4 npm 22 이상 필요 ○ 이미 Node.js를 쓰고 있을 때

방법 1 · VS Code 확장 — 가장 쉬움

  1. VS Code를 열고 왼쪽 확장(Extensions) 아이콘을 누름 — 단축키 Ctrl+Shift+X (Mac은 Cmd+Shift+X)
  2. 검색창에 Claude Code를 입력 → 만든 이가 Anthropic인 것을 확인하고 Install
  3. 설치되면 왼쪽 활동 표시줄에 ✱ 아이콘이 생김. 누르면 대화 패널이 열림
  4. 처음 열면 로그인 화면이 뜸 → Sign in → 브라우저에서 승인

단, 한 가지만 기억할 것 — 확장을 깔아도 터미널에서 claude라고 치면 안 됨. 확장은 자기 패널 안에서만 돎. 터미널 명령까지 쓰려면 방법 2~4를 추가로 해야 함. 이 특강의 실습은 터미널에서 claude를 실행하는 방식으로 적혀 있지만, 확장 패널에서 같은 프롬프트를 넣어도 결과는 같음. (폴더 여는 법은 12-1 참고)

방법 2 · 공식 설치 스크립트 — 터미널에서 claude를 쓰려면

자기 운영체제·자기 터미널에 맞는 한 줄만 복사해 붙여넣을 것. 섞어 쓰면 반드시 실패함.

# macOS · Linux · WSL  (터미널)
curl -fsSL https://claude.ai/install.sh | bash
# Windows — PowerShell 창에서
irm https://claude.ai/install.ps1 | iex
REM Windows — 명령 프롬프트(CMD) 창에서
curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd

지금 내가 PowerShell인지 CMD인지 구분하는 법 — 프롬프트 맨 앞을 볼 것

화면에 이렇게 보이면 이것은 써야 할 명령
PS C:\Users\홍길동> PowerShell (앞에 PS가 붙음) irm ... | iex
C:\Users\홍길동> CMD (PS가 없음) curl ... && install.cmd ...
~ $ · 사용자@컴퓨터:~$ macOS · Linux · Git Bash curl ... | bash

방법 3 · 패키지 관리자 — 스크립트가 막힐 때

# Windows (PowerShell 또는 CMD)
winget install Anthropic.ClaudeCode
# macOS (Homebrew가 깔려 있어야 함)
brew install --cask claude-code

방법 4 · npm — 이미 Node.js를 쓰고 있다면

npm install -g @anthropic-ai/claude-code

Codex를 고른 경우 — 설치

아래 중 한 줄만 실행함. 처음이면 npm 줄을 권함(Node.js가 이미 깔려 있다는 전제).

# (권장) npm — Windows · macOS 공통. Node.js 16 이상
npm install -g @openai/codex
# Windows — PowerShell, Node.js 없이
irm https://chatgpt.com/codex/install.ps1 | iex

# Windows — winget
winget install OpenAI.Codex
# macOS · Linux — Node.js 없이
curl -fsSL https://chatgpt.com/codex/install.sh | sh

# macOS — Homebrew
brew install --cask codex

Antigravity(Google)를 고른 경우 — 설치

# Windows — PowerShell
irm https://antigravity.google/cli/install.ps1 | iex
REM Windows — 명령 프롬프트(CMD)
curl -fsSL https://antigravity.google/cli/install.cmd -o install.cmd && install.cmd && del install.cmd
# macOS · Linux
curl -fsSL https://antigravity.google/cli/install.sh | bash

8-3. 작업 폴더 만들기 — 도구를 처음 켜기 전에#

AI 코딩 도구는 "지금 열려 있는 폴더"를 작업 공간으로 삼음. 그 폴더의 파일을 읽고, 만들고, 고침. 그래서 로그인(8-4)을 포함해 도구를 처음 켜기 전에 작업 폴더부터 만듦. 순서가 뒤바뀌면 엉뚱한 곳에 파일이 생기거나 홈 폴더 전체가 작업 대상이 됨.

규칙이유
Windows는 C:\vibecoding\ 아래바탕화면은 OneDrive 동기화 때문에 실제 경로가 C:\Users\...\OneDrive\바탕 화면\처럼 한글·띄어쓰기가 섞인 주소가 되어 오류가 잦음
macOS는 ~/Desktop/ 아래찾기 쉽고 경로 문제가 거의 없음
폴더 이름은 영문 소문자 + 밑줄(_)·하이픈(-)한글·공백·특수문자는 일부 도구에서 오류
실습 하나 = 폴더 하나CLAUDE.md·AGENTS.md·.claude/·.codex/는 폴더 단위로 적용됨. 실습 1·2를 섞으면 규칙이 엉킴(12-1·13-1)
홈 폴더·바탕화면 자체에서 그냥 실행하지 않음그 안의 모든 파일이 작업 대상이 됨

① 연습용 폴더를 만듦 — 8-4의 첫 실행·로그인을 여기서 함. 자기 운영체제 블록만 복사.

# Windows (PowerShell)
cd C:\
mkdir vibecoding -ErrorAction SilentlyContinue
cd vibecoding
mkdir hello_vibe
cd hello_vibe
# macOS
cd ~/Desktop
mkdir hello_vibe
cd hello_vibe

② VS Code에서 그 폴더를 엶 — File → Open Folder → hello_vibe 선택. "이 폴더의 작성자를 신뢰하나요?"가 뜨면 신뢰. 이렇게 열면 VS Code 터미널이 자동으로 그 폴더에서 시작하고, 확장(방법 1) 패널도 이 폴더를 작업 공간으로 씀.

③ 위치를 눈으로 확인 — 도구를 실행하기 전 매번 터미널 경로 끝을 봄.

PS C:\vibecoding\hello_vibe>          ← Windows
사용자이름@맥북 hello_vibe %           ← macOS

8-4. 설치 확인과 로그인#

터미널 경로 끝이 hello_vibe인지 확인한 뒤:

claude --version      # 2.1.xxx (Claude Code) 처럼 버전이 찍히면 성공
claude doctor         # 설치 상태를 스스로 점검해 문제를 알려 줌
claude                # 실행 → 브라우저 로그인 → 끝내려면 /exit
단계 기대하는 화면
claude --version 2.1.211 (Claude Code) 같은 줄 하나
claude 첫 실행 브라우저가 열리며 로그인 요청 → 승인하면 터미널로 돌아옴
로그인 후 프롬프트 입력창이 뜸. 아무 말이나 걸어 답이 오면 끝

로그인 따라 하기 — 구독한 사람 기준

로그인은 처음 한 번만 하면 됨. 터미널로 하든 VS Code 확장으로 하든 같은 계정 정보를 함께 씀. 비밀번호를 터미널에 치는 일은 없음 — 항상 브라우저에서 로그인하고 "허용"만 누르면 끝남.

먼저 8-3의 작업 폴더(hello_vibe)로 이동해 둠. 아래 첫 실행·로그인은 모두 그 폴더에서 함.

① Claude Code — 터미널에서

  1. 터미널에 claude 입력 → Enter
  2. 글자 색 테마를 고르라는 화면 → 방향키로 고르고 Enter (아무거나 괜찮음)
  3. 로그인 방법 선택 화면 → Claude account with subscription(Pro·Max·Team·Enterprise)을 고르고 Enter
  4. 브라우저가 저절로 열림 → 구독한 claude.ai 계정으로 로그인 → Authorize(승인) 클릭
  5. "로그인 성공" 문구가 뜨면 터미널로 돌아와 Enter
  6. "이 폴더의 파일을 신뢰하느냐"는 질문 → Yes, proceed (작업 폴더 안에서 실행했을 때만 Yes)
  7. 입력창에 안녕이라고 쳐서 답이 오면 끝. 나갈 때는 /exit

② Claude Code — VS Code 확장에서

  1. 왼쪽(또는 편집기 오른쪽 위)의 ✱ 아이콘을 눌러 Claude 패널을 엶
  2. Sign in → Claude.ai 구독(Claude.ai Subscription) 쪽을 고름
  3. 브라우저에서 로그인 → Authorize
  4. 브라우저가 "Visual Studio Code를 여시겠습니까?"라고 물으면 열기 → VS Code로 돌아와 패널에 입력창이 보이면 끝

③ Codex — 터미널에서 (Codex를 고른 경우)

  1. 터미널에 codex 입력 → Enter
  2. 로그인 방법 화면에서 Sign in with ChatGPT를 고르고 Enter
  3. 브라우저가 열림 → ChatGPT 계정으로 로그인 → 승인(Continue) → "Codex에 로그인됨" 화면이 나오면 브라우저를 닫음
  4. 터미널로 돌아오면 입력창이 뜸. 안녕을 쳐서 답이 오면 끝. 나갈 때는 /quit
  5. 확인: codex login status → Logged in using ChatGPT가 나오면 정상

④ Antigravity — 터미널에서 (Google을 고른 경우)

  1. 터미널에 agy 입력 → Enter
  2. 브라우저가 저절로 열림 → Google 계정으로 로그인 → 권한 허용
  3. 터미널로 돌아와 입력창이 뜨면 끝. 계정을 바꾸려면 /logout

유료 구독이 필요함. Claude Code는 Pro·Max·Team·Enterprise 구독 또는 Console(API) 계정에서 동작함. 무료 claude.ai 계정으로는 쓸 수 없음. PART 2 전까지 결제를 마칠 것. (실습 1의 Gemini·Tavily 키와는 별개임 — 10장 참조)

8-5. 설치가 안 될 때#

화면에 뜨는 말 원인 해결
command not found: claude
'claude'은(는) ... 인식되지 않습니다
설치 경로가 아직 반영 안 됨 터미널을 완전히 껐다 켜기. VS Code 자체를 재시작하면 더 확실함
'irm' is not recognized ... CMD에서 PowerShell 명령을 씀 PowerShell 창을 새로 열거나, CMD용 명령(방법 2)을 쓸 것
The token '&&' is not a valid statement separator PowerShell에서 CMD 명령을 씀 PowerShell용 irm ... | iex를 쓸 것
syntax error near unexpected token '<' · 403 설치 스크립트를 못 받아옴(네트워크·방화벽) VPN을 끄고 내 휴대폰 핫스폿으로 바꿔 같은 명령을 재시도. 안 되면 방법 3(winget·brew)
npm 권한 오류 EACCES 전역 설치 폴더에 쓰기 권한 없음 sudo를 붙이지 말 것. 방법 1·2·3으로 전환
[Codex] macOS에서 npm install -g @openai/codex가 EACCES Node.js 공식 설치 파일로 깐 Mac에서 흔함. 전역 폴더가 관리자 소유 sudo 금지. npm을 포기하고 brew install --cask codex 또는 curl -fsSL https://chatgpt.com/codex/install.sh | sh로 설치 → 터미널 새로 열고 codex --version
[Codex] npm 설치 중 ETIMEDOUT · ECONNRESET · ENOTFOUND · 403 · self-signed certificate 학교·회사망이 npm 저장소나 Codex 실행 파일 내려받기를 막음 내 휴대폰 핫스폿으로 바꿔 같은 명령을 다시 실행하는 것이 가장 확실함(8장 첫머리의 망 안내). 망을 못 바꾸면 Windows는 winget install OpenAI.Codex, macOS는 brew install --cask codex를 시도 (이 방법도 인터넷이 필요하므로 같은 망에서 막힐 수 있음)
[Codex] 설치는 성공했는데 codex를 인식 못 함 npm 전역 폴더가 PATH에 없음 ① 터미널을 완전히 닫았다 열기 ② npm prefix -g로 나온 폴더(Windows는 보통 C:\Users\내이름\AppData\Roaming\npm)가 PATH에 있는지 확인 — 없으면 Node.js 설치 파일을 다시 실행해 Add to PATH 체크
[Codex] codex가 바로 꺼지거나 "액세스 거부" · 백신 경고 백신(Windows Defender 등)이 codex.exe를 차단·격리 codex doctor로 점검 → 백신의 격리 목록에서 복원·허용. 학교 PC처럼 내가 못 바꾸는 PC면 개인 노트북을 쓸 것
[Claude Code] npm 설치 끝에
Native package "@anthropic-ai/claude-code-win32-x64" not found
(Mac은 ...-darwin-arm64 등)
운영체제용 본체 파일을 내려받다 실패함(망 차단·중간 끊김), 또는 npm 설정이 선택 패키지를 건너뜀 같은 명령 npm install -g @anthropic-ai/claude-code를 다시 실행. 또 실패하면 휴대폰 핫스폿 등 다른 망에서 재시도하거나 방법 2(공식 설치 스크립트)로 전환
[Claude Code] Failed to place binary · EBUSY · EPERM Claude가 실행 중이라 파일을 바꿀 수 없음(업데이트·재설치할 때 흔함), 또는 백신이 잡고 있음 열려 있는 claude를 모두 /exit, VS Code 터미널도 모두 닫음 → 새 터미널에서 다시 설치
[Claude Code] Mac에서 running x64 Node under Rosetta 2 Apple Silicon(M1~) Mac에 Intel용 Node.js가 깔림 nodejs.org에서 Node.js LTS를 다시 내려받아 설치 → 재설치. 번거로우면 방법 2(curl ... | bash)로 전환 — Node.js가 필요 없음
[Claude Code] claude doctor가 설치가 여러 개라고 경고 · 고쳐도 옛 버전이 실행됨 npm 설치와 공식 스크립트 설치가 둘 다 있음 하나만 남김. npm 쪽을 지우려면 npm uninstall -g @anthropic-ai/claude-code → 터미널 새로 열고 claude --version
EBADENGINE 경고 Node.js 버전이 22 미만 Node.js LTS를 다시 설치하거나 방법 2로 전환
PowerShell에서 스크립트 실행이 차단됨 실행 정책 제한(회사 PC에 흔함) 방법 3(winget) 또는 방법 1(VS Code 확장)
이 시스템에서 스크립트를 실행할 수 없으므로
... codex.ps1 (또는 claude.ps1) 파일을 로드할 수 없습니다
Windows PowerShell의 실행 정책이 npm 명령 파일을 막음 (새 PC의 기본값) PowerShell에 Set-ExecutionPolicy -Scope CurrentUser RemoteSigned 입력 → Y → 터미널 새로 열기. 관리자 권한 필요 없음. 가상환경 Activate.ps1 오류도 같이 풀림
Codex에서 setup refresh had errors
또는 명령 실행이 모두 실패
Windows용 Codex 샌드박스(관리자 모드) 준비 실패 %USERPROFILE%\.codex\config.toml을 메모장으로 열어 맨 아래에 [windows] 줄과 sandbox = "unelevated" 줄을 넣고 저장. [windows] 줄이 이미 있으면 새로 넣지 말고 그 아래 sandbox = "elevated"를 "unelevated"로 고침(같은 줄이 두 번 있으면 Codex가 안 켜짐). 13-8 설치 스크립트는 작업 폴더에 이 설정을 미리 넣어 둠
gemini 로그인이 안 됨 · 서비스 중단 안내 Gemini CLI는 2026-06-18부터 개인 계정 미지원 Antigravity CLI(agy)를 설치해 씀 (8-2)
python을 못 찾음 (Windows) PATH에 안 잡힘 설치 파일 재실행 → Modify → Add to PATH 체크
로그인 화면이 계속 다시 뜸 브라우저 승인이 안 돌아옴 기관 Wi-Fi라면 먼저 핫스폿으로 바꿔 재시도. 그래도 안 되면 다른 브라우저를 기본으로 두고 재시도. 확장이면 Developer: Reload Window

PART 2 전 과제 — 수업 전에 집 Wi-Fi에서 끝내 올 것 (8장 첫머리의 망 안내 참조)


PART 2. 팩트체크 도구 실습#

9장. 실습의 전제#

실습 1 — 웹 실습 2 — 에이전트
산출물 index.html 하나 (분석 + 챗봇) 로컬 폴더 1식 (서브에이전트 3 + 스킬 1)
판정 LLM gemini-3.1-flash-lite (브라우저에서 API 호출) Claude (Claude Code 본체가 직접 판정)
검색원 Tavily Search (basic) Tavily + Claude Code 내장 WebSearch
필요한 키 TAVILY_API_KEY + GEMINI_API_KEY TAVILY_API_KEY 하나
실행 위치 브라우저 (GitHub Pages) 내 컴퓨터 터미널
작업 폴더 factcheck_tavily/ factcheck_agent/ (별도 폴더)

판정 척도 — SNU 팩트체크 6단계#

판정 기준
사실 객관적 증거에 비추어 완전히 정확하고 참인 경우
대체로 사실 대체로 맞으나 일부 세부 보충 설명이나 해명이 필요한 경우
절반의 사실 사실과 거짓이 섞여 있거나 중요한 맥락이 빠져 일부만 맞는 경우
대체로 사실 아님 핵심 주장에 오류가 있거나 사실보다 허위가 더 많은 경우
전혀 사실 아님 객관적 증거와 명백히 다르며 거짓으로 판명된 경우
판단 유보 증거가 부족하거나 진위를 판가름하기 어려운 경우

이 도구는 팩트체크를 대신해 주지 않음. AI의 판정은 초벌 정리일 뿐임. 근거로 달린 URL을 사람이 열어 확인하지 않으면 그 판정은 쓸 수 없음. 이 실습의 목표는 "AI에게 판정을 맡기는 법"이 아니라 "AI의 판정을 검증하는 틀을 만드는 법"임.

10장. API 키 발급#

API 키란 — 바깥 서비스를 쓸 때 "나"임을 증명하는 긴 문자열임. 비밀번호와 같게 다뤄야 함. 남에게 보이면 그 사람이 내 요금으로 쓸 수 있음.

주소 카드 비고
Tavily https://app.tavily.com 불필요 키가 tvly-로 시작 · 검색 담당
Gemini https://aistudio.google.com/api-keys 불필요 키가 AIza로 시작 · 판정 담당 · gemini-3.1-flash-lite

Tavily 크레딧 — Search basic 1 / 질의, advanced 2 / 질의. 이 실습은 basic만 씀. crawl은 절대 금지(URL 1,000개에 약 300크레딧). 1인 실습 전체 약 40크레딧.

# 발급 직후 확인 — 키가 살아 있는지 미리 확인해 두면 실습 중 헤매지 않음
curl -X POST "https://api.tavily.com/search" \
  -H "Content-Type: application/json" -H "Authorization: Bearer YOUR_TAVILY_KEY" \
  -d '{"query":"백신 자석","search_depth":"basic","max_results":5}'

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-lite:generateContent" \
  -H "x-goog-api-key: YOUR_GEMINI_KEY" -H "Content-Type: application/json" \
  -d '{"contents":[{"parts":[{"text":"안녕"}]}]}'

11장. GitHub 저장소#

GitHub란 — 코드를 올려 두는 웹 공간임. GitHub Pages는 거기 올린 index.html을 누구나 열 수 있는 웹사이트 주소로 바꿔 주는 무료 기능임. 실습 1의 결과물을 여기에 올림.

단계 작업
① 가입 https://github.com/signup — 사용자명이 배포 URL에 그대로 들어감(신중히 정할 것)
② 저장소 https://github.com/new — 이름 factcheck_tavily · Public · README 체크
③ 파일 Add file → Upload files로 index.html을 맨 위(루트)에 올림
④ Pages Settings → Pages → Source Deploy from a branch → main / (root) → Save
⑤ 확인 1~3분 뒤 https://<사용자명>.github.io/factcheck_tavily/

Public으로 올린다는 것은 전 세계에 공개한다는 뜻임. 배포 전 점검 — [ ] 코드에 AIza로 시작하는 문자열 없음 [ ] tvly-로 시작하는 문자열 없음
VS Code에서 Ctrl+F로 AIza와 tvly-를 각각 검색해 0건인 것을 눈으로 확인할 것. 한 번 올라간 키는 지워도 회수되지 않음. 실수로 올렸다면 즉시 해당 서비스에서 키를 폐기하고 재발급할 것.


12장. 실습 1 — 팩트체크 판정 도구 (웹)#

12-1. 작업 폴더부터 — 여기서 시작함#

# macOS · Linux
cd ~/Desktop
mkdir factcheck_tavily
cd factcheck_tavily
claude
# Windows (PowerShell) — 경로가 단순한 곳을 권함
cd C:\
mkdir vibecoding -ErrorAction SilentlyContinue
cd vibecoding
mkdir factcheck_tavily
cd factcheck_tavily
claude

VS Code 확장(8장 방법 1)으로 하는 경우 — 터미널 명령 없이 이렇게 함.

  1. 탐색기에서 C:\vibecoding\factcheck_tavily 폴더를 먼저 만듦
  2. VS Code → File → Open Folder → 그 폴더를 선택
  3. 왼쪽 ✱ 아이콘을 눌러 Claude 패널을 열고, 12-2의 프롬프트를 붙여넣음
확인할 것 이유
폴더 이름을 GitHub 저장소 이름과 같게 둠 나중에 올릴 때 헷갈리지 않음
바탕화면이나 홈 폴더에서 그냥 실행하지 않음 그 폴더 전체가 작업 대상이 되어 버림
실습 2는 다른 폴더에서 함 규칙 파일이 섞임 (13-1 참조)

12-2. 던지는 것 — 프롬프트 한 장#

팩트체크 자동화 웹페이지 만들기

주장을 입력하면 자동으로 팩트체크해주는 웹페이지를 만들어줘. html js css 사용. GitHub 배포 예정.
이 웹페이지는 분석과 챗봇 2개 버전을 갖춰야 함.
LLM은 gemini-3.1-flash-lite 사용. GEMINI_API_KEY는 외부 이용자가 스스로 입력해서 사용. 발급 절차 간단 포함.
분석에서는 주장을 입력하면 검색어 뽑고 TAVILY 검색으로 참조자료를 수집한 뒤 판단해서 알려줘야 함.
TAVILY_API_KEY는 외부 이용자가 스스로 입력해서 사용. 발급 절차 간단 포함.
챗봇에서는 LLM이 일반 대화하다가 팩트체크나 그와 유사한 요청과 주장이 입력되면
앞의 분석 작동해 결과를 챗봇 대화창에 보여줘야 함.

초보자가 읽을 수 있게 간결하게 만들어줘. 화려한 UI보다 동작과 가독성을 우선. 주석은 한국어로.
만들기 전에 무엇을 만들지 먼저 알려줘.

판단은 다음 6단계 가운데 하나로 보여줘:
| 사실 | 제시된 주장이 객관적 증거에 비추어 볼 때 완전히 정확하고 참인 경우 |
| 대체로 사실 | 대체로는 맞으나 일부 세부적인 보충 설명이나 해명이 필요한 경우 |
| 절반의 사실 | 사실과 거짓이 섞여 있거나, 중요한 맥락이 빠져 있어 일부만 맞는 경우 |
| 대체로 사실 아님 | 핵심 주장에 오류가 있거나 사실보다 허위가 더 많은 경우 |
| 전혀 사실 아님 | 객관적 증거와 명백히 다르며 거짓으로 판명된 경우 |
| 판단 유보 | 증거가 부족하거나 진위 여부를 판가름하기 어려운 경우 |

왜 "만들기 전에 먼저 알려줘"인가 — 곧바로 파일을 만들지 않고 계획 화면이 먼저 뜸. 읽지 않고 승인하지 않는 습관을 여기서 잡음. 계획이 엉뚱하면 이 단계에서 되돌리는 것이 가장 쌈.

12-3. 돌아올 것 — 예측#

① 반드시 나와야 하는 것 — 프롬프트가 못박은 것

항목 확인 방법
키 입력칸 2개 + 발급 안내 화면 상단에 보이는가
분석 / 챗봇 두 화면 둘 다 접근 가능한가
Tavily 검색 → Gemini 판정 순서 검색 없이 판정하지 않는가
6단계 중 하나의 판정 6개 밖의 말이 나오지 않는가
챗봇에서 주장 입력 시 분석이 작동 일반 대화와 구분되는가
한국어 주석 코드를 열어 확인

② AI가 알아서 정할 것 — 예측

항목 예상
파일 개수 index.html 하나로 올 가능성이 높음. "GitHub 배포"가 단서가 됨
두 화면 전환 탭 또는 버튼
키 저장 방식 localStorage
Tavily 파라미터 search_depth="basic" · max_results 5 안팎
판정 표시 텍스트 또는 색 배지
오류 처리 401·429 정도는 잡아 줄 가능성이 높음

③ 어떤 형식으로 올까 — 골격 예측

<!DOCTYPE html>
<html lang="ko">
<head> … <style> … </style> </head>
<body>

  <!-- ① 키 입력칸 2개 — 코드에 키가 없어야 함 -->
  <input type="password" id="tavilyKey" placeholder="tvly-...">
  <input type="password" id="geminiKey" placeholder="AIza...">

  <!-- ② 두 화면 — 탭이나 버튼으로 전환 -->
  <section id="분석">…</section>
  <section id="챗봇">…</section>

<script>
/* ③ 키 저장 — localStorage 로 올 가능성이 높음 */
localStorage.setItem("tavily_key", …);

/* ④ Tavily 호출 — 이 형식이 핵심 */
await fetch("https://api.tavily.com/search", {
  method: "POST",
  headers: { "Content-Type": "application/json",
             "Authorization": "Bearer " + tavilyKey },
  body: JSON.stringify({ query, search_depth: "basic", max_results: 5 })
});

/* ⑤ Gemini 호출 — 모델명과 헤더가 맞는지 확인할 자리 */
await fetch("https://generativelanguage.googleapis.com/v1beta/models/"
          + "gemini-3.1-flash-lite:generateContent", {
  method: "POST",
  headers: { "Content-Type": "application/json",
             "x-goog-api-key": geminiKey },
  body: JSON.stringify({
    system_instruction: { parts: [{ text: 판정지시문 }] },
    contents: [{ role: "user", parts: [{ text: 주장 + 수집자료 }] }]
  })
});
</script>
</body></html>

판정 지시문(system_instruction)에 들어갈 내용 — 이것도 형식이 정해짐

너는 팩트체크 판정자다. 아래 [수집 자료]만을 근거로 [주장]을 판정한다.
판정은 다음 여섯 개 중 정확히 하나만 고른다.
  사실 / 대체로 사실 / 절반의 사실 / 대체로 사실 아님 / 전혀 사실 아님 / 판단 유보
출력 형식 — 첫 줄은 반드시 "판정: <여섯 개 중 하나>" 로 시작한다.
그다음 판정 근거를 쓰고, 각 근거 끝에 출처 URL을 괄호로 표기한다.
수집 자료에 없는 내용을 쓰지 않는다.

대조하는 법 — 다섯 자리를 순서대로 확인

자리 무엇을 볼까
① 키 입력칸 AIza·tvly-로 시작하는 문자열이 코드에 없는가
② 두 화면 분석과 챗봇이 둘 다 있는가
④ Tavily search_depth가 "basic"인가. crawl이 없는가
⑤ Gemini 모델명이 gemini-3.1-flash-lite인가. 헤더가 x-goog-api-key인가
지시문 6단계가 그대로 들어 있는가

④ 나오면 안 되는 것 — 적신호

적신호 왜 문제인가 조이는 말
키가 코드에 박혀 있음 공개 저장소에 올라가면 회수 불가 "키를 코드에서 빼고 화면 입력으로 바꿔 줘"
검색 0건인데 판정을 냄 근거 없는 판정 "근거가 0건이면 판단 유보로 고정해 줘"
"가짜뉴스" 같은 6단계 밖의 말 척도를 벗어남 "판정은 6단계 중 하나만 쓰게 해 줘"
판정 근거에 출처 URL이 없음 대조가 불가능해짐 "각 근거 끝에 출처 URL을 붙여 줘"
advanced 검색이나 crawl 사용 크레딧 급소모 "Search basic만 쓰게 고쳐 줘"
실패 시 자동 재시도 반복 크레딧 폭주 "재시도하지 말고 실패하면 멈추게 해 줘"

12-4. 진행 순서 — 한 번 던지고 두 번 나눠 읽음#

시간 하는 일
0~10분 작업 폴더 생성(12-1) → 프롬프트를 던지고 계획 화면을 끝까지 읽음. 승인
10~25분 분석 부분을 읽음. 키 입력 → 주장 하나 넣고 동작 확인 → ③ 다섯 자리 대조 → ④ 적신호 점검
25~30분 GitHub에 올려 배포. URL로 열림을 확인
30~45분 챗봇 부분을 읽음. 일반 대화 / 주장 입력을 각각 시험
45~50분 어긋난 곳 하나를 골라 조이는 말로 고침. 다시 배포

12-5. 체크포인트#

12-6. 자주 막히는 곳#

증상 해결
화면은 뜨는데 아무 반응이 없음 F12로 개발자 도구를 열고 Console 탭의 빨간 글씨를 확인. 그 글씨를 그대로 복사해 AI에게 붙여넣을 것
Tavily 호출 실패 (CORS) 브라우저가 외부 호출을 막은 것. 폴더에서 python -m http.server 8000을 돌리고 http://localhost:8000으로 열어 볼 것
401 · 403 키 오류. 앞뒤 공백이 딸려 들어갔는지 확인하거나 재발급
429 호출 한도 초과. 잠시 후 재시도
404 (Gemini) 모델명을 gemini-3.5-flash-lite 또는 gemini-2.5-flash-lite로 대체
크레딧이 빨리 줄어듦 basic인지, 재시도 코드가 없는지 확인
GitHub Pages가 404 index.html이 맨 위 폴더에 있는지 확인. 반영까지 1~3분 걸림

확장 과제 — 챗봇의 검색 발동 판단을 키워드 대신 Gemini에게 맡겨 {"need_search": true, "query": "..."}를 받아 분기. 이것이 라우팅(routing)의 기본 형태임.


13장. 실습 2 — 팩트체크 자동화 에이전트#

13-1. 작업 폴더부터 — 반드시 새 폴더에서#

# macOS · Linux
cd ~/Desktop
mkdir factcheck_agent
cd factcheck_agent
claude
# Windows (PowerShell)
cd C:\vibecoding
mkdir factcheck_agent
cd factcheck_agent
claude

왜 분리하는가

이유 설명
CLAUDE.md는 폴더 단위로 적용됨 웹 실습 폴더에 두면 웹앱 규칙과 에이전트 규칙이 섞임
.claude/도 폴더 단위임 서브에이전트가 엉뚱한 프로젝트에서 발동함
에이전트가 폴더 전체를 작업 대상으로 봄 같은 폴더에 있으면 index.html까지 고쳐 버림
GitHub 저장소가 달라짐 실습 1만 배포함. 에이전트는 로컬에 둠

13-2. 던지는 것 — 프롬프트 한 장#

팩트체크 자동화 에이전트 워크플로 만들기

주장을 입력하면 팩트체크하는 에이전트 워크플로를 만들고자 해.
CLAUDE.md, subagents(searcher, judge, reviewer), 그리고 필요한 skills로 구성하자.
searcher에서는 Tavily와 Claude의 자체 web search 기능을 사용해 참조자료를 수집.
.env의 TAVILY_API_KEY를 설정해 사용. Tavily Python 코드가 필요하면 scripts에 생성해 사용.
judge에서는 위 참조자료를 바탕으로 아래 6단계 가운데 하나로 판단.
reviewer에서는 위 판단 결과가 참조자료와 비교해 정확한지 재검토.
입력 주장은 input/의 txt 파일에 여러 개 입력해 동시에 진행할 수 있도록 하고,
결과는 output/에 md 파일로 보고서 생성.
시간이 너무 오래 걸리지 않도록 해.

만들기 전에 무엇을 만들지 먼저 알려줘.

6단계 판단:
| 사실 | 제시된 주장이 객관적 증거에 비추어 볼 때 완전히 정확하고 참인 경우 |
| 대체로 사실 | 대체로는 맞으나 일부 세부적인 보충 설명이나 해명이 필요한 경우 |
| 절반의 사실 | 사실과 거짓이 섞여 있거나, 중요한 맥락이 빠져 있어 일부만 맞는 경우 |
| 대체로 사실 아님 | 핵심 주장에 오류가 있거나 사실보다 허위가 더 많은 경우 |
| 전혀 사실 아님 | 객관적 증거와 명백히 다르며 거짓으로 판명된 경우 |
| 판단 유보 | 증거가 부족하거나 진위 여부를 판가름하기 어려운 경우 |

Codex·Antigravity를 쓰는 사람은 이 프롬프트를 쓰지 말 것. 위 프롬프트는 Claude Code 전용 폴더 구조(.claude/)를 만듦. Codex는 이 위치를 읽지 않아 서브에이전트·스킬이 나타나지 않음. → Codex는 13-8, Antigravity는 13-9로 바로 갈 것.

13-3. 돌아올 것 — 예측#

① 거의 확실한 것 — 경로가 규약으로 정해져 있음

factcheck_agent/
├── CLAUDE.md                                 매 세션 자동 로드
├── .claude/agents/searcher.md                검색 담당
├── .claude/agents/judge.md                   판정 담당
├── .claude/agents/reviewer.md                검토 담당
├── .claude/skills/<이름>/SKILL.md            보고서 절차
├── scripts/search_tavily.py                  Tavily 호출
├── input/claims.txt                          조사할 주장
├── output/                                   보고서 저장
└── .env.example · .gitignore · requirements.txt

② 어떤 형식으로 올까 — 파일별 골격

CLAUDE.md — 프론트매터가 없음. 그냥 마크다운임

# 작업 흐름
1. searcher 로 근거를 모은다.
2. judge 로 6단계 중 하나를 고른다.
3. reviewer 로 검토한다. 지적이 있으면 judge 가 한 번만 고친다.
4. 보고서 스킬로 output/ 에 저장한다.

# 검색원
- Tavily (scripts/search_tavily.py) — 1회 = 1크레딧
- WebSearch (Claude Code 내장) — 크레딧 무관
- 주장 하나당 각 검색원을 1회씩만 호출한다.

# 하지 말 것
- .env 를 커밋하지 않는다.
- 자동 재시도 루프를 만들지 않는다. 실패하면 멈춘다.
- 근거가 없으면 판단 유보를 고른다.

서브에이전트 — ---로 감싼 프론트매터가 핵심임

---
name: searcher
description: 주장의 근거 자료를 웹에서 수집해야 할 때 사용한다.
             모으기만 하고 해석하거나 판단하지 않는다.
tools: Bash, Read, Write, WebSearch
---

너는 자료 수집만 담당하는 조사원이다.
1. 주장에서 핵심 명사 2~3개를 뽑아 검색어를 만든다.
2. Tavily 와 WebSearch 를 각각 1회씩 실행한다.
3. 결과를 [Tavily] · [WebSearch] 출처를 붙여 그대로 넘긴다.
해석하지 않는다. 참·거짓을 언급하지 않는다.
---
name: judge
description: 수집이 끝난 자료로 주장을 6단계 중 하나로 판정할 때 사용한다.
             직접 검색하지 않고 주어진 자료만 쓴다.
tools: Read, Write
---
… 6단계 척도 … 자료 밖의 지식으로 판정하지 않는다 …
근거가 부족하면 판단 유보를 고른다. 애매하면 한 단계 약하게 판정한다.
---
name: reviewer
description: 판정 결과를 저장 전에 검토할 때 사용한다.
             근거보다 센 판정과 출처 없는 문장을 잡아낸다.
tools: Read
model: haiku
---
… 점검 항목을 순서대로 확인하고 통과 / 지적 으로 답한다 …
직접 고치지 않는다. 지적만 한다.
에이전트 tools: 막히는 것
searcher Bash 포함 — (검색 스크립트를 실행해야 함)
judge Bash 없음 검색을 실행할 수단 자체가 없음
reviewer Read 하나 쓰기도 실행도 못 함

스킬 — 폴더 안에 SKILL.md로 둠

---
name: factcheck-report
description: 팩트체크 판정 결과를 보고서 파일로 저장할 때 사용한다.
             주장별 판정이 끝나고 output 폴더에 결과를 남기는 단계에서 이 절차를 따른다.
---

- 저장: output/factcheck_YYYY-MM-DD_HHMM.md  (덮어쓰지 않음)
- 주장마다: 판정 / 판정 근거(+출처 URL) / 사용한 검색어 /
            수집된 근거 / 자료의 한계 / 검토 기록
- 끝에 「부록. 판정 요약」 표를 붙인다.
- 근거 0건인 주장도 빼지 않고 기록한다.

scripts/search_tavily.py — 볼 곳은 세 군데뿐

def search(query, max_results=5):
    # ① 캐시 우선 — 같은 검색어면 크레딧 0
    if cache_path(query).exists():
        return json.loads(cache_path(query).read_text(encoding="utf-8"))

    res = requests.post(
        "https://api.tavily.com/search",
        headers={"Authorization": f"Bearer {os.environ['TAVILY_API_KEY']}"},
        json={"query": query,
              "search_depth": "basic",   # ② advanced 는 2크레딧이므로 쓰지 않는다
              "max_results": max_results},
        timeout=30)

    if not res.ok:
        raise SystemExit(f"검색 실패 HTTP {res.status_code}")   # ③ 재시도하지 않고 멈춤
    ...
볼 곳 확인할 것
① 캐시 있으면 좋은 신호. 프롬프트에 없던 것을 AI가 붙인 것
② search_depth "basic"이어야 함. advanced나 crawl이면 고칠 것
③ 실패 처리 raise로 멈춰야 함. while 재시도가 있으면 크레딧 폭주

③ 예측하기 어려운 것

항목 왜
각 파일의 줄 수와 문장 표현 매번 다름
tools: 줄을 넣을지 넣으면 좋은 신호 (권한 제한을 스스로 설계한 것)
검색 결과 캐시를 붙일지 프롬프트에 없음. 붙으면 크레딧 절약
reviewer의 점검 항목 개수 3개일 수도 6개일 수도 있음
보고서의 구체적 섹션 이름 스킬 본문이 정함

④ 나오면 안 되는 것 — 적신호

적신호 조이는 말
judge에게 검색 권한이 있음 "judge의 tools에서 검색 도구를 빼 줘"
reviewer가 직접 고침 "reviewer는 tools를 Read 하나만 주고 지적만 하게 해 줘"
description이 두루뭉술함 "description을 '언제 쓰는지' 문장으로 다시 써 줘"
재시도 루프가 있음 "실패하면 멈추게 해 줘. 재시도 루프를 만들지 마"
.env가 .gitignore에 없음 ".env를 .gitignore에 넣어 줘"
search_depth가 advanced "basic으로 고쳐 줘"

읽을 때 볼 곳 세 군데 ① description — 자동 발동을 좌우함. ② tools: — 그 에이전트가 할 수 없는 일을 정함. ③ # 하지 말 것 — harness engineering의 실물. 여기 적힌 만큼만 막힘.

13-4. 스킬의 결과, 어디까지 예측되는가#

내용
예측 가능 파일 경로 · 프론트매터(name·description) · 보고서가 output/에 .md로 저장됨
예측 불가 보고서의 섹션 이름과 순서 · 문장 표현 · 파일 분량
관찰로 확인 주장 3개를 넣었을 때 보고서 3건의 형식이 같은가

13-5. 설정 순서#

단계 작업
① 13-1대로 factcheck_agent/ 새 폴더를 만들고 그 안에서 claude 실행
② 13-2 프롬프트를 던지고 계획 화면을 읽은 뒤 승인
③ 생성된 파일을 13-3의 네 목록과 대조. 적신호가 있으면 조이는 말로 고침
④ cp .env.example .env (Windows는 copy .env.example .env) → 키 입력
⑤ python -m venv .venv → 활성화 → pip install -r requirements.txt
⑥ input/claims.txt에 주장 3개를 한 줄에 하나씩 작성
⑦ 검색 스크립트 단독 테스트: python scripts/search_tavily.py "백신 자석"
⑧ claude 실행 → "input/claims.txt의 주장들을 조사해 줘"

⑤ 가상환경(venv) 활성화 명령 — 운영체제마다 다름

source .venv/bin/activate          # macOS · Linux
.venv\Scripts\Activate.ps1         # Windows PowerShell
.venv\Scripts\activate.bat         # Windows CMD

13-6. 관찰 포인트#

13-7. 자동 발동이 안 걸릴 때#

정리 — 폴더가 "무엇이 있는지", description이 "언제 쓰는지", CLAUDE.md가 "그래도 놓치지 마라"를 담당함.

13-8. Codex로 할 때 — 반드시 이 순서#

Codex를 고른 사람은 13-2~13-7 대신 이 절만 따라 하면 됨. 아래 절차는 Codex CLI 0.160(2026년 10월 최신)으로 빈 폴더에서 처음부터 끝까지 실제로 돌려 서브에이전트 3개 호출 → 보고서 저장까지 확인한 순서임.

왜 Claude Code처럼 하면 Codex에서 안 나타나는가 — 직접 재현해 확인한 원인 다섯

원인겉으로 보이는 증상
①스킬 위치가 다름 — Codex는 .agents/skills/만 읽음 (.claude/skills·.codex/skills는 무시)스킬이 목록에 없음
②"신뢰한 폴더"에서만 .codex/ 안의 설정과 서브에이전트를 읽음파일은 있는데 서브에이전트가 default·explorer·worker만 보임
③Codex의 안전장치(샌드박스)가 .codex/ 폴더를 쓰기 금지 구역으로 막음Codex에게 만들라고 시키면 PC마다 되기도 하고 "액세스 거부"로 실패하기도 함
④샌드박스가 기본으로 인터넷을 막음Tavily 스크립트가 늘 "연결 실패·시간 초과"
⑤Codex는 서브에이전트를 알아서 부르지 않음혼자 다 해 버리고 searcher·judge·reviewer가 안 불림

따라 하기 — ①부터 ⑨까지 순서대로

단계할 일성공하면 보이는 것
①작업 폴더를 만듦 (아래 명령). 아직 codex를 실행하지 않음터미널 경로 끝이 factcheck_agent
②VS Code → File → Open Folder → 그 폴더 선택 → 왼쪽 탐색기의 새 파일 아이콘 → 이름을 setup_codex.py로 → 아래 코드 전체를 복사해 붙여넣고 Ctrl+S 저장
(또는 코드 위의 내려받기 버튼으로 받아 이 폴더로 옮김)
탐색기에 setup_codex.py 하나
③VS Code 터미널(Ctrl+백틱)에서
python setup_codex.py (macOS는 python3 setup_codex.py)
만듦: ... 12줄 + 신뢰 폴더 등록 + 완료
④탐색기에서 .env를 열어 tvly-YOUR_KEY를 내 Tavily 키로 바꾸고 저장—
⑤검색만 따로 시험:
python scripts/search_tavily.py --query "백신 자석"
"results": [가 들어 있는 검색 결과. "error"가 나오면 아래 문제 해결 표
⑥같은 터미널에서 codex 실행
(이미 켜 둔 Codex가 있으면 /quit로 끄고 다시 실행 — 설정은 켤 때만 읽음)
입력창. Trust this folder?가 뜨면 Yes
⑦인식 확인 — 이렇게 물음:
사용할 수 있는 서브에이전트(agent_type)와 이 폴더 스킬 이름을 알려줘
searcher·judge·reviewer와 factcheck-report가 모두 나옴
⑧input/claims.txt에 주장 3개(한 줄에 하나)를 적고 저장한 뒤, Codex에:
input/claims.txt의 주장들을 searcher, judge, reviewer 서브에이전트로 팩트체크하고 factcheck-report 스킬로 보고서를 저장해 줘
서브에이전트가 차례로 불리는 표시 → 주장별 판정 요약
⑨output/factcheck_날짜_시각.md를 열어 확인주장마다 판정·근거 URL·검토 기록 + 끝에 「부록. 판정 요약」
# ① Windows (PowerShell)
cd C:\
mkdir vibecoding -ErrorAction SilentlyContinue
cd vibecoding
mkdir factcheck_agent
cd factcheck_agent
# ① macOS
cd ~/Desktop
mkdir factcheck_agent
cd factcheck_agent

설치 스크립트 setup_codex.py — 그대로 복사

# setup_codex.py — Codex용 팩트체크 에이전트 뼈대를 한 번에 만든다.
# 사용법: 빈 작업 폴더(factcheck_agent)에 이 파일을 저장하고
#         Windows: python setup_codex.py   /   macOS: python3 setup_codex.py
import os, sys
from pathlib import Path

ROOT = Path.cwd()
PY = "python" if os.name == "nt" else "python3"   # 에이전트가 쓸 파이썬 명령

FILES = {}

FILES["AGENTS.md"] = f"""# 팩트체크 에이전트 작업 규칙

## 작업 흐름 (반드시 이 순서)
팩트체크 요청이 오면 주장마다 아래 순서로 서브에이전트를 spawn해서 진행한다.
1. searcher 서브에이전트: 근거 자료 수집 (Tavily + 내장 웹 검색)
2. judge 서브에이전트: searcher 자료만으로 6단계 중 하나로 판정
3. reviewer 서브에이전트: 판정이 자료와 맞는지 1회 재검토
4. 메인 에이전트가 factcheck-report 스킬(.agents/skills/factcheck-report/SKILL.md)을 읽고 output/에 보고서 저장
서브에이전트를 쓸 수 없으면 쓴 척하지 말고 사용자에게 알린다.

## 입력
- input/claims.txt 에 한 줄에 주장 하나. 빈 줄은 건너뛴다.
- 주장이 여러 개면 최대 3개까지 동시에 진행한다.

## 검색원
- Tavily: `{PY} scripts/search_tavily.py --query "검색어"` (1회 = 1크레딧, 주장당 1회)
- 내장 웹 검색: 주장당 최대 2회
- 검색어는 문장 통째가 아니라 핵심 명사 2~3개로 만든다.

## 6단계 판정
| 판정 | 기준 |
| --- | --- |
| 사실 | 제시된 주장이 객관적 증거에 비추어 볼 때 완전히 정확하고 참인 경우 |
| 대체로 사실 | 대체로는 맞으나 일부 세부적인 보충 설명이나 해명이 필요한 경우 |
| 절반의 사실 | 사실과 거짓이 섞여 있거나, 중요한 맥락이 빠져 있어 일부만 맞는 경우 |
| 대체로 사실 아님 | 핵심 주장에 오류가 있거나 사실보다 허위가 더 많은 경우 |
| 전혀 사실 아님 | 객관적 증거와 명백히 다르며 거짓으로 판명된 경우 |
| 판단 유보 | 증거가 부족하거나 진위 여부를 판가름하기 어려운 경우 |

## 하지 말 것
- .env 내용이나 API 키를 화면·보고서에 출력하지 않는다.
- 실패하면 재시도 루프를 돌지 않는다. 실패 사실을 기록하고 다음으로 넘어간다.
- 근거가 없으면 판단 유보를 고른다. 검색 실패는 거짓의 증거가 아니다.
"""

FILES[".codex/config.toml"] = """# 이 폴더에서만 쓰는 Codex 설정 (폴더를 '신뢰'해야 읽힘)
sandbox_mode = "workspace-write"   # 이 폴더 안에서만 파일 생성·수정
web_search = "live"                # 내장 웹 검색을 실시간으로

[sandbox_workspace_write]
network_access = true              # Tavily 스크립트가 인터넷에 접속하도록 허용

[windows]
sandbox = "unelevated"             # Windows: 관리자 권한 없이 동작하는 샌드박스
"""

FILES[".codex/agents/searcher.toml"] = f'''name = "searcher"
description = "팩트체크할 주장의 근거 자료를 웹에서 수집해야 할 때 사용한다. 모으기만 하고 판정하지 않는다."
developer_instructions = """
너는 자료 수집만 담당하는 조사원이다. 판정하지 않고 참·거짓을 말하지 않는다.
1. 주장에서 핵심 명사 2~3개를 뽑아 검색어를 만든다.
2. 터미널에서 {PY} scripts/search_tavily.py --query "검색어" 를 1회 실행한다.
3. 내장 웹 검색을 최대 2회 실행해 지지·반박 자료를 찾는다.
4. 자료마다 [Tavily] 또는 [WebSearch] 표시, 제목, 실제 URL, 핵심 문장 인용을 정리해 돌려준다.
5. 실패한 검색원은 실패 이유를 적는다. 없는 URL이나 내용을 지어내지 않는다.
"""
'''

FILES[".codex/agents/judge.toml"] = '''name = "judge"
description = "수집이 끝난 자료로 주장을 6단계 중 하나로 판정할 때 사용한다. 직접 검색하지 않는다."
sandbox_mode = "read-only"
developer_instructions = """
너는 판정자다. 전달받은 searcher 자료만 근거로 쓴다. 새로 검색하지 않고 파일을 고치지 않는다.
판정은 사실 / 대체로 사실 / 절반의 사실 / 대체로 사실 아님 / 전혀 사실 아님 / 판단 유보 중 정확히 하나.
첫 줄은 반드시 "판정: <여섯 개 중 하나>" 로 시작한다.
그다음 판정 근거를 쓰고, 각 근거 끝에 출처 URL을 괄호로 붙인다.
근거가 부족하면 판단 유보를 고르고, 애매하면 한 단계 약하게 판정한다.
"""
'''

FILES[".codex/agents/reviewer.toml"] = '''name = "reviewer"
description = "judge의 판정을 저장하기 전에 참조자료와 대조해 검토할 때 사용한다."
sandbox_mode = "read-only"
developer_instructions = """
너는 검토자다. 직접 고치지 않고 지적만 한다. 검토는 1회로 끝낸다.
점검: (1) 판정이 6단계 중 하나인가 (2) 근거마다 출처 URL이 있고 자료에 실제로 있는 URL인가
(3) 근거보다 센 판정이 아닌가 (4) 자료 밖의 내용을 쓰지 않았나.
답 형식: 첫 줄 "검토: 통과" 또는 "검토: 지적", 이어서 지적 사항과 권하는 최종 판정.
"""
'''

FILES[".agents/skills/factcheck-report/SKILL.md"] = """---
name: factcheck-report
description: 팩트체크 판정과 검토가 끝난 뒤 결과를 output 폴더에 보고서 파일로 저장할 때 사용한다.
---

# 팩트체크 보고서 저장 절차
1. 파일 이름: output/factcheck_YYYY-MM-DD_HHMM.md (기존 파일을 덮어쓰지 않는다)
2. 주장마다 아래 순서로 쓴다.
   - ## 주장 N: <원문>
   - **판정:** reviewer 검토를 반영한 최종 판정 (6단계 중 하나)
   - **판정 근거:** 문장마다 끝에 출처 URL
   - **사용한 검색어:** Tavily / 웹 검색
   - **수집된 근거:** 표 (출처 | 제목 | URL)
   - **자료의 한계**
   - **검토 기록:** judge 판정 → reviewer 의견 → 최종 판정
3. 맨 끝에 「부록. 판정 요약」 표 (번호 | 주장 | 최종 판정)
4. 근거 0건이거나 실패한 주장도 빼지 않고 판단 유보로 기록한다.
"""

FILES["scripts/search_tavily.py"] = '''# Tavily 검색 스크립트 — 파이썬 기본 기능만 사용 (추가 설치 불필요)
# 사용: python scripts/search_tavily.py --query "백신 자석"
import argparse, json, os, sys, urllib.error, urllib.request
from pathlib import Path

sys.stdout.reconfigure(encoding="utf-8")  # Windows 한글 깨짐 방지


def load_key():
    # 환경변수 → .env 파일 순서로 키를 찾는다
    key = os.environ.get("TAVILY_API_KEY", "")
    env = Path(__file__).resolve().parent.parent / ".env"
    if not key and env.exists():
        for line in env.read_text(encoding="utf-8-sig").splitlines():
            if line.strip().startswith("TAVILY_API_KEY="):
                key = line.split("=", 1)[1].strip().strip('"').strip("'")
    return key


def main():
    p = argparse.ArgumentParser()
    p.add_argument("--query", required=True)
    p.add_argument("--max-results", type=int, default=5)
    q = p.parse_args()

    key = load_key()
    if not key.startswith("tvly-") or "YOUR" in key:
        print(json.dumps({"error": ".env 파일에 실제 TAVILY_API_KEY를 넣어 주세요"}, ensure_ascii=False))
        sys.exit(1)

    body = json.dumps({"query": q.query, "search_depth": "basic",  # basic = 1크레딧
                       "max_results": q.max_results}).encode("utf-8")
    req = urllib.request.Request(
        "https://api.tavily.com/search", data=body, method="POST",
        headers={"Content-Type": "application/json", "Authorization": "Bearer " + key})
    try:
        with urllib.request.urlopen(req, timeout=30) as res:
            data = json.loads(res.read().decode("utf-8"))
    except urllib.error.HTTPError as e:      # 401 키 오류, 429 한도 초과 등 — 재시도하지 않고 멈춘다
        print(json.dumps({"error": "Tavily HTTP 오류", "status": e.code}, ensure_ascii=False))
        sys.exit(1)
    except Exception as e:                   # 인터넷 차단·시간 초과
        print(json.dumps({"error": "Tavily 연결 실패", "detail": str(e)}, ensure_ascii=False))
        sys.exit(1)

    results = [{"title": r.get("title"), "url": r.get("url"), "content": r.get("content")}
               for r in data.get("results", [])]
    print(json.dumps({"query": q.query, "results": results}, ensure_ascii=False, indent=2))


if __name__ == "__main__":
    main()
'''

FILES[".env.example"] = "TAVILY_API_KEY=tvly-YOUR_KEY\n"
FILES[".gitignore"] = ".env\n__pycache__/\n"
FILES["input/claims.txt"] = "대한민국의 수도는 서울이다.\n물은 압력과 관계없이 항상 섭씨 100도에서 끓는다.\n코로나19 백신을 맞으면 몸에 자석이 붙는다.\n"
FILES["output/.gitkeep"] = ""


def write_files():
    for rel, text in FILES.items():
        path = ROOT / rel
        if path.exists() and rel in ("input/claims.txt", ".env.example"):
            continue  # 이미 쓰던 입력은 덮어쓰지 않는다
        path.parent.mkdir(parents=True, exist_ok=True)
        path.write_text(text, encoding="utf-8", newline="\n")
        print("  만듦:", rel)
    env = ROOT / ".env"
    if not env.exists():
        env.write_text(FILES[".env.example"], encoding="utf-8")
        print("  만듦: .env  ← 여기에 Tavily 키를 넣을 것")


def trust_folder():
    # Codex는 '신뢰한 폴더'에서만 .codex/ 설정과 서브에이전트를 읽는다.
    # Codex 첫 화면의 'Trust this folder? → Yes'와 같은 일을 미리 해 둔다.
    home = Path(os.environ.get("CODEX_HOME", Path.home() / ".codex"))
    cfg = home / "config.toml"
    key = str(ROOT)
    old = cfg.read_text(encoding="utf-8") if cfg.exists() else ""
    if key in old or key.lower() in old.lower():
        print("  신뢰 폴더: 이미 등록됨")
        return
    home.mkdir(parents=True, exist_ok=True)
    entry = f"\n[projects.'{key}']\ntrust_level = \"trusted\"\n"
    cfg.write_text(old.rstrip("\n") + "\n" + entry if old else entry.lstrip(), encoding="utf-8")
    print("  신뢰 폴더 등록:", key)


if __name__ == "__main__":
    if "'" in str(ROOT):
        sys.exit("폴더 경로에 작은따옴표(')가 있으면 안 됨. C:\\vibecoding\\factcheck_agent 같은 경로에서 실행할 것.")
    print("작업 폴더:", ROOT)
    write_files()
    trust_folder()
    print("\n완료. 다음 순서:")
    print(" 1) .env 파일을 열어 tvly-YOUR_KEY 를 내 Tavily 키로 바꾸고 저장")
    print(f" 2) {PY} scripts/search_tavily.py --query \"백신 자석\"  로 검색 확인")
    print(" 3) codex 실행 → '사용할 수 있는 서브에이전트와 스킬 이름을 알려줘'")

이 스크립트가 만드는 것 — 13-3의 Claude 버전과 1:1로 대응함

factcheck_agent/
├── AGENTS.md                                  ← CLAUDE.md 자리 (작업 흐름 · 6단계 · 하지 말 것)
├── .codex/config.toml                         ← 이 폴더 전용 설정 (인터넷 허용 · 웹 검색 · Windows 샌드박스)
├── .codex/agents/searcher.toml                ← 검색 담당
├── .codex/agents/judge.toml                   ← 판정 담당 (sandbox_mode = "read-only")
├── .codex/agents/reviewer.toml                ← 검토 담당 (sandbox_mode = "read-only")
├── .agents/skills/factcheck-report/SKILL.md   ← 보고서 절차 (Codex의 스킬 위치)
├── scripts/search_tavily.py                   ← Tavily 호출 (추가 설치 불필요)
├── input/claims.txt · output/
└── .env · .env.example · .gitignore

Codex 문제 해결

증상원인해결
⑦에서 서브에이전트가 default·explorer·worker뿐폴더가 신뢰되지 않음 · 다른 폴더에서 실행터미널 경로 끝이 factcheck_agent인지 확인 → 그 자리에서 python setup_codex.py 재실행 → Codex 재시작
⑦에서 factcheck-report가 없음스킬 파일 위치 오류.agents/skills/factcheck-report/SKILL.md가 있는지 탐색기로 확인. 없으면 스크립트 재실행
⑤에서 .env 파일에 실제 TAVILY_API_KEY를 넣어 주세요키를 안 넣었거나 저장 안 함.env의 tvly-YOUR_KEY를 실제 키로 바꾸고 Ctrl+S
"status": 401키 오류키 앞뒤 공백 확인, Tavily 대시보드에서 키를 다시 복사
⑤는 되는데 Codex 안에서만 Tavily 연결 실패인터넷 허용 설정이 안 읽힘(원인 ②·④)폴더 신뢰 확인(이 표 첫 줄) 후 Codex 재시작
명령이 전부 setup refresh had errors로 실패Windows 샌드박스8-5 표의 해당 줄
python을 못 찾음PATH8-5 표. macOS는 python3

Claude Code와 비교해 관찰할 것 — 같은 일을 시켰는데 설정 파일의 이름·위치·형식(.md 대 .toml)이 모두 다름. 그러나 규칙 파일 + 역할별 서브에이전트 + 권한 제한 + 보고서 스킬이라는 설계는 그대로임. 도구가 바뀌어도 3·4단계의 설계 방식은 그대로 옮겨 감 — 이것이 이 절의 학습 목표임.

13-9. Antigravity(Google)로 할 때#

단계할 일
①13-8의 ①처럼 factcheck_agent 새 폴더를 만들고 그 안에서 agy 실행
②아래 프롬프트를 붙여넣음 → 계획을 읽고 승인
③파일이 다 만들어지면 /exit → agy를 다시 실행(새 설정 읽기)
④/agents를 입력해 searcher·judge·reviewer가 보이는지 확인
⑤13-8의 ④⑤처럼 .env에 키를 넣고 검색 스크립트를 단독 시험
⑥input/claims.txt의 주장들을 searcher, judge, reviewer 서브에이전트로 팩트체크하고 factcheck-report 스킬로 보고서를 저장해 줘
팩트체크 자동화 에이전트 워크플로 만들기 (Antigravity CLI용)

주장을 입력하면 팩트체크하는 에이전트 워크플로를 만들고자 해.
아래 경로 규칙을 반드시 지켜서 만들어줘. 경로가 틀리면 Antigravity가 인식하지 못함.
- 규칙 파일: AGENTS.md (폴더 맨 위)
- 서브에이전트 3개: .agents/agents/searcher.md, .agents/agents/judge.md, .agents/agents/reviewer.md
  각 파일 맨 위 --- 프론트매터에 name, description, tools, subagent: true 를 반드시 넣음.
  tools에는 네가 지금 실제로 쓸 수 있는 도구 이름만 정확한 철자로 적음. 없는 이름을 적으면 멈춤.
  searcher는 웹 검색·명령 실행·파일 읽기 도구, judge와 reviewer는 파일 읽기 도구만 줌.
- 스킬: .agents/skills/factcheck-report/SKILL.md (맨 위에 name, description 프론트매터)
searcher에서는 Tavily와 너의 자체 웹 검색 기능을 사용해 참조자료를 수집.
.env의 TAVILY_API_KEY를 설정해 사용. Tavily 호출 코드는 scripts/search_tavily.py 로 만들고,
파이썬 기본 라이브러리(urllib)만 써서 추가 설치 없이 돌게 해줘. search_depth는 basic, 실패하면 재시도하지 말고 멈춤.
judge에서는 위 참조자료를 바탕으로 아래 6단계 가운데 하나로 판단.
reviewer에서는 위 판단 결과가 참조자료와 비교해 정확한지 재검토.
AGENTS.md에는 "팩트체크 요청이 오면 반드시 searcher → judge → reviewer 서브에이전트를 차례로 호출해서 진행하고,
마지막에 factcheck-report 스킬로 보고서를 저장한다"는 작업 흐름을 적어줘.
입력 주장은 input/claims.txt 에 한 줄에 하나씩 여러 개 넣어 동시에 진행할 수 있도록 하고,
결과는 output/에 md 파일로 보고서 생성.
.env.example 과 .gitignore(.env 포함)도 만들어줘.
시간이 너무 오래 걸리지 않도록 해.

만들기 전에 무엇을 만들지 먼저 알려줘.

6단계 판단:
| 사실 | 제시된 주장이 객관적 증거에 비추어 볼 때 완전히 정확하고 참인 경우 |
| 대체로 사실 | 대체로는 맞으나 일부 세부적인 보충 설명이나 해명이 필요한 경우 |
| 절반의 사실 | 사실과 거짓이 섞여 있거나, 중요한 맥락이 빠져 있어 일부만 맞는 경우 |
| 대체로 사실 아님 | 핵심 주장에 오류가 있거나 사실보다 허위가 더 많은 경우 |
| 전혀 사실 아님 | 객관적 증거와 명백히 다르며 거짓으로 판명된 경우 |
| 판단 유보 | 증거가 부족하거나 진위 여부를 판가름하기 어려운 경우 |

유료 Gemini API 키로 옛 Gemini CLI(gemini)를 쓰는 경우 — 규칙 GEMINI.md(또는 AGENTS.md) · 서브에이전트 .gemini/agents/<이름>.md · 스킬 .agents/skills/. 처음 실행 때 뜨는 Do you trust the files in this folder?에서 신뢰를, 이어 뜨는 New Agents Discovered에서 Acknowledge and Enable을 눌러야 서브에이전트가 등록됨. 이 창을 건너뛰면 파일이 있어도 서브에이전트가 없는 것처럼 동작함.


용어 미니 사전#

낱말 뜻
터미널 (Terminal · CLI) 명령을 글자로 입력하는 검은 창. 마우스 대신 키보드로 컴퓨터에 일을 시킴
PATH 컴퓨터가 프로그램을 찾아보는 폴더 목록. 여기 등록이 안 되면 "명령을 찾을 수 없음"이 뜸
LLM Large Language Model. ChatGPT·Claude·Gemini의 속 알맹이인 언어 모델
문맥창 (context window) AI가 한 번에 읽어 둘 수 있는 분량. 책상 위에 펼친 자료의 크기
API 다른 서비스의 기능을 프로그램이 불러 쓰는 창구
API 키 그 창구에서 "나"임을 증명하는 긴 문자열. 비밀번호처럼 다룰 것
프롬프트 AI에게 주는 지시문
서브에이전트 메인이 불러내는 별도의 일꾼. 자기 문맥창에서 한 가지 일만 함
프론트매터 파일 맨 위에 ---로 감싼 설정 구역. 도구는 여기 적힌 것만 읽음
마크다운 (.md) #·- 같은 기호로 서식을 표시하는 글자 문서 형식
저장소 (repository) GitHub에서 프로젝트 하나가 들어가는 방
커밋 (commit) 바뀐 내용을 기록으로 남기는 저장
.gitignore GitHub에 올리지 않을 파일 목록. .env는 반드시 여기 넣음
.env API 키 같은 비밀값을 따로 담아 두는 파일
CORS 브라우저가 다른 사이트로의 호출을 막는 보안 규칙
콘솔 (Console) F12로 여는 개발자 도구의 탭. 웹페이지 오류가 여기 찍힘
크레딧 유료 API에서 호출할 때마다 깎이는 사용량

참고 링크#

항목 URL
바이브 코딩 가이드 https://jonghhhh.github.io/vibecoding_guide/
Claude Code 공식 문서 https://code.claude.com/docs/
Claude Code 설치 안내 https://code.claude.com/docs/en/setup
Claude Code VS Code 확장 https://code.claude.com/docs/en/vs-code
VS Code 내려받기 https://code.visualstudio.com
Node.js 내려받기 (LTS) https://nodejs.org
파이썬 내려받기 https://www.python.org/downloads/
Git for Windows https://git-scm.com/downloads/win
Gemini API 문서 https://ai.google.dev/gemini-api/docs?hl=ko
Gemini 키 발급 https://aistudio.google.com/api-keys
Tavily 가입 https://app.tavily.com
Tavily API 문서 https://docs.tavily.com/documentation/api-reference/introduction
GitHub 가입 https://github.com/signup
GitHub 새 저장소 https://github.com/new
SNU 팩트체크 https://factcheck.snu.ac.kr

실습 전 최종 점검#

  1. 설치와 로그인이 끝났는가 — claude --version이 찍히거나, VS Code 확장 패널에서 답이 오는가 (8-4)
    Codex는 codex login status, Antigravity는 agy에서 답이 오는지. Codex는 13-8의 ⑦ 인식 확인까지 미리 해 둘 것
  2. 유료 구독이 활성 상태인가 — 무료 claude.ai 계정으로는 실습 2가 진행되지 않음
  3. 키 두 개가 살아 있는가 — 10장의 curl 두 줄로 미리 확인해 둘 것
  4. gemini-3.1-flash-lite가 호출되는가 — 404면 gemini-3.5-flash-lite 또는 gemini-2.5-flash-lite
  5. 작업 폴더 두 개를 미리 만들어 두었는가 — factcheck_tavily/와 factcheck_agent/는 서로 다른 폴더여야 함 (13-1)
  6. 시험할 주장 5~6개를 준비했는가 — 검색 결과가 잘 나오는 것으로 골라 둘 것. 너무 최근 사건이나 너무 사소한 주장은 근거가 안 잡힘
  7. Tavily 크레딧이 남아 있는가 — 대시보드에서 잔량 확인. 1인 실습 전체 약 40크레딧

버전 주의 — 모델명·요금·무료 한도·API 인증 방식·설치 명령은 변동이 잦음. 실습 직전에 각 공식 문서에서 확인할 것. 이 특강의 내용은 2026년 9월 기준임.