GYMCODING

하네스·루프·그래프 엔지니어링 차이: AI 에이전트 설계 실전 가이드

하네스·루프·그래프 엔지니어링의 차이와 사용 시점, AI 에이전트 설계 예시, 복사 프롬프트와 Python 코드를 한 번에 정리합니다.

이런 분을 위한 글입니다

  • AI에게 일을 맡겼지만 결과가 들쭉날쭉해 계속 직접 수정하는 분
  • 하네스, 루프, 그래프 엔지니어링의 차이가 헷갈리는 분
  • Claude Code와 AI 에이전트로 반복 업무를 자동화하고 싶은 분

읽고 나면 이렇게 달라집니다

  • AI가 실패했을 때 프롬프트가 아니라 어느 구조를 고쳐야 하는지 판단할 수 있습니다
  • 검증 루프와 병렬 조사 그래프를 복사 프롬프트와 코드로 바로 적용할 수 있습니다
  • 하네스·루프·그래프를 하나의 시스템으로 결합하는 방법을 이해할 수 있습니다

AI가 일을 제대로 끝내지 못하면 우리는 보통 프롬프트부터 고칩니다.

“더 구체적으로 써야 하나?”, “역할을 하나 더 부여해야 하나?”, “좋은 예시를 더 넣어야 하나?”라고 생각하면서 같은 요청을 여러 번 바꿔 입력하죠.

물론 프롬프트가 문제일 때도 있습니다. 하지만 AI가 파일에 접근하지 못하고, 이전 작업을 잊고, 결과를 검사하지 않고, 복잡한 업무 순서를 엉키게 만드는 문제는 프롬프트만 고쳐서 해결하기 어렵습니다.

이때 봐야 할 것이 하네스 엔지니어링, 루프 엔지니어링, 그래프 엔지니어링입니다.

한 문장 답변: 하네스는 AI가 일할 환경과 통제 장치, 루프는 결과를 검사하고 개선하는 피드백 주기, 그래프는 다음에 실행할 작업을 정하는 워크플로 경로입니다.
이 세 용어가 업계 전체에서 하나의 표준 3계층 분류로 통일되어 쓰이는 것은 아닙니다. 이 글에서는 AI 업무의 실패 원인을 찾기 위한 실무 설계 관점으로 구분합니다.

세 개념은 서로 경쟁하지 않습니다. 한 시스템에서 하네스가 실행 환경을 제공하고, 그래프가 작업 경로를 제어하며, 필요한 구간에 루프가 포함될 수 있습니다. 이 관계는 흔한 구성 예시이지 반드시 지켜야 하는 단 하나의 구조는 아닙니다.

바쁜 사람을 위한 30초 비교

구분설계하는 것대표 구성먼저 써야 하는 순간
하네스 엔지니어링AI가 일하는 환경도구, 권한, 상태, 메모리, 로그, 승인자료에 접근하지 못하거나 작업을 잊을 때
루프 엔지니어링작업과 검증의 반복목표, 증거, 피드백, 재시도, 종료 조건첫 결과의 신뢰성이 낮거나 검증 없이 끝날 때
그래프 엔지니어링전체 실행 경로노드, 분기, 병렬 실행, 합류, 상태 전환여러 단계와 조건부 경로를 제어해야 할 때

기억하기 쉽게 정리하면 다음과 같습니다.

하네스 = 어디서 무엇을 가지고 일할 것인가
루프   = 언제 다시 시도하고 언제 멈출 것인가
그래프 = 어떤 조건에서 무엇을 다음에 실행할 것인가

AI가 실패했을 때 무엇부터 고쳐야 할까요?

나타나는 문제먼저 점검할 것해결 방향
AI가 파일이나 데이터에 접근하지 못한다하네스도구와 데이터 연결
세션이 바뀌면 이전 작업을 잊는다하네스상태 저장과 체크포인트
AI가 과도한 권한으로 위험한 행동을 한다하네스최소 권한과 승인 규칙
첫 결과가 그럴듯하지만 정확도가 들쭉날쭉하다루프외부 검사와 수정 반복
성공했는데도 계속 작업한다루프증거 기반 종료 조건
같은 실패를 무한히 반복한다루프최대 재시도와 사람에게 넘기는 조건
여러 자료를 동시에 처리해야 한다그래프병렬 실행과 결과 합류
단계마다 필요한 전문성이 다르다그래프역할별 노드 분리
결과에 따라 다음 작업이 달라진다그래프조건부 분기와 라우팅
실패할 때 전체 작업을 처음부터 다시 한다그래프문제가 생긴 노드만 재실행
AI가 실패했다고 모델이나 프롬프트부터 바꾸지 마세요. 실패를 소유한 층을 먼저 고쳐야 합니다.

