경력·사례·글은 한국어 원문으로 제공됩니다.

← 모든 기록

실험 기록 / 개발 방식

n8n·Windmill 비교와 공통 프롬프트 개선

n8n과 Windmill에 같은 DeepSeek 모델과 문서를 연결했다. 인용문은 모델이 고르고 원문 위치는 코드가 계산하도록 바꾸자 재시험 결과가 달라졌다.

작업 2026.10

약 7분 소요3,094자

#같은 일을 시키고 싶었다

n8n과 Windmill에서 분석, 평가, 수정, 재평가를 이어 실행해 보려 했다. 어느 쪽이 낫다고 말하려면 먼저 같은 자료와 질문으로 시작해야 했다.

n8n과 Windmill은 이 단계를 이어 실행하고 결과를 남기는 플랫폼으로 썼다. 링크는 각 플랫폼의 공개 소스다. 실험의 모델은 양쪽 모두 OpenRouter의 deepseek/deepseek-v4-flash로 맞췄다. 플랫폼을 바꾸면서 모델과 입력까지 바꾸면 결과 차이를 설명하기 어려웠다.

정상 공고, 정상 뉴스, 설명이 상충하는 공고를 양쪽에 하나씩 넣었다. 공통 프롬프트와 결과 형식을 사용하고 수정은 최대 2회로 제한했다. 끝까지 통과하지 못하면 needs_review로 남기도록 했다.

흐름은 입력 → 분석·평가 → 필요할 때 수정·재평가 → 최종 저장이었다. 분석·수정 응답과 평가 응답에는 각각 JSON Schema로 필드를 안내했다. API가 형식을 강제하도록 설정한 시험은 아니었다. 받은 JSON의 필드와 인용은 자체 코드에서 다시 검사했다.

기록을 재생해 연결만 확인하는 시험과 실제 모델 호출도 구분했다. 재생이 통과해도 모델이 제대로 읽고 답하는지는 별도 문제였다.

#첫 6건은 모두 검토 필요였다

첫 실제 시험에서는 두 플랫폼을 합쳐 6건, 모델 호출 36회가 끝났다. 결과는 accepted 0건, needs_review 6건이었다. 응답 비용 합계 $0.00351930도 공급자 누적 사용액 증가분과 맞았다.

호출과 비용 정산은 동작했다. 그러나 인용 위치와 사실 연결이 맞지 않았다. 최종 인용 14개는 모두 위치 검사를 통과하지 못했다. 뉴스 응답에서는 필수 필드 event 대신 설명에 쓰인 event (news)가 그대로 들어오기도 했다.

둘 다 같은 문제를 보인 부분은 플랫폼 비교보다 공통 입력을 먼저 살펴야 했다. 허용할 필드 이름과 설명이 섞여 있었고, 모델이 원문 위치까지 정확하게 계산하도록 요구하고 있었다.

상충하는 공고는 또 달랐다. 원문에 서로 맞지 않는 사실이 있는데 수정 횟수를 늘린다고 그 모순이 없어지지는 않는다. 통과시키기 위해 충돌 내용을 지우면 시험 목적을 잃는다.

#저장 실패를 모델 실패로 돌리지 않았다

Windmill의 첫 공고는 모델 호출을 마친 뒤 결과를 변수에 저장하다 길이 제한으로 실패했다. 응답은 실행 이력에 남아 있었다.

전체 요청과 사용량을 결과 변수에 중복해서 넣던 부분을 줄이고, 상세 기록은 실행 이력에 보존했다. 저장 복구에는 모델 노드가 없는 별도 흐름을 사용했다. 추가 모델 호출은 0회였다.

이 실패를 처음부터 다시 실행했다면 정상적으로 받은 응답까지 새로 생성했을 것이다. 어느 단계가 실패했는지 나누니 고칠 범위도 작아졌다. 당시 사용한 무료판에서는 시도한 단계 재시작 기능이 거부됐다는 제약도 기록했다. 이를 모든 배포판의 일반 기능으로 소개하지 않았다.

#인용문은 모델이, 위치는 코드가

