레오파드 토론 한 번 — 인용 게이트가 지운 8건이 전부 진짜 출처였다
멀티벤더 전략 토론 엔진 레오파드를 실제 주제 하나로 돌렸다. 주제는 “프리키친랩처럼 이기종 주방장비를 AIoT 로 통합 관제하는 접근이 외식업에서 지속가능한 사업이 될 수 있는가”, 업종은 외식. 580초(9분 40초) 만에 끝났고 종료 코드는 0, 결석한 참가자는 없었다.
토론 결론보다 먼저 눈에 띈 건 리포트 맨 위에 붙은 검증 경고 8줄이었다. 인용 게이트가 “출처 목록에 없는 URL” 8건을 본문에서 잘라냈다는 경고다. 그런데 그 8건을 하나씩 확인해 보니 지어낸 URL 은 한 건도 없었다. 이 글은 그 이야기다.
1. 레오파드가 실제로 어떤 형태로 돌아가나
한 줄로 말하면 레오파드는 LLM 을 API 로 부르지 않는다. 벤더별 CLI 를 자식 프로세스로 띄운다.
역할과 백엔드 매핑은 src/leopard/speaker.py 에 상수로 박혀 있다.
BACKENDS = {
"proposer": "claude_code", # 제안자
"challenger": "codex", # 도전자
"moderator": "hermes", # 종합
}
세 어댑터는 전부 ouroboros.providers.create_llm_adapter 로 만든다. 즉 우로보로스는 레오파드의
런타임 의존성이다(레오파드 venv 안에 ouroboros-ai 가 들어 있다). 우로보로스를 지우면 레오파드도 같이 죽는다.
이번 런의 실제 흐름은 events.jsonl 에 8개 이벤트로 남았다.
debate.started
debate.research.completed count=12 (웹 수집 12건)
debate.turn.completed R1 proposer prompt 3,431자 → content 5,373자
debate.turn.completed R1 challenger prompt 3,452자 → content 4,469자
debate.turn.completed R2 proposer prompt 7,930자 → content 5,146자
debate.turn.completed R2 challenger prompt 8,815자 → content 6,703자
debate.turn.completed R3 moderator prompt 25,166자 → content 4,999자
debate.completed absentees=[] aborted=false
여기서 읽히는 설계 몇 가지.
- 수집과 토론의 권한이 다르다. 자료 수집기만
allowed_tools=["WebSearch"]와max_turns=12, 타임아웃 900초를 받는다. 토론 참가자 셋은allowed_tools=[],max_turns=1, 타임아웃 300초다. 토론 중에 웹을 뒤지지 못하게 막아야 인용 게이트가 의미를 갖기 때문이다. 참가자는 수집된 12건 안에서만 근거를 대야 한다. WebFetch는 일부러 뺐다. 코드 주석에 이유가 적혀 있다 — 페이지 본문을 통째로 컨텍스트에 실으면 수집이 끝나기 전에 오토컴팩트가 폭주해서, 실측 396초를 쓰고 자료 0건이 나왔다고. 지금은 검색 결과의 제목·URL·요약만으로 출처를 채운다. 이 선택이 뒤에서 문제가 된다.- 프롬프트가 라운드마다 누적된다. 3,431 → 7,930 → 25,166자. 종합자는 앞선 네 발언을 전부 받는다.
- 모든 발언이 이벤트로 적힌다.
--replay를 쓰면 LLM 을 다시 부르지 않고 저장된 이벤트만으로 리포트를 다시 렌더한다. 게이트를 고친 뒤 같은 런을 다시 판정할 수 있다는 뜻이다.
2. 토론이 내놓은 답
요지만 옮긴다. 전체는 리포트에 있다.
합의: 이기종 주방장비를 하나의 관제 레이어로 묶는 문제 자체는 실재한다. 다만 현재 공개 자료만으로는 독립 관제사업의 지속가능성을 입증할 수 없다 — 설치·연동 원가, 유료 전환율, 구독료, 장애율, 갱신률 같은 단위경제 수치가 어디에도 없다. “프로토콜 파편화가 곧 해자”라는 주장은 성립하지 않는다. 파편화는 기회인 동시에 제조사별 연동·시험·유지보수 비용의 원인이다.
갈린 쟁점 다섯 가지에는 각각 결판 조건이 붙었다. 예컨대 “인증·위생 로그가 유료 핵심 기능이 될 수 있는가”는 식약처에 외부 AIoT 로그의 공식 증빙 인정 범위를 확인해야 결판난다. 조리로봇 식품용 기기 안전관리 인증은 2025년 7월 기준 시범사업이고 의무 진입장벽이 아니다.[1][2]
권고 3개: ① 이기종 장비가 실제로 공존하고 예산권자가 하나인 현장 1곳에서 “한 가지 손실”과 지불 의사를 동시에 검증하라 ② 제품 범위를 읽기·감지·작업자 알림으로 제한하고 안전·인증 책임을 먼저 문서화하라 ③ 표준 플랫폼 확장보다 반복 가능한 연동과 비용 회수 구조를 먼저 확보하라.
결론 문장은 “지속가능한 사업으로 입증됨”이 아니라 “특정 현장에서 단위경제와 책임 경계를 검증할 가치가 있음”이었다.
3. 게이트가 지운 8건 — 전수 확인
리포트 상단 경고는 이렇게 생겼다.
> **검증 경고**
> - 출처 목록에 없는 URL 을 제거했다: https://www.mt.co.kr/2026/08/22/2026082110330691185/
> - 출처 목록에 없는 URL 을 제거했다: https://fortune.com/.../short-order-cook-flippy/
> - 출처 목록에 없는 URL 을 제거했다: https://www.platum.kr/archives/206572
> - 출처 목록에 없는 URL 을 제거했다: https://www.wowtale.net/2026/08/20/263190/
... (총 8줄)
게이트 구현은 report.py 의 check_citations() 다. 수집된 출처의 URL 을 집합에 넣고 문자열이
정확히 일치하는지만 본다.
known = {s.url for s in sources}
...
if url in known: ... # 일치하면 통과
else: "[출처 미확인]" # 아니면 본문에서 지우고 경고
8줄을 중복 제거하면 서로 다른 URL 5개다. 각각을 https?://(www\.)? 제거 + 끝 슬래시 제거로 정규화해
수집 목록과 다시 맞춰 봤다.
| 게이트가 지운 URL | 수집 목록의 실제 URL | 판정 |
|---|---|---|
www.mt.co.kr/…/2026082110330691185/ |
www.mt.co.kr/…/2026082110330691185 |
끝 슬래시 차이 |
www.platum.kr/archives/206572 |
platum.kr/archives/206572 |
www. 차이 |
platum.kr/archives/206572/ |
platum.kr/archives/206572 |
끝 슬래시 차이 |
www.wowtale.net/2026/08/20/263190/ |
wowtale.net/2026/08/20/263190/ |
www. 차이 |
fortune.com/…/short-order-cook-flippy/ |
fortune.com/…/short-order-cook-flippy-labor-shortage/ |
경로 잘림 |
5개 중 4개가 같은 문서를 가리키는 표기 차이다. 나머지 하나도 도메인·기사가 조작된 게 아니라 같은 기사 URL 의 뒷부분이 잘린 형태였다. 즉 이번 런에서 게이트는 환각 URL 을 0건 잡았고, 대신 진짜 출처 8건을 지웠다.
지운 자리는 그냥 빈칸이 아니다. 문자열이 [출처 미확인] 으로 치환된다. 그래서 최종 리포트에는
이런 문장이 남았다.
LG전자 투자가 실제 제품 협업·판매채널·설치망 제공을 의미한다는 근거는 없다. 출처: [출처 미확인]
조리 시간·온도 추적과 작업자 알림은 상용 사례가 있다. 출처: [출처 미확인]
사람이 읽으면 “근거 없이 한 말”로 읽힌다. 실제로는 근거가 있었고, 게이트가 지웠다.
더 우스운 건 같은 문서 안에서 같은 URL 이 한 번은 살고 한 번은 지워졌다는 것이다.
종합자가 어떤 줄에는 wowtale.net/… 을, 어떤 줄에는 www.wowtale.net/… 을 적었기 때문이다.
원인은 두 겹이다. 참가자에게 넘기는 출처 목록이 [3] 제목 / URL 형태의 텍스트라서 모델이 그걸 손으로
다시 타이핑하고, 그 과정에서 www. 과 끝 슬래시가 흔들린다. 그리고 게이트는 그 흔들림을 흡수할
정규화를 하지 않는다. 고칠 자리는 명확하다 — known 을 만들 때와 대조할 때 양쪽 다 스킴·www.·끝 슬래시를
정규화하면 8건 중 6건이 즉시 사라진다.
4. 더 큰 구멍은 게이트가 아니라 수집이었다
수집된 12건에는 1차 출처가 없었다. 프리키친랩 관련 4건(머니투데이·와우테일·벤처스퀘어·플래텀)은 모두 같은 날 같은 보도자료에서 파생된 기사다. 정작 LG전자가 직접 낸 공식 보도자료는 목록에 없다.
이 글을 쓰며 따로 찾아보니 LG 공식 미디어에 올라온 2026년 4월 26일자 보도자료가 있다. 사내벤처 프로그램 ‘스튜디오341’ 데모데이에서 스핀오프 자격을 얻은 4개 팀 중 하나로 프리키친랩(“주방 자동화 로봇 및 운영관리 B2B 솔루션”)이 선정됐고, 각 팀은 심사 결과에 따라 최대 4억 원의 초기 투자를 받으며, 7월 중 분사 절차를 마무리한다는 내용이다. 분사 이후에도 시장 안착까지 지원을 잇고 AI 자동화·로봇 영역에서 상호 시너지를 모색한다는 문장도 들어 있다.[3]
이건 토론이 “확인되지 않았다”고 남긴 미해결 항목 하나 — LG전자의 투자 범위가 재무적 참여를 넘어 협업으로 이어지는지 — 를 부분적으로 답한다. 8월의 시드투자는 규모와 기업가치가 비공개이므로[4] “최대 4억 원”은 스튜디오341 초기 투자 상한이지 시드투자 규모가 아니다. 두 숫자를 섞으면 안 된다.
수집이 1차 출처를 놓친 이유는 1절에서 본 설계 선택과 이어져 있다. WebFetch 를 뺀 대가로 수집기는
검색 결과 요약만 본다. 검색 상위를 언론사가 채우면 보도자료 원문까지 내려가지 못한다.
게이트를 아무리 정확하게 만들어도, 목록 자체에 1차 출처가 없으면 “목록 안에서만 인용하라”는 규칙은
2차 출처를 성실히 인용하게 만들 뿐이다.
5. 돌리면서 새로 든 비용
- 텔레그램 폴러 가드가
leopard를 못 막는다. 이 맥에는 봇 세션을 보호하려고claude토큰이 들어간 Bash 명령을 차단하는 훅이 있다. 그런데leopard "주제"에는claude라는 글자가 없다. 훅은 통과하고, 자식으로 뜬 claude CLI 가TELEGRAM_STATE_DIR을 상속받아 봇의 폴러를 죽인다. 에러도 안 난다 — 세션은 살아 있고 수신만 0이 된다. 그래서 실행할 때TELEGRAM_STATE_DIR=$(mktemp -d)를 앞에 붙였다. - 맥에는
timeout이 없다. 9분 40초 걸리는 작업이 hang 되면 알림이 오지 않는다(알림은 프로세스가 끝날 때 오니까). 25분 상한을 두고 10초마다kill -0으로 확인하다 넘기면 TERM→KILL 하는 래퍼를 직접 씌워서 돌렸다.
6. 한 달 전 글과 달라진 것
8월 3일 글에서 레오파드는 “경영학 커리큘럼 11분과 × 33개 세부과목을 학문 렌즈로 강제하는” 엔진이었고,
커버리지 게이트가 33/33 을 판정했다. 지금 코드에는 그 렌즈가 없다. src/leopard/ 전체를 훑어도
‘분과’나 ‘lens’ 라는 문자열이 한 건도 나오지 않는다. 남은 건 참가자 3인, 프롬프트 3장, 그리고 인용 게이트다.
넓은 커버리지를 강제하는 장치를 빼고 근거의 진위를 확인하는 장치를 남긴 셈인데, 이번 런이 보여준 건 남긴 쪽도 아직 제 일을 못 하고 있다는 것이다. 게이트는 있으면 안심되지만, 무엇을 잡고 무엇을 흘리는지 한 번은 전수로 세어 봐야 한다. 안 세어 보면 이번처럼 정확도 0%인 채로 8줄짜리 경고를 매번 붙이고, 사람은 그 경고를 신뢰하다 진짜 근거를 버린다.
References
- 식약처, 조리로봇 4종 식품용 기기 안전관리 인증 (KDI 경제정보센터 정책자료) — 2025-07-14
- 식품의약품안전처 규제혁신 추진현황 — 식약처 공식
- AI·로봇·첨단 소재 기반 사내벤처, 스타트업으로 독립한다 (LG 공식 보도자료) — 2026-04-26
- ‘요식업 로봇 자동화’ 프리키친랩, LG전자·블루포인트 시드투자 유치 (머니투데이) — 2026-08-20. 투자 규모·기업가치 비공개. 회사 발표를 옮긴 기사이며, 동일 발표에 기반한 기사가 여러 매체에 같은 날 실렸다.
- 레오파드 — 경영학 커리큘럼 11분과를 기계로 강제하는 멀티벤더 전략 토론 엔진 (본 블로그, 2026-08-03)
본문의 실행 수치(580초, 이벤트 8건, 수집 12건, 프롬프트 길이, 지워진 URL 8건)는 이번 런의
events.jsonl·sources.json·report.md 에서 직접 읽은 값이다. 코드 인용은 src/leopard/speaker.py,
src/leopard/report.py 현재 내용이다. 조리로봇 인증제의 시범사업 단계 여부는 위 1·2번 자료 기준이며,
그 이후 제도 변경은 반영돼 있지 않다.