1. 하네스 엔지니어링: AI의 작업 환경 만들기

하네스란 무엇인가요?

AI 모델 자체는 텍스트를 생성할 수 있지만, 혼자서 회사 문서를 열거나 데이터베이스를 조회하거나 파일을 저장하지는 못합니다.

AI가 실제 업무를 수행하려면 모델 주변에 여러 장치가 필요합니다. 이 장치들은 크게 세 범주로 나눌 수 있습니다.

기반 환경실행 통제운영과 복구
시스템 지침과 업무 정책도구별 읽기·쓰기·삭제 권한이전 작업과 현재 상태를 보존하는 기억
파일·브라우저·API·데이터베이스실행 시간과 비용 제한중단 후 재개하는 체크포인트
작업에 필요한 컨텍스트위험한 행동 전 사람의 승인도구 호출 로그와 실패 복구 경로
하네스는 도구만 연결하는 일이 아닙니다. AI가 안전하게 일하고, 중단 후 다시 이어가며, 실패했을 때 복구할 수 있는 환경 전체를 설계하는 일입니다.

이처럼 모델 밖에서 AI의 실제 행동을 가능하게 하고 통제하는 실행 환경 전체를 하네스라고 생각하면 쉽습니다.

모델이 작업자라면 하네스는 도구와 자료, 출입 권한, 안전 수칙, 작업 기록이 준비된 작업실입니다. 아무리 뛰어난 작업자라도 자료 접근이 막혀 있고 어제 하던 일을 기억하지 못하면 제대로 일할 수 없습니다.

OpenAI Agents SDK에서도 에이전트는 모델 하나만을 뜻하지 않습니다. 지침, 도구, 구조화된 출력, 가드레일, 핸드오프 등이 함께 구성되고 Runner가 모델 호출과 도구 실행을 관리합니다. 자세한 내용은 OpenAI Agents SDK의 Agents실행 루프 문서에서 확인할 수 있습니다.

하네스는 언제 필요한가요?

AI가 실제 자료에 접근하지 못할 때

“지난달 매출을 분석해줘”라고 요청했지만 매출 데이터가 연결되지 않았다면 더 좋은 프롬프트를 써도 정확한 분석은 나오지 않습니다.

이때 필요한 것은 데이터베이스나 스프레드시트 연결, 읽을 수 있는 범위, 데이터 구조 설명, 호출 실패 시 처리 규칙입니다.

작업이 길어질수록 앞의 내용을 잊을 때

장기 작업에서는 모든 대화를 계속 들고 가기보다 다음 작업에 필요한 상태를 별도로 저장하는 편이 좋습니다.

project_state.md
├── 최종 목표
├── 완료된 작업
├── 아직 남은 작업
├── 확인된 사실과 출처
├── 현재 막힌 문제
└── 다음 실행에서 시작할 위치

새 세션이 이 파일을 먼저 읽게 하면 작업을 처음부터 다시 설명하지 않아도 됩니다.

위험한 작업을 마음대로 실행할 때

고객에게 이메일을 보내거나 파일을 삭제하거나 실제 서비스를 배포하는 작업은 자료 읽기보다 위험합니다. 권한을 다음처럼 나눌 수 있습니다.

행동권장 정책
자료 읽기자동 허용
초안 작성자동 허용
외부 발송사람 승인
삭제·결제·배포별도 승인
민감 정보 접근허용 목록과 기록 적용

사람의 승인이 필요한 도구 호출에서 실행을 멈추고 승인 후 재개하는 구조는 OpenAI Agents SDK의 Human-in-the-loop 문서에서도 확인할 수 있습니다.

복사해서 사용하는 하네스 설계 프롬프트

이 프로젝트에서 AI 에이전트가 안전하게 장기 작업을 수행할 수 있는
최소 하네스를 설계해줘.

반드시 포함할 것:
1. 사용할 수 있는 도구와 각 도구의 목적
2. 읽기·쓰기·삭제·외부 발송 권한의 구분
3. 작업 상태를 저장할 파일과 데이터 구조
4. 중단 후 재개할 때 읽어야 할 정보
5. 최대 실행 시간과 비용 제한
6. 사람이 승인해야 하는 행동
7. 실행 로그에 남길 항목
8. 실패했을 때 복구하거나 사람에게 넘기는 조건

