Sign In

3-Incident Logs

All
troubleshooting
how-it-works
고쳤는데 또 나왔다 — 설정 파일이 두 곳일 때 생기는 일
어제 고쳤는데 오늘 또 청구됐다. 설정을 바꿨다고 해서 진짜 바뀐 게 아닐 수 있다. 이런 상황이었어요 어제 Gemini API 청구서를 보고 원인을 분석했다. 엘론이 Pro 모델로 설정돼 있었고, 앤드류가 그룹방 메시지에 자동 반응하면서 내부에서 엘론을 호출하는 구조가 문제였다. 그래서 fix_all.py 스크립트로 엘론 모델을 gemini-3.1-pro-preview에서 gemini-3-flash-preview로 바꿨다. Docker를 재시작했다. 게이트웨이 로그에 agent model: google/gemini-3-flash-preview가 찍혔다. 됐다고 생각했다. 오늘 다시 청구 내역을 확인했더니 어제와 비슷한 규모의 비용이 또 올라가 있었다. 오늘은 대화를 하지 않았는데. 원인을 찾아보니 오늘 비용의 정체: 빌링 지연 먼저 오늘(4/19) Docker 로그를 확인했다. LLM 호출 기록이 없었다. 신규 API 사용이 아니었다. 오늘 보이는 비용은 어제(4/18)의 실제 사용분이었다. 어제 앤드류에게 리서치를 요청했고, 엘론과 1:1 대화를 1턴 했다. Google은 API 사용 비용을 하루 정도 지연해서 청구한다. 이게 오늘 나타난 것이었다. 청구서 타이밍과 실제 사용 시점이 달라서 "또 발생했다"고 착각한 거였다. 진짜 문제: 설정 파일이 두 곳 그런데 파고들다 더 심각한 걸 발견했다. openclaw.json을 직접 열어봤더니 이런 구조가 있었다. 엘론(main)의 모델이 agents.list 안에 직접 박혀 있었고, 값은 아직 Pro였다. fix_all.py가 수정한 파일은 ~/.openclaw/agents/main/agent/models.json이었다. 이 파일은 분명히 Flash로 바뀌어 있었다. 그런데 openclaw.json 안의 agents.list[].model 필드가 이 파일보다 우선순위가 높았다. OpenClaw의 모델 적용 우선순위: 우선순위 위치 상태 1 (높음) openclaw.json > agents.list[].model
  1. troubleshooting
  • R
    Raon
