AI NATIVE COMPANY

AX4U 바이브코딩 마스터 과정

근거를 찾아 말하고 허락받아 움직이는 AI 도우미

모델 원리부터 구조화 출력·검색·다중 매체·도구 연결·승인형 출시까지 가상 책방 프로젝트로 배운다. 기본은 무료 오프라인 모의 실습이며 외부 API·벡터DB·자동화 서비스 실행은 선택 심화다.

읽음과 숙련은 별개입니다. 자동채점은 선택형에만 적용합니다.

교육자의 독립: 개념을 이해하고 실전 사례를 직접 검증해 현실 문제를 해결하는 시스템을 스스로 개발합니다.

공동체 기여: 결과와 실패·복구 과정을 다른 사람에게 설명하고 함께 개선합니다. 이 과정은 숙련을 보장하지 않습니다.

첫 단원 시작하기 → · 단원 목록 보기

내 기기의 학습 기록

이 기기에만 저장됩니다. 자동 동기화되지 않으며 개인정보·비밀키를 적지 마세요. 읽음·답변·증거는 숙련 인증이 아닙니다.

학습 단원

말 잘하는 기계의 안과 밖

해결할 문제와 목표

모델이 책방의 최신 공지를 안다고 믿고 답을 게시하면 없는 혜택을 안내할 수 있다.

생성형 모델·트랜스포머·전이학습·프롬프트의 역할을 구분하고 검증된 답변 규칙을 쓴다.

먼저 알아둘 것

필수 선수지식 없음

핵심 한 문장: 모델은 다음 토큰을 예측하며, 최신 운영 사실은 별도 자료로 제공해야 한다.

지금 할 일준비물개념과 원리따라 하기예상 결과와 검증오류 복구혼자 변형설명과 기여

큰 그림: 비유와 경계

문장을 이어 쓰는 숙련자에게 오늘의 공지를 건네는 모습이다.

비유가 닿지 않는 곳: 사람처럼 참·거짓을 직접 경험하지 않으며 토큰 예측만으로 출처 보증이 생기지 않는다.

실제로 작동하는 원리

대규모 사전학습은 범용 패턴을 학습한다. 트랜스포머의 attention은 입력 토큰 사이의 관련 정보를 문맥에 따라 섞는다. 전이학습은 기존 모델을 다른 작업에 적응시키는 큰 범주이고 파인튜닝은 가중치 업데이트다. 프롬프트·검색 문맥은 가중치를 바꾸지 않는다. 토큰·문맥창 제한 때문에 긴 문서에는 검색/요약 전략이 필요하다.

따라 하기

  1. 가상 자료를 종이에 적는다: 「가람책방 토요일 11~18시, 행사 신청은 담당자 확인 뒤 확정」.
  2. 어떤 기존 대화형 AI를 쓸 수 있으면 다음 입력을 그대로 붙여넣고, 없으면 동료가 모델 역할을 맡는다: 「아래 자료만 사용해 질문에 답하라. 없는 사실은 모른다고 쓰고 근거 문장을 따로 적어라. 자료: 가람책방 토요일 11~18시, 행사 신청은 담당자 확인 뒤 확정. 질문: 토요일 17시 방문 가능? 주차 무료? 신청 즉시 확정?」
  3. 답변에서 근거 있는 방문 시간과 근거 없는 주차, 아직 확정되지 않은 신청을 서로 다른 상태로 표시한다.

입력 예제

17시 방문/주차 무료/신청 즉시 확정

예상 결과

17시는 영업시간 안; 주차는 자료 없음; 신청은 아직 미확정. 표현은 달라도 세 판단이 유지되어야 한다.

검증 방법

  1. 주차를 무료라고 단정하지 않는지 확인한다.
  2. 입력 문구에서 「담당자 확인 뒤」를 제거하고 같은 질문을 반복해 확정 판단이 바뀌는지 본다.

흔한 오해와 실패 복구

  1. AI가 그럴듯한 주차 정책을 꾸며내면 원문에서 근거 줄을 지목하도록 요구하고, 없으면 미확인으로 교정한다.
  2. 전이학습·파인튜닝·문맥 입력을 혼동하면 어느 단계가 모델 가중치를 실제로 바꾸는지 표시한다.

확인 문제

「17시 방문/주차 무료/신청 즉시 확정」의 출력으로 맞는 것은?

자동채점 · 선택형

답을 고르세요
해설과 정답 보기

주차를 무료라고 단정하지 않는지 확인한다.

정답: 17시는 영업시간 안; 주차는 자료 없음; 신청은 아직 미확정. 표현은 달라도 세 판단이 유지되어야 한다.

열 살 학습자에게 attention·프롬프트·파인튜닝을 구별하고, 주차 질문이 왜 답할 수 없는지 자료 문장으로 설명한다.

동료평가 · 자동채점 아님

평가 기준: 세 상태 모두 정확하고 외부 운영 사실을 가상 사실로 게시하지 않으며 프롬프트가 학습(가중치 변경)이 아님을 설명한다. 동료에게 해당 입력의 중간 상태·오류 반례를 시연한다.

해설 보기

정답 암기보다 새 상황에 원리를 옮겨 설명하고 실제 결과를 보이는 것이 목표다.

독립 실습

다른 가상 공지로 3문항 안내문을 직접 작성하고 근거·미확인·보류를 구분한다.

남길 증거: 질문별 답변 3개와 각각의 근거 줄 또는 「자료 없음」 표기.

가상 공지

가람책방(가상): 토요일 11~18시. 행사 신청은 담당자 확인 뒤 확정. 주차 정보 없음.
실습 해설 보기

17시 방문 가능 / 주차 무료 여부 미확인 / 신청만으로 확정 아님. 단, 실제 방문·예약 전에 실제 기관에 재확인한다.

평가 기준: 세 상태 모두 정확하고 외부 운영 사실을 가상 사실로 게시하지 않으며 프롬프트가 학습(가중치 변경)이 아님을 설명한다.

새 맥락에 적용하기

기관 대관 신청 공지로 바꾸고 「접수」와 「승인」을 구분하는 문답을 작성한다.

내 말로 설명하고 가르치기

열 살 학습자에게 attention·프롬프트·파인튜닝을 구별하고, 주차 질문이 왜 답할 수 없는지 자료 문장으로 설명한다.

실습·전이·설명 결과는 본인 또는 동료가 기준에 따라 검토하세요. 이 페이지는 숙련을 자동 인증하지 않습니다.

읽음과 숙련은 별개입니다.

참고 출처와 확인 범위

학습 단원

약속한 모양으로 답하고 일은 허락받기

해결할 문제와 목표

자유형 답변은 프로그램이 읽기 어렵고, 「예약했습니다」라는 말은 실제 기록이 아니다.

JSON 출력 계약과 도구 호출의 요청/실행 분리를 구현한다.

먼저 알아둘 것

  1. model-map

핵심 한 문장: 구조화 출력은 모양을 제약하고 도구 실행은 별도의 검증·승인을 요구한다.