도구를 많이 추가하는 방향보다
이 업무에 꼭 필요한 최소 구성으로 설계해줘.

하네스 체크리스트

2. 루프 엔지니어링: 작업하고 확인하고 멈추게 만들기

루프란 무엇인가요?

기존의 AI 사용 방식은 사람이 AI의 반복을 대신 관리하는 구조입니다.

사람이 요청한다
→ AI가 답한다
→ 사람이 문제를 발견한다
→ 사람이 다시 요청한다
→ AI가 수정한다

루프 엔지니어링은 이 반복을 시스템 안으로 옮깁니다.

목표 설정
→ 작업 수행
→ 결과 검사
→ 기준 미달이면 수정
→ 다시 검사
→ 통과하거나 한도에 도달하면 종료

하지만 “좋아질 때까지 계속 고쳐”라고 쓰는 것은 잘 설계된 루프가 아닙니다. 잘 만든 루프에는 다음 일곱 가지가 필요합니다.

요소결정해야 할 질문
트리거언제 작업을 시작하는가?
목표어떤 결과를 만들어야 하는가?
상태다음 시도에 무엇을 넘기는가?
작업 정책AI가 무엇을 변경하거나 호출할 수 있는가?
증거성공을 무엇으로 확인하는가?
피드백실패한 이유를 어떻게 전달하는가?
종료 규칙언제 성공하거나 포기하는가?

AI의 확신이 아니라 증거로 끝내세요

AI가 “완료했습니다”라고 말하는 것은 완료의 증거가 아닙니다.

다음과 같은 결과가 실제 완료의 증거입니다.

  • 테스트가 통과했다.
  • 깨진 링크가 없다.
  • 모든 주장에 출처가 연결됐다.
  • 요구된 항목이 모두 포함됐다.
  • JSON이 지정한 스키마를 통과했다.
  • 숫자가 원본 데이터와 일치한다.
  • 검사자 또는 사람이 승인했다.

이런 결과가 실제 종료 조건이 되어야 합니다. OpenAI Agents SDK의 Runner는 도구 호출이 있으면 도구를 실행한 뒤 그 결과를 다시 모델에 전달하고, 최종 출력이 나오면 루프를 끝냅니다. 또한 최대 턴 수로 실행이 끝없이 이어지는 것을 제한할 수 있습니다.

대표적인 루프 세 가지

검증 루프

결과물을 만든 뒤 검사하고 실패한 부분만 수정합니다.

초안 작성
→ 사실·논리·누락 검사
→ 실패 항목 수정
→ 재검사
→ 통과 또는 최대 2회 후 사람에게 전달

보고서, 코드, 콘텐츠, 데이터 정리에 가장 쉽게 적용할 수 있습니다.

이벤트 기반 루프

일정, 웹훅, 새로운 문서, 고객 문의, 테스트 실패처럼 특정 사건이 발생할 때 AI를 깨웁니다.

매일 오전 9시
→ 새로운 AI 뉴스 수집
→ 중복 제거
→ 중요도 평가
→ 요약 작성
→ 결과 발송

개선 루프

실제 실패 사례를 모아 지침이나 도구 자체를 개선합니다.

실패 기록 수집
→ 공통 원인 분류
→ 지침 또는 도구 수정
→ 이전 실패 사례로 재평가
→ 개선됐을 때 새 버전 적용

복사해서 사용하는 검증 루프 프롬프트

목표:
[만들어야 할 최종 결과물을 적습니다.]

성공 기준:
1. [반드시 포함할 항목]
2. [숫자·출처·형식의 검사 기준]
3. [통과해야 하는 테스트 또는 검토 기준]

작업 방식:
1. 먼저 결과물을 만든다.
2. 결과물을 성공 기준과 하나씩 대조한다.
3. 통과하지 못한 항목만 수정한다.
4. 수정 후 같은 기준으로 다시 검사한다.
5. 모든 기준을 통과하면 종료한다.

종료 규칙:
- 최대 재시도는 2회다.
- 같은 오류가 반복되면 더 이상 추측하지 않는다.
- 확인할 증거가 없으면 해당 내용을 단정하지 않는다.
- 2회 후에도 실패하면 남은 문제와 필요한 사람의 판단을 보고하고 멈춘다.

마지막에는 아래 형식으로 보고한다.
- 최종 결과물
- 통과한 기준
- 남은 문제
- 재시도 횟수

오늘 바로 쓰는 가장 작은 검증 루프

