소개
그동안 "언젠가는 회사일을 자동화를 해봐야지"라고 별러왔던 그 첫 번째 자동화를, 7시간 사투 끝에 완성
매일 아침 9시, 아무도 손대지 않아도 18개 키워드의 네이버 검색량이 엑셀로 정리되어 지메일로 날아오게 됨
시도하고자 했던 것과 그 이유------
회사 후배들이 매일 하는 반복작업이 짠했습니다. 광고 중인 브랜드와 연관 검색어를 매일 사이트에서 직접 찾아서 엑셀에 수동으로 입력하는 일이었습니다.
• 문제점: 18개 키워드의 검색량을 매일 수동으로 수집하고 엑셀에 입력하는 반복 작업이 후배들의 시간을 낭비하고 있었습니다.
• 목표: 키워드 검색량 수집부터 엑셀 정리, 메일 발송까지 전 과정을 자동화하여 매일 아침 9시에 리포트가 자동으로 전달되게 하는 것.
진행 방법-----------------
1) 3번째 봇 '긍정이' 탄생 — 총사령관의 등장
사실 이미 오픈클로 봇 '다정이'와 헤르메스 봇 '냉정이'가 있었습니다. 그런데 헤르메스를 두 번 설치하면서 뭔가 꼬인 상태였고, 냉정이에게 특별한 자동화를 시키지 않은 채 방치된 상황이었습니다.
그래서 결정했습니다. 처음부터 깔끔하게 재설치하자고. 모델은 그동안의 경험치로 가장 안정적이었던 클로드 하이쿠로 선택했습니다. 소네트와 오퍼스는 사라져도 하이쿠는 그대로라는 말을 들었고, API 키로 돌아가는 작업이라 토큰이 좀 들더라도 초기 투자비용이라 생각하고 넉넉히 쓰기로 했습니다.
새 봇의 이름은 '긍정이' 입니다.
이름에는 이유가 있습니다. 봇을 만들면서 가장 힘들었던 순간은 에러 지옥에 빠져 몇 시간씩 붙잡고 있을 때였습니다. 그때마다 "아, 그만둘까"라는 생각이 들었고, 그 순간 가장 필요했던 건 다름 아닌 긍정 마인드였습니다.
왜 정신과 의사쌤이신 승현님이 잘할 수 밖에 없는지 깨달아가는 과정이랄까…. 앞으로의 봇 생활을 위해서는 지치지 않는 긍정적인 에너지가 필요하다는 생각으로, 총사령관의 이름을 긍정이라 짓고 정(正) 자 돌림의 대가족을 만들었습니다. 다정이, 냉정이, 그리고 긍정이.
2) 네이버 검색량 API 연동 — 예상치 못한 벽
자동화의 첫 번째 관문은 네이버 검색량 데이터 수집이었습니다. 처음에는 간단할 것이라 생각했습니다. 그런데 현실은 달랐습니다.
1차 시도 — 네이버 DataLab API: 네이버 개발자 센터에 등록하고 API 키를 발급받았습니다. 그런데 치명적인 한계가 있었습니다. 네이버 DataLab은 일간 상대값만 제공합니다. 절대 검색량이 나오지 않습니다. "오늘 이 키워드가 100이면 어제보다 많은 건지 적은 건지"는 알 수 있지만, "실제로 몇 명이 검색했는지"는 알 수 없었습니다.
2차 시도 — 서핑(Surfing) 사이트 크롤링: 절대 검색량을 제공하는 다른 사이트를 찾아서 웹 크롤링을 시도했습니다. 그런데 해당 사이트는 크롤링을 막아두고 있었습니다. 번번이 실패했습니다.
최종 해법 — 네이버 광고주 센터 API: 긍정이와 함께 의논하며 찾아낸 해법은 네이버 검색광고 API였습니다. 네이버 광고주 센터에 사업자 등록을 하면 키워드의 월간 절대 검색량을 API로 가져올 수 있었습니다. DataLab의 일간 상대값과 광고주 센터의 월간 절대값, 두 가지를 함께 활용하는 방식으로 방향을 잡았습니다.
데이터 소스
제공 값
특징
네이버 DataLab API
일간 상대값
트렌드 흐름 파악
네이버 검색광고 API
월간 절대값
실제 검색량 파악
3) 엑셀 자동화 — 7번의 수정
데이터 수집에 성공했다고 끝이 아니었습니다. 이제 그 데이터를 보기 좋은 엑셀 파일로 만들어야 했습니다. 처음 만들어진 시트를 보니 마음에 들지 않았습니다. 글자 크기, 열 너비, 합계 계산 방식, 탭 구성... 하나씩 수정 요청을 하다 보니 총 7번의 수정 끝에 원하는 형태가 완성됐습니다.
최종 엑셀 구성은 다음과 같습니다.
• 탭 1: 18개 키워드별 일간 상대값 (DataLab)
• 탭 2: 18개 키워드별 월간 절대값 + 합계 (검색광고 API)
• 글자 크게, 한 줄 정렬, 한눈에 보이는 포맷
4) 지메일 자동 발송 — 앱 비밀번호의 벽
엑셀까지 완성됐으니 이제 매일 아침 9시에 자동으로 메일만 보내면 됩니다. 간단할 것 같았습니다. 그런데 여기서 또 한 번 벽을 만났습니다.
구글은 일반 계정 비밀번호로는 외부 앱에서 Gmail을 사용할 수 없습니다. 앱 비밀번호(App Password) 라는 별도의 인증 방식이 필요했습니다. 구글 계정 보안 설정에서 2단계 인증을 켜고, 앱 비밀번호를 발급받아 설정 파일에 입력하는 과정이었는데, 처음 몇 번은 계속 인증 오류가 났습니다. 여러 번의 시도 끝에 결국 해냈습니다.
launchd로 스케줄링을 설정하여 매일 오전 9시에 자동 실행되도록 구성했습니다.
결과와 배운 점-----------------
좋았던 점))
완성된 순간, 긍정이가 이렇게 말할 때 보상받는 느낌이 들었죠
와아아! 🎉🎉🎉
정말 축하합니다!!! 🚀
내일부터 매일 아침 자동으로:
1 키워드 데이터 수집 ✨ 2 Excel에 저장 📊 3 이메일로 발송 📧
당신은 그냥 받아서 보기만 하면 돼요! 😊
시행착오 / 아쉬운 점))
• 절대 검색량 수집의 우회로: 처음부터 네이버 광고주 센터 API를 알았다면 시간을 많이 아꼈을 것입니다. 네이버 DataLab만으로는 절대값을 얻을 수 없다는 점을 미리 알고 시작하는 것이 중요합니다.
• 7시간을 썼다: 본업을 했어야 마땅한 상황에 7시간을 쏟아붓고 너무 지쳐서 쓰러졌습니다. 자동화 작업은 집중할 수 있는 별도의 시간을 확보하고 시작하는 것을 권장합니다.
(꿀팁)
• Gmail 자동 발송은 앱 비밀번호 필수: 구글 계정의 일반 비밀번호로는 외부 스크립트에서 메일 발송이 안 됩니다. 2단계 인증 활성화 후 앱 비밀번호를 별도로 발급받아야 합니다.
• 엑셀 포맷은 처음부터 요구사항을 명확히: "보기 좋게 만들어줘"보다 "글자 크기 12pt, 열 너비 자동 맞춤, 합계 행 추가"처럼 구체적으로 요청할수록 수정 횟수가 줄어듭니다.
앞으로의 계획-------------------------------------------------------
봇을 만들고 키워가며 자동화를 해내는 이 일은 사실상 에러지옥을 마주하는 멘탈관리의 문제라고 생각합니다.
앞으로도 수많은 시련과 포기하고 싶은 순간이 있겠지만 긍정이와 긍정 회로를 돌리며 이겨낼 생각입니다.
다음 목표는 이번에 구축한 기반 위에 더 많은 반복 업무 루틴을 하나씩 자동화하는 것입니다.
업무 자동화의 첫 성공은 기술이 아니라 포기하지 않는 무한 긍정 마인드!
모두 감사했습니다. 이번 22기 스터디방 멤버들 너무 좋았고, 스터디장님 용기주셔서 너무 푸근했고 유익했어요!
본업이 바쁜 사람이다 보니 4주가 훨씬 더 짧아 아쉽네요. 계속 들어야 겠어요! 또 뵈어요!
같은 LLM 베이스에서 갈라져 나온 두 카카오 봇을 한 단톡방에서 토론시키고, 그 결과를 엑셀 보고서로 자동 정리해 다시 카톡에 쏘기까지.
2026-06-06, 맥미니 로컬 환경에서 하루 만에 구현·검증한 기록.
📝 한줄 요약
카카오톡 단톡방에 @토론 [주제]라고 치면 → 회계사 봇과 세무사 봇이 3턴 주고받으며 토론하고 → 토론이 끝나면 [쟁점 | 회계 관점 | 세무 관점 | 통합 결론] 비교표 엑셀 보고서가 자동으로 단톡방에 업로드됩니다.
겉보기엔 "두 AI가 카톡방에서 토론하고 보고서까지 써준다"지만, 실제 구조는 그렇게 단순하지 않습니다. 카카오의 기술적 제약 때문에 우회 설계가 필요했기 때문입니다.
실제 업무에 활용하고 있는 에이전트이기 때문에 부득이하게 정보지운점 감안해주시면 감사하겠습니다.^^
바쁘시면 이것만:
카카오는 Bot-to-Bot이 안 됨 → 사회자 릴레이 + 카카오는 출력구만
무한 루프는 author_id 가드 + 사회자 호출 + router 분리로 구조 차단
회계·세무 기존 answer.py 재사용 → 토론 끝나면 엑셀 2시트 자동 업로드
🎯 이런 분들께 도움돼요
카카오톡(LOCO)으로 멀티봇·자동화를 붙이려는 분
"봇끼리 대화"가 무한 루프·계정 정지로 이어질 수 있다는 걸 알고 우회 설계가 필요한 분
이미 돌아가는 1:1 봇 두뇌를 단톡방 토론·보고서 파이프라인에 재사용하고 싶은 분
실제 접근성 때문에 업무에서 슬랙이나 디스코드 말고 카카오톡을 써야할것 같은 분
😫 문제 상황 (Before)
LOCO 프로토콜의 벽
카카오톡은 일반 오픈 API가 아니라 LOCO라는 자체 바이너리 프로토콜로 동작합니다. 텔레그램·디스코드처럼 "봇이 다른 봇의 메시지를 이벤트로 받는" 구조가 공식적으로 열려 있지 않기 때문입니다.
그래서 처음 떠올린 순진한 그림 — "단톡방에 봇 둘을 넣고 서로 메시지에 자동응답하게 한다" — 은 절대 가면 안 되는 길이었습니다:
회계사 답변 → 세무사가 그걸 메시지로 받음 → 세무사 답변 → 회계사가 그걸 받음 → 회계사 답변 → 세무사가 받음 → ... (무한 루프)
무한 핑퐁 + 카카오의 자동 응답 패턴 탐지 = 두 계정 모두 정지 위험.
해결 아이디어 — 카카오는 "출력 채널"로만 쓴다
핵심 발상의 전환:
대화 로직(두뇌)은 카카오 밖에서 돌리고, 카카오는 완성된 메시지를 발사하는 출력구로만 쓴다.
즉 봇끼리 직접 대화하게 두지 않고, 별도의 '사회자(moderator)' 프로세스가 중간에서:
회계사 두뇌를 호출해 답을 받고 → 회계사 계정으로 카톡에 발사
그 답을 세무사 두뇌에 입력으로 넘겨 답을 받고 → 세무사 계정으로 카톡에 발사
다시 회계사에게… (정해진 턴 수만큼)
두 봇은 서로의 메시지를 보지 않습니다. 다음 발화자를 항상 사회자가 호출하므로, 봇끼리 서로를 트리거하는 일이 구조적으로 불가능합니다. → 무한 루프 원천 차단.
즉 단톡방에 토론주제를 던지면
회계사가 해당 내용을 확인합니다.
회계사가 메인오케스트레이션(헤르메스)한테 토론주제를 던집니다.
확인한 헤르메스는 하위 애들인 회계사(오픈클로), 세무사(오픈클로) 한테 오픈클로 내에서 토론을 시킵니다. 즉 핑퐁핑퐁
내용들을 순차적으로 카카오 loco로 각 에이전트들이 발신해서 띄웁니다.
🛠️ 사용한 도구
항목
내용
환경
맥미니 로컬, OpenClaw 멀티봇, Hermes(오케스트레이션)
카카오 연동
agent-messenger kakaotalk 모듈 (2.19.1+)
회계 두뇌
accountant_yuseong_answer.py (K-IFRS·KASB 옵시디언 LLM Wiki)
세무 두뇌
tax_yuseong_answer.py (세법조문·판례 옵시디언 LLM Wiki)
사회자
debate_moderator.py (launchd ai.openclaw.debate-moderator, poll 15s)
보고서
debate_report.py + openpyxl, LLM anthropic/claude-sonnet-4-6
상시 서비스
회계 1:1 router + 세무 1:1 router + debate-moderator (3개 동시 가동)
🏗️ 아키텍처 (전체 구조)
한눈에 보기 — 3층 구조
층
역할
핵심 파일·프로세스
① 카카오 (출력·입력)
단톡방 UI, 메시지 송수신
chat_id 470828588411727, 회계·세무 계정 각각 send
② 사회자 (오케스트레이션)
트리거 감지, 턴 릴레이, 보고서 호출
debate_moderator.py
③ 두뇌 + 보고서 (로직)
RAG 답변 생성, 엑셀 정리
accountant_* / tax_* / debate_report.py
설계 원칙: 봇끼리는 직접 대화하지 않음. 카카오는 완성 메시지 발사만. 토론 순서는 사회자만 제어.
데이터 흐름 (Mermaid)
flowchart TB subgraph KAKAO["① 카카오톡 단톡방 (토론방)"] U["👤 이용자\n@토론 [주제]"] OUT1["💬 회계사 발화"] OUT2["💬 세무사 발화"] OUT3["💬 회계사 발화"] XLS["📊 엑셀 보고서"] end subgraph MOD["② 사회자 — debate_moderator.py"] POLL["polling 15s\n(단톡방만)"] GUARD["author_id 가드\n(봇 메시지 무시)"] LOOP["턴 루프 TURNS=3\n회계 ↔ 세무 릴레이"] CALL["debate_report.py 호출"] end subgraph BRAIN["③ 두뇌 (기존 answer.py 재사용)"] ACC["accountant_answer.py\nK-IFRS·KASB 옵시디언 LLM WIKI"] TAX["tax_answer.py\n세법조문·판례 옵시디언 LLM WIKI"] end subgraph RPT["③ 보고서 — debate_report.py"] LLM["LLM 비교정리\nJSON 4필드"] XL["openpyxl 2시트"] end subgraph ROUTER["※ 1:1 router (단톡방 미관여)"] R1["accountant-router"] R2["tax-router"] end U -->|새 메시지| POLL POLL --> GUARD --> LOOP LOOP -->|호출| ACC LOOP -->|호출| TAX ACC -->|send 회계사 계정| OUT1 TAX -->|send 세무사 계정| OUT2 LOOP -->|3턴 후| CALL CALL --> LLM --> XL -->|upload| XLS LOOP --> OUT3 R1 -.->|allowlist 1:1만| KAKAO R2 -.->|allowlist 1:1만| KAKAO
상세 ASCII 다이어그램
┌──────────────────── 카카오톡 "토론방" (chat_id) ────────────────────┐
│ 이용자: "@토론 [주제]" → 회계사 발화 → 세무사 발화 → 회계사 발화 → 📊 엑셀 │
└────▲──────────────▲─────────────────▲─────────────────▲───────────▲──┘ │ polling │ send(회계) │ send(세무) │ send(회계) │ upload │ │ │ │ │
┌────┴──────────────┴──────────────────┴──────────────────┴────────────┴────────┐
│ debate_moderator.py (사회자) │
│ ① 단톡방만 polling → 이용자 @토론 감지 (봇 author_id 트리거 제외) │
│ ② 턴 루프: 회계 두뇌 ↔ 세무 두뇌 번갈아 호출, 상대 답을 다음 입력으로 전달 │
│ ③ 종료 → debate_report.py → 엑셀 생성 → 카카오 업로드 │
└────┬─────────────────────┬────────────────────────┬───────────────────────────┘ │ │ │
┌────▼─────────────┐ ┌─────▼──────────────┐ ┌──────▼─────────────────┐
│ accountant_ │ │ tax_ │ │ debate_report.py │
│ answer │ │ answer │ │ LLM 비교정리 → openpyxl │
│ (회계 두뇌) │ │ (세무 두뇌) │ │ → 2시트 엑셀 │
│ K-IFRS·KASB │ │ 세법조문·판례 │ │ │
└──────────────────┘ └────────────────────┘ └────────────────────────┘ ※ 회계사·세무사 1:1 router → 이 단톡방 chat_id를 절대 polling하지 않음 (§ 무한 루프 방지)
컴포넌트 역할표
컴포넌트
입력
출력
카카오와의 관계
이용자
—
@토론 [주제]
유일한 토론 트리거
debate_moderator
단톡방 새 메시지
두뇌 호출 + send + report 호출
유일한 단톡방 polling 주체
accountant_answer
질문 문자열
draft_answer JSON
회계사 계정으로 발사만
tax_answer
--q 질문
answer JSON
세무사 계정으로 발사만 (격리 config)
debate_report
발화 전문
xlsx 2시트
파일 upload
1:1 router ×2
allowlist 1:1 chat
1:1 자동응답
단톡방 미참여
핵심: 기존 두뇌(answer.py)를 재사용합니다. 새 토론 엔진을 만들지 않았습니다. 회계사·세무사의 지식이 업데이트되면 토론 품질도 자동으로 따라 올라갑니다.
▲ 단톡방 "토론방"에서 @토론으로 시작된 실제 토론. 회계사 → 세무사로 발화가 이어집니다.
🔧 작업 과정
1. 사전 검증 — 진짜 되는지부터 실측
추측으로 설계하지 않고, 불확실한 지점을 먼저 실제로 찔러봤습니다.
카카오가 단톡방을 다룰 수 있나?
사용 중인 CLI 도구(agent-messenger의 kakaotalk 모듈)에 단톡방 지원이 있는지 확인:
chat list --resolve-titles --search → 단톡방(MultiChat) 명시적 지원 확인
message list <chat-id> / message send <chat-id> → 1:1이든 단톡방이든 chat_id 하나로 동일하게 동작
member list <chat-id> → 방 멤버 조회 가능
두 봇이 같은 방에 공존하나? (결정적 검증)
카톡 앱에서 단톡방 "회계세무토론방"을 직접 만들고 봇 둘을 초대한 뒤, 양쪽 계정으로 같은 방을 조회했더니:
chat_id: 사용자아이디 (type: MultiChat)
active_members: 3 → 사용자(00000000) + 회계사(0000000) + 세무사(00000000)
*사정상 뒤 아이디는 가립니다.
두 봇이 같은 chat_id를 동시에 인식 ✓
member list로 세 user_id 전부 확인 ✓
흥미로운 디테일: 세무사 눈엔 "회계사", 회계사 눈엔 "세무사"로 서로를 멤버로 정확히 인식
⚠️ 함정 하나: 카카오 LOCO는 메시지가 한 번도 안 오간 방은 chat list 스냅샷에 안 잡힙니다. 방만 만들고 가만히 두면 빈 배열이 나옵니다. 아무 메시지나 한 줄 쳐야 방이 잡힙니다.
2. 무한 루프를 막은 3중 안전장치
이 프로젝트의 진짜 핵심은 "토론을 시키는 것"이 아니라 "봇 둘을 안 꼬이게 만드는 것"이었습니다.
#
장치
내용
5.1
트리거는 사람만
사회자는 author_id가 이용자(00000000)이고 @토론으로 시작하는 것만 인식. 봇 author_id 메시지 무시 → 봇 발화가 또 토론을 부르는 일 불가능
5.2
발화자는 사회자 호출
봇은 "상대 메시지를 보고 반응"하지 않음. for i in range(TURNS) 루프에서 사회자가 다음 발화자 직접 호출
5.3
1:1 router 분리
회계·세무 router는 allowlistChatIds만 polling. 단톡방 chat_id를 절대 넣지 않음 → 1:1처럼 자동응답하는 사고 차단
검증 (최악 시나리오 테스트)
state를 토론 직전으로 되돌려 봇 메시지 5개가 전부 "새 메시지"로 보이게 만든 뒤 사회자를 폴링시켰습니다 → 토론 재시작 0건. author_id 가드가 완벽히 작동함을 실측.
3. 까다로웠던 디테일 — 두 두뇌의 인터페이스가 다르다
회계사와 세무사 두뇌(answer.py)는 따로 만들어져서 호출 규약이 서로 달랐습니다. 사회자가 이걸 구분해서 호출하지 않으면 답이 빈 문자열로 나오거나 엉뚱한 계정으로 발사됩니다.
항목
회계사
세무사
질문 인자
positional "<질문>"
--q "<질문>"
JSON 답변 키
draft_answer
answer
카톡 발신 방식
기본 디렉토리 + --account 00000000
환경변수 AGENT_MESSENGER_CONFIG_DIR=~/.config/agent-messenger-tax
두 봇이 안 꼬이고 공존하는 비결: 카카오 config 디렉토리를 환경변수로 완전 격리 + 디바이스 타입 분리(tablet/desktop) + agent-messenger 2.19.1 이상.
4. 토론 품질 설계 — "동의합니다" 빈말 방지
같은 LLM 베이스라 그냥 두면 둘 다 "맞습니다, 동의합니다"만 반복할 위험이 있었습니다. 각 턴마다 역할을 명시한 프롬프트로 강제했습니다:
턴
발화자
프롬프트 요지
1
회계사
주제를 회계(K-IFRS) 관점에서 핵심 쟁점·결론 제시
2
세무사
회계사 답 수신 → "세무 리스크·빠진 세법 쟁점만. 동의는 한 줄로."
3
회계사
세무사 답 수신 → "회계처리상 보완·수정 결론만. 동의는 한 줄로."
마지막 발화(회계사 3턴)가 앞 내용을 종합하므로 자연스럽게 통합 결론 역할을 합니다. 별도의 '사회자 멘트' 계정 없이 마지막 턴이 결론이 되게 설계.
▲ 빈말 방지가 실제로 작동한 장면. 세무사는 "동의"를 한 줄로 끝내고 곧바로 세법 쟁점(손금불가 판례 3건, 소득세법 §20, 조특법 §16의2)을 짚습니다.
턴 수는 3으로 시작 (변수로 분리)
정밀도를 위해 5턴도 고려했지만, 검증 안 된 파이프라인에 비용을 키우지 않기 위해 TURNS 변수로 빼고 3턴으로 시작했습니다. "제시→반박→정리" 한 사이클이면 충분. 필요하면 숫자 하나만 5로 바꾸면 승급.
5. 토론 → 엑셀 보고서 자동화
토론 내용을 사례 자료로 보존하려면 카톡 메시지로 흩어두기보다 문서가 났습니다. 토론이 끝나면 사회자가 debate_report.py를 호출합니다.
3단계 파이프라인
토론 발화 전문 │ ▼
① LLM 비교정리 (anthropic/claude-sonnet-4-6) → {쟁점, 회계 관점, 세무 관점, 통합 결론} JSON ※ "토론에 실제 나온 내용만" 프롬프트로 환각 차단 │ ▼
② openpyxl 엑셀 (2시트) · 비교정리: 쟁점 | 회계 | 세무 | 통합 결론 표 · 발화전문: 턴별 원문 전체 │ ▼
③ 카카오 업로드 message upload --as file --account 00000000 <chat_id> <xlsx>
▲ 토론 종료 → "보고서로 정리하고 있어요" 안내 → 엑셀 파일 자동 업로드까지 한 화면에. 상단의 "멤버 3"도 두 봇 + 이용자의 공존을 보여줍니다.
환각 차단이 실제로 작동한 증거
가업승계 주제 토론에서 회계사가 다루지 않은 쟁점에 대해, 보고서는 "회계 관점에서 직접적으로 다뤄지지 않았다"고 정직하게 적었습니다. 없는 내용을 억지로 채우지 않습니다.
완성된 보고서 (2시트)
▲ 시트1 「비교정리」 — 쟁점별로 회계·세무 관점과 통합 결론을 한눈에 비교.
▲ 시트2 「발화전문」 — 턴별 원문 전체를 그대로 보존(검증·재인용용).
6. 트러블슈팅 메모
이슈
해결
Unknown model
openclaw infer 모델명에 provider 접두어 필수. claude-sonnet-4-6(❌) → anthropic/claude-sonnet-4-6(✓)
LLM 인증 실패
answer.py와 동일하게 _infer_env()로 ANTHROPIC_API_KEY(= ~/.hermes/.env의 ANTHROPIC_TOKEN) 주입
과거 트리거 재실행
서비스 최초 등록·재시작 전 --prime-state로 과거 @토론 무시(high-water mark). 안 하면 옛 메시지로 토론 또 돔
엑셀 추가기능 컴파일 에러(ufrmMsg)
생성 파일 문제 아님 — 여는 쪽 엑셀 깨진 add-in. unzip -l로 vbaProject.bin 0개 확인. 엑셀 옵션 → 추가기능 해제
macOS엔 timeout 없음
폴링 테스트는 --max-loops로 self-terminate
✅ 결과 (After)
사용법
단톡방에 한 줄:
@토론 임직원 스톡옵션 부여·행사 시 회계처리와 세무처리 차이
→ 회계사·세무사가 3턴 토론 → 비교정리 엑셀 보고서 자동 업로드.
Before vs After
항목
Before
After
Bot-to-Bot
카카오 LOCO상 불가, 무한 루프 위험
사회자 릴레이로 구조적 우회
토론 결과
카톡 메시지에 흩어짐
엑셀 2시트 자동 업로드
두뇌
1:1 전용
기존 answer.py 재사용 + 단톡방 전용 사회자
가동
—
router 2 + moderator 3프로세스 동시 running
가동 상태 (실측, 2026-06-06)
accountant-router: state = running (회계사 1:1)
taxg-router: state = running (세무사 1:1)
debate-moderator: state = running (토론 사회자)
세 프로세스가 충돌 없이 동시 가동.
📦 구성 요소 정리
구분
경로 / 식별자
사회자 스크립트
~/.openclaw/workspace/scripts/debate_moderator.py (424줄)
보고서 모듈
~/.openclaw/workspace/scripts/debate_report.py (318줄)
회계사 두뇌
~/.openclaw/workspace/scripts/accountant_answer.py
세무사 두뇌
~/.openclaw/workspace/scripts/tax_answer.py
사회자 상시 서비스
launchd ai.openclaw.debate-moderator (poll 15s)
단톡방
"토론방" chat_id 0000000000 (멤버 3)
사회자 state
~/.openclaw/workspace/data/debate/moderator_state.json
보고서 산출물
~/.openclaw/workspace/data/debate/reports/토론보고서_<주제>_<날짜>.xlsx
회계사 계정
00000000 (cpa_agent, 기본 config 디렉토리)
세무사 계정
00000000 (cta_agent, 격리 config 디렉토리)
💬 이 과정에서 배운 AI 활용 팁
효과적이었던 것
제약을 인정하고 우회. "카카오는 Bot-to-Bot이 안 된다"를 부정하지 않고, "카카오를 출력구로만 쓴다"로 발상을 틀었습니다. 겉보기엔 봇끼리 토론하지만 실제론 릴레이가 됩니다.
안전을 '조심'이 아니라 '구조'로. author_id 제외 + 사회자 호출 + router 분리했습니다. 사람이 실수해도 무한 루프가 발생할 수 없는 구조입니다.
기존 부품 재사용. 새 두뇌를 만들지 않고 회계사·세무사 answer.py를 릴레이로 엮었습니다. 변경 최소, 품질은 기존 지식에 자동 연동됩니다.
추측 대신 실측. 단톡방 공존, 무한루프 차단, 풀 파이프라인을 전부 실제로 돌려 확인하고 완료라고 말했습니다.
실제 토론 내용과 결과물 스크린샷
이렇게 하면 안 돼요
단톡방에 봇 둘을 넣고 서로 메시지에 자동응답하게 두기 (무한 루프 + 계정 정지)
1:1 router의 polling 대상에 단톡방 chat_id 포함 (이중 응답·꼬임)
검증 전에 턴 수·비용만 키우기 (TURNS=3으로 시작한 이유)
한 줄로: "카카오의 Bot-to-Bot 불가를, 사회자 릴레이 + 출력구 전략으로 우회해 두 AI 봇의 토론과 자동 보고서화를 안전하게 구현했습니다."
📋 재사용 가능한 프롬프트
토론 시작 (카톡 단톡방)
@토론 [여기에 회계·세무 쟁점 주제]
턴별 역할 강제 (사회자 내부 프롬프트 요지)
1턴(회계): K-IFRS 관점 핵심 쟁점·결론 제시
2턴(세무): 세무 리스크·빠진 세법 쟁점만. 동의는 한 줄
3턴(회계): 회계처리 보완·수정 결론만. 동의는 한 줄
보고서 LLM (환각 차단)
토론 발화 전문만 근거로 {쟁점, 회계 관점, 세무 관점, 통합 결론} JSON 정리.
토론에 나오지 않은 내용은 "다뤄지지 않았다"고 명시. 지어내지 마라.
상승장 꼭대기를 알려주는 알람을 만들었더니, 지금 "0/14 양호"라고 한다
공격적인 포트폴리오를 들고 있는 사람이 매일 던지는 질문 하나 — "이 상승, 언제까지 가는 거지?" 그 질문에 감(感) 말고 다른 걸로 답해보고 싶어서 만든 대시보드 이야기입니다.
소개
고백부터 하자면, 제 포트폴리오는 공격적입니다.
상승장에선 천국입니다. 계좌가 알아서 불어나고, 사는 족족 오르고, "역시 내가 맞았지" 하는 자신감이 붙습니다.
문제는 항상 그다음입니다.
상승장은 종을 치고 끝나지 않습니다. 어느 날 갑자기 "오늘부터 하락장입니다"라는 안내방송이 나오지 않아요. 그냥 어느 순간 돌아보면 고점은 한참 전이었고, 공격적으로 들고 있던 만큼 토해내는 속도도 빠릅니다. 그동안 번 걸 몇 주 만에 반납하고 나서야 "아, 그때가 꼭대기였구나" 하고 깨닫습니다.
저는 그 "언제 꺾이는가"를 오랫동안 감으로 버티고 있었습니다.
뉴스를 보고, 커뮤니티 분위기를 보고, 차트를 보고, 막연히 "아직은 괜찮은 것 같은데" 하고 넘겼습니다. 그런데 감은 두 방향으로 다 배신합니다. 너무 빨리 겁먹어서 상승장을 통째로 놓치거나, 너무 늦게 알아채서 고점에서 못 내려오거나.
그래서 결심했습니다.
예측은 포기하자. 대신 관측을 하자.
진행 방법
1. 맞히려는 게 아니라, 무너지는 신호를 보려는 것
먼저 마음을 고쳐먹는 게 제일 중요했습니다.
저는 톱(top)을 맞히려는 게 아닙니다. 그건 아무도 못 합니다. 어떤 화려한 지표 조합도 "여기가 꼭대기"라고 안정적으로 찍어주지 않습니다.
하지만 다른 건 가능합니다.
과거에 상승장이 무너질 때를 돌아보면, 그 직전·직후에 거의 항상 같이 나빠졌던 신호들이 있습니다. 장기 추세가 깨지고, 변동성이 튀고, 신용 스프레드가 벌어지고, 금리 커브가 뒤집히고, 고용이 빠르게 식는 패턴이요. 매번 똑같진 않지만, "시장 내부 구조에 금이 가고 있다"는 건 숫자로 관측이 됩니다.
그래서 목표를 이렇게 정했습니다.
시장 꼭대기를 예측하는 대시보드가 아니라, 시장 내부 구조가 무너지고 있는지 한 화면에서 관측하는 대시보드.
2. 무엇을 볼 것인가 — 여러 축을 14점 복합 점수로
핵심은 하나의 지표를 과신하지 않는 것이었습니다. 어떤 지표든 혼자서는 자주 거짓 신호를 냅니다. 그래서 성격이 다른 신호들을 모아서, 여러 경고가 동시에 켜질수록 점수가 올라가는 14점 만점 복합 점수로 묶었습니다.
화면 맨 위 헤드라인은 가장 직관적인 3개입니다.
추세 — S&P500 vs 200일선: 장기 추세 위에 있는지 아래로 깨졌는지. 거의 모든 하락 국면의 공통 1번 신호입니다.
공포 — VIX: 시장의 변동성 체온계. 구조가 흔들리면 급등합니다.
신용 — HY OAS(하이일드 스프레드): 신용시장이 위험을 얼마나 더 비싸게 요구하는지. 주식보다 먼저 위험 신호를 내는 경우가 많습니다.
그 아래로 고용(실업률·Sahm Rule), 금리 커브(10Y-2Y, 10Y-3M), 장단기 금리, 금융여건(NFCI)까지 공식 지표를 같이 봅니다. 하나하나는 노이즈여도, 여러 개가 같은 방향으로 켜지면 의미가 완전히 달라지니까요.
3. 데이터는 전부 "공식 RAW"만, 그리고 출처를 추적 가능하게
여기가 제가 가장 신경 쓴 부분입니다.
투자 대시보드는 숫자에 책임을 못 지면 그냥 예쁜 장식입니다. 그래서 두 원칙을 박았습니다.
mock 데이터 미사용. 화면의 모든 숫자는 FRED, CBOE 같은 공식 소스에서 실제로 가져온 RAW 값입니다.
출처 역추적. 핵심 수치는 전부 원본 URL과 수집 시각으로 되짚을 수 있게 했습니다. "이 숫자 어디서 났어?"에 항상 답할 수 있어야 한다고 봤거든요.
그리고 솔직하게, 아직 비워둔 칸도 일부러 그대로 뒀습니다. 시장 폭(breadth)과 섹터 순환 — RSP/SPY, IWM/SPY, XLY/XLP, XLK/XLU, SMH/SPY 비율, 등락 종목 누적선, 200일선 위 종목 비율 같은 7개 항목은 공식 무료 RAW 경로가 아직 부족해서 자동 점수에서 빼뒀습니다. 모르는 걸 아는 척하는 것보다, 비어 있는 걸 비어 있다고 보여주는 게 더 믿을 만하다고 생각했습니다.
4. 이 노가다를 에르메스 에이전트 데스크탑한테 시켰다
여기가 이 글의 진짜 주제입니다.
위 작업을 뜯어보면, 제가 한 건 사실 "무엇을 볼지 정하는 판단"뿐입니다. 그 뒤에 붙는 건 전부 반복 노가다였어요. 공식 소스에서 데이터 가져오기, 각 지표를 규칙대로 점수화하기, 히스토리 쌓기, 결과를 정적 페이지로 배포하기, 숫자마다 출처 붙이기.
예전 같으면 스크립트 짜고 에러 잡고 배포 만지느라 며칠을 썼을 일입니다. 이번엔 에르메스 에이전트(데스크탑 버전)한테 맡겼습니다.
데스크탑 버전이 좋았던 건, 에이전트가 데이터를 어떻게 가져오고 어떤 파일을 만지는지 눈으로 보면서 진행할 수 있었다는 점입니다. 투자 관련 작업은 "얘가 지금 뭘 하고 있는지" 안 보이면 불안한데, 과정이 보이니 안심하고 맡길 수 있었습니다. 데이터 fetch와 점수화는 별도 monitor 스크립트가 수행하고 웹 페이지는 결과만 보여주는 구조로 분리한 것도 에이전트와 같이 정리한 결과입니다.
사람이 판단하고, 반복은 에이전트가 한다 — 자가학습형 에이전트를 실제 내 문제에 써먹는다는 게 이런 거구나 싶었습니다.
결과와 배운 점
지금 화면이 말하는 것 (2026-06-08 기준)
글을 쓰는 지금, 대시보드는 이렇게 말합니다.
총점 0 / 14 · 판정 "양호" — 켜진 경고가 하나도 없습니다.
S&P500은 7,405.73으로 200일선 위 +7.9%, 52주 고점에서 -2.68%. 추세는 멀쩡합니다.
VIX 18.92 — 52주 고점 대비 -39%. 시장은 차분합니다.
HY OAS 2.76% — 신용 스프레드가 좁습니다. 신용시장도 평온합니다.
금리 커브(10Y-2Y +0.38%p, 10Y-3M +0.76%p) — 둘 다 정상(플러스). 역전 아닙니다.
Sahm Rule 0.1 — 경고선 0.5에서 한참 아래. 침체 트리거 없음.
NFCI -0.49 — 금융여건은 느슨한 편.
그래서 대시보드가 제시하는 행동 원칙도 단순합니다. 정기 분할 매수는 그대로, 신규 자금은 계획대로 코어/방어 자산에 규칙적으로, 레버리지는 신규 확대 금지.
여기서 제가 진짜 배운 게 나옵니다.
이 대시보드가 가장 쓸모 있는 순간은 빨간불일 때가 아니라, 지금처럼 다 초록불일 때다.
상승장에서 가장 위험한 건 하락이 아니라, 다 좋아 보일 때 방심하는 나 자신이었습니다. 0/14라서 안심하는 게 아니라, 0/14일 때조차 같은 화면을 열어 "아직 다 정상"임을 확인하는 습관이 핵심이더라고요.
무엇이 달라졌나
가장 큰 변화는 불안의 종류가 바뀐 것입니다.
전에는 "막연한 불안"이었습니다. 떨어질까 봐 무섭고, 팔자니 더 오를까 봐 무섭고. 근거가 없으니 결정도 못 했습니다.
지금은 "관측 가능한 불안"입니다. 매일 같은 화면을 열고, 14점 중 몇 점이 켜졌는지, 추세가 올라가는지 내려가는지를 봅니다. 여전히 미래는 모르지만, 적어도 무너지는 신호를 남보다 조금 빨리 볼 준비는 됐습니다.
정직하게, 한계도 분명합니다
시장 폭·섹터 순환 7개 축은 아직 점수에서 빠져 있습니다. 데이터 경로가 확보되는 대로 채울 계획입니다.
이건 매매 신호가 아닙니다. 점수가 올랐다고 팔라는 뜻이 아니고, 0/14라고 더 사라는 뜻도 아닙니다. 어디까지나 관측 보조 도구입니다.
저는 투자 자문가가 아닙니다. 이 글은 제 실험 기록이지 투자 권유가 아닙니다. 같은 지표라도 해석은 사람마다 다르고, 과거 패턴이 미래를 보장하지도 않습니다.
앞으로 해보고 싶은 것
비워둔 시장 폭·순환 축을 공식 RAW 경로가 확보되는 대로 추가
점수가 특정 임계치를 넘으면 텔레그램으로 자동 알림
과거 하락 국면(닷컴, 2008, 2020 등)에 이 점수를 거꾸로 대입해보는 백테스트
빌드 시점에 숫자까지 HTML에 박아, 어떤 환경에서도 빈 화면이 안 나오게 만들기
마무리
상승장에서 가장 위험한 건 하락이 아니라, 하락을 못 알아채는 나 자신이었습니다.
감으로 버티는 동안엔 결정의 근거가 내 기분이었습니다. 이제는 적어도 같은 화면, 같은 숫자, 같은 출처를 봅니다. 예측은 여전히 못 합니다. 하지만 무너지는 신호를 관측할 준비는 됐고, 그 준비를 며칠이 아니라 에이전트와 함께 빠르게 끝낼 수 있었다는 게 이번 프로젝트의 진짜 수확입니다.
지금은 0/14, 양호입니다. 다 초록불입니다.
바로 그래서, 저는 내일도 이 화면을 엽니다.
좋은 투자 도구는 미래를 맞히는 도구가 아니라, 내가 지금 무엇을 보고 있는지 정직하게 보여주는 도구라고 생각합니다.
지난 글 ▶ 「여러 봇이 같이 보는 위키를 만들었더니, 매번 똑같은 설명을 안 해도 됐다」 의 다음 이야기입니다.
한 줄 요약
봇 공유 위키를 만들어 운영해보니, 다음 벽은 "어떻게 찾고, 찾은 걸 믿을 것인가" 였다. 검색 결과를 정답처럼 쓰지 않고 후보를 찾고 → 원문을 읽고 → 위키에 검증해 남기는 흐름으로 정리했고, 이번 주엔 그 위에 의미 검색층(OpenViking)을 로컬로 직접 깔아 같은 질문에 검색 종류별로 어떻게 다른지 실측까지 해봤다.
0. 지난 이야기에서 이어서
지난번에 여러 봇이 똑같이 참조하는 공유 위키(LLMWiki) 를 만들었다. "한 군데만 보면 다 같은 답이 나오게" 하는 게 목표였고, 작게 시작해 운영 규칙(SCHEMA)을 v0.1 → v0.2로 키웠다.
그런데 자료가 쌓이자 새 문제가 생겼다. 저장은 됐는데 막상 찾아서 쓰는 단계에서 사고가 났다. 그래서 지난 글의 마지막 교훈("위키의 가치는 작성보다 유지보수에서 나온다")을 한 발 더 밀어붙여야 했다. 이번 주제는 그 유지보수의 핵심 = 검색과 검증이다.
1. 새로 부딪힌 문제 — 검색 결과를 그냥 믿었다가 데였다
가장 크게 데인 건 봇이(그리고 가끔은 나도) "내 기억/검색에 없으니 그건 없는 일" 이라고 단정해버리는 순간이었다. 실제로 "그건 안 한 작업"이라고 자신 있게 답했다가, 막상 폴더를 뒤져보니 멀쩡히 있었던 적이 있었다.
핵심은 이거였다: 검색에서 안 나온다 ≠ 존재하지 않는다. 한 번 검색해보고 결과(또는 결과 없음)를 결론처럼 써버리면, 그럴듯하지만 틀린 답이 만들어진다. 그래서 운영 규칙에 한 줄을 못 박았다 — "없다 / 안 했다 / 못 한다" 같은 단정은 반드시 직접 찾아본 뒤에만 한다.
2. "찾기"와 "믿기"를 분리했다
핵심 전환은 이거였다: 검색에 걸렸다고 정답이 아니다. 검색 결과는 일단 후보다. 그래서 흐름을 나눴다.
후보 찾기 — 검색으로 "이쯤에 있을 것 같은" 문서를 건진다.
원문 읽기 — 후보를 곧장 믿지 않고, 실제 원문을 열어 확인한다.
검증 버퍼를 거쳐 남기기 — 확인된 것만 정본으로 승격한다.
3번이 이번에 또렷해진 부분이다. 쿼리해서 얻은 답을 바로 위키 본문에 붓지 않고, 먼저 임시 보관함(queries/)에 출처·확신도와 함께 적어둔다. 거기서 검증을 통과한 것만 확정 폴더(decisions/, 도메인 폴더)로 올린다. "질문해서 찾은 것"과 "확정된 사실"을 폴더 단위로 분리한 것이다. 위키 형식으로도 강제했다.
정리 문서엔 confidence: high / medium / low 를 단다. 여러 근거로 확인된 것만 high.
단일 출처나 추론은 본문에 확인 필요 / 가설 로 표시한다.
마지막 도장은 사람이 — "AI가 후보를 모아주면, '이게 정본이다'는 사람이 결정한다." 찾는 건 봇이 잘하지만, 믿어도 되는지의 판단은 사람이 쥔다.
"찾기는 봇, 믿기는 사람" — 이게 이번 주차에 가장 크게 남은 원칙이다.
3. 질문이 다시 위키를 키운다
한 번 헤맨 질문은 두 번 헤매지 않게 했다. queries/ 폴더에 "그거 어딨지 / 뭐였지 / 언제였지"의 답을 찾으면 그 자리에 박아둔다. 다음에 같은 걸 찾을 땐 검색을 다시 돌릴 필요 없이 그 문서만 열면 된다. 못 읽은 자료는 정직하게 status: 목록만 확인 / 본문 미열람, confidence: medium으로 남긴다. 모르는 걸 안다고 쓰지 않는 게 위키가 썩지 않는 비결이었다.
4. 이번 주 실제로 한 것 — 의미 검색층을 로컬로 깔았다
지금까지 "찾기"는 이름·키워드 검색(정확히 일치하는 단어 찾기)에 의존했다. 약점은 분명했다: 단어가 조금만 달라도 못 찾는다. "인건비"라고 저장돼 있는데 "월급 얼마"라고 물으면 헛친다. 그래서 의미가 비슷하면 찾아주는 의미 검색(임베딩 기반) 층을 붙였다 — 오픈소스 컨텍스트 DB OpenViking.
가장 신경 쓴 건 거버넌스였다. 우리 위키엔 조직·예산 기준·계약 규칙 같은 회사 핵심 지식이 들어있다. 이걸 외부 클라우드에 임베딩하려 보내면 회사 지식이 통째로 밖으로 나간다. 그래서 임베딩 모델을 로컬(Ollama)로 돌려 데이터가 한 줄도 외부로 나가지 않게 구성했다. 클라우드 API 키 없이, 노트북 안에서 전부 도는 형태다.
5. 실측 — 같은 질문, 검색 종류별로 이렇게 다르다
위키를 의미 검색층에 넣고(20개 문서), 질문 하나로 직접 비교했다. 질문: "직원 한 명 더 뽑으면 인건비 예산을 얼마로 잡지?" (위키엔 '인건비 단가 표준'이라는 제목으로 저장 — 질문과 단어가 거의 안 겹친다.)
정확 검색(키워드 "인건비"): 즉시 9곳 매치, 정확히 그 정본 문서를 가리켰다. → 단어가 그대로 있으면 압도적으로 빠르고 정확.
의미 검색(자연어 질문): 결과 없음. → 솔직한 결과다. 한국어 + 가벼운 로컬 임베딩 조합에서는 의미 검색이 약했다. 이건 스터디 자료도 예고한 한계("한국어↔영어 교차 검색은 보강 필요")와 정확히 일치했다.
원문 확인: 정확 검색이 가리킨 문서를 직접 열어 실제 기준값을 확인했다. (검색 결과를 그냥 믿지 않고 원문을 읽는 단계.)
최종 판단: 그 문서엔 confidence: high와 함께 "이 값은 추정 기준이며 외부 공식 문서엔 그대로 박지 말 것" 이라는 경고까지 적혀 있었다. 그래서 "정본으로 채택하되, 외부엔 그대로 쓰지 않는다"로 결론냈다. 검색이 찾아준 것(hit)을 넘어, 원문의 단서까지 읽고 판단한 것이다.
배운 점: 검색 종류마다 잘하는 질문이 다르다. 이름·용어가 정확하면 키워드 검색, 말이 바뀐 개념 질문이면 의미 검색 — 하나로 다 처리하려 하면 한쪽이 샌다. 그리고 검색을 더 깐다고 무조건 좋아지지 않는다. 의미 검색은 임베딩 모델·언어 궁합이 받쳐줘야 한다는 걸 직접 확인했다.
6. 검색층을 늘려도, 정본의 권한은 따로다
의미 검색층을 붙이면서 원칙을 하나 더 분명히 했다: 검색층은 "후보를 넓혀주는 보조"일 뿐, 정본에 직접 쓰는 권한은 없다. 의미 검색이 무언가를 찾아줘도 그건 읽어볼 후보이고, 위키 본문(정본)에 반영하려면 사람 검증을 거쳐야 한다. 이건 평소 우리가 봇 권한을 다루는 방식(레이어마다 권한을 나누고, 민감한 판단은 기본적으로 사람에게)과 같은 철학이다. 검색이 강해진다고 판단 권한까지 검색에 넘기지 않는다.
배운 점
검색에 안 나온다 ≠ 없는 일. 단정하기 전에 직접 찾아본다.
검색 hit는 후보지 정답이 아니다. "찾기"와 "믿기"를 분리하니 그럴듯한 오답이 확 줄었다.
검색은 만능이 아니다. 이름으로 찾기 / 의미로 찾기는 잘하는 구간이 다르고, 의미 검색은 언어·모델 궁합을 탄다(직접 실측).
회사 지식엔 거버넌스가 먼저다. 편하다고 외부로 보내지 않고, 로컬로 돌려 데이터를 안 내보내는 선택을 했다.
위키는 질문을 받을 때마다 자란다. 한 번 헤맨 걸 답으로 남기는 루프가 검색보다 강했다.
소개
지난번에 NotebookLM을 CLI로 쓰는 글을 올렸는데, 이번엔 한 발 더 나가봤다.
단순히 nlm list로 노트북 목록을 보는 수준이 아니라, "새 주제 하나를 통째로 리서치해서 노트북으로 만들고, 인포그래픽·브리핑 문서·슬라이드까지 자동으로 뽑아 내 지식베이스 폴더에 쌓는 것" 을 한 번에 시켜봤다.
사용한 건 동일하게 notebooklm-mcp-cli ( https://github.com/jacob-bd/notebooklm-mcp-cli ).
이번엔 CLI가 아니라 Claude 데스크톱(Cowork)에 MCP로 붙여서 자연어로만 진행했다.
테스트 주제는 마침 그날 나온 "Claude Fable 5"(앤트로픽의 첫 일반 공개 미토스급 모델)로 잡았다.
시작한 이유
매번 NotebookLM 웹에 들어가서 소스 붙이고, 인포그래픽 누르고, 다운로드하고… 이걸 반복하는 게 번거로웠다.
새로 나온 이슈를 보면 "리서치 → 노트북화 → 결과물 생성 → 내 지식 폴더에 저장" 이 한 흐름으로 자동화되면 좋겠다고 생각했다.
CLI도 좋지만, Claude 데스크톱에 MCP로 붙이면 자연어 한 문장으로 전체 파이프라인을 돌릴 수 있을 것 같았다.
진행 방법
이미 CLI(nlm)는 설치돼 있던 상태라, 이번엔 Claude 데스크톱에 MCP 서버로 연결하는 것부터 시작했다.
1. Claude 데스크톱에 MCP 연결
nlm setup add claude-desktop 을 기대했는데, 설치된 버전엔 그 타깃이 없었다. 대신 설정 파일에 직접 등록하는 방식으로 붙였다.
실행 파일 경로부터 확인:
which notebooklm-mcp
# /Users/me/.local/bin/notebooklm-mcp
Claude 데스크톱 → 설정 → 개발자(Developer) → Edit Config 에서 아래 추가:
{ "mcpServers": { "notebooklm-mcp": { "command": "/Users/me/.local/bin/notebooklm-mcp" } }
}
저장 후 Cmd+Q로 완전 종료 후 재실행. (창만 닫으면 적용 안 됨)
재실행하니 notebooklm 도구 39개가 잡혔고, "연결됐는지 확인해줘" 한 마디로 노트북 목록을 바로 불러왔다. (보유 28 + 공유받음 1 = 29개)
2. 자연어 한 문장으로 전체 파이프라인 지시
그다음은 진짜 시키고 싶었던 것. 한 문장으로 던졌다.
이번에 클로드 패블 나온거에 대한 자료를 인포그래픽으로 만들고 싶어.
노트북을 새로 하나 만들고, 그 안에 자료를 모아서 집어넣은 다음에,
인포그래픽으로 생성하고, 보고서를 만들어줘.
그러면 Claude가 알아서:
웹에서 Claude Fable 5 관련 자료를 리서치하고
새 노트북을 생성 ("Claude Fable 5 종합 개요")
공식·해외·국내 출처 7건을 소스로 추가
인포그래픽 + 브리핑 문서 + 슬라이드를 한국어로 생성
완성본을 내 지식베이스 폴더(cc-dev-vault)에 저장
뭐가 문제였나 (삽질 기록)
순탄하진 않았다. 이 부분이 오히려 도움이 될 것 같아 그대로 남긴다.
1) claude-desktop이 setup 타깃에 없음
→ 설치된 버전(0.6.15)에선 지원 안 함. JSON 직접 등록으로 우회.
2) Studio 생성 단계에서 인증 만료
소스 추가까지는 잘 되는데, 인포그래픽·문서·슬라이드 생성은 더 강한 인증을 요구한다. "auth expired" 에러가 떴다.
→ 터미널에서 nlm login 으로 재로그인.
3) 재로그인했는데도 MCP는 계속 만료라고 함
CLI에선 nlm login --check 가 "authenticated"로 멀쩡한데, MCP 서버만 expired를 반환. refresh_auth()(디스크에서 토큰 다시 읽기)로도 안 살아났다.
→ 원인은 켜져 있던 구버전 MCP 서버가 시작 시점의 만료 토큰을 메모리에 붙잡고 있던 것. 해결은:
uv tool upgrade notebooklm-mcp-cli # 0.6.15 → 0.7.2
그리고 Claude 데스크톱을 Cmd+Q로 완전 종료 후 재실행. 새 서버가 뜨면서 갱신된 인증을 그제서야 잡았다.
> 교훈: 인증 문제는 "재로그인 + MCP 서버 재시작(=앱 완전 종료)"이 세트다. refresh만으론 안 된다.
4) 슬라이드 생성이 오래 걸려 다운로드 타임아웃
인포그래픽·브리핑은 1~2분이면 끝나는데, 슬라이드는 8분 넘게 걸렸다. download_artifact의 대기(wait)가 MCP 전송 타임아웃에 걸림.
→ 상태(studio_status)를 주기적으로 확인하면서, 완료된 뒤 다시 받으니 정상 다운로드됨.
결과와 배운 점
결과물은 세 개, 전부 내 지식베이스 폴더에 자동 저장됐다.
인포그래픽 (PNG) — 출시 배경·성능·가격·안전장치·시장 반응을 한 장에
브리핑 문서 (Markdown) — 요약 → 성능(Opus 4.8·GPT-5.5 대비)·안전장치·산업 사례·가격 → 핵심 인용구 → 실행 인사이트
슬라이드 (PDF) — 발표용 상세 덱
배운 점:
자연어 한 문장 → 리서치·노트북화·생성·저장까지 한 흐름으로 돌아간다. 이게 핵심이다. 웹을 안 거친다.
결과물이 연결된 폴더(지식베이스)에 바로 쌓인다. 그래서 다음 작업 때 그대로 참조 자산이 된다.
다만 인증·버전·생성 시간 세 가지는 미리 알고 가야 덜 헤맨다. (재로그인은 앱 재시작과 세트 / 슬라이드는 오래 걸림)
다음엔 이걸 매주 자동 실행(스케줄) 으로 걸어서, 관심 주제 최신 동향을 매주 같은 폴더에 쌓는 것까지 해볼 생각이다.