← 리포트 목록
openclaw:main routing 400 investigation
2026-04-14
openclaw
[openclaw, llm, gateway, incident]
진행 기록
현재 확인한 사실
- 운영 로그에서
openclaw:main호출이HTTP Error 400: Bad Request를 반복함. ~/.openclaw/logs/llm/20260414.jsonl기준 10시대에도openclaw:main400이 계속 기록됨.agent_queue_worker.py는 에이전트별 모델맵이 없을 때get_model_chain(default_model="openclaw:main")경로를 사용함.orchestrator.py도RON_CHAT_MODEL = openclaw:main기본값을 사용하고,chat_completion_with_fallback()에서 공용 LLM 호출로 넘김.- Hermes LaunchAgent의 활성 plist에는 API 서버 환경변수(
API_SERVER_ENABLED/HOST/PORT)가 빠져 있었고, 백업 plist에는 존재했음. - API 서버 환경변수는 활성 plist에 복구했고 Hermes gateway LaunchAgent는 재시작했지만, 현재
127.0.0.1:18789는 여전히 LISTEN 상태가 아님. Hermes gateway는 메시징/크론 게이트웨이로는 살아 있음. - 직접 LLM 라우팅 검증에서는
openclaw:main을 구체 모델 체인으로 풀면 로컬 Ollama 폴백으로 성공 가능함.
중단 전 수행한 변경
/Users/ron/Library/LaunchAgents/ai.hermes.gateway.plistAPI_SERVER_ENABLED=trueAPI_SERVER_HOST=127.0.0.1API_SERVER_PORT=18789- 백업:
/Users/ron/Library/LaunchAgents/ai.hermes.gateway.plist.bak-20260414-api-server - Hermes gateway와 agent queue workers/orchestrator-loop 재시작 완료.
현재 사용자 지시
shared/llm.py의llm_chat_with_fallback는 더 수정하지 말 것.openclaw:main이 상류 모델로 번역되는 위치를 찾고, 그 위치에서 GPT-5 계열이max_completion_tokens를 쓰도록 보장할 것.
다음 작업
openclaw:main번역 위치를 코드에서 재탐색.- 로컬 OpenClaw/Hermes gateway HTTP API가 왜 18789를 열지 않는지 확인.
- 번역 지점 또는 gateway chat handler에서 payload 변환을 적용.
- 재시작 후
openclaw:main실제 호출이 400이 아닌지 검증.
2026-04-14 재개 기록
- 작업 재개. 사용자 추가 지시:
shared/llm.py의llm_chat_with_fallback는 수정 금지. - 현재 초점:
openclaw:main이 실제 upstream 모델로 새는 위치를 찾아, 그 경로에서 구체 모델 체인으로 변환되게 한다. - 우선 수정 후보:
scripts/orchestrator.py,scripts/agent_queue_worker.py의 기본 모델 체인 fallback.
재탐색 결과
scripts/orchestrator.py에서RON_CHAT_MODEL기본값이get_primary_model("openclaw:main")이고, 현재 함수는 그대로openclaw:main을 반환한다.scripts/agent_queue_worker.py에도 fallback_get_model_chain_orig(default_model="openclaw:main")이 있으나, 실제 LaunchAgent의--agent값은 모두AGENT_MODEL_MAP에 있는 정식 이름이다. 따라서 주된 400 원인은 Ron orchestrator 기본 모델이 추상 라벨을 그대로 공용 LLM에 넘기는 경로로 보인다.- OpenClaw 문서/TS gateway 기준
openclaw:main은 upstream 모델명이 아니라 agent selector이다. Python 운영 경로에서는 이를 구체 모델 체인으로 풀어야 한다.
적용한 수정
scripts/orchestrator.pyopenclaw:main/openclaw/*추상 라벨을~/.openclaw/openclaw.json의agents.defaults.model체인으로 변환하도록 수정.- 설정 로드 실패 또는 cloud 실패 대비 최종 로컬 폴백
ollama/qwen2.5:3b유지. RON_CHAT_MODEL기본값은openclaw:main으로 유지하고, 호출 직전get_model_chain()에서 전체 구체 모델 체인으로 변환한다.scripts/agent_queue_worker.py- fallback
_get_model_chain_orig()에서도openclaw:main을 구체 모델 체인으로 변환하도록 수정. shared/llm.py의llm_chat_with_fallback는 이번 재개 작업에서 수정하지 않음.
수정 보정
- 최초 수정에서
RON_CHAT_MODEL기본값을 primary 단일 모델로 바꾸면 fallback 체인이 잘릴 수 있음을 검증 중 발견했다. - 보정:
RON_CHAT_MODEL기본값은openclaw:main으로 유지하되, 호출 직전get_model_chain()에서 전체 구체 모델 체인으로 변환한다. - 이 방식은 로그/상류 호출에는
openclaw:main을 보내지 않으면서, 설정된 fallback 체인을 유지한다.
검증 결과
- 문법 검사 통과:
python3 -m py_compile scripts/orchestrator.py scripts/agent_queue_worker.py- 라우팅 단위 검증 통과:
orchestrator.get_model_chain("openclaw:main")→github-copilot/gpt-5-mini,openai-codex/gpt-5.4,ollama/qwen2.5:3bagent_queue_worker.get_model_chain("openclaw:main", agent_name=None)→ 동일 구체 체인- 결과 체인에
openclaw:main없음. - payload 검증 통과:
github-copilot/gpt-5-mini의 실제 payload key는max_completion_tokens이며max_tokens없음.- 실제 호출 검증 통과:
orchestrator.chat_completion_with_fallback()수동 호출은 Copilot quota 429 후ollama/qwen2.5:3b로 성공.- 운영 반영:
- agent queue workers 8개와
com.openclaw.orchestrator-loop재시작 완료. - 운영 로그 확인:
- 10:54 이후
~/.openclaw/logs/llm/20260414.jsonl에서HTTP Error 400= 0건. - 10:54 이후
openclaw:main+ 400 = 0건. - Ron orchestrator 로그는 이후 LLM 응답을
ollama/qwen2.5:3b로 받고 있음. - Required Checks:
knowledge_os.py mcp-check→ 4/4 healthy.- dashboard structure API → 응답 확인.
- dashboard command queue API → 13개 항목 응답 확인.
남은 리스크
- Copilot
github-copilot/gpt-5-mini는 현재 일일 rate limit 429 상태라 운영은 당분간 Ollama fallback에 의존한다. openai-codex/gpt-5.4는 현재 GitHub Models endpoint에서 unsupported로 기록된다. 이 문제는 400 원인과는 별개지만 fallback 지연/로그 잡음을 만든다.openclaw:main의 원래 OpenClaw HTTP gateway 의미는 agent selector이고, 현재 Hermes gateway는 18789 HTTP API를 열지 않는다. 이번 수정은 Python 운영 경로에서 추상 라벨이 upstream 모델명으로 새는 문제를 막는 조치다.