복잡한 자동화를 만들지 않아도 검사 역할 하나부터 분리할 수 있습니다.

  1. AI가 작성한 결과물을 복사합니다.
  2. 새로운 대화창을 엽니다.
  3. 결과물을 붙여넣습니다.
  4. 다음 프롬프트를 사용합니다.
이 글을 처음 보는 검사자라고 생각하세요.

잘한 점은 쓰지 마세요.
“전반적으로 좋습니다” 같은 평가는 금지합니다.
글을 대신 고쳐 쓰지 말고 틀린 곳만 찾으세요.

다음 항목만 검사하세요.
1. 근거 없이 단정한 내용
2. 앞뒤가 어긋나는 내용
3. 숫자·날짜·이름의 오류
4. 원래 요청에서 빠진 항목
5. 독자가 오해할 수 있는 표현

출력 형식:
판정: 통과 | 수정 필요

지적:
1. 문제가 있는 문장
2. 문제가 되는 이유
3. 무엇을 확인하거나 수정해야 하는지

지적은 최대 5개로 제한하세요.
문제가 없다면 억지로 만들지 말고 통과라고 답하세요.

새 대화창을 쓰면 검사자가 작성 과정의 의도와 자기방어적인 맥락을 그대로 이어받는 문제를 줄일 수 있습니다. 가능하다면 AI 검사만 사용하지 말고 코드 테스트, 링크 검사기, 스키마 검증, 원본 숫자 비교 같은 확정적인 검사도 함께 사용하세요.

3. 그래프 엔지니어링: 여러 작업의 실행 흐름 설계하기

그래프란 무엇인가요?

루프가 하나의 작업을 반복하는 방법을 설계한다면, 그래프는 여러 작업이 어떻게 연결되는지를 설계합니다.

그래프에서는 작업 단위를 **노드(Node)**라고 하고 노드 사이의 이동 경로를 **엣지(Edge)**라고 합니다. 노드는 반드시 사람 역할이나 별도의 AI일 필요가 없습니다. 모델 호출, 도구 실행, 일반 코드, 사람 승인도 노드가 될 수 있습니다. 엣지는 순차 실행과 분기, 병렬 실행, 합류, 반복, 복구 경로를 정의합니다.

여기서 그래프는 데이터의 관계를 표현하는 지식 그래프가 아닙니다. 여러 AI 역할을 늘리는 기술도 아닙니다. 작업 단계와 실행 조건을 연결해 다음에 무엇이 실행될 수 있는지를 통제하는 워크플로 그래프입니다.

루프와 그래프의 차이

루프
작업 → 검사 → 수정 → 재검사
              ↑        ↓
              └────────┘
그래프
          → 조사자 A →
기획자 → 조사자 B → 통합자 → 검사자 → 결과
          → 조사자 C →              ↓
                       ← 문제 노드로 되돌림

루프는 “다시 할 것인가?”를 중심으로 설계하고, 그래프는 “어떤 조건에서 어느 경로로 이동할 것인가?”를 중심으로 설계합니다. 루프도 그래프의 순환 엣지로 표현할 수 있으므로 둘은 배타적인 개념이 아닙니다.

Anthropic도 미리 정한 코드 경로로 모델과 도구를 조정하는 워크플로와 모델이 스스로 과정을 지휘하는 에이전트를 구분합니다. 병렬화와 평가자-개선자 패턴은 각각 그래프와 루프를 이해하는 데 유용한 사례입니다. 자세한 내용은 Anthropic의 Building Effective AI Agents에서 확인할 수 있습니다.

그래프를 설계할 때 결정할 여섯 가지

  1. 어떤 작업이 먼저 실행되는가?
  2. 어떤 작업을 동시에 실행할 수 있는가?
  3. 결과는 어디에서 합쳐지는가?
  4. 어떤 조건에서 경로가 달라지는가?
  5. 실패하면 어느 단계로 돌아가는가?
  6. 어느 지점에서 사람이 승인해야 하는가?

LangGraph 공식 문서에서도 워크플로를 순차 실행, 병렬 실행, 라우팅, 오케스트레이터-워커, 평가자-개선자 등의 패턴으로 설명합니다.

그래프를 써야 하는 네 가지 신호

역할을 나누면 무조건 결과가 좋아진다고 생각하기 쉽지만, 대부분의 일은 나누면 오히려 손해입니다. 담당이 늘어날수록 역할 설계, 맥락 전달, 결과 병합, 중복 제거, 비용과 실패 지점이 함께 늘어납니다.

다음 네 가지 중 하나라도 분명할 때만 그래프를 고려하세요.

1. 단계마다 보는 눈이 다를 때