지금 할 일준비물개념과 원리따라 하기예상 결과와 검증오류 복구혼자 변형설명과 기여

큰 그림: 비유와 경계

주문서를 정해진 칸에 적는 것과 실제 계산대 결제는 다른 일이다.

비유가 닿지 않는 곳: JSON 파싱 성공은 사실 검증도, 외부 행위 승인도 아니다.

실제로 작동하는 원리

JSON Schema의 required/enum으로 필드를 제한할 수 있다. API structured output은 공급자 기능·모델 지원·비용 확인이 필요하며 이 단원의 오프라인 코드는 예시 응답을 파싱할 뿐 실제 모델 호출은 하지 않는다. Tool call은 모델의 제안→서버 인자 검사→권한 확인→도구 실행→결과 재검증의 단계다.

따라 하기

  1. 아래 mock-contract.py를 저장하고 python3 mock-contract.py 실행한다. Python 3 표준 라이브러리만 사용한다.
  2. status를 approved로 바꾸어 다시 실행하고 어떤 검사가 막는지 확인한다.
  3. 선택 심화(미실행): 공급자 문서에서 JSON Schema response format과 function calling을 비교한다. API 키를 브라우저/교재에 넣지 않고 유료 호출은 별도 승인 후 서버에서만 수행한다.

입력 예제

{"action":"reserve","status":"requested","event":"독서회"}

예상 결과

requested 객체 파싱 성공; 승인 전에는 실제 예약 생성 없음.

검증 방법

  1. 터미널에 status=requested와 NO WRITE가 보이는지 확인한다.
  2. status를 approved로 변경하면 AssertionError가 나와야 한다.

흔한 오해와 실패 복구

  1. JSONDecodeError면 따옴표와 쉼표를 검사한다.
  2. 유효 JSON이더라도 승인 주체가 없으면 쓰기 도구 실행을 금지한다.

확인 문제

「{"action":"reserve","status":"requested","event":"독서회"}」의 출력으로 맞는 것은?

자동채점 · 선택형

답을 고르세요
해설과 정답 보기

터미널에 status=requested와 NO WRITE가 보이는지 확인한다.

정답: requested 객체 파싱 성공; 승인 전에는 실제 예약 생성 없음.

형식이 맞는 답과 권한 있는 예약 완료가 왜 다른지 승인 절차까지 그려 설명한다.

동료평가 · 자동채점 아님

평가 기준: 정상 입력 통과, 거부 입력 실패, 실행과 제안을 분리해 말하면 통과. 동료에게 해당 입력의 중간 상태·오류 반례를 시연한다.

해설 보기

정답 암기보다 새 상황에 원리를 옮겨 설명하고 실제 결과를 보이는 것이 목표다.

독립 실습

event가 빈 문자열인 제안을 거부하고 거부 사유를 기록한다.

남길 증거: 실행 출력과 실패 입력 테스트, 실제 외부 쓰기 없음 확인.

오프라인 구조화 응답

import json
raw = '{"action":"reserve","status":"requested","event":"독서회"}'
data = json.loads(raw)
assert set(data) == {"action", "status", "event"}
assert data["action"] == "reserve" and data["status"] == "requested"
assert isinstance(data["event"], str) and data["event"].strip()
print("status=" + data["status"] + " / NO WRITE")
실습 해설 보기

빈 event는 assert data["event"].strip()에서 실패한다. 운영 서비스에서는 명시적 오류처리·스키마 라이브러리·승인 로그가 추가로 필요하다.

평가 기준: 정상 입력 통과, 거부 입력 실패, 실행과 제안을 분리해 말하면 통과.

새 맥락에 적용하기

도서관 대관 신청서 JSON에 날짜 형식을 추가하고 형식 오류를 거부한다.

내 말로 설명하고 가르치기

형식이 맞는 답과 권한 있는 예약 완료가 왜 다른지 승인 절차까지 그려 설명한다.

실습·전이·설명 결과는 본인 또는 동료가 기준에 따라 검토하세요. 이 페이지는 숙련을 자동 인증하지 않습니다.

읽음과 숙련은 별개입니다.

참고 출처와 확인 범위

학습 단원

찾아서 근거와 함께 답하기

해결할 문제와 목표

여러 안내문 중 관련 없는 문장을 모델에 넣으면 그럴듯한 오답이 나온다.

문서 파싱·청킹·메타데이터·희소/밀집 검색·재정렬·RAG 평가를 손으로 그리고 코드로 시험한다.

먼저 알아둘 것

  1. model-map

핵심 한 문장: RAG는 질문에 맞는 조각을 찾아 출처와 함께 모델 입력에 붙이는 파이프라인이다.

지금 할 일준비물개념과 원리따라 하기예상 결과와 검증오류 복구혼자 변형설명과 기여

큰 그림: 비유와 경계

책장 색인에서 관련 페이지를 찾은 뒤 직원에게 해당 페이지만 읽히는 일이다.

비유가 닿지 않는 곳: 색인에 없거나 잘못 끊긴 문장은 검색되지 않고 인용도 진실 보증이 아니다.

실제로 작동하는 원리

텍스트 파싱→의미 단위 청킹→문서 ID/갱신일 보관→질문 정규화·키워드/BM25 또는 embedding 유사도 검색→결과 재정렬→답변·출처→정답셋 평가. Chroma·FAISS·Qdrant는 벡터 검색 구현 옵션이며 아래 코드는 의존성 없는 정확 키워드 기준선이다. hybrid는 희소+밀집 결과를 결합하고 query rewriting은 질문 표현을 바꾸며 contextual retrieval은 조각에 원문 맥락을 보강한다.

따라 하기

  1. rag-baseline.py를 저장하고 python3 rag-baseline.py 실행한다.
  2. 질문을 「대관 취소 수수료?」로 바꾸고 검색 결과가 없으면 없는 정보라고 답하는지 본다.
  3. 선택 심화(미실행): 동일 가상 문서를 Chroma/FAISS/Qdrant 중 하나에 적재하고 embedding 모델·거리함수·갱신/삭제·top-k를 기록한다. 설치·API 비용 발생 전 별도 승인 필요.

입력 예제

질문: 토요일 영업시간 / 문서 d1,d2

예상 결과

d1에서 11~18시를 찾고 d1 ID와 함께 답함. 취소 수수료는 미확인.

검증 방법

  1. 토요일 검색 결과가 d1인지와 빈 결과가 미확인인지 확인한다.
  2. 평가표에 정답 문서 d1과 비정답 d2를 적고 precision@1=적중/1을 직접 계산한다.

흔한 오해와 실패 복구

  1. 한국어 활용형 때문에 단어가 불일치하면 검색어 정규화 또는 동의어 규칙을 추가하되 모든 문서를 무작정 정답 처리하지 않는다.
  2. PDF 파싱에서 표가 깨지면 원본의 표 머리글과 행을 확인하고 사람이 정정한 텍스트로 재색인한다.

확인 문제

「질문: 토요일 영업시간 / 문서 d1,d2」의 출력으로 맞는 것은?

자동채점 · 선택형

답을 고르세요
해설과 정답 보기