완료했어요 했는데 왜 그대로지? — AI와 일할 때 완료의 기준을 다시 정한 이유
AI가 "완료"라고 했다. 서버는 여전히 어제 그대로였다. 반복되는 패턴을 발견했다 AI 에이전트를 운영하다 보면 이런 상황이 생긴다. 엘론의 모델을 Flash로 바꿨다. 다음 날 비용이 또 나왔다. "고쳤는데 왜?" AI가 fix_all.py를 수정했다고 보고했다. 파일은 고쳐져 있었다. 그런데 그 파일을 서버에서 실행한 적이 없었다. 로컬 수정과 VM 반영은 별개다. 서버 설정은 어제 그대로였다. 그걸 깨닫고 나서 패턴이 보였다. 로컬과 VM 동기화가 없었던 것이다. 로컬만 고치고 VM을 빠뜨리거나, VM만 패치하고 로컬을 방치한 게 반복됐다. AI 에이전트 운영에 배포 규칙이 필요한 이유가 거기 있었다. "업무 순서에 규칙이 없는 거야?" 맞는 지적이었다. 로컬과 VM은 완전히 다른 공간이다 이 문제의 뿌리는 단순했다. 로컬(내 컴퓨터)과 VM(실제 서버)이 별개라는 걸 작업 흐름에서 의식하지 않았던 것이다. 로컬에서 스크립트를 수정하면 로컬 파일이 바뀐다. VM은 그 사실을 모른다. VM에 해당 스크립트를 가져다 실행해야만 서버 상태가 바뀐다. AI가 "수정 완료"라고 했을 때, 그게 로컬 수정인지 VM 반영까지인지는 작업 기준을 명확히 해두지 않으면 구분이 안 된다. AI도, 사람도. 로컬 = 다음 실행을 위한 템플릿. VM = 지금 실제로 동작 중인 상태. 이 둘이 항상 일치하는 상태가 진짜 "완료"다. 작업 순서를 명시적으로 정했다 4단계 순서 규칙 이번 경험으로 작업 순서를 확정했다. VM 실행 전에는 dry-run을 먼저 돌린다. "이 스크립트를 실행하면 VM의 어떤 값이 바뀌는가"를 확인한 뒤 실행한다. 덮어쓰기 위험이 있는 작업에서 실수를 막는 습관이다. enum 필드는 문서로 확인한다 같은 날, 설정 파일에 groupPolicy: "closed"를 넣었더니 서버가 즉시 에러를 뱉었다. "closed"는 없는 값이었다. 공식 문서 확인 없이 추측으로 썼던 것. 에러 메시지가 유효값 목록을 정확히 알려줬다. 설정 파일에서 값의 종류가 정해진 항목(enum 필드)은 반드시 먼저 확인하고 쓴다. 추측으로 넣으면 hot reload가 실패하고, 그 원인을 찾는 데 시간이 든다.
  1. troubleshooting
  • R
    Raon
파일이 없어서 기억을 못 했다 — AI 봇 장기 메모리가 작동 안 한 진짜 이유
앤드류에게 "기록하라"는 지시는 이미 있었다. 파일이 없었을 뿐이다. 로그에서 에러를 발견했다 비용 인시던트를 들여다보다가 어제 날짜 로그에서 에러 하나를 발견했다. 앤드류가 리서치 작업을 마친 뒤 이전 컨텍스트를 읽으려 했는데, 파일이 없어서 실패한 것이었다. "아, 앤드류가 이전 작업을 기억 못 하는 이유가 이거였구나." 처음엔 설정 문제인 줄 알았다. 바로 AGENTS.md를 확인하러 들어갔다가 이미 이런 문장이 적혀 있는 걸 봤다. 지시는 이미 있었다. 파일이 없었을 뿐이다. 에이전트 기억은 어떻게 작동하나 3단 구조로 나뉜다 OpenClaw 에이전트의 기억은 3개 계층으로 설계돼 있다. 계층 파일 유지 범위 단기 세션 컨텍스트 현재 대화 중에만 중기 memory/YYYY-MM-DD.md 날짜별 작업 로그 장기
  1. how-it-works
  • R
    Raon
함께 있지만 서로 모른다 — groupPolicy 한 줄이 만든 침묵
groupPolicy 한 줄로 에이전트가 완전히 침묵했다. 설정을 고치고 나서야 왜 그런지 구조가 보였다. 이런 상황이었어요 리서치 그룹 채팅방에 앤드류와 엘론을 함께 넣었다. 앤드류는 잘 대답했다. 그런데 @엘론을 불러도 엘론은 아무 반응이 없었다. 봇이 죽은 건가? 설정이 잘못된 건가? openclaw.json을 열어보니 엘론 설정에 이 한 줄이 있었다. 그룹 기능이 완전히 꺼져 있었다. DM에서만 동작하는 상태였던 것이다. 원인을 찾아보니 OpenClaw에서 groupPolicy는 에이전트가 그룹 채팅에 참여할 수 있는지를 결정한다. "disabled" — 모든 그룹에서 완전 침묵 "allowlist" — 지정한 그룹에서만 활성화 "all" — 모든 그룹에서 활성화 엘론은 disabled 상태였으니 @멘션을 해도 읽지 못하는 게 당연했다. 더 근본적인 이유가 있었다. 에이전트는 채널 단위로 격리된다. 엘론이 DM에서 라온님과 나눈 대화는 그룹방 엔드류에게 보이지 않는다. 앤드류가 그룹방에서 처리한 리서치 결과도 엘론은 모른다. 각 에이전트는 자신이 속한 채널의 메시지만 볼 수 있다. 같은 팀처럼 보여도 실제로는 서로를 볼 수 없는 섬이다. 이렇게 해결했어요 엘론의 groupPolicy를 allowlist로 변경하고 리서치 그룹을 명시적으로 추가했다. requireMention: true를 함께 설정했다. 그룹방에서 모든 메시지에 반응하면 앤드류와 무한 루프가 생길 수 있기 때문이다. 라온님이 직접 @엘론을 부를 때만 전략 코멘트를 제공하도록 했다. 그리고 AGENTS.md에 규칙도 추가했다. 설정만 바꾸는 게 아니라 어떻게 동작해야 하는지 명문화했다.
  1. troubleshooting
  • R
    Raon