후속에서는 모델이 인용문을 반환하면 코드가 원문에서 위치를 찾도록 바꿨다. 모델은 원문 라벨 줄을 그대로 복사하고, 코드는 그 문자열이 유일하게 나타날 때만 Unicode 문자 기준 start와 end, 출처를 채웠다. 원문에 없거나 여러 곳에 나타나는 문장은 자동 통과시키지 않았다. 모델 응답은 그대로 남기고 코드의 위치 계산 결과를 따로 보관했다.

필드 안내도 바꿨다. 공고의 사실 이름은 budget, eligibility, deadline, 뉴스는 event만 허용한다고 적었다. event (news)처럼 설명을 필드 값으로 복사할 여지를 줄였다. 인용문 선택과 위치 계산, 응답 형식 검사를 나누니 어느 부분을 고쳐야 하는지도 분명해졌다.

재시험 중에는 JSON을 코드블록으로 감싼 응답이 형식 오류로 멈췄다. 바깥 코드블록만 제거한 뒤 JSON 문법과 내용 검사는 그대로 적용하도록 양쪽 처리를 맞췄다. 실패한 호출의 비용과 횟수도 장부에 남겼다.

재시험에서는 양쪽 모두 정상 공고와 뉴스가 수정 없이 accepted로 끝났다. 상충 공고는 2회 수정 뒤에도 needs_review로 남았다. 합계는 accepted 4건, needs_review 2건이었다. 최종 인용 14개의 위치도 모두 원문과 일치했다. 원문에 있는 모순을 지워 통과시키지는 않았다.

형식 오류 1회를 포함해 재시험은 21회 호출, $0.00172035가 들었다. 첫 시험까지 합친 값은 57회, $0.00523965였다. 두 회차의 결과와 비용을 따로 남겼다. 같은 작은 표본을 보완한 시험이어서 새 문서에서도 같은 품질이 나온다는 결론은 내리지 않았다.

#아직 플랫폼을 고를 때는 아니다

첫 시험 도중 다른 작업용 컨테이너의 변동이 발견돼 실험 스택만 중지했다. 후속 재시험에서도 독립 개발 작업의 정리·교체가 감지되면서 관찰이 중단됐다. 이를 실험이 일으킨 장애로 단정하지 않았고, 중단된 구간을 통과로 고치지도 않았다.

이후 소유자와 변경 기록을 확인한 개발 실행본만 별도 기록하도록 감시 대상을 정리했다. 공급자 키 연결을 제거한 상태로 저장된 결과 화면을 다시 확인했고, Windmill의 Input부터 Result까지 전체 그래프도 확보했다. 이 화면 확인에는 새 모델 호출이 없었다.

후속 보고에는 10월 28일 13:54:18~14:09:35 KST, 916.9초의 관찰 완료가 남아 있다. 해당 구간에서 보호 대상의 제거·교체·재시작·새 OOM·unhealthy와 경고는 0건이었다. 추가 AI 호출도 0회였다. 30초 간격의 유한 관찰 결과이며, 앞서 중단된 구간을 소급해 통과로 바꾼 것은 아니다.

지금 비교에서 분명해진 것은 플랫폼 순위보다 실패를 나누는 방법이다. 요청 생성, 모델 응답, 근거 검사, 결과 저장, 기존 서비스 영향은 다른 검사였다. 한 단계의 성공으로 다음 단계까지 통과했다고 쓰지 않아야 원인을 고칠 수 있었다.

실제 운영 데이터 연동과 장기 반복 안정성, 플랫폼별 속도·품질 우열은 아직 미검증이다. Hermes를 쓰며 점검과 판단을 나눈 과정에서 정리했던 구분을 이번에는 같은 문서의 실행 결과에 적용해 보고 있다.

작성 2026-11-03

2026년 10월 28일 첫 시험·재시험 보고서와 저장 결과의 화면 확인 기록을 대조한 기록이다. 이번 작성에서 모델을 호출하거나 플랫폼을 조작하지 않았다. 안정 관찰의 마지막 상태는 본문에 따로 적었으며 플랫폼 우열은 판정하지 않는다.