feat: mining_state 설정 최적화 및 GLM 예외 처리 개선

- `mine_resource` 함수에서 채굴 상태를 매 루프마다 반복 설정하던 로직을 제거하여, 우클릭 유지와 유사한 동작으로 최적화
- GLM API 호출 실패 시 예외 처리 로직을 개선하여, 다양한 오류 원인을 로그로 출력하고 상태 요약 기반의 폴백 로직 추가
- 새로운 연결 검사 스크립트 추가 및 README.md에 GLM API 연결 문제 디버깅 섹션 추가
- 관련 문서 및 주의사항 업데이트
This commit is contained in:
kswdev0
2026-03-26 09:49:47 +09:00
parent abd388fc1e
commit 3d118fe649
5 changed files with 366 additions and 20 deletions

View File

@@ -122,13 +122,30 @@ planner.set_goal(
---
## GLM API 연결 문제 디버깅
타임아웃·연결 오류가 나면 **원인을 로그로 먼저 구분**하는 것이 좋습니다.
1. **전용 검사 스크립트** (에이전트와 동일한 `urllib` 경로):
```bash
ZAI_API_KEY="your-key" python scripts/glm_connection_check.py
```
2. **실행 시 상세 로그**: `GLM_DEBUG=1`을 켜면 재시도마다 `[GLM 원인] …` 한 줄에 `URLError.reason`, SSL/소켓 `errno`, DNS 힌트 등이 붙고, 스택 트레이스도 출력됩니다.
3. **자주 있는 원인**: Docker/서버에서 **외부 HTTPS(443) 차단**, **프록시 필요**( `HTTPS_PROXY` ), **DNS 실패**, **API 키 만료·오타**, **응답이 느려 타임아웃**( `GLM_HTTP_TIMEOUT_SECONDS` 증가 ).
---
## 주의사항
- 순수 플레이이므로 **걷기, 채굴, 제작에 실제 시간이 소요**됩니다
- AI가 "move 먼저 → 작업" 패턴을 학습하도록 프롬프트가 설계되어 있습니다
- `agent_log.jsonl`에 모든 행동과 타임스탬프가 기록됩니다
- `ai_planner.py`는 GLM 응답이 잘리거나(중괄호/대괄호 불일치) 마크다운이 섞여도 JSON 파싱을 복구하도록 `{} / []` 균형 추적과 보정 로직을 사용합니다.
- `ai_planner.py`의 `AIPlanner.decide()`는 `TimeoutError`/`ConnectionError`/`urllib.error.URLError` 같은 GLM HTTP 지연/연결 오류도 재시도 후 폴백(explore)합니다.
- `ai_planner.py`의 `AIPlanner.decide()`는 `TimeoutError`/`ConnectionError`/`urllib.error.URLError` 같은 GLM HTTP 지연/연결 오류도 3회 재시도한 뒤, **상태 요약에 나온 광맥(앵커) 좌표가 있으면 `mine_resource`(먼 경우 `move` 후 채굴)로 폴백**하고, 광맥 정보가 없을 때만 `explore` 방향을 순환하며 탐색합니다(동일 방향 탐색 루프 완화).
- GLM HTTP 읽기 제한 시간은 기본 120초이며, `GLM_HTTP_TIMEOUT_SECONDS`로 조정할 수 있습니다. 광맥은 플레이어와 200타일 이상 떨어진 경우에만 폴백에서 `move`를 끼우며, 임계값은 `GLM_FALLBACK_MOVE_THRESHOLD`(기본 200)로 바꿀 수 있습니다.
- `ai_planner.py`의 `_call_glm()`에서 GLM 지연 원인 분석을 위한 타이밍 로그가 출력됩니다.
- `total`: 요청 시작~콘텐츠 반환까지 전체 소요
- `http_read`: HTTP 응답 본문 수신까지 소요
@@ -144,6 +161,7 @@ planner.set_goal(
- 또한 `main inventory`가 비어 캐시 fallback이 동작하면, 로드된 캐시의 `items/total`도 함께 출력합니다.
- `mine_resource`에서 실패한 채굴 타일 제외(`exclude`)는 Lua와 Python 양쪽에서 정수 타일 좌표(`tx, ty`) 키로 통일해, 제외한 좌표가 반복 선택되지 않도록 합니다.
- 또한 채굴 시작(`mining_state`) 좌표는 정수 타일이 아니라, Lua가 찾은 실제 자원 엔티티의 `e.position`(정확 실수 좌표)을 사용해 “플레이어가 타일 위에 있는데도 즉시 채굴 감지 실패”를 줄입니다.
- `mine_resource`는 `LuaControl.mining_state`를 **해당 타깃에 대해 한 번만** 설정합니다. 이전에는 대기 루프마다 같은 값을반복 설정해 우클릭을 연타하는 것과 비슷한 동작이었으며, 이제는 인간이 우클릭을 누른 채로 두는 것에 가깝게 유지합니다.
- `mine_resource`는 move 후 `p.position` 근처(반경 1.2)에서 실제로 해당 광물 엔티티가 있는지 재확인하고, 없으면 채굴을 시도하지 않고 다음 후보로 넘어갑니다.
- `scan_resources()`는 패치 평균 중심(`center_x/y`)만이 아니라 플레이어 기준 가장 가까운 실제 엔티티 좌표(`anchor_x/y`)도 함께 반환하며, `summarize_for_ai()`에서는 앵커를 기준으로 거리/추천을 계산합니다.
- `mine_resource`의 초기 “후보 엔티티 탐색” 반경은 패치 중심 오차를 흡수하기 위해 250으로 확장해, 이동 직후 바로 실패하는 케이스를 줄입니다.