조사자는 사실과 출처를 찾아야 하고, 작성자는 독자가 이해할 구조를 만들어야 하며, 검사자는 오류와 누락만 찾아야 하는 일입니다.

2. 동시에 펼칠 일이 있을 때

자료 다섯 개, 경쟁사 세 곳, 파일 여덟 개처럼 서로 의존하지 않는 대상을 동시에 살펴볼 수 있는 일입니다. 병렬 처리에는 결과를 하나로 합치는 기준도 필요합니다. LangGraph는 이런 구조를 fan-out과 fan-in으로 설명합니다. LangGraph Graph API

3. 단계마다 도구와 권한이 다를 때

조사 노드는 웹과 문서를 읽을 수 있지만 파일을 수정하지 못하게 하고, 작성 노드만 초안을 저장하게 만들 수 있습니다. 외부 발송은 별도의 승인 노드에서만 허용할 수도 있습니다.

4. 검사가 자꾸 놓칠 때

사실, 논리, 문체, 숫자, 누락, 규정을 한 번에 확인하게 하면 일부 기준을 놓칠 수 있습니다. 이때 사실·출처 검사, 숫자 검사, 논리 검사, 누락 검사처럼 필요한 기준만 분리할 수 있습니다.

신호 하나가 발견됐다고 담당을 세 명씩 늘리지 마세요. 신호 하나당 새로운 노드 하나만 추가하는 것이 안전합니다.

그래프를 쓰지 말아야 할 때

단순한 작업에는 그래프를 사용하지 마세요.

짧은 글 요약, 간단한 이메일 초안, 정해진 형식의 문서 변환, 작은 코드 수정, 자료 하나의 핵심 정리, 대화로 발전시키는 브레인스토밍은 한 명의 AI와 명확한 완료 기준만으로 충분할 가능성이 높습니다.

그래프는 복잡한 작업을 정리하는 수단이지, 단순한 작업을 복잡하게 만드는 장식이 아닙니다. Anthropic 역시 가능한 가장 단순한 해법에서 시작하고, 성능상 가치가 있을 때만 복잡성을 높이라고 권합니다.

4. 실전 예시: 경쟁사 5곳 비교 보고서 만들기

이 작업에는 그래프를 사용할 이유가 있습니다. 경쟁사별 조사를 동시에 진행할 수 있고 조사, 작성, 검사의 관점이 다르며, 검사 결과에 문제가 발생한 단계를 연결해 두었다면 해당 단계만 다시 실행할 수 있기 때문입니다.

[기획자]
비교 대상과 기준 확정

[조사자 A] ─┐
[조사자 B] ─┤
[조사자 C] ─┼→ [통합 작성자] → [검사자] → 통과 → [최종 보고서]
[조사자 D] ─┤                     ↓
[조사자 E] ─┘              문제가 있는 노드만 재실행

1단계: 기획 노드

너는 기획 노드다.

요청을 읽고 다음 항목만 결정한다.
1. 조사할 대상
2. 모든 대상에 공통으로 적용할 비교 기준
3. 반드시 확인해야 하는 숫자와 날짜
4. 최종 결과물의 형식
5. 조사 완료를 판단할 기준

직접 조사하거나 결론을 내리지 마라.
출력은 작업 명세서 형식으로 작성하라.

2단계: 조사 노드

각 조사자는 한 대상만 맡습니다.

너는 조사만 하는 노드다.
글을 쓰거나 최종 결론을 내리지 마라.

맡은 대상:
[경쟁사 이름]

확인할 기준:
[기획 노드가 정한 공통 기준]

다음 형식으로만 반환한다.

## 확인된 사실
- 한 줄 사실 — 출처: URL 또는 문서명

## 확인하지 못한 것
- 확인되지 않은 주장 — 확인하지 못한 이유

규칙:
- 사실 한 줄마다 출처 하나를 붙인다.
- 출처가 없으면 사실로 포함하지 않는다.
- 숫자, 날짜, 가격, 고유명사는 원문 그대로 옮긴다.
- 추측으로 빈칸을 채우지 않는다.
- 원문 전체나 링크 목록을 덤프하지 않는다.
- 결과는 15줄 이내로 제한한다.

3단계: 통합 노드

너는 조사 노트를 통합하는 노드다.

규칙:
1. 중복된 사실은 하나로 합친다.
2. 출처가 없는 문장은 버린다.
3. 서로 충돌하는 숫자는 임의로 선택하지 않는다.
4. 충돌한 정보는 각각의 출처와 함께 표시한다.
5. 확인하지 못한 내용은 사실과 분리한다.
6. 새로운 사실을 추가하거나 직접 조사하지 않는다.

