diff --git a/journey/README.md b/journey/README.md index 4d170f5..49ada36 100644 --- a/journey/README.md +++ b/journey/README.md @@ -14,6 +14,7 @@ - research: `research/260315_모델SSOT_하드코딩_분산과_workspace_config_로컬이식_통합리서치.md` - plans: `plans/260316_llm_model_ssot_transition_계획.md` - worklog: `worklog/260316_llm_model_ssot_1차구현_및_로컬검증.md` + - worklog: `worklog/260316_gpt5_mini_전환과_skill_news_provider_agnostic_정리.md` ## Troubleshooting Journey @@ -98,6 +99,7 @@ - 브리핑 조회 윈도우 직전 영업일 기준 확장 – `worklog/260310_briefing_window_직전영업일기준_확장.md` - Company X 내부문서 RAG 근거응답 구현 및 시나리오 검증 – `worklog/260312_companyx_내부문서_rag_근거응답_구현및시나리오검증.md` - LLM 모델 SSOT 1차구현 및 로컬검증 – `worklog/260316_llm_model_ssot_1차구현_및_로컬검증.md` +- gpt-5-mini 전환과 skill-news provider-agnostic 정리 – `worklog/260316_gpt5_mini_전환과_skill_news_provider_agnostic_정리.md` ## Scenarios diff --git a/journey/worklog/260316_gpt5_mini_전환과_skill_news_provider_agnostic_정리.md b/journey/worklog/260316_gpt5_mini_전환과_skill_news_provider_agnostic_정리.md new file mode 100644 index 0000000..e9f92be --- /dev/null +++ b/journey/worklog/260316_gpt5_mini_전환과_skill_news_provider_agnostic_정리.md @@ -0,0 +1,60 @@ +tags: [worklog, llm, gpt-5-mini, provider-agnostic, skill-news, rb8001, runtime] + +# 260316 gpt-5-mini 전환과 skill-news provider-agnostic 정리 + +## 상위 원칙 + +- [LLM 모델 SSOT 전환 계획](../plans/260316_llm_model_ssot_transition_계획.md) +- [모델 SSOT 하드코딩 분산과 workspace-config 로컬이식 통합 리서치](../research/260315_모델SSOT_하드코딩_분산과_workspace_config_로컬이식_통합리서치.md) +- [260316 LLM 모델 SSOT 1차구현 및 로컬검증](./260316_llm_model_ssot_1차구현_및_로컬검증.md) + +## 상태 + +- completed +- server-runtime-verified + +## 이번 작업에서 확인한 추가 사실 + +- 기존 닫힘 검증은 `DEFAULT_LLM_MODEL` 키 수렴까지는 맞았지만, provider 전환까지 설정 1회 변경으로 닫히는 상태는 아니었습니다. +- `skill-news`에는 `google.generativeai` 직접 호출이 남아 있어 `DEFAULT_LLM_MODEL=gpt-5-mini`만 바꾸면 실제 런타임이 깨지는 상태였습니다. +- `rb8001`은 `gpt-5-mini` 핸들러 선택까지는 가능했지만, compose 오버라이드와 OpenAI 파라미터 호환성 때문에 실제 호출은 실패했습니다. + +## 구현한 것 + +- `skill-news` + - `news_summarizer.py`, `companyx_news_summarizer.py`, `sea_news_filter.py`의 Gemini SDK 직접 호출을 제거했습니다. + - `llm_gateway_client.py`를 추가해 `skill-news -> rb8001 /api/llm/generate` 공용 경로만 사용하도록 정리했습니다. + - `test_sea_news_filter.py` 모킹 대상을 새 공용 호출 메서드명에 맞게 갱신했습니다. +- `rb8001` + - `docker-compose.yml`에서 `OPENAI_API_KEY`, `GEMINI_API_KEY`, `DEFAULT_LLM_MODEL` 직접 오버라이드 줄을 제거해 `workspace-config` 우선순위가 실제 런타임에 반영되게 맞췄습니다. + - `openai_handler.py`에서 `gpt-5-mini` 호출 시 `max_completion_tokens`를 사용하고 `temperature`를 보내지 않도록 모델별 파라미터 분기를 추가했습니다. +- `skill-slack` + - 기본 모델 설정 기본값을 `gpt-5-mini`로 맞췄습니다. +- 공용 런타임 + - 51124 서버 `/home/admin/workspace-config/runtime.env`의 `DEFAULT_LLM_MODEL`을 `gpt-5-mini`로 변경했습니다. + +## 검증 + +- `python3 -m compileall` + - `rb8001`, `skill-slack`, `skill-news` 변경 파일 기준 통과 +- `pytest /home/admin/robeing/skill_news/tests/test_sea_news_filter.py -q` + - `5 passed` +- 51124 런타임 검증 + - `rb8001`, `skill-slack`, `robeing-skill-news` 컨테이너 모두 healthy 확인 + - 세 컨테이너 내부 `settings.DEFAULT_LLM_MODEL`이 모두 `gpt-5-mini`로 읽히는 것 확인 + - `rb8001` 컨테이너 내부 `OPENAI_API_KEY`가 `workspace-config/secrets.env`의 실제 키를 읽는 것 확인 + - `http://localhost:8001/api/llm/generate`에 `model=gpt-5-mini` 요청 시 `200` 응답 확인 + - `skill-news` 컨테이너에서 `http://192.168.0.106:8001/api/llm/generate`로 같은 요청을 보냈을 때 `200` 응답 확인 + - 실제 응답 본문에서 `model_used: gpt-5-mini` 확인 + +## 트러블슈팅으로 확인한 런타임 함정 + +- `rb8001/.env`의 placeholder `OPENAI_API_KEY`가 compose `environment` 오버라이드와 결합되면 `workspace-config/secrets.env`의 실제 키를 덮어쓸 수 있었습니다. +- `gpt-5-mini`는 기존 OpenAI 경로의 `max_tokens`, `temperature` 파라미터를 그대로 받지 않아, handler 레벨 호환성 보정이 필요했습니다. +- 따라서 이번 전환의 실제 닫힘 조건은 단순 모델명 변경이 아니라, provider 직접 호출 제거 + secrets/runtime 우선순위 정리 + 모델별 API 파라미터 호환성 정리까지 포함해야 했습니다. + +## 결과 + +- 이제 `skill-news`는 provider SDK를 직접 선택하지 않고 공용 LLM 경로만 사용합니다. +- `rb8001`, `skill-slack`, `skill-news`의 기본 모델은 51124 런타임에서 모두 `gpt-5-mini`로 수렴했습니다. +- 최소 현재 운영 범위 기준으로 `gpt-5-mini` 전환은 실제 호출 성공까지 검증됐습니다.