사람과 기계, 시스템과 시스템 사이의 '경계면'을 설계하는 층—의도를 명세로 번역하고, 기계출력을 사람이 신뢰할 형태로 되번역하며, 프로토콜로 연결한다.
4컷으로 보기 — 부처 간 협의

- 1막연한 민원, 애매한 요구
- 2창구 직원, 신청서식으로 번역하다
- 3공문 서식·전자연계 규약으로 처리
- 4이해하기 쉬운 안내문으로 되돌려주다
왜 중요한가
AI는 홀로 존재하지 않는다. 도구·데이터·타 기관 시스템, 그리고 사람과 맞닿는다. 그 경계에서 번역이 어긋나면 아래 세 겹(프롬프트·컨텍스트·하네스)이 아무리 좋아도 실무에서 신뢰받지 못한다. 세 가지 경계 실패가 대표적이다. (1) 의도→명세 번역 실패: 실무자의 막연한 요구를 기계가 실행할 구조화 명세로 옮기지 못해 '엉뚱하지만 그럴듯한' 결과가 나온다. (2) 출력→인간 되번역 실패: 결과가 검증 불가능한 형태(근거·출처·불확실성 표기 없는 한 덩어리 텍스트)라 실무자가 결재·판단에 못 쓴다. (3) 시스템 연계 규약 부재: 도구·데이터·타 기관과 주고받을 표준 프로토콜이 없어 매번 임시 연결을 짜다 깨진다. '헤르메스 엔지니어링'은 아직 업계 표준 용어가 아니다—MCP·함수/도구 인터페이스·에이전트 간 메시징·의도↔명세 번역·해석학(hermeneutics)·기계출력의 인간가독화라는 실재하는 실천들을 하나로 묶어 이 커리큘럼이 제시하는 통합적 명명이다. 공공 영역에서 이 층은 특히 중요하다. 행정은 '설명책임'과 '이의제기'가 법적 의무이기 때문에, 출력의 근거·출처·불확실성을 표기하고 AI 생성물을 고지하며 재검토 경로를 여는 경계 설계가 곧 신뢰이자 준법이다.
행정 실무 비유
부처 간 협의·민원 창구·통역이 한자리에 결합된 자리다. 주민이 창구에서 던지는 막연한 요구("우리 동네 이거 어떻게 좀…")를 담당자는 처리 가능한 신청서식(명세)으로 바꿔 받아 적는다—이것이 의도→명세 번역이다. 처리 결과로 나온 법령용어 범벅 공문을, 주민이 이해할 안내문(근거·처리기한·불복절차 포함)으로 풀어 돌려준다—이것이 기계출력의 인간가독화다. 타 기관과 자료를 주고받을 땐 아무 종이에나 쓰지 않고 공문 서식과 전자정부 연계 규약(프로토콜)을 따른다—이것이 MCP다. 창구 직원이 "이 부분은 규정이 애매해 담당과 확인이 필요합니다"라고 단서를 다는 것이 불확실성 표기이고, "AI 초안입니다, 최종은 담당자 검토를 거칩니다"라고 밝히는 것이 AI 생성물 고지다. 위임전결 규정이 '누가 어디까지 결정하나'를 정하듯, 인터페이스 계약(API contract)은 '기계가 무엇을 요청하면 무엇을 돌려받나'를 못박는다. 요컨대 이 층의 품질은 곧 창구의 번역 품질이고, 창구의 번역 품질이 곧 기관의 신뢰다.
헤르메스 방법론을 SKILL.md로 재사용하기
가능합니다. 아래 프로젝트 스킬을 한 번 저장하면 Claude가 관련 업무에서 자동으로 선택하거나, Desktop Code 탭과 VS Code에서 /hermes-boundary로 직접 실행할 수 있습니다. 팀과 공유하려면 .claude/skills/를 저장소에 커밋하고, 혼자 모든 프로젝트에서 쓰려면 같은 폴더를 ~/.claude/skills/ 아래에 만드세요.
1. 프로젝트에 스킬 넣기
프로젝트 루트에서 폴더를 만든 뒤, 아래 내용을 .claude/skills/hermes-boundary/SKILL.md로 저장합니다.
mkdir -p .claude/skills/hermes-boundary # 위의 SKILL.md 예제를 다음 경로에 저장 # .claude/skills/hermes-boundary/SKILL.md
--- name: hermes-boundary description: 막연한 업무 요청을 실행 명세로 번역하고, 결과를 근거·출처·불확실성·검토 경로가 있는 사람용 문서로 되번역한다. 민원, 보고서, 안내문, 시스템 연계 업무에 사용한다. --- # 헤르메스 경계 설계 사용자의 요청을 바로 실행하지 말고 다음 순서를 지킨다. 1. 의도 → 명세 - 목적, 독자, 입력, 산출물, 제약, 성공조건을 분리한다. - 모호한 표현은 가정하지 말고 확인 질문으로 드러낸다. 2. 시스템 경계 - 입력·출력 필드와 타입, 필수값, 허용값, 오류 형식을 정의한다. - 외부 도구가 필요하면 최소 권한과 승인 지점을 먼저 밝힌다. 3. 기계 검증 - 구조화 출력은 스키마로 검증한다. - 출처 없는 주장과 확인되지 않은 수치는 만들지 않는다. 4. 사람용 되번역 - 핵심 결과, 근거·출처, 불확실·확인필요 항목, AI 보조 고지를 표시한다. - 최종 승인자와 이의제기·재검토 경로를 적는다. 5. 완료 전 점검 - 개인정보·비밀이 포함되지 않았는지 확인한다. - 실행한 검증과 남은 위험을 짧게 보고한다. 사용자가 특정 업무를 주지 않았다면 먼저 적용할 업무와 대상 독자를 묻는다.
2A. Claude Desktop Code 탭
- Claude Desktop에서 Code 탭을 열고 환경은 Local, 프로젝트 폴더는 방금 스킬을 넣은 폴더로 선택합니다.
- 입력창의 + → Slash commands에서
hermes-boundary를 고르거나/hermes-boundary를 입력합니다. - 이어서 “도로 파손 민원 5건을 팀장 보고와 민원인 안내로 바꿔줘”처럼 대상 업무를 씁니다.
- 처음에는 Plan 또는 Ask permissions로 경계·명세를 검토하고, diff에서 실제 변경을 승인합니다.
개인 스킬은 로컬 세션에서 이 PC의 ~/.claude/skills/를 읽습니다. 원격·클라우드 세션은 스킬 위치와 적용 방식이 다르므로 이 실습은 Local로 시작하세요.
2B. VS Code 확장
- VS Code 확장에서 Claude Code를 설치하고 프로젝트 폴더 전체를 엽니다.
- 우측 상단 Spark 아이콘 또는 명령 팔레트의 “Claude Code: Open in New Tab”으로 패널을 엽니다.
- 새 대화에서
/hermes-boundary를 입력하고 업무를 이어 씁니다. 파일 일부는 선택 후@파일명으로 함께 지정할 수 있습니다. - Plan으로 명세를 먼저 확인한 뒤 구현을 허용하고, inline diff와 Problems/터미널 결과를 검토합니다.
확장 패널은 CLI를 내장하지만, VS Code 통합 터미널에서 claude 명령을 쓰려면 별도 CLI 설치가 필요합니다.
3. 첫 실행과 성공 판정
/hermes-boundary 다음 요청을 처리해줘. "밀린 도로 파손 민원을 정리해 팀장에게 보고하고 민원인에게도 안내해줘." 지금은 실행하지 말고 먼저: 1) 모호한 점과 확인 질문 2) 입력·출력 스키마 3) 개인정보·외부전송 경계 4) 사람 승인 지점 5) 완료 판정 기준 을 제시해줘. 합성 데이터만 사용해.
- 확인되지 않은 처리기한·법조문을 지어내지 않고 확인 필요로 남겼는가
- 기계용 스키마와 사람용 보고서가 분리되어 있는가
- 출처·불확실성·AI 보조 고지·최종 승인자가 보이는가
- 실제 개인정보 없이 합성 데이터로만 검증했는가
🖐 실무 따라하기 — 복붙해서 따라 하면 됩니다
- 1막연한 요구 → 실행 가능한 명세로 번역 (의도→명세)
/playground(또는 ChatGPT·Claude 웹)를 연다. 아래 프롬프트를 처음부터 끝까지 통째로 복사해 붙여넣어, 팀장의 구두 지시를 '입력/처리/출력/제약'이 명시된 작업명세서(spec)로 번역시킨다. 이 단계는 코드가 아니라 '무엇을 만들지 계약서'를 뽑는 단계다.
프롬프트 (복사해서 AI에 입력)당신은 공공행정 업무를 실행 가능한 명세로 번역하는 분석가입니다. 아래 '막연한 지시'를 개발/실행이 가능한 작업명세서로 변환하세요. [막연한 지시] "요즘 밀린 도로 파손 민원들, 상황 좀 정리해서 위에 보고하고 민원인한테도 안내 나가게 해줘." [출력 형식] 아래 6개 항목을 표가 아닌 번호 목록으로 작성하세요: 1. 목적(한 문장) 2. 입력(무엇을 받는가: 데이터 항목을 구체적으로 나열 — 예: 접수번호, 위치, 민원 요지) 3. 산출물(정확히 몇 종을 어떤 형태로 — 예: 보고용 요약 1건 + 민원인 안내문 N건) 4. 각 산출물의 필수 필드(항목명 나열) 5. 처리 규칙(우선순위·분류 기준 등. 지시에 근거가 없으면 항목 끝에 '(가정)'이라고 표시) 6. 애매해서 팀장에게 되물어야 할 질문 정확히 3개 [제약] - 실제 개인정보는 다루지 않고 합성 데이터만 가정한다. - 지시에 없는 사실(법조문·처리기한 숫자 등)은 지어내지 말고 '확인필요'로 남긴다. - 6개 항목을 빠짐없이 채우고, 5번의 각 규칙에는 근거 유무를 '(가정)' 표기로 구분한다.
→ 결과 6개 항목이 모두 채워진 명세서가 나온다. 특히 3번에 '보고용 요약 1건 + 민원인 안내문 N건'처럼 개수/형태가 명확해지고, 5번의 규칙에 '(가정)' 표기가 붙고, 6번에 되물을 질문 3개(예: 처리기한 며칠? 우선순위 기준은? 안내문 발송 방식은?)가 뜨는지 확인. 애매함이 질문으로 '밖으로 드러나는' 것이 이 단계의 핵심.
- 2기계 인터페이스 설계 — JSON 스키마 확정 (스키마 설계)
명세의 '필수 필드'를 기계가 검증할 수 있는 계약으로 고정한다. 아래 명령을 터미널에 통째로 붙여넣으면 스키마 파일이 저장되고 내용까지 화면에 출력된다(무설치자는 히어독 안의 JSON 텍스트만 메모장에 복사해 두면 됨). confidence(신뢰도)와 source(출처: 접수메모/AI추정)를 필드로 강제하는 것이 포인트 — 나중에 인간가독화 단계에서 그대로 표기로 이어진다.
터미널 명령cat > /tmp/minwon.schema.json <<'JSON' { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "도로파손 민원 정리 스키마", "type": "object", "required": ["generated_by", "cases"], "properties": { "generated_by": { "type": "string", "description": "AI 생성물 표기" }, "cases": { "type": "array", "minItems": 1, "items": { "type": "object", "required": ["receipt_no", "location", "category", "priority", "confidence", "source", "citizen_notice"], "properties": { "receipt_no": { "type": "string", "pattern": "^MW-2026-[0-9]{4}$" }, "location": { "type": "string" }, "category": { "type": "string", "enum": ["포트홀", "균열", "침하", "기타"] }, "priority": { "type": "string", "enum": ["상", "중", "하"] }, "confidence": { "type": "number", "minimum": 0, "maximum": 1 }, "source": { "type": "string", "enum": ["접수메모", "AI추정"] }, "citizen_notice": { "type": "string", "minLength": 20 } } } } } } JSON echo '--- 저장된 스키마 내용 ---' cat /tmp/minwon.schema.json→ 결과 '--- 저장된 스키마 내용 ---' 아래로 방금 저장한 JSON 스키마 전문이 화면에 그대로 출력되면 성공(아무 출력이 없으면 히어독이 EOF까지 안 닫힌 것). 무설치자는 셸 대신 히어독 안의 JSON 텍스트만 보관. 핵심은 priority/category를 enum으로 가둬 AI가 임의 값을 못 넣게 하고, confidence·source·generated_by로 신뢰도/출처/AI표기를 스키마 차원에서 강제했다는 점.
- 3합성 민원 원자료를 스키마에 맞춰 구조화 (기계출력 생성)
아래 프롬프트를 처음부터 끝까지 통째로 복사해 /playground(또는 Claude·ChatGPT 웹)에 붙여넣는다. [스키마] 자리에는 step2 히어독 안의 JSON 스키마 전문을 그대로 붙여 넣는다(요약하지 말 것). 합성 접수메모 5건은 프롬프트 안에 이미 포함되어 있다. AI는 스키마를 100% 만족하는 JSON'만' 출력해야 하며, 원문에 없어 추정한 값은 source를 'AI추정', confidence를 낮게 매긴다.
프롬프트 (복사해서 AI에 입력)아래 [스키마]를 100% 만족하는 JSON 하나만 출력하세요. 설명·마크다운 코드펜스(```) 없이 JSON 본문만 출력합니다. [규칙] - generated_by 값은 정확히 "AI생성물(모델보조) — 담당자 검토 전"로 넣는다. - 접수메모에 적힌 사실은 source="접수메모", confidence는 0.9 이상. - 메모에 없어 네가 추정한 값(category/priority 등)은 source="AI추정", confidence는 0.6 이하로 낮춘다. - category는 반드시 ["포트홀","균열","침하","기타"] 중 하나, priority는 ["상","중","하"] 중 하나만 쓴다. - citizen_notice는 민원인에게 보낼 존댓말 안내문(20자 이상). 처리기한 등 확인 안 된 숫자는 지어내지 말고 '확인 후 별도 안내'로 표현한다. - receipt_no는 반드시 MW-2026-000x 형식으로 쓴다. [스키마] (여기에 step2의 JSON 스키마 전문을 그대로 붙여넣기) [합성 접수메모 5건] 1. MW-2026-0001 / 홍길동 010-0000-0000 / 경북대로 12 앞 / "차선 가운데 구멍 나서 타이어 터질 뻔" 2. MW-2026-0002 / 김영희 010-0000-0000 / 안동시 서동문로 사거리 / "바닥 쩍쩍 갈라짐, 밤에 안 보임" 3. MW-2026-0003 / 이철수 010-0000-0000 / 포항 죽도시장 입구 / "도로가 푹 꺼져서 물 고임" 4. MW-2026-0004 / 박민수 010-0000-0000 / 구미 인동로 / "맨홀 주변 울퉁불퉁" 5. MW-2026-0005 / 최지은 010-0000-0000 / 경산 하양읍 / "과속방지턱 페인트 벗겨짐" (도로파손 아닐 수도)
→ 결과 코드펜스 없는 순수 JSON이 출력된다. cases 5개, 각 항목에 receipt_no(MW-2026-0001~0005), category(enum 중 하나), source가 접수메모/AI추정으로 구분되고, 추정 항목(예: 5번 과속방지턱은 category='기타'·confidence 0.6 이하)이 실제로 낮은 confidence를 갖는지 눈으로 확인. 이 JSON 출력 전체를 다음 step에서 /tmp/minwon.json 으로 저장한다.
- 4기계 검증 — 스키마 위반 자동 적발 (도구/함수 인터페이스)
AI 출력을 사람이 믿기 전에 기계로 검증한다. 먼저 step3의 JSON 전체를 /tmp/minwon.json 에 저장한다: 아래 첫 명령(`cat > /tmp/minwon.json`)을 실행하고 step3 JSON을 붙여넣은 뒤 Enter, Ctrl-D로 저장한다. 그 다음 두 번째 블록(검증 스크립트)을 통째로 붙여넣어 실행한다. 무설치·망분리자는 jsonschemavalidator.net 에 왼쪽=step2 스키마, 오른쪽=step3 JSON을 각각 붙여넣어 'valid'가 뜨는지로 동일하게 검증한다.
터미널 명령# (1) step3의 JSON을 저장 — 아래 실행 후 step3 JSON을 붙여넣고 Enter, 그다음 Ctrl-D cat > /tmp/minwon.json # (2) 저장했으면 아래 블록을 통째로 붙여넣어 검증 실행 python3 -m pip install --quiet jsonschema 2>/dev/null python3 - <<'PY' import json, sys from jsonschema import Draft202012Validator schema = json.load(open('/tmp/minwon.schema.json')) data = json.load(open('/tmp/minwon.json')) errs = sorted(Draft202012Validator(schema).iter_errors(data), key=lambda e: list(e.path)) if not errs: n = len(data['cases']) low = [c['receipt_no'] for c in data['cases'] if c['confidence'] < 0.6] print(f'PASS: 스키마 통과, 민원 {n}건.') print('저신뢰(검토 우선) 건:', low or '없음') else: print(f'FAIL: {len(errs)}개 위반') for e in errs[:10]: print(' -', list(e.path), e.message) sys.exit(1) PY→ 결과 정상이면 'PASS: 스키마 통과, 민원 5건.'과 '저신뢰(검토 우선) 건: [...]'가 출력된다. AI가 enum 밖 값(예: priority="긴급")이나 필드 누락을 냈다면 'FAIL: N개 위반'과 함께 위반 경로(예: ['cases', 4, 'priority'])가 찍힌다 — 이때 step3로 돌아가 재생성. 이 검증기가 바로 사람↔기계 경계의 '민원창구 심사' 역할이다. 온라인 검증기 사용 시엔 'valid' 표시가 곧 PASS.
- 5인간가독화 — 보고 요약 + 민원인 안내문 (기계출력의 인간가독화·표기)
검증 통과한 JSON을 사람이 읽을 두 산출물로 변환한다. 아래 프롬프트를 통째로 붙여넣고, [JSON] 자리에 /tmp/minwon.json 내용(step3 출력) 전체를 붙여 넣는다. 신뢰도·출처를 문장 안에 자연스럽게 표기하고, AI생성물 고지문을 하단에 넣게 한다. 처리기한 등 미확인 수치는 지어내지 않는다.
프롬프트 (복사해서 AI에 입력)아래 검증완료 JSON을 두 개의 사람이 읽을 문서로 변환하세요. [문서 A: 팀장 보고용 요약] (한 화면 분량) - 첫 줄에 총 건수, 우선순위 '상' 건수, 카테고리 분포(예: 포트홀 O·균열 O·침하 O·기타 O)를 요약. - 그 아래 표: 접수번호 | 위치 | 분류 | 우선순위 | 신뢰도(%) | 출처. - confidence 0.6 미만 건은 위치 뒤에 (담당자 재확인 필요) 표시. - category가 '기타'인 건은 '도로파손 아닐 수 있음'을 명시. [문서 B: 민원인 안내문] (건별, 존댓말) - 각 건의 citizen_notice를 다듬어 실제 발송 가능한 안내문으로. - 상단 제목: "[접수번호] 도로 파손 민원 처리 안내" - 확인 안 된 처리기한/보상 등은 절대 숫자로 지어내지 말고 "확인 후 개별 안내드리겠습니다"로. [공통] 두 문서 맨 아래에 정확히 이 고지문을 넣으세요: "※ 본 문서는 AI 보조로 초안 작성되었으며 담당 공무원 검토 전입니다. 개인정보는 합성 데이터입니다." [JSON] (여기에 /tmp/minwon.json 전체를 붙여넣기)
→ 결과 문서 A(요약: 첫 줄에 '총 5건, 우선순위 상 O건, 포트홀 O·균열 O…', 저신뢰 건에 '(담당자 재확인 필요)', 표 6열)와 문서 B(접수번호별 존댓말 안내문 5개)가 나온다. 두 문서 하단에 지정한 AI생성물·합성데이터 고지문이 그대로 붙는지, 처리기한이 '확인 후 개별 안내'로 남아 지어낸 숫자가 없는지 확인. 이 상태로 담당자 최종검토만 거치면 실제 업무 흐름에 투입 가능.
스택 내 위치
AI 엔지니어링 스택 5계층 중 ④번째. 안쪽 ③하네스(반복 처리절차·도구실행·재시도·HITL 게이트)를 바깥에서 감싸고, 가장 바깥 ⑤메타(평가·제도화·개선) 안쪽에 놓인다. 하네스가 'AI 안쪽의 일 처리'라면 헤르메스는 그 처리 결과가 사람·타 시스템과 맞닿는 '경계면'을 다룬다. 아래쪽 경계는 하네스와의 접점(하네스가 어떤 도구를 어떤 스키마로 부를지)이고, 위쪽 경계는 사람(실무자·주민·감사)과 외부 기관 시스템이다. 헤르메스는 새 계산 능력을 더하지 않는다—이미 만들어진 능력을 '넘겨주고 되받는' 번역·연결·표기의 층이다.
핵심 개념 (17)
사람·기계·타 시스템이 서로 맞닿아 정보를 주고받는 접점. 헤르메스 엔지니어링이 설계하는 대상 전체를 가리킨다.
💡 경계에서 번역이 어긋나면 안쪽 세 겹의 품질이 실무 신뢰로 이어지지 못한다.
AI 모델·에이전트를 외부 도구·데이터 소스에 연결하기 위한 공개 표준 프로토콜. 도구/리소스/프롬프트를 서버가 노출하고 클라이언트(모델 호스트)가 발견·호출한다.
💡 매번 임시 연결을 짜는 대신 표준 규약을 따르면 재사용·상호운용·감사가 가능해진다. 전자정부 연계 규약의 AI판.
모델이 호출할 수 있도록 함수의 이름·설명·입력 스키마(파라미터)를 구조화해 정의한 것. tool use의 계약서.
💡 스키마가 모호하면 모델이 잘못된 인자를 채워 오작동한다. 인터페이스 품질이 곧 도구 사용 성공률.
사람의 자연어 요구(막연한 의도)를 기계가 실행할 구조화된 요구(파라미터·제약·성공조건)로 옮기는 작업.
💡 번역이 부실하면 '그럴듯하지만 엉뚱한' 결과가 나온다. 창구에서 요구를 신청서식으로 받아 적는 일.
모델의 산출물을 사람이 읽고 검증·신뢰·활용할 수 있는 형태(근거·출처·구조·요약·불확실성 표기)로 되번역하는 작업.
💡 검증 불가능한 한 덩어리 텍스트는 결재·판단에 쓸 수 없다. 되번역 없이는 설명책임을 못 진다.
결과가 왜 그렇게 나왔는지, 어떤 근거·자료에 기댔는지를 함께 제시해 사람이 판단을 검토할 수 있게 하는 성질.
💡 행정은 처분에 이유를 붙일 법적 의무가 있다. 근거 없는 AI 출력은 공문서로 쓸 수 없다.
출력의 확실한 부분과 불확실·추정·미확인 부분을 구분해 표시하는 것. '이 값은 추정', '규정 확인 필요' 같은 단서.
💡 불확실성을 감추면 사람이 과신한다. 표기해야 검토·재확인이 트리거된다. 창구의 '담당과 확인 필요' 단서.
결과의 근거 자료 출처를 밝히고, 산출물이 AI로 생성·보조되었음을 고지하는 것.
💡 출처 없는 주장은 검증 불가, 고지 없는 AI 산출물은 신뢰·책임 소재를 흐린다. 공공에서는 준법 요건.
시스템 간에 '무엇을 요청하면 무엇을 어떤 형식으로 돌려받는지'를 사전에 못박은 약속(스키마·에러규약·버전).
💡 계약이 없으면 연결이 조금만 바뀌어도 깨진다. 위임전결 규정처럼 경계의 책임과 형식을 고정한다.
도구·리소스·데이터의 구조(필드·타입·필수여부·제약)를 정의하는 일. 구조화 출력(structured output)의 뼈대.
💡 좋은 스키마는 모델의 자유도를 유용하게 제약해 오류를 줄이고 후속 시스템이 파싱할 수 있게 한다.
여러 AI 에이전트(또는 에이전트와 서비스)가 역할·요청·결과를 구조화된 메시지로 주고받는 통신 방식.
💡 오케스트레이션에서 에이전트들이 서로를 이해하려면 공통 메시지 규약이 필요하다. 부처 간 공문 왕래.
같은 말이 사람마다·맥락마다 다른 의미를 갖는다는 전제 아래, 요구의 진짜 의미를 맥락과 대화로 좁혀 맞추는 실천.
💡 '빠르게'·'간단히'·'적절히' 같은 말은 사람마다 다르다. 의미를 되물어 정렬하지 않으면 번역이 틀린다.
서로 다른 시스템·기관이 표준 규약을 통해 데이터·기능을 주고받을 수 있는 성질.
💡 기관 간 벽을 넘어 연계하지 못하면 AI는 부서 안 장난감에 그친다. 전자정부 연계의 정신.
AI 보조 결정에 대해 당사자가 이유를 묻고 재검토를 요청하며, 최종 책임자가 특정되는 절차.
💡 행정 처분은 불복·이의 절차가 법적 권리다. 경로 없는 AI 도입은 위법 소지이자 신뢰 붕괴 지점.
기계의 자동 처리와 사람의 판단·승인이 만나는 지점의 설계. 하네스의 HITL 게이트가 경계면에서 사람에게 어떻게 제시되는가.
💡 사람이 승인 화면에서 근거·불확실성을 못 보면 '눈감고 결재'가 된다. 게이트의 인간 쪽 UX가 핵심.
같은 결과를 실무자·주민·감사·관리자 등 서로 다른 독자에게 각자 필요한 형태로 번역해 제시하는 일.
💡 실무자에겐 근거 로그가, 주민에겐 쉬운 안내문이, 감사에겐 추적 가능한 이력이 필요하다. 한 형태로는 모두를 못 만족시킨다.
경계에서 발생하는 전형적 실패(의도 오해·스키마 불일치·환각 출처·과신 표기 등)를 유형화해 진단·예방하는 실천.
💡 실패를 유형으로 알아야 재발을 막는다. 경계 오역은 조용히 누적되다 큰 사고로 터진다.
학습 목표
- 헤르메스 계층이 '경계면 설계'임을 이해하고 세 가지 경계(사람↔기계, 시스템↔시스템, 의도↔명세)를 자기 업무 예로 든다
- MCP·도구 인터페이스·인간가독화가 각각 무엇을 해결하는지 행정 비유로 설명한다
- AI 출력에 근거·출처·불확실성·AI 생성 고지가 왜 필요한지 설명책임 관점에서 말한다
- 막연한 실무 요구를 파라미터·제약·성공조건이 있는 구조화 명세로 번역한다
- 도구/함수 인터페이스의 스키마(이름·설명·입력 필드)를 모호하지 않게 설계한다
- 기계출력을 근거·출처·불확실성 표기·독자별 요약을 갖춘 '검토 가능한' 형태로 되번역하는 템플릿을 만든다
- 경계 오역 실패모드를 유형별로 진단하고 최소한의 방어(스키마 검증·출처 강제·불확실성 표기)를 건다
- MCP 서버/클라이언트 개념으로 도구·리소스를 노출·소비하는 연결을 설계한다
- 다중 이해관계자(실무자·주민·감사)를 위한 번역·설명책임·이의제기 경로를 하네스의 HITL 게이트와 통합 설계한다
- 인터페이스 계약(스키마·에러규약·버전·고지)을 문서화하고 평가(eval)로 경계 품질을 지속 측정·개선하는 체계를 세운다
세션 구성
| 회차 | 주제 | 시수 | 내용 | 산출물 |
|---|---|---|---|---|
| 1 | 경계면이라는 발상 — 헤르메스 계층 개관 | 2h | AI 엔지니어링 스택에서 ④헤르메스의 자리(하네스 바깥, 메타 안쪽)를 세운다. 세 가지 경계(사람↔기계, 시스템↔시스템, 의도↔명세)를 정의하고, '헤르메스 엔지니어링'이 표준 용어가 아니라 실재 실천들의 통합 명명임을 정직하게 밝힌다. 창구·통역·부처 협의 비유로 왜 이 층이 없으면 아래 세 겹이 신뢰받지 못하는지 실패 사례로 보인다. | 내 업무의 세 경계 지도 1장(어디서 사람·시스템·의도가 맞닿는가) |
| 2 | 의도→명세 번역과 해석학 | 3h | 막연한 자연어 요구를 파라미터·제약·성공조건으로 구조화하는 번역 기법. '빠르게·간단히·적절히' 같은 모호어를 되물어 좁히는 해석학적 의미 정렬. 명세 템플릿(무엇을·왜·성공기준·금지사항·출력형식)과 되묻기 프롬프트 패턴을 익힌다. | 내 실무 요구 3건을 구조화 명세로 옮긴 번역표 |
| 3 | 도구/함수 인터페이스와 스키마 설계 | 3h | tool use의 계약서인 함수 인터페이스(이름·설명·입력 스키마)를 모호하지 않게 설계한다. 구조화 출력(structured output) 스키마로 모델의 자유도를 유용하게 제약하기. 좋은 설명·나쁜 설명 대조, 필수/선택 필드·타입·enum·제약 조건 명세. Anthropic 도구 정의 형식을 실제 예로 다룬다. | 업무 도구 1개의 인터페이스 정의(이름·설명·입력 스키마) 초안 |
| 4 | MCP와 시스템 연계·상호운용성 | 3h | 모델 컨텍스트 프로토콜(MCP)의 구조—서버가 도구·리소스·프롬프트를 노출하고 호스트가 발견·호출—를 전자정부 연계 규약에 빗대 이해한다. 임시 연결 대비 표준 프로토콜의 재사용·감사 이점. 에이전트 간 메시징과 상호운용성의 기본. 언제 MCP를 쓰고 언제 단순 함수로 충분한지 판단. | 우리 부서가 연결하고픈 데이터/도구를 MCP 관점으로 스케치한 연계도 |
| 5 | 기계출력의 인간가독화 — 되번역과 설명책임 | 3h | 모델 출력을 근거·출처·불확실성 표기·독자별 요약을 갖춘 '검토 가능한' 형태로 되번역한다. 설명가능성(근거 제시), 출처·AI 생성물 고지, 불확실성/신뢰도 표기, 이의제기·설명책임 경로. 다중 이해관계자(실무자·주민·감사) 번역을 한 결과에서 세 형태로 파생한다. | AI 초안 1건을 근거·출처·불확실성·고지·독자별 요약을 갖춘 되번역 결과물로 변환 |
| 6 | 경계 오역 실패모드 진단과 방어 게이트 | 2h | 의도 오해·스키마 불일치·환각 출처·과신 표기 등 경계 오역 실패를 유형화한다. 각 유형에 최소 방어(스키마 검증·출처 강제·불확실성 표기·HITL 승인 화면의 근거 노출)를 건다. 하네스의 HITL 게이트가 사람 쪽에서 어떻게 보여야 '눈감고 결재'를 막는지 설계한다. | 경계 실패모드 체크리스트 + 내 워크플로에 건 방어 게이트 명세 |
| 7 | 통합 실습·평가 연결 | 2h | 세션 2~6 산출물을 하나의 경계 설계 문서로 통합한다. 인터페이스 계약(스키마·에러규약·버전·고지) 문서화. 경계 품질을 어떻게 평가(eval)로 측정하고 메타 계층에서 개선·제도화할지 연결한다. 발표·상호검토. | 완결형 '경계 설계 계약서' 1부 + 평가 지표 초안 |
실습 랩
랩 A — 막연한 요구를 실행 가능한 명세로: 의도→명세 번역
목표 · 실무자의 한 줄 요구를 기계가 그대로 실행할 수 있는 구조화 명세로 번역하고, 모호어를 해석학적으로 좁히는 되묻기를 몸에 익힌다.
- 대상 요구 선정: 본인 업무의 막연한 요구 1건을 한 문장으로 적는다(예: '민원 답변 초안을 좀 빠르고 간단하게 만들어줘').
- 모호어 표시: 문장에서 사람마다 다르게 해석될 단어(빠르게·간단히·적절히·좋게 등)에 밑줄을 긋는다.
- 되묻기 목록화: 각 모호어를 확정하는 질문을 만든다('간단히=몇 문장 이내?', '빠르게=오늘 중? 즉시?', '대상 독자는 민원인? 상급자?').
- 명세표 작성: [목적 / 대상 독자 / 입력 자료 / 출력 형식 / 길이·톤 제약 / 반드시 포함 / 절대 금지 / 성공 판정 기준] 8칸 표를 채운다.
- 실행·대조: 원래 한 줄 요구로 AI에 한 번, 완성된 명세로 다시 한 번 같은 결과물을 생성해 나란히 비교한다.
- 성공기준 검증: 명세의 '성공 판정 기준' 항목으로 두 결과를 채점하고 차이를 기록한다.
✅ 성공 기준 · 같은 요구를 '한 줄 vs 명세'로 실행했을 때, 명세 버전이 성공 판정 기준에서 명확히 우위이고, 그 우위를 표의 어느 칸 덕분인지 설명할 수 있다.
↗ 확장 · 명세표를 재사용 가능한 템플릿(빈 8칸 서식)으로 만들어 동료가 다른 업무에 그대로 적용하게 한다.
랩 B — 검토 가능한 결과물 만들기: 인간가독화 되번역 + 도구 인터페이스
목표 · AI의 한 덩어리 출력을 근거·출처·불확실성·AI 고지·독자별 요약을 갖춘 '결재에 올릴 수 있는' 형태로 되번역하고, 그 과정에 쓰이는 도구의 인터페이스 스키마를 설계한다.
- 원출력 확보: 근거·출처 없는 AI 초안 1건을 준비한다(예: 규정 해석 답변, 통계 요약 등 합성/가짜 데이터 기반).
- 되번역 골격 정의: 결과물에 [핵심 답변 / 근거·인용 / 확실한 부분 / 불확실·확인필요 부분 / 참고 출처 / AI 보조 고지 / 담당자 최종검토란]의 골격을 씌운다.
- 불확실성 강제: 프롬프트에 '확신하지 못하는 항목은 반드시 [확인 필요]로 표시하고 임의 단정 금지'를 넣어 재생성한다.
- 출처 강제: '주장마다 근거 자료를 명시하고, 근거가 없으면 근거 없음이라 밝혀라'를 넣어 환각 출처가 줄어드는지 관찰한다.
- 도구 인터페이스 설계: 이 되번역을 자동화할 함수 1개를 상상해 [함수명 / 한 줄 설명 / 입력 스키마(필드·타입·필수여부·설명)]를 정의한다. 예: summarize_with_sources(text, audience, max_len).
- 다중 이해관계자 파생: 같은 되번역 결과에서 (가)실무자용 근거 상세, (나)주민용 쉬운 안내문, (다)감사용 이력 요약 세 형태를 파생한다.
✅ 성공 기준 · 되번역 결과물이 근거·출처·불확실성·AI 고지·최종검토란을 모두 갖추고, 제3자가 그것만 보고 결과의 신뢰도를 판단·이의제기할 수 있으며, 도구 인터페이스 스키마에 모호한 필드가 없다.
↗ 확장 · 설계한 도구 인터페이스를 MCP '도구' 관점으로 재서술하고(서버가 노출·호스트가 호출), 어떤 리소스(자료)를 함께 노출해야 근거가 채워지는지 연계도로 그린다.
사례 연구
상황 · 한 지자체 부서가 반복 민원 회신을 AI로 초안 작성하기 시작했다. 초기엔 담당자가 한 줄 요구를 던지면 AI가 그럴듯한 공문 문체의 답변을 통째로 뱉었고, 담당자는 대충 훑고 발송했다. 몇 달 뒤 근거 법령을 잘못 인용한 회신, 처리기한을 틀린 회신이 발견되며 이의제기가 들어왔다.
문제의 뿌리는 모델 성능이 아니라 '경계 설계 부재'였다. 세 경계가 모두 열려 있었다. (1) 의도→명세: 담당자의 한 줄 요구가 그대로 들어가 모델이 맥락을 임의로 채웠다. → 민원 유형별 명세 템플릿(적용 법령·처리기한·필수 문구·금지 표현)을 도입해 요구를 구조화했다. (2) 출력→인간: 답변이 근거·출처 없는 한 덩어리라 검증이 불가능했다. → 되번역 골격을 강제해 '주장마다 근거 법령 조항 명시, 확인 필요 항목은 [확인 필요] 표기, AI 보조 고지, 담당자 최종검토란'을 넣었다. (3) 설명책임: 이의제기 시 근거를 소명할 이력이 없었다. → 출처·불확실성 로그를 남기고, 회신문에 이의제기 경로를 명시했다. 개편 후 담당자는 [확인 필요] 표시가 붙은 항목만 집중 검토하게 되어 오히려 검토 시간이 줄고, 잘못된 법령 인용이 발송 전에 걸러졌다.
교훈 · 경계에서의 실패는 모델을 더 좋은 것으로 바꾼다고 해결되지 않는다. 의도를 명세로 받고, 출력을 근거·불확실성과 함께 되번역하며, 설명책임 경로를 여는 '경계 설계'가 신뢰를 만든다. 불확실성 표기는 검토를 늘리는 게 아니라 검토를 '옳은 곳'으로 모은다.
상황 · 한 팀이 AI 어시스턴트에 사내 위키·이슈트래커·문서 검색을 붙이려 했다. 처음엔 각 시스템마다 맞춤 연결 코드를 짰다. 시스템이 늘고 API가 바뀔 때마다 연결이 깨졌고, 어떤 도구가 어떤 데이터에 접근하는지 감사도 어려웠다.
팀은 각 데이터 소스를 MCP '서버'로 감쌌다. 각 서버는 자신이 제공하는 도구(예: search_wiki)와 리소스(문서 목록)를 표준 스키마로 노출했고, AI 호스트(클라이언트)는 연결된 서버들에서 사용 가능한 도구를 발견·호출했다. 효과는 세 가지였다. (1) 상호운용: 새 데이터 소스는 MCP 서버로 감싸기만 하면 기존 호스트가 별도 코드 없이 발견했다. (2) 계약 안정: 인터페이스 계약(도구 이름·입력 스키마·에러 규약)이 못박혀, 내부 구현이 바뀌어도 경계가 유지됐다. (3) 감사: 어떤 도구가 어떤 리소스에 접근하는지 프로토콜 차원에서 드러나 접근 권한·로그를 일관되게 관리했다. 팀은 '단순 함수 하나로 충분한 것까지 MCP로 감싸지 말라'는 원칙도 세웠다—표준의 이점(재사용·감사·상호운용)이 오버헤드를 넘어설 때만 프로토콜을 도입했다.
교훈 · 임시 연결은 처음엔 빠르지만 시스템이 늘수록 유지비가 폭증한다. 표준 프로토콜(MCP)은 경계에 '계약'을 도입해 재사용·상호운용·감사를 가능케 한다. 단, 모든 것을 프로토콜로 감쌀 필요는 없다—경계가 여러 소비자와 만나고 오래 살아야 할 때 표준의 값어치가 나온다.
흔한 실패 · 안티패턴
- 의도→명세 번역을 건너뛰고 막연한 한 줄 요구를 그대로 넣어, 모델이 맥락을 임의로 채운 '그럴듯하지만 엉뚱한' 결과를 받는다.
- 출력을 근거·출처 없이 한 덩어리로 받아 검증이 불가능한데도 결재·발송에 그대로 쓴다(되번역 부재).
- 불확실성을 표기하지 않아 사람이 모든 출력을 동등하게 과신하거나, 반대로 전부 불신해 AI를 방치한다.
- 환각 출처(존재하지 않는 조항·문서)를 그대로 인용한다. '근거 없으면 근거 없음이라 밝혀라'는 강제가 없다.
- AI 생성물임을 고지하지 않아 책임 소재와 신뢰가 흐려지고, 공공에서는 준법 문제로 번진다.
- 이의제기·설명책임 경로를 만들지 않아, 당사자가 재검토를 요청할 방법도 최종 책임자도 특정되지 않는다.
- 도구 인터페이스 설명·스키마가 모호해 모델이 잘못된 인자를 채운다(경계 실패를 모델 탓으로 오진).
- 필요 없는 곳까지 MCP·프로토콜로 감싸 오버엔지니어링한다. 단순 함수로 충분한데 표준화 비용만 치른다.
- HITL 승인 화면에 근거·불확실성을 노출하지 않아, 사람이 내용을 못 보고 '눈감고 결재'한다.
- 한 가지 출력 형태로 실무자·주민·감사를 모두 만족시키려다 아무도 못 만족시킨다(다중 이해관계자 번역 실패).
- '헤르메스 엔지니어링'을 이미 존재하는 업계 표준 용어처럼 소개해 학습자를 오도한다(정직한 명명 고지 누락).
평가
| 평가 기준 | 초급 | 능숙 | 전문 |
|---|---|---|---|
| 의도→명세 번역 | 막연한 요구를 그대로 프롬프트에 넣고, 모호어를 인지하지 못한다. | 모호어를 식별해 되묻고, 목적·독자·제약·성공기준이 담긴 명세표로 옮긴다. | 재사용 가능한 명세 템플릿을 만들고, 해석학적 되묻기로 이해관계자별 의미 차이를 사전에 정렬한다. |
| 기계출력의 인간가독화 | 출력을 한 덩어리로 받아 근거·불확실성 없이 그대로 사용한다. | 근거·출처·불확실성 표기·AI 고지·최종검토란을 갖춘 되번역 골격을 적용한다. | 같은 결과를 실무자·주민·감사용으로 파생하고, 출처 강제·불확실성 강제로 환각을 구조적으로 억제한다. |
| 인터페이스·프로토콜 설계 | 도구/연결을 임시로 짜고 스키마·계약 개념이 없다. | 모호하지 않은 도구 인터페이스(이름·설명·입력 스키마)를 정의하고, MCP가 무엇을 해결하는지 설명한다. | MCP 서버/클라이언트로 도구·리소스를 노출·소비하는 연계를 설계하고, 인터페이스 계약(스키마·에러·버전·고지)을 문서화하며 언제 표준화가 값어치 있는지 판단한다. |
| 설명책임·경계 실패 진단 | 이의제기·설명책임 경로가 없고, 경계 실패를 모델 탓으로 돌린다. | 경계 오역 실패모드를 유형화해 최소 방어(스키마 검증·출처 강제·불확실성 표기)를 걸고, 이의제기 경로를 명시한다. | HITL 게이트의 인간 쪽 UX와 설명책임 경로를 통합 설계하고, 경계 품질을 평가(eval)로 지속 측정·개선한다. |
- '프롬프트를 잘 쓰면 됐지, 그 결과를 사람이 쓸 형태로 바꾸는 별도의 일이 왜 필요한가?'를 자기 업무 예로 설명해 보라.
- AI가 만든 문서를 상급자 결재에 올릴 때, 무엇이 함께 있어야 결재자가 믿고 서명할 수 있는가? 3가지 이상 적어라.
- 서로 다른 시스템(예: 우리 부서 문서, 타 기관 데이터)을 AI에 연결할 때 매번 맞춤 코드를 짜면 어떤 문제가 생길지 예상해 보라.
- 막연한 실무 요구 1건을 목적·독자·제약·성공기준이 담긴 구조화 명세로 번역하고, 원요구 대비 결과가 왜 나아지는지 설명하라.
- 근거·출처 없는 AI 초안 1건을 근거·출처·불확실성 표기·AI 고지·독자별 요약을 갖춘 '결재 가능한' 형태로 되번역하라.
- 우리 부서가 AI에 붙이고 싶은 도구/데이터 1건을 MCP 관점(서버가 도구·리소스 노출, 호스트가 호출)으로 연계도로 그리고, 단순 함수로 충분한 경우와 표준 프로토콜이 값어치 있는 경우를 구분하라.
- 경계 오역 실패모드 3가지를 들고 각각에 대한 최소 방어와 이의제기 경로를 설계하라.
읽을거리 · 도구
- Model Context Protocol 공식 문서·사양 — MCP의 서버/클라이언트 구조, 도구·리소스·프롬프트 노출 방식, 메시지 규약을 1차 자료로 확인한다. (개념 소개 글이 아니라 사양 자체를 읽어야 '표준이 무엇을 못박는지'가 정확해진다. 우리 부서 연계를 상상하며 읽어라.)
- Anthropic의 도구 사용(tool use) 개발 문서 — 함수/도구 인터페이스를 이름·설명·입력 스키마로 정의하는 실제 형식과 좋은 스키마 작성법을 익힌다. (랩 B의 인터페이스 설계 직전에 읽어라. 좋은 설명·나쁜 설명 대조 예시에 집중하라.)
- 구조화 출력(structured output)·JSON 스키마 강제 기법 자료 — 모델 출력을 정해진 스키마로 강제해 후속 시스템이 파싱·검증할 수 있게 만드는 방법을 다룬다. (인간가독화 되번역과 도구 인터페이스 양쪽의 토대. 왜 자유 텍스트보다 스키마가 경계를 안전하게 하는지에 주목하라.)
- 설명가능 AI(XAI)·AI 투명성 개론 자료 — 근거 제시·불확실성 표기·출처 고지가 왜 신뢰와 책임의 전제인지, 특히 공공·고위험 영역에서의 요구를 개관한다. (기법서가 아니라 '왜 되번역이 준법이자 신뢰인가'의 근거로 읽어라. 우리 기관의 설명책임 의무와 연결하라.)
- 행정기본법·행정절차법의 이유 제시·불복(이의제기) 조항 및 소속 기관의 AI 활용 지침 — AI 보조 결정에 근거를 붙이고, 당사자에게 이의제기·재검토 경로를 보장해야 하는 법·제도적 근거를 확인한다. (기술이 아니라 제도가 경계 설계의 요건을 정한다. '설명책임 경로'가 선택이 아니라 의무임을 이 자료로 못박아라.)
- 해석학(hermeneutics) 개론 — 의미가 맥락에 따라 달라진다는 관점 — 같은 말이 사람·맥락마다 다른 의미를 갖는다는 통찰을, 요구를 되물어 정렬하는 실천의 이론적 배경으로 삼는다. (철학 전체를 읽을 필요는 없다. '의미는 협상된다'는 핵심만 잡아 의도→명세 번역에 적용하라.)