최종 작성자에게 전달할 정리 노트만 출력한다.

4단계: 작성 노드

너는 작성만 하는 노드다.
직접 조사하지 마라.

원래 요청과 전달받은 정리 노트만 보고 결과물을 작성한다.
노트에 없는 사실은 사용하지 않는다.
부족한 내용은 “자료가 부족해 작성하지 못한 부분”으로 따로 표시한다.
확인하지 못한 내용은 단정하지 말고 “확인 필요”라고 표시한다.
숫자, 날짜, 가격, 이름은 노트의 표기를 그대로 사용한다.
본문만 출력하고 작업 과정은 설명하지 않는다.

5단계: 검사 노드

검사자는 작성 과정의 불필요한 맥락을 제외하고 원래 요청, 검증된 노트, 결과물, 검사 기준만 받습니다. 맥락을 분리하면 작성 때의 가정에 그대로 끌려갈 가능성을 줄일 수 있지만, 검사 정확성을 보장하지는 않으므로 숫자 비교나 스키마 검증처럼 코드로 확인할 수 있는 항목은 자동 검사도 함께 사용하세요.

너는 이 결과물을 처음 보는 검사 노드다.

잘한 점은 쓰지 마라.
“전반적으로 좋습니다” 같은 평가는 금지한다.
결과물을 대신 고쳐 쓰지 마라.
어디가 왜 틀렸는지만 지적한다.

검사할 것:
1. 노트에 없는 주장이 추가됐는가?
2. 숫자, 날짜, 가격, 이름이 바뀌었는가?
3. 앞뒤 논리가 어긋나는가?
4. 원래 요청에서 빠진 항목이 있는가?
5. 확인하지 못한 내용을 사실처럼 단정했는가?

출력:
판정: 통과 | 수정 필요

## 지적
1. 위치 — 문제인 이유 — 확인하거나 수정할 것

지적은 최대 5개로 제한한다.
문제가 없다면 억지로 만들지 말고 통과라고 답한다.

6단계: 되돌림 규칙

- 통과하면 최종 결과물을 출력한다.
- 수정 필요라면 지적 목록만 작성 노드에 전달한다.
- 작성 노드는 지적받은 부분만 수정한다.
- 수정한 결과를 새로운 검사 노드에 보낸다.
- 최대 두 번까지만 되돌린다.
- 두 번 후에도 실패하면 남은 문제를 보여주고 사람에게 넘긴다.

가격 정보 하나가 잘못됐다고 경쟁사 다섯 곳을 모두 다시 조사할 필요는 없습니다. 다만 노드 단위로 되돌리려면 검사 결과에 target_node이나 company 같은 재실행 대상을 포함하고, 그래프가 그 값에 따라 해당 조사 노드로 라우팅하도록 구현해야 합니다.

5. 프레임워크 없이 이해하는 Python 코드

아래 코드는 실제 모델 호출 부분을 함수로 분리한 개념 예시입니다. 특정 AI 서비스에 종속되지 않도록 단순화했으며, 검사 실패 시 작성 단계만 수정합니다. 앞에서 설명한 특정 조사 노드 재실행까지 구현하려면 검사 결과에 재실행 대상을 넣고 조건부 라우팅을 추가해야 합니다.

from concurrent.futures import ThreadPoolExecutor, as_completed

MAX_REVISIONS = 2


def call_model(role: str, payload: dict) -> dict:
    """실제 환경에서는 여기에서 AI API를 호출합니다."""
    raise NotImplementedError


def plan(request: str) -> dict:
    return call_model("planner", {"request": request})


def research(company: str, criteria: list[str]) -> dict:
    return call_model(
        "researcher",
        {
            "company": company,
            "criteria": criteria,
            "rules": [
                "Every fact must have one source.",
                "Do not guess missing values.",
                "Preserve numbers, dates, prices and names.",
            ],
        },
    )


def research_in_parallel(companies: list[str], criteria: list[str]) -> list[dict]:
    if not companies:
        return []

    notes = []
    worker_count = min(5, len(companies))

    with ThreadPoolExecutor(max_workers=worker_count) as executor:
        jobs = {
            executor.submit(research, company, criteria): company
            for company in companies
        }

        for job in as_completed(jobs):
            company = jobs[job]

            try:
                notes.append(job.result())
            except Exception as error:
                notes.append({
                    "company": company,
                    "status": "failed",
                    "error": str(error),
                })

    return notes