토요일 검색 결과가 d1인지와 빈 결과가 미확인인지 확인한다.

정답: d1에서 11~18시를 찾고 d1 ID와 함께 답함. 취소 수수료는 미확인.

검색 실패와 모델 환각의 차이, 청킹과 메타데이터가 왜 필요한지 근거 문서 하나로 설명한다.

동료평가 · 자동채점 아님

평가 기준: 정답셋 최소 3질의(정답/미답/오래된 문서)를 만들고 각 질의의 검색·답변·근거를 확인하면 통과. 동료에게 해당 입력의 중간 상태·오류 반례를 시연한다.

해설 보기

정답 암기보다 새 상황에 원리를 옮겨 설명하고 실제 결과를 보이는 것이 목표다.

독립 실습

「행사 신청」 질의와 잘못된 날짜의 오래된 공지를 추가해 갱신일 우선 기준을 설계한다.

남길 증거: 첫 줄 d1 출처, 둘째 줄 「자료 없음: 미확인」; 새 문서에서 오래된 공지 제외 이유.

로컬 검색 기준선

docs = [("d1", "토요일 영업시간 11~18시"), ("d2", "행사 신청은 확인 뒤 확정")]
def lookup(term):
    return [(i,t) for i,t in docs if term in t]
for question,term in [("토요일 영업시간?","토요일"),("대관 취소 수수료?","취소 수수료")]:
    hits=lookup(term)
    print(question, "|", hits[0][0]+": "+hits[0][1] if hits else "자료 없음: 미확인")
실습 해설 보기

적중 문장과 문서 ID만 제시하고 매칭이 없으면 답을 보류한다. 실전은 검색 품질과 생성 사실성을 별개로 평가한다.

평가 기준: 정답셋 최소 3질의(정답/미답/오래된 문서)를 만들고 각 질의의 검색·답변·근거를 확인하면 통과.

새 맥락에 적용하기

기관 자료실의 이용시간/휴관/반납 공지로 바꾸고 무응답 질문을 포함한 평가표를 만든다.

내 말로 설명하고 가르치기

검색 실패와 모델 환각의 차이, 청킹과 메타데이터가 왜 필요한지 근거 문서 하나로 설명한다.

실습·전이·설명 결과는 본인 또는 동료가 기준에 따라 검토하세요. 이 페이지는 숙련을 자동 인증하지 않습니다.

읽음과 숙련은 별개입니다.

참고 출처와 확인 범위

학습 단원

관계와 이미지도 근거로 다루기

해결할 문제와 목표

기관 규정의 관계 정보와 이미지 속 글자를 일반 텍스트 검색만으로 놓칠 수 있다.

Agentic RAG·GraphRAG·멀티모달 RAG의 사용 조건과 사람 검토 경계를 설계한다.

먼저 알아둘 것

  1. search-evidence

핵심 한 문장: 그래프는 관계를, 멀티모달은 매체를, 에이전트는 다음 검색 행동을 확장하지만 출처 검증은 그대로 필요하다.

지금 할 일준비물개념과 원리따라 하기예상 결과와 검증오류 복구혼자 변형설명과 기여

큰 그림: 비유와 경계

색인 카드에 책→모임→장소의 화살표를 추가하고 사진에 붙은 설명도 별도 색인하는 것과 같다.

비유가 닿지 않는 곳: 사진 OCR 오류와 관계 추론은 정확한 규정 증거가 아니며 자율 탐색은 비용과 위험을 높인다.

실제로 작동하는 원리

GraphRAG는 엔티티·관계 추출과 그래프 탐색 뒤 원문 근거를 회수한다. 멀티모달은 이미지 텍스트·설명 등 추출 결과를 원본 문서/페이지에 연결한다. agentic 검색은 검색 실패를 감지하고 재질문할 수 있지만 최대 반복 횟수·허용 자료·비용 상한이 필요하다. LangGraph/Dify는 구현 선택지이며 아래 오프라인 실습은 구조 판단만 검증한다.

따라 하기

  1. 가상 세 문장을 카드에 적는다: 「모임 A는 방 B에서 열린다」「방 B는 토요일 닫는다」「모임 A는 토요일 예정」.
  2. 모임 A→방 B→토요일 닫음 관계를 그린 뒤 「모임 진행 가능?」은 충돌 가능성이 있으므로 담당자 확인으로 보류한다.
  3. 이미지 속 시간표가 있다면 공개 가능한 가상 이미지에서 사람이 먼저 전사하고 원본/전사/검수자를 별개 기록한다. 인물 사진·개인정보는 사용하지 않는다.

입력 예제

토요일 모임 A 운영 가능?

예상 결과

방 B 휴관 규칙과 충돌 가능. 확정하지 않고 담당자 확인 요청.

검증 방법

  1. 세 개 원문 노드와 두 개 이상 관계 화살표가 있는지 확인한다.
  2. 가짜 OCR 오타 「토오일」을 넣어도 무검증 확정이 아닌 보류인지 확인한다.

흔한 오해와 실패 복구

  1. 관계의 방향을 뒤집으면 모임과 장소가 혼동되므로 관계별 근거 문장을 표시한다.
  2. 에이전트가 끝없이 검색하면 최대 2회 재시도 후 사람에게 넘긴다.

확인 문제

「토요일 모임 A 운영 가능?」의 출력으로 맞는 것은?

자동채점 · 선택형

답을 고르세요
해설과 정답 보기

세 개 원문 노드와 두 개 이상 관계 화살표가 있는지 확인한다.

정답: 방 B 휴관 규칙과 충돌 가능. 확정하지 않고 담당자 확인 요청.

열 살 아이에게 왜 사진에서 읽은 날짜도 확인해야 하며 그래프가 정답 생성기가 아닌지 설명한다.

동료평가 · 자동채점 아님

평가 기준: 관계와 원문 근거 2개 이상, OCR 오인식 위험, 반복 상한을 설명하면 통과. 동료에게 해당 입력의 중간 상태·오류 반례를 시연한다.

해설 보기

정답 암기보다 새 상황에 원리를 옮겨 설명하고 실제 결과를 보이는 것이 목표다.

독립 실습

기관의 대관→담당 부서→승인 상태 관계를 만들어 결론 보류 사례를 작성한다.

남길 증거: 원문 세 줄, 관계도, 모순 판단 및 사람 확인 안내.

가상 관계 카드

모임 A는 방 B에서 열린다.
방 B는 토요일 닫는다.
모임 A는 토요일 예정이다.
실습 해설 보기

토요일 진행은 공지끼리 충돌한다. 규칙 확인 담당자에게 질의하고 승인 전 공지 게시를 보류한다.

평가 기준: 관계와 원문 근거 2개 이상, OCR 오인식 위험, 반복 상한을 설명하면 통과.

새 맥락에 적용하기

책방 행사 사진 포스터에서 날짜와 장소를 추출해 텍스트 공지와 충돌 여부를 점검한다.

내 말로 설명하고 가르치기

열 살 아이에게 왜 사진에서 읽은 날짜도 확인해야 하며 그래프가 정답 생성기가 아닌지 설명한다.

