AI 5봇이 매주 자율 회의를 한다 — bot_meeting.py 구축 과정

Qwen3, Gemma4, Gemma3, Claude, Codex 5개 AI가 매주 일요일 밤 스스로 토론하고 합의하는 시스템. 어떻게 만들었나.

AI 5봇이 매주 자율 회의를 한다 — bot_meeting.py 구축 과정

아이디어

AI 하나한테 “뭘 개선할까?” 물어보면 틀에 박힌 답변만 나왔습니다.

여러 AI가 서로 다른 관점에서 토론하면 다른 결과가 나올까?

그게 bot_meeting.py의 시작이었습니다.


참여 봇 구성

모델역할
Qwen3qwen3:14b (Ollama)논리·전략
Gemma4gemma4:e4b (Ollama)즉각 실행
Gemma3gemma3:12b (Ollama)기술 자동화
Claudeclaude -p (CLI)메타 전략
Codexcodex.ps1 (CLI)코드 구현

전부 로컬이거나 CLI로 실행됩니다. API 비용 최소화.


회의 진행 방식

1. 주제 추출
   growth_log.md (지난 주 배운 것들)
   → Qwen3:14b가 핵심 인사이트 5개 추출

2. 주제 투표
   Qwen3 + Gemma4가 5개 중 이번 주 논의할 주제 선택

3. 5봇 토론
   선택된 주제를 놓고 5봇이 각자 의견 제시
   각 봇은 다른 봇들의 발언을 보고 반응

4. 합의 도출
   Qwen3:14b가 토론 내용 종합 → 결론과 액션 아이템 작성

5. 기록 저장
   goal_state.json 갱신
   debates/YYYY-MM-DD-meeting.md 저장
   Telegram 그룹에 결과 보고

코드 구조 (핵심 부분)

def run_meeting():
    # 1. 인사이트 추출
    raw_log = read_growth_log()
    topics = qwen3_extract_topics(raw_log)  # 5개 추출
    
    # 2. 투표
    chosen_topic = vote_topic(topics)  # Qwen3 + Gemma4
    
    # 3. 5봇 토론
    debate_history = []
    for bot in [qwen3, gemma4, gemma3, claude, codex]:
        response = bot.respond(chosen_topic, debate_history)
        debate_history.append({"bot": bot.name, "text": response})
    
    # 4. 합의
    consensus = qwen3_summarize(debate_history)
    
    # 5. 저장
    save_meeting_record(consensus, debate_history)
    send_telegram_report(consensus)

만들면서 삽질한 것들

삽질 1: 타임아웃

처음에 devstral:24b 모델을 썼습니다. 파라미터가 커서 생각을 잘 할 것 같았습니다.

현실: 한 번 응답하는 데 23분. 5봇이 한 라운드만 돌려도 1015분.

타임아웃 60초로 설정해뒀더니 봇들이 전부 타임아웃으로 실패했습니다.

해결:

  • devstral:24b → gemma3:12b 교체 (빠름)
  • 타임아웃 150초로 늘림

삽질 2: JSON 파싱 실패

LLM한테 “5개 인사이트를 JSON 형식으로 출력해”라고 했는데 마크다운 코드블록으로 감싸거나, 쉼표 빠뜨리거나, 한국어 키를 쓰는 등 형식이 제각각이었습니다.

# LLM이 출력한 예시 (파싱 실패)
```json
{
  "인사이트1": "...",
  "인사이트2": "..."
}

해결: JSON 파싱 실패 시 2회 재시도. 재시도 프롬프트에 "반드시 순수 JSON만, 마크다운 없이"를 명시.

```python
def parse_with_retry(response: str, max_retries: int = 2):
    for attempt in range(max_retries + 1):
        try:
            # 코드블록 제거 후 파싱
            cleaned = re.sub(r'```json?\n?|```', '', response).strip()
            return json.loads(cleaned)
        except json.JSONDecodeError:
            if attempt < max_retries:
                response = retry_llm_call(stricter_prompt)
    return None

삽질 3: 봇들이 같은 말만 반복

처음엔 각 봇이 주제만 받고 독립적으로 의견을 냈습니다. 결과: 비슷한 말만 5번.

해결: 토론 히스토리를 각 봇에게 넘겨줌. 이전 봇들이 말한 걸 읽고 다른 관점에서 반론하거나 보완하도록 프롬프트 수정.

prompt = f"""
주제: {topic}

지금까지 토론 내용:
{format_history(debate_history)}

위 내용을 읽고 당신의 입장(역할: {your_role})에서 
새로운 관점을 추가하거나 반론하세요.
"""

결과물 예시

회의 후 debates/ 폴더에 저장되는 형태:

# 봇회의 2026-05-19

## 선택 주제
Pearl Finder 포스트 품질 개선

## 토론 요약
- Qwen3: 키워드 밀도보다 독자 경험 중심으로
- Gemma4: 즉시 적용 가능한 변경 → 포스트 길이 제한 800자
- Gemma3: 이미지 생성 자동화로 체류 시간 개선
- Claude: 검색 의도 파악 후 역방향 설계 필요
- Codex: 실제 구현 — make_markdown.py 수정안 제시

## 합의 액션 아이템
1. 포스트 본문 최소 400자, 최대 800자
2. 소제목 3개 이상
3. 실제 수치/경험 포함 필수

스케줄 등록

# 매주 일요일 22:00 자동 실행
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At "22:00"
$action = New-ScheduledTaskAction -Execute "python" `
  -Argument "D:\bots\bot_meeting.py" `
  -WorkingDirectory "D:\bots"
Register-ScheduledTask -TaskName "JARVIS\BotMeeting" `
  -Trigger $trigger -Action $action -RunLevel Highest

실제로 유용한가

회의 결과가 항상 금방 적용되는 건 아닙니다. 하지만 방향 설정에 도움이 됩니다.

이 포스트를 쓰는 것도 봇회의 결과 중 하나입니다: “실제 경험을 기록하라.”

#멀티에이전트#봇회의#Python#자동화#AI협업