def synthesize(request: str, notes: list[dict]) -> str:
    return call_model(
        "writer",
        {
            "request": request,
            "notes": notes,
            "rule": "Use only facts contained in the notes.",
        },
    )


def verify(request: str, notes: list[dict], draft: str) -> dict:
    return call_model(
        "verifier",
        {"request": request, "notes": notes, "draft": draft},
    )


def revise(draft: str, findings: list[dict]) -> str:
    return call_model(
        "reviser",
        {
            "draft": draft,
            "findings": findings,
            "rule": "Revise only the sections identified by the verifier.",
        },
    )


def run_competitor_report(request: str) -> dict:
    specification = plan(request)
    notes = research_in_parallel(
        specification["companies"],
        specification["criteria"],
    )
    draft = synthesize(request, notes)

    for revision_count in range(MAX_REVISIONS + 1):
        review = verify(request, notes, draft)

        if review["decision"] == "pass":
            return {
                "status": "complete",
                "report": draft,
                "revision_count": revision_count,
                "unresolved": [],
            }

        if revision_count == MAX_REVISIONS:
            return {
                "status": "needs_human_review",
                "report": draft,
                "revision_count": revision_count,
                "unresolved": review["findings"],
            }

        draft = revise(draft, review["findings"])

    raise RuntimeError("Unreachable state")

이 코드 안에는 세 가지 층이 모두 들어 있습니다.

  • 하네스: call_model() 주변에서 모델, 도구, 권한, 로그와 비용을 관리합니다.
  • 그래프: plan, research_in_parallel, synthesize, verify, revise가 노드가 됩니다.
  • 루프: 검사에 실패하면 최대 두 번 수정하고 다시 검사합니다.

6. AI 코딩 도구에 전체 그래프를 만들어달라는 프롬프트

다음 업무를 순차 실행이 아니라 제어 가능한 워크플로 그래프로 설계해줘.

업무:
[구체적인 업무를 적습니다.]

먼저 이 일이 그래프를 쓸 만큼 복잡한지 판단해줘.

다음 네 가지 중 하나도 해당하지 않으면 그래프를 만들지 말고,
단일 에이전트와 명확한 완료 기준만 제안해줘.

1. 단계마다 서로 다른 전문성이 필요한가?
2. 서로 독립적인 작업을 병렬로 실행할 수 있는가?
3. 단계마다 필요한 도구나 권한이 다른가?
4. 하나의 검사자가 여러 기준을 계속 놓치고 있는가?

그래프가 필요하다면 다음을 설계해줘.

1. 각 노드의 이름과 단 하나의 책임
2. 각 노드가 받을 입력과 반환할 출력
3. 순차 실행되는 구간
4. 병렬 실행되는 구간
5. 병렬 결과가 합쳐지는 지점
6. 결과에 따른 분기 조건
7. 실패했을 때 돌아갈 노드
8. 전체가 아니라 실패한 노드만 재실행하는 방법
9. 각 노드가 사용할 수 있는 도구와 권한
10. 최대 재시도 횟수와 사람에게 넘기는 조건
11. 저장해야 할 상태와 체크포인트
12. 각 실행의 비용과 결과를 기록하는 방법

마지막에는 아래를 제공해줘.

- 전체 흐름도
- 노드별 프롬프트
- 상태 데이터 구조
- 실행 가능한 코드
- 테스트 시나리오
- 실패와 복구 시나리오

7. 세 가지를 함께 쓰면 어떻게 작동할까요?

연구 보고서 작성 시스템을 예로 들면 다음처럼 중첩됩니다.

[하네스]
파일 시스템 · 웹 도구 · API 권한 · 상태 저장 · 로그 · 승인 규칙
    └── [그래프]
        기획 → 병렬 조사 → 통합 → 작성 → 검사 → 승인
                                └── [루프]
                                    검사 실패 → 수정 → 재검사
하네스가 제공하는 것그래프가 결정하는 것루프가 결정하는 것
사용할 도구와 자료작업의 실행 순서결과의 검사 기준
노드별 접근 권한병렬로 실행할 구간실패 이유를 전달하는 방법
상태와 체크포인트결과가 합쳐지는 지점수정할 범위
실행 기록과 관찰 수단조건에 따라 달라지는 경로최대 재시도 횟수
시간과 비용 제한사람이 승인할 단계사람에게 넘길 시점
하네스 안에서 그래프가 실행되고, 그래프의 필요한 구간에서 루프가 반복됩니다.