실습·전이·설명 결과는 본인 또는 동료가 기준에 따라 검토하세요. 이 페이지는 숙련을 자동 인증하지 않습니다.

읽음과 숙련은 별개입니다.

참고 출처와 확인 범위

학습 단원

연결해도 멈출 줄 아는 도우미

해결할 문제와 목표

외부 도구를 붙인 AI가 권한을 넘거나 자동 반복하며 잘못된 공지를 발행할 수 있다.

MCP·ReAct·planning·memory·HITL·자동화·배포 평가를 안전한 모의 프로젝트로 끝까지 설계한다.

먼저 알아둘 것

  1. contract-tools
  2. search-evidence

핵심 한 문장: 연결 프로토콜과 실행 권한은 별개이며 사람 승인과 관찰 가능한 로그가 있어야 배포할 수 있다.

지금 할 일준비물개념과 원리따라 하기예상 결과와 검증오류 복구혼자 변형설명과 기여

큰 그림: 비유와 경계

비서에게 공용 열쇠함의 위치를 알려줘도 문 잠금 권한을 자동으로 주는 것은 아니다.

비유가 닿지 않는 곳: MCP 자체가 권한 통제·사실 검증·인간 승인을 대신하지 않는다.

실제로 작동하는 원리

MCP의 도구/리소스/프롬프트 인터페이스와 클라이언트-서버 구조를 구분한다. ReAct는 관찰→행동 제안→결과 관찰 반복이며 planning은 단계 설계, memory는 상태 유지(개인정보 보존 위험 포함), human-in-the-loop는 발송/쓰기 직전 승인이다. n8n 등 자동화는 트리거→검사→초안→승인→발송으로 나눈다. 로컬 프로토타입은 정보 제공만 하고 실제 배포에 앞서 성능·비용·안정성·사용성을 테스트한다.

따라 하기

  1. 종이에 워크플로를 작성한다: 질문→허용 문서 검색→답 초안→근거 확인→사람 승인→공개. 외부 API/유료 도구는 호출하지 않는다.
  2. 승인 전에는 publish=false, 승인 후에도 문서 버전이 바뀌면 무효 처리하는 상태표를 만든다.
  3. 선택 심화(미실행): 공식 MCP 문서의 tools/list 및 tools/call 구조를 읽고 로컬 테스트 서버에서 읽기 전용 도구만 노출한다. API 키·파일 시스템 전체 권한을 주지 않는다.

입력 예제

근거 d1, 승인=false, 공개 요청

예상 결과

공개 보류; 근거 부재·문서 변경 시 승인 재요청.

검증 방법

  1. 무근거 답, 자료 만료, 중복 요청, 외부 서비스 장애 네 경우 모두 공개 보류 또는 명확한 오류인지 점검한다.
  2. 평가표에 정답 일치·요청당 예상 호출 횟수·장애 시 대체 메시지·키보드 사용성 확인 칸을 채운다.

흔한 오해와 실패 복구

  1. 「MCP 연결됨=실행 허가됨」은 틀리다. 인증·최소권한·사용자 승인 따로 확인한다.
  2. 자동화 루프가 중복 발행하면 idempotency 키와 재시도 상한을 설계한다.

확인 문제

「근거 d1, 승인=false, 공개 요청」의 출력으로 맞는 것은?

자동채점 · 선택형

답을 고르세요
해설과 정답 보기

무근거 답, 자료 만료, 중복 요청, 외부 서비스 장애 네 경우 모두 공개 보류 또는 명확한 오류인지 점검한다.

정답: 공개 보류; 근거 부재·문서 변경 시 승인 재요청.

도구 연결, 계획, 기억, 사람 승인 중 무엇이 데이터를 변경하는지와 배포 전 반례 2개를 설명한다.

동료평가 · 자동채점 아님

평가 기준: 네 실패 주입에 안전한 결과, 최소권한, 동료가 재현한 데모까지 충족해야 통과. 동료에게 해당 입력의 중간 상태·오류 반례를 시연한다.

해설 보기

정답 암기보다 새 상황에 원리를 옮겨 설명하고 실제 결과를 보이는 것이 목표다.

독립 실습

가상 문화센터의 휴강 공지 초안 승인 플로를 만들고 실패 주입 표를 작성한다.

남길 증거: 입력-출력 흐름도, 4실패 테스트 표, 승인 상태 및 발표용 데모 시나리오.

모의 출시 체크리스트

근거ID=d1
승인=false
발행=false
최대도구호출=2
실패시=보류
실습 해설 보기

승인=false면 발행=false. 승인=true라도 문서가 바뀌면 발행 보류. 비용·성능·안정성·사용성을 실제 측정하기 전 공개 서비스 준비 완료라고 말하지 않는다.

평가 기준: 네 실패 주입에 안전한 결과, 최소권한, 동료가 재현한 데모까지 충족해야 통과.

새 맥락에 적용하기

도서관 반납 알림 자동화로 바꾸되 개인 연락처 없는 가상 데이터만 써 승인 분기와 실패처리를 재설계한다.

내 말로 설명하고 가르치기

도구 연결, 계획, 기억, 사람 승인 중 무엇이 데이터를 변경하는지와 배포 전 반례 2개를 설명한다.

실습·전이·설명 결과는 본인 또는 동료가 기준에 따라 검토하세요. 이 페이지는 숙련을 자동 인증하지 않습니다.

읽음과 숙련은 별개입니다.

참고 출처와 확인 범위

학습 단원

숫자로 보는 임베딩과 혼합 검색

해결할 문제와 목표

정확 단어가 다른 문서와 오래된 문서가 검색 상위에 섞인다.

수치 거리·버전 필터·rewrite/hybrid/rerank/contextual을 순서별로 재현한다.

먼저 알아둘 것

  1. search-evidence

핵심 한 문장: 임베딩은 의미 벡터 후보 검색이고 답변의 진실 판정은 별개다.

지금 할 일준비물개념과 원리따라 하기예상 결과와 검증오류 복구혼자 변형설명과 기여

큰 그림: 비유와 경계

비슷한 주제의 문서를 가까운 좌표에 놓는 지도.

비유가 닿지 않는 곳: 이 좌표는 사람이 만든 합성값이며 실제 언어 임베딩의 의미를 증명하지 않는다.

실제로 작동하는 원리

질문 (.8,.2), d1 (1,0), d2 (0,1), 구버전 d3 (.9,.1)의 유클리드 거리는 각각 약 .283, 1.131, .141이다. 필터 없이 d3가 먼저 나와 오답을 만들지만 v2 필터 뒤 d1이 첫째다. 「영업시간」 정확 문자열은 셋 어디에도 없어 키워드 결과는 빈 배열. rewrite 「토요일」은 d1을 회수한다. hybrid는 dense/sparse 순위 역수를 합치고 rerank는 시간·출처를 읽어 확정한다. contextual은 짧은 조각에 문서명·시행버전을 붙여 색인하되 잘못된 맥락 첨가를 금한다. Chroma는 로컬 임베딩 저장, FAISS는 인덱스 라이브러리, Qdrant는 서버형 벡터DB 선택지; 셋 모두 여기서 미설치·미실행.