아무것도 안 했는데 청구서가 왔다 — agentToAgent가 만든 보이지 않는 호출
며칠간 대화하지 않았는데 청구서가 날아왔다. 원인을 추적하다 에이전트 내부 라우팅 구조를 이해하게 됐다. 이런 상황이었어요 에이전트와 며칠간 대화를 하지 않았는데 API 비용이 발생했다. 처음엔 혹시 heartbeat나 cron 설정이 있나 확인했다. 없었다. 그럼 뭔가? Docker 로그를 열어봤더니 며칠 전 실제 작업 세션이 있었다. 리서치 그룹 채팅방에서 앤드류가 쇼핑 검색을 수행한 기록이었다. 그리고 그 사이에 낯선 로그 한 줄이 있었다. 엘론이 호출됐는데 응답을 못 한 것이었다. 엘론을 부른 건 라온님이 아니었다. 앤드류였다. 원인을 찾아보니 agentToAgent 설정이 켜져 있었다. 처음엔 이게 텔레그램에서 두 봇이 서로 대화하는 기능인 줄 알았다. 아니었다. agentToAgent는 서버 내부 라우팅이다. 앤드류가 작업을 처리하다가 전략 판단이 필요하면 내부적으로 엘론을 호출한다. 텔레그램에는 앤드류의 답변만 보이지만, 뒤에서는 엘론이 이미 한 번 돌았다. 메시지 1개가 들어오면 실제로는 2개 에이전트가 처리한다. 비용도 2배다. 그런데 문제가 하나 더 있었다. 앤드류의 그룹 설정이 이랬다. 그룹방에 올라오는 모든 메시지에 자동 반응하는 설정이었다. 누군가 그룹방에 메시지를 보내면 앤드류가 반응하고, 앤드류가 agentToAgent로 엘론을 부른다. 라온님이 직접 대화하지 않아도 비용이 발생하는 구조였다. 이렇게 해결했어요 핵심은 엘론의 requireMention 설정이었다. 변경 전: 엘론이 그룹에서 아예 비활성화(groupPolicy: disabled) 변경 후: 엘론이 그룹에서 @멘션 시에만 응답(requireMention: true) 앤드류는 requireMention: false를 유지했다. 사용자 메시지에는 자동으로 반응해야 하니까. 추가로 엘론 모델도 Pro에서 Flash로 변경했다. agentToAgent 호출이 발생하더라도 비용 부담이 줄어든다. 알게 된 것 텔레그램에서 보이는 건 앤드류의 메시지뿐이다. 그 뒤에서 엘론이 호출됐는지, 몇 번 돌았는지는 보이지 않는다. agentToAgent는 텔레그램 대화가 아니라 내부 라우팅이다. 비용이 예상보다 많이 나왔다면 이 구조를 먼저 의심해봐야 한다.
  1. troubleshooting
  • R
    Raon
Made with Slashpage