좋은 그래프가 있어도 하네스가 자료 접근 권한을 제공하지 않으면 조사할 수 없습니다. 좋은 하네스가 있어도 결과를 검사하는 루프가 없으면 그럴듯한 오류를 그대로 내보낼 수 있습니다. 좋은 루프가 있어도 여러 역할과 분기가 뒤엉켜 있다면 어디에서 실패했는지 찾기 어렵습니다.

8. 비싼 대가를 치르는 다섯 가지 실수

작업을 이해하기 전에 그래프부터 그립니다

처음부터 기획자, 관리자, 조사자 다섯 명, 작성자, 검사자 세 명을 만들지 마세요. 먼저 한 명의 AI로 업무를 실행하고 실제로 반복되는 경로와 병목을 관찰해야 합니다.

역할을 나누면 무조건 좋아진다고 생각합니다

역할이 늘어나면 전달 과정과 충돌 가능성도 늘어납니다. 하나의 AI가 충분히 처리할 수 있는 작업은 그대로 두고 실제 문제가 발생한 역할만 분리하세요.

작성자에게 자기 결과를 검사하게 합니다

작성자가 같은 맥락과 가정을 그대로 들고 검사하면 놓친 문제를 다시 놓칠 수 있습니다. 별도 검사에는 원래 요청, 검증된 조사 노트, 완성된 결과물, 검사 기준만 전달하세요. 다만 새 대화창이나 새 검사자가 정확성을 자동으로 보장하지는 않으므로, 가능한 항목은 코드 기반 검사와 함께 확인하세요.

“될 때까지 계속해”를 종료 규칙으로 사용합니다

무제한 반복은 품질 보장이 아니라 비용 누수입니다. 측정 가능한 성공 기준, 새로운 증거, 최대 시도 횟수, 시간과 비용 제한, 사람에게 넘기는 조건이 필요합니다.

하네스에 도구를 너무 많이 넣습니다

불필요한 도구는 AI가 잘못된 도구를 선택할 가능성을 높이고 컨텍스트를 복잡하게 만듭니다. 이 업무에 필요한 최소 도구만 제공하세요.

9. 처음에는 이렇게 작게 시작하세요

1단계: 완료 기준부터 정합니다

이 작업은 다음 조건을 모두 충족하면 끝난다.
1. 필수 항목 다섯 개가 포함된다.
2. 모든 숫자에 출처가 있다.
3. 깨진 링크가 없다.
4. 검사 결과가 통과다.
5. 최대 두 번까지만 수정한다.

2단계: 검사 역할 하나를 분리합니다

작성 결과를 새로운 대화창에서 검사하게 합니다. 이것만으로도 가장 작은 검증 루프가 만들어집니다.

3단계: 반복되는 상태를 저장합니다

목표, 완료된 작업, 확인된 사실, 남은 문제를 하나의 파일이나 데이터 구조에 보관합니다. 이 단계부터 작은 하네스가 생깁니다.

4단계: 병렬화할 작업 하나를 찾습니다

경쟁사별 조사나 여러 문서 확인처럼 서로 의존하지 않는 작업만 동시에 실행합니다. 이 단계부터 그래프가 시작됩니다.

5단계: 실패한 단계만 되돌립니다

가격 정보 하나가 틀렸다면 전체를 다시 실행하지 말고 해당 조사 노드와 영향을 받은 작성 부분만 다시 실행합니다.

자주 묻는 질문

최종 정리

하네스, 루프, 그래프 엔지니어링은 업계의 단일 표준 3계층 이름이라기보다, AI에게 실제 업무를 맡길 때 생기는 문제를 구분하는 실용적인 관점입니다.

환경이 문제면 하네스를, 반복이 문제면 루프를, 흐름이 문제면 그래프를 점검하세요.

처음부터 세 가지를 모두 만들 필요는 없습니다. 명확한 완료 기준을 정하고, 검사 역할 하나를 분리하고, 반복되는 상태를 저장한 뒤 실제로 병렬화하거나 분기할 필요가 생겼을 때 그래프를 추가하세요.

복잡한 AI 시스템은 역할이 많은 시스템이 아닙니다. 필요한 작업만 움직이고, 증거로 결과를 확인하며, 끝나거나 막혔을 때 정확히 멈추는 시스템입니다.

짐코딩 뉴스레터
AI 개발·클로드 코드 실전 노하우를 이메일로 받아보세요. 도움 되는 글만.

구독하면 마케팅 정보 수신 및 개인정보처리방침에 따른 이메일 수집·이용에 동의하게 됩니다. 언제든 수신거부할 수 있어요.