따라 하기

  1. search-lab.py를 같은 폴더에 저장해 python3 search-lab.py 실행한다. 출력의 keyword 빈 배열과 거리 세 값을 계산기로 대조한다.
  2. version==2 필터를 해제해 d3가 dense 1위인지 확인한 다음 다시 복구한다.
  3. rewrite를 「토요일」에서 「행사」로 바꾸어 sparse 결과와 hybrid 순위 변화를 기록한다. 실제 문서는 출처/시행버전/권한 메타데이터와 chunk ID를 함께 색인한다.

입력 예제

영업시간? / q=(.8,.2) / d1=(1,0),d2=(0,1),d3=(.9,.1) v1

예상 결과

keyword=[]; 거리 d3=.141<d1=.283<d2=1.131; v2 필터 후 d1 답 11~18시 [d1 v2].

검증 방법

  1. 키워드 공백과 d3 최근접이 동시에 일어나는지 비교하고, 필터 후 d1만 근거로 답했는지 확인한다.
  2. 문서 날짜를 v1로 바꾸면 근거가 없어 보류되어야 한다.

흔한 오해와 실패 복구

  1. 순위 1위가 오래된 문서면 질의어가 아니라 시행버전 필터부터 수정한다.
  2. 거리만 낮고 사실 문장이 없으면 rerank 또는 보류; 임의 좌표를 실제 embedding 성능이라 주장하지 않는다.

확인 문제

「영업시간? / q=(.8,.2) / d1=(1,0),d2=(0,1),d3=(.9,.1) v1」의 출력으로 맞는 것은?

자동채점 · 선택형

답을 고르세요
해설과 정답 보기

키워드 공백과 d3 최근접이 동시에 일어나는지 비교하고, 필터 후 d1만 근거로 답했는지 확인한다.

정답: keyword=[]; 거리 d3=.141<d1=.283<d2=1.131; v2 필터 후 d1 답 11~18시 [d1 v2].

새 자료에서 수치 거리·버전 필터·rewrite/hybrid/rerank/contextual을 순서별로 재현한다. 입력부터 판정까지 동료에게 시연한다.

동료평가 · 자동채점 아님

평가 기준: 키워드와 거리의 숫자 반례, 버전 필터 전후, 미답 처리, 두 새 질문의 근거를 모두 재현해야 통과. 동료에게 해당 입력의 중간 상태·오류 반례를 시연한다.

해설 보기

정상/실패 출력 및 근거를 비교한다.

독립 실습

기관 휴관/반납 규칙으로 문서를 교체하고 쿼리 두 개의 recall@1을 계산한다.

남길 증거: 직접 실행 출력·실패 주입 기록과 수정 후 출력; 동료 재현 여부는 별도 확인.

전체 실행 또는 입력 자료

"""합성 2차원 임베딩 교육 모형: 실제 embedding 모델/DB가 아니다."""
from math import dist
D={
 'd1':{'text':'토요일 문 여는 시간 11~18시','vec':(1,0),'version':2},
 'd2':{'text':'행사 신청은 담당 확인 뒤 확정','vec':(0,1),'version':2},
 'd3':{'text':'토요일 운영시간 10~17시 [폐기]','vec':(.9,.1),'version':1},
}
q=(.8,.2); term='영업시간'
# 사용자가 정해 놓은 좌표다. 학습 모델이 텍스트에서 이 숫자를 만들어 낸 것은 아니다.
print('keyword', [k for k,v in D.items() if term in v['text']])
for k,v in D.items(): print('distance',k,round(dist(q,v['vec']),3))
# cosine/dot product와 Euclidean 순위는 정규화하지 않으면 달라질 수 있다.
active={k:v for k,v in D.items() if v['version']==2}
dense=sorted(active,key=lambda k:dist(q,active[k]['vec']))
rewritten='토요일'; sparse=[k for k,v in active.items() if rewritten in v['text']]
# hybrid: 각 리스트 순위를 역수로 합침. 재정렬: 실제 답 문구의 시간+출처 버전 확인.
scores={k:sum(1/(i+1) for rank in (dense,sparse) for i,x in enumerate(rank) if x==k) for k in active}
print('dense',dense,'sparse',sparse,'hybrid',sorted(scores,key=scores.get,reverse=True))
print('rerank', 'd1' if '11~18시' in active['d1']['text'] else '보류')
# contextual: 짧은 조각에 원문에서 검증된 문서명·시행버전만 덧붙인다.
chunk='11~18시'; context='가상 책방 토요일 영업시간 [d1 v2] '+chunk
print('contextual before',chunk,'after',context)
assert '토요일' not in chunk and '토요일' in context
print('answer','11~18시 [d1 v2]' if dense[0]=='d1' else '보류')
assert not [k for k in D if term in D[k]['text']]
assert dense[0]=='d1' and 'd3' not in dense
실습 해설 보기

정답 d1만 유효; 구버전 d3의 더 가까운 거리도 사실성 보증이 아니다.

평가 기준: 키워드와 거리의 숫자 반례, 버전 필터 전후, 미답 처리, 두 새 질문의 근거를 모두 재현해야 통과.

새 맥락에 적용하기

도서관 「열람실 여는 시간」으로 표현을 바꿔 rewrite 유무의 결과를 비교한다.

내 말로 설명하고 가르치기

입력→중간 상태→출력→실패 반례를 실제 사례로 설명한다.

실습·전이·설명 결과는 본인 또는 동료가 기준에 따라 검토하세요. 이 페이지는 숙련을 자동 인증하지 않습니다.

읽음과 숙련은 별개입니다.

학습 단원

관계·재검색·이미지 근거를 각각 시험

해결할 문제와 목표

장소 폐쇄와 행사 일정이 충돌하고 포스터 OCR 글자가 틀리다.

Graph/Agentic/Multimodal RAG의 중간 상태와 실패를 로컬 코드로 구분한다.

먼저 알아둘 것

  1. vector-lab

핵심 한 문장: 관계 탐색·재검색·매체 변환은 각기 다른 실패를 낳는다.

지금 할 일준비물개념과 원리따라 하기예상 결과와 검증오류 복구혼자 변형설명과 기여

큰 그림: 비유와 경계

카드 연결선, 다시 찾는 사서, 포스터 전사 담당자를 나누는 것.

비유가 닿지 않는 곳: 관계 추출과 OCR이 틀리면 세 담당자가 많아도 틀린 근거다.

실제로 작동하는 원리

edge에는 a/b/c 원문 ID를 보존한다. 질문에 요일이 없으면 c를 한 번 재검색하고 b 폐쇄와 c 일정을 대조한다. 포스터 OCR 「토오일」은 원본 페이지의 사람이 검수하지 않아 근거에서 제외한다. LangGraph/Dify의 상태/노드는 선택 구현이며 이 예제는 의존성 없는 결정적 흐름이지 해당 제품 실행이 아니다.

따라 하기

  1. extended-rag.py를 저장하고 python3 extended-rag.py 실행한다.
  2. 질문 「모임 A 운영 가능?」에서 재검색 c와 OCR 제외 로그를 찾고 「모임 Z」는 보류인지 확인한다.
  3. edge b의 출처를 제거해 관계 확정 금지로 수정하거나 OCR verified를 True로 변경하기 전에 원본과 대조 기준을 작성한다.

입력 예제

모임 A 운영 가능? / a장소B,b방B휴관,c모임A토요일,OCR 토오일

예상 결과

c 재검색 후 b/c 충돌, 담당자 확인 전 보류; OCR 시간은 제외.

검증 방법

  1. A에서 c 재검색 로그와 b/c 근거가 모두 출력되는지 본다.
  2. Z 질문은 관계 없음 보류, 검수 안 된 OCR 시각은 결론에 쓰지 않는다.

흔한 오해와 실패 복구

  1. 그래프 간선 방향이나 출처가 틀리면 해당 edge를 제거하고 원문부터 재추출한다.
  2. 반복 검색이 끝나지 않으면 최대 2회 뒤 중단하고 질문을 담당자에게 넘긴다.

확인 문제

「모임 A 운영 가능? / a장소B,b방B휴관,c모임A토요일,OCR 토오일」의 출력으로 맞는 것은?

자동채점 · 선택형

답을 고르세요
해설과 정답 보기

A에서 c 재검색 로그와 b/c 근거가 모두 출력되는지 본다.

정답: c 재검색 후 b/c 충돌, 담당자 확인 전 보류; OCR 시간은 제외.

새 자료에서 Graph/Agentic/Multimodal RAG의 중간 상태와 실패를 로컬 코드로 구분한다. 입력부터 판정까지 동료에게 시연한다.

동료평가 · 자동채점 아님

평가 기준: 두 원문 출처 ID, 재검색 상한, OCR 검수 상태, 보류 판정을 모두 기록해야 통과. 동료에게 해당 입력의 중간 상태·오류 반례를 시연한다.

해설 보기

정상/실패 출력 및 근거를 비교한다.

독립 실습

가상 대관→담당부서→승인 상태의 관계를 추가하고 OCR 오타 하나를 넣어 보류를 재현한다.

남길 증거: 직접 실행 출력·실패 주입 기록과 수정 후 출력; 동료 재현 여부는 별도 확인.

전체 실행 또는 입력 자료

"""가상 자료의 결정적 graph/agentic/multimodal RAG 교육용, OCR/LLM 호출 없음."""
claims={'a':'모임 A는 방 B에서 열린다','b':'방 B는 토요일 닫는다','c':'모임 A는 토요일 예정이다'}
edges=[('모임 A','장소','방 B','a'),('방 B','닫음','토요일','b'),('모임 A','예정','토요일','c')]
poster={'page':'가상포스터 1쪽','ocr':'모임 A 토오일 14시','verified':False}
def answer(question):
 trace=[]
 if '모임 A' not in question: return '보류: 관계 없음',trace
 trace.append('a: 모임 A→방 B');trace.append('b: 방 B→토요일 닫음')
 if '토요일' not in question: trace.append('재검색 c: 예정 토요일')
 trace.append('c: 예정 토요일')
 if not poster['verified']: trace.append('포스터 OCR 토오일 미검수: 시간은 증거 제외')
 return '충돌: 담당자 확인 전 운영 확정 불가',trace
for q in ['모임 A 운영 가능?','모임 A 토요일 가능?','모임 Z 가능?']:
 result,trace=answer(q);print(q,'=>',result,'|',trace)
assert answer('모임 A 운영 가능?')[0].startswith('충돌')
assert answer('모임 Z 가능?')[0].startswith('보류')
실습 해설 보기

A는 장소 폐쇄와 일정 충돌, Z는 정보 없음이다. 이미지 원본 확인 전 날짜 확정 금지.

평가 기준: 두 원문 출처 ID, 재검색 상한, OCR 검수 상태, 보류 판정을 모두 기록해야 통과.

새 맥락에 적용하기

강좌→강의실→휴관 관계로 바꿔 충돌과 무관 질문을 시험한다.

내 말로 설명하고 가르치기

입력→중간 상태→출력→실패 반례를 실제 사례로 설명한다.

실습·전이·설명 결과는 본인 또는 동료가 기준에 따라 검토하세요. 이 페이지는 숙련을 자동 인증하지 않습니다.

읽음과 숙련은 별개입니다.

학습 단원

진짜 표준입출력 도구 연결과 거부

해결할 문제와 목표

MCP라고 부른 설계도만으로는 host/client/server 통신을 이해하기 어렵다.

로컬 프로세스 사이에 initialize, tools/list, tools/call 및 인수 오류를 주고받는다.

먼저 알아둘 것

  1. contract-tools

핵심 한 문장: 프로토콜 연결은 도구의 발견과 호출이지 외부 행위 승인 자체가 아니다.

지금 할 일준비물개념과 원리따라 하기예상 결과와 검증오류 복구혼자 변형설명과 기여

큰 그림: 비유와 경계

host가 접수대, client가 전화기, server가 자료 담당이다.

비유가 닿지 않는 곳: 전화가 연결되어도 자료 담당에게 삭제 권한이 생기지는 않는다.

실제로 작동하는 원리

학습 스크립트가 host 역할로 client 호출을 주도하며 같은 파일의 server 프로세스를 stdio로 실행한다. JSON-RPC 줄 하나씩 보내 initialize→initialized 알림→tools/list의 inputSchema→tools/call 결과 content/isError를 검증한다. 도구는 d1 읽기만 허용하고 ../../secret 및 publish는 오류로 반환한다. 이는 공식 SDK가 아닌 프로토콜 일부를 구현한 최소 학습 모형: 전체 협상/인증/transport 구현 아님. 진짜 호스트 제품 연결은 승인된 설정에서 SDK 서버 경로를 지정해야 하며 여기서는 하지 않는다.

따라 하기

  1. mcp-local.py 저장 후 python3 mcp-local.py 실행; 같은 Python 실행파일로 자식 server 프로세스가 시작된다.
  2. tools/list의 read_notice 스키마(required doc_id, enum d1, additionalProperties false)와 정상 tools/call의 d1 문장을 코드에서 추적한다.
  3. arguments doc_id를 ../../secret으로 바꿔 isError=true를 확인한 뒤 원복한다. stdio 서버 stdout에 일반 print 로그를 넣으면 JSON 응답이 깨지므로 진단은 stderr로 보낸다.

입력 예제

tools/call read_notice {doc_id:d1}; 잘못된 경로; publish 도구

예상 결과

d1 가상 공지 반환; 잘못된 경로와 publish는 isError=true; 모델 호출·외부 쓰기 없음.

검증 방법

  1. initialize/list/call의 ID와 스키마가 맞고 정상 출력에 d1 텍스트가 있는지 확인한다.
  2. ../../secret과 publish 모두 거부되고 승인 전 쓰기가 없는지 확인한다.

흔한 오해와 실패 복구

  1. JSON 파싱 오류면 server stdout에 로그를 섞었는지 검사하고 stderr로 옮긴다.
  2. 실제 외부 서비스 연결 시 별도 OAuth/토큰·최소범위·사용자 승인·타임아웃이 필요하며 학습용 스키마만으로 보안을 주장하지 않는다.

확인 문제

「tools/call read_notice {doc_id:d1}; 잘못된 경로; publish 도구」의 출력으로 맞는 것은?

자동채점 · 선택형

답을 고르세요
해설과 정답 보기

initialize/list/call의 ID와 스키마가 맞고 정상 출력에 d1 텍스트가 있는지 확인한다.

정답: d1 가상 공지 반환; 잘못된 경로와 publish는 isError=true; 모델 호출·외부 쓰기 없음.

새 자료에서 로컬 프로세스 사이에 initialize, tools/list, tools/call 및 인수 오류를 주고받는다. 입력부터 판정까지 동료에게 시연한다.

동료평가 · 자동채점 아님

평가 기준: 정상·잘못된 인수·없는 도구의 실제 JSON 출력과 권한 경계를 동료가 재현해야 통과. 동료에게 해당 입력의 중간 상태·오류 반례를 시연한다.

해설 보기

정상/실패 출력 및 근거를 비교한다.

독립 실습

read_notice에 다른 가상 문서 d2를 추가하되 enum과 서버 데이터 양쪽을 수정하고 미등록 d3는 거부한다. 교육자 재사용 과제: 강사용 변형: 허용 문서 d4="가상 정리일 토요일 13시"를 당일 제시한다. 학습자는 먼저 예상 JSON 상태를 기록하고 새 enum/자료를 수정·실행한다. 동료에게 저장 파일명·python3 실행 위치·stdout 전용 규칙·오류 발생 시 stderr 확인법을 넘긴다. d4 미실행이면 미검증으로 기록한다.

남길 증거: 직접 실행 출력·실패 주입 기록과 수정 후 출력; 동료 재현 여부는 별도 확인. 보강 증거: 예측→관측→수정 후 출력과 타인 인계/미실시 기록을 구분한다.

전체 실행 또는 입력 자료

"""학습용 MCP stdio JSON-RPC 서버+클라이언트. 외부 SDK/모델 미사용.
서버 stdout=JSON-RPC만. 로컬 학습용 최소 subset; 인증/네트워크/프로덕션 호스트 아님.
"""
import json,sys,subprocess
DOCS={'d1':'가상 책방 토요일 11~18시'}
SCHEMA={'type':'object','properties':{'doc_id':{'type':'string','enum':['d1']}},'required':['doc_id'],'additionalProperties':False}
def serve(req):
 i=req.get('id'); method=req.get('method')
 if method=='initialize': return {'jsonrpc':'2.0','id':i,'result':{'protocolVersion':'2025-06-18','capabilities':{'tools':{}},'serverInfo':{'name':'fictional-notice','version':'0.1'}}}
 if method=='notifications/initialized': return None
 if method=='tools/list': return {'jsonrpc':'2.0','id':i,'result':{'tools':[{'name':'read_notice','description':'가상 d1 읽기 전용','inputSchema':SCHEMA}]}}
 if method=='tools/call':
  p=req.get('params',{}); a=p.get('arguments',{})
  if p.get('name')!='read_notice' or not isinstance(a,dict) or set(a)!={'doc_id'} or a.get('doc_id') not in DOCS:
   return {'jsonrpc':'2.0','id':i,'result':{'content':[{'type':'text','text':'invalid arguments or unknown tool'}],'isError':True}}
  return {'jsonrpc':'2.0','id':i,'result':{'content':[{'type':'text','text':DOCS[a['doc_id']]}],'isError':False}}
 return {'jsonrpc':'2.0','id':i,'error':{'code':-32601,'message':'Method not found'}}
if len(sys.argv)>1 and sys.argv[1]=='server':
 for line in sys.stdin:
  try:
   request=json.loads(line); response=serve(request)
   if response is not None: print(json.dumps(response,ensure_ascii=False),flush=True)
  except (ValueError,TypeError) as exc: print('parse error: '+str(exc),file=sys.stderr)
else:
 proc=subprocess.Popen([sys.executable,__file__,'server'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,text=True)
 def call(i,method,params=None):
  req={'jsonrpc':'2.0','id':i,'method':method}
  if params is not None: req['params']=params
  proc.stdin.write(json.dumps(req,ensure_ascii=False)+'\n');proc.stdin.flush()
  return json.loads(proc.stdout.readline())
 try:
  init=call(1,'initialize',{'protocolVersion':'2025-06-18','capabilities':{},'clientInfo':{'name':'local-lesson','version':'0.1'}})
  proc.stdin.write(json.dumps({'jsonrpc':'2.0','method':'notifications/initialized'})+'\n');proc.stdin.flush()
  listed=call(2,'tools/list'); ok=call(3,'tools/call',{'name':'read_notice','arguments':{'doc_id':'d1'}})
  bad=call(4,'tools/call',{'name':'read_notice','arguments':{'doc_id':'../../secret'}})
  unknown=call(5,'tools/call',{'name':'publish','arguments':{}})
  assert [x.get('id') for x in (init,listed,ok,bad,unknown)]==[1,2,3,4,5]
  assert all(x.get('jsonrpc')=='2.0' for x in (init,listed,ok,bad,unknown))
  assert init['result']['protocolVersion']=='2025-06-18' and 'tools' in init['result']['capabilities']
  assert listed['result']['tools'][0]['inputSchema']==SCHEMA
  assert ok['result']['isError'] is False and ok['result']['content'][0]=={'type':'text','text':DOCS['d1']}
  assert bad['result']['isError'] is True and unknown['result']['isError'] is True
  print('host(학습 스크립트) → client → server: initialize/list/call =',ok['result']['content'][0]['text'])
  print('bad path/publish = rejected; no model, external service or writes')
 finally:
  proc.stdin.close();proc.wait(timeout=3)
실습 해설 보기

d1은 조회만 가능하고 잘못된 인수/미등록 도구는 isError. 실제 호스트와 원격 서비스 연동은 이 예제의 범위 밖.

평가 기준: 정상·잘못된 인수·없는 도구의 실제 JSON 출력과 권한 경계를 동료가 재현해야 통과.

새 맥락에 적용하기

기관 공지 ID를 두 개로 늘리고 허용된 도구만 노출하는 스키마를 만든다. 독립 전이·실패주입: 새 입력: d2="가상 수리교실 금요일 16시, 비용 미기재"를 DOCS와 SCHEMA enum에 동시에 넣는다. 실행 전 tools/list에서 d2 허용, d2 조회 문장 반환, d3와 publish는 isError=true를 예측한다. 둘 중 한 곳만 고친 스키마/구현 불일치도 일부러 만들고 원복한다.

내 말로 설명하고 가르치기

입력→중간 상태→출력→실패 반례를 실제 사례로 설명한다. 독립 설명·인수 판정: 판정: 초기 d1과 신규 d2가 각각 재현되고 d3/쓰기 도구는 거절된다. 상대에게 JSON-RPC id·inputSchema·결과 content를 짚으며 스키마는 권한 승인이나 서버 인증이 아니라고 설명한다. AI 도움은 설계 질문→오류 힌트→도움 없이 d2 재시험 순서로 줄인다.

실습·전이·설명 결과는 본인 또는 동료가 기준에 따라 검토하세요. 이 페이지는 숙련을 자동 인증하지 않습니다.

읽음과 숙련은 별개입니다.

참고 출처와 확인 범위

학습 단원

생각-행동-관찰을 멈추는 자동화

해결할 문제와 목표

빈 근거인데 반복 검색하거나 승인 없이 공지가 전송된다.

ReAct형 작은 추적·계획·세션 기억·HITL 및 n8n 노드 구성을 검증한다.

먼저 알아둘 것

  1. mcp-local-lab

핵심 한 문장: 계획과 기억은 작업 상태이며 승인과 발송은 별도의 권한 경계다.

지금 할 일준비물개념과 원리따라 하기예상 결과와 검증오류 복구혼자 변형설명과 기여

큰 그림: 비유와 경계

체크리스트 옆 메모와 출고 도장.

비유가 닿지 않는 곳: 메모에 적힌 승인 표식은 실제 발송 권한·기록을 대체하지 않는다.

실제로 작동하는 원리

agent-flow.py는 읽기→근거검사 두 번의 결정적 관찰/행동 추적과 메모리 last_doc을 보여준다. 모델이 사고해 행동을 고르는 ReAct 자체는 실행하지 않는다. n8n에서 수동 Trigger→Set 가상 공지(id/version)→IF 근거·버전 일치→초안 Set→승인 대기(사람 승인 외부 경계)→후속 발송은 별도 승인 시에만 연결한다. IF false는 오류 로그로 끝내고 발송 노드는 실습에서 만들지 않는다. 중복방지 키 id+version과 최대 재시도 2회, 개인정보 비저장을 요구한다.

따라 하기

  1. python3 agent-flow.py 실행해 시간 질문, 주차 질문, 오래된 버전의 결과를 비교한다.
  2. n8n 편집기가 기존 승인된 환경에 있으면 Manual Trigger, Edit Fields(Set) id=d1/version=2, IF version==2 및 근거 존재, Set draft=「11~18시 [d1]」을 연결해 테스트 실행 로그만 확인한다. 서비스 설치/새 계정/외부 노드 실행은 하지 않는다.
  3. 중복 id+version 입력은 같은 초안 하나로 묶고 사람 승인 전 Send 노드가 전혀 없는지 점검한다. n8n 미보유면 위 필드·IF 결과를 종이 상태표에 그대로 추적한다.

입력 예제

question=시간, approved=false, version=2 / question=주차 / version=1

예상 결과

시간=승인 대기; 주차=근거 없음 보류; 구버전=버전 불일치 보류; 발송 없음.

검증 방법

  1. 세 케이스 출력과 trace의 읽기/검토 2단계를 확인한다.
  2. 주차나 버전 오류를 approved=true로 바꿔도 보류여야 한다.

흔한 오해와 실패 복구

  1. n8n IF 실패 분기에 발송이 연결되면 끊고 오류 기록으로만 보낸다.
  2. 세션 기억을 영속 저장해 개인정보가 쌓이면 삭제·TTL을 설계하고 최소 상태만 유지한다.

확인 문제

「question=시간, approved=false, version=2 / question=주차 / version=1」의 출력으로 맞는 것은?

자동채점 · 선택형

답을 고르세요
해설과 정답 보기

세 케이스 출력과 trace의 읽기/검토 2단계를 확인한다.

정답: 시간=승인 대기; 주차=근거 없음 보류; 구버전=버전 불일치 보류; 발송 없음.

새 자료에서 ReAct형 작은 추적·계획·세션 기억·HITL 및 n8n 노드 구성을 검증한다. 입력부터 판정까지 동료에게 시연한다.

동료평가 · 자동채점 아님

평가 기준: 근거없음/구버전/중복의 분기, 도구 횟수 상한, 인간 승인 경계와 실행 여부 4개를 근거로 판정한다. 동료에게 해당 입력의 중간 상태·오류 반례를 시연한다.

해설 보기

정상/실패 출력 및 근거를 비교한다.

독립 실습

가상 휴관 질문을 추가하고 실패 분기와 중복 id 처리 추적표를 만든다.

남길 증거: 직접 실행 출력·실패 주입 기록과 수정 후 출력; 동료 재현 여부는 별도 확인.

전체 실행 또는 입력 자료

"""ReAct-like 관찰/도구선택/결과, 계획, 비민감 세션 상태, HITL. LLM/n8n/발송 없음."""
DOC={'id':'d1','version':2,'text':'토요일 11~18시'}
def run(question,approved=False,version=2,doc=DOC):
 memory={'last_doc':None} # 요청 범위 안에서만; 실명/연락처 영속 저장 금지
 plan=['읽기 전용 검색','근거 비교','초안','사람 승인 필요 시 보류']
 trace=[]
 for step in range(2):
  action='read_notice' if step==0 else 'review_evidence'
  trace.append((step,action))
  if step==0: memory['last_doc']=doc['id'] if doc else None
  if step==1: break
 if not doc or doc['version']!=version: return '보류: 근거 없음/버전 불일치',trace,plan
 if '주차' in question: return '보류: 주차 근거 없음',trace,plan
 draft=doc['text']+' ['+doc['id']+']'
 # 이 모의 흐름은 절대 발송/기록하지 않는다. 승인 플래그도 외부 권한 아님.
 return ('승인 대기: ' if not approved else '사람 승인 표식만 있음(발송 없음): ')+draft,trace,plan
for args in [('시간',False,2,DOC),('주차',True,2,DOC),('시간',True,1,DOC)]: print(run(*args))
assert run('시간')[0].startswith('승인 대기')
assert run('주차',True)[0].startswith('보류')
assert run('시간',True,1)[0].startswith('보류')
실습 해설 보기

승인 표식은 발송 실행이 아니며, 이 코드에는 외부 발송이 없다. n8n 실제 워크플로 실행 여부를 별도로 표시한다.

평가 기준: 근거없음/구버전/중복의 분기, 도구 횟수 상한, 인간 승인 경계와 실행 여부 4개를 근거로 판정한다.

새 맥락에 적용하기

기관 휴관 초안 자동화로 바꾸고 담당자 승인 전후의 경계 상태를 표시한다.

내 말로 설명하고 가르치기

입력→중간 상태→출력→실패 반례를 실제 사례로 설명한다.

실습·전이·설명 결과는 본인 또는 동료가 기준에 따라 검토하세요. 이 페이지는 숙련을 자동 인증하지 않습니다.

읽음과 숙련은 별개입니다.

참고 출처와 확인 범위

  • https://docs.n8n.io/ — 공식 참고 URL. 이 보완 작업에서 본문 직접 열람·현행 기능/요금 확인은 하지 않음.

← 전체 과정