어제 만든 인적성(사전 성향) 설문 기능(ADR-0027, #163·#164)을 로컬에서 끝까지 돌려 봤고, 팀장 이탈로 죽어 있던 클라우드 AI를 내 결제로 되살리는 1단계(키 재발급·로컬 검증)를 끝냈다. 오늘 API 지출 총합: 약 3센트.
오늘 한 것 (TL;DR)
- Anthropic API 개인 결제 → identity 연결형 키 함정에 한 번 걸리고, 워크스페이스(Default) 범위 키로 재발급해 해결
- Haiku 첫 실측: 채팅 6.8초 / 요약 9.1초 — qwen3:4b(로컬) 대비 채팅 2배, 요약 1.6배 빠름
- 인적성 설문 로컬 E2E 완주: 발송 API → 메일 감사 기록 → 공개 링크 → 10문항 응답 제출 → 통계 + 아르 관찰 요약이 지원자 상세에 붙는 것까지
- 실메일 수신만 로컬에서 불가(설계상 SES·SQS 자격이 서버 전용) — 운영 배포 후 검증 예정
1. 클라우드 복구 1단계 — 키 재발급 삽질기
배경: 팀장이 이탈하며 개인 결제 키를 폐기해서 운영 AI(요약·채팅·FAQ)가 09/02 저녁부터 전면 중단된 상태다. 갈림길은 (a) 새 키로 클라우드 복구 vs (b) 운영도 로컬 sLLM. (a)를 검증하려고 내 카드로 결제했다.
첫 키를 넣고 스모크를 쏘니 채팅 500, 요약 422. 로그의 에러 원문:
anthropic.BadRequestError: 400 - 'anthropic-workspace-id is required when
authenticating with an identity-linked API key; send the id of the workspace
this request acts in.'
콘솔의 새 키 생성 UI는 기본값이 “범위: 연결된 계정과 동일” 인데, 이대로 만들면 특정 워크스페이스에 소속되지 않은 identity 연결형 키가 나온다. 이런 키는 요청마다 워크스페이스 id 헤더를 요구해서, 헤더를 안 보내는 우리 백엔드(표준 anthropic SDK 사용)에서는 전부 400이다.
해결: 키 생성 시 범위를 Default 워크스페이스로 지정 → “이 키는 Default 워크스페이스에서만 작동”이라고 뜨는 키로 재발급 → 즉시 정상. 요청이 거부만 된 거라 실패 동안 과금은 0이었다.
교훈 두 가지:
- 서버
.env에 넣을 키는 워크스페이스 범위 키로 만들 것. 콘솔 기본값을 그대로 두면 안 된다. - identity 키는 “조직을 떠나면 비활성화”된다. 어느 쪽이든 개인 계정에 묶인 키로 운영을 돌리는 구조 자체가 팀장 사태의 반복이라, 팀 공지에 이 사실을 명시하기로 했다.
2. Haiku 첫 실측 — qwen3:4b와 나란히
| qwen3:4b (로컬, 09/02 실측) | claude-haiku-4-5 (오늘) | |
|---|---|---|
| 채팅 1발 | 15초 | 6.8초 · $0.017* |
| 요약 1명 (3체인) | 15초 | 9.1초 · $0.005 |
*첫 호출이라 시스템 프롬프트 캐시 쓰기(12.6K 토큰) 포함. 이후 호출은 캐시를 0.1배 요율로 읽는다.
품질에서 흥미로운 차이 하나: 자기소개가 9자뿐인 더미 지원자(김도현)를 qwen은 어제 그럭저럭 요약해 줬는데, Haiku는 insufficient(정보 부족)로 판정하고 요약을 거부했다. 지어내지 않는다는 점에서는 오히려 바람직한 보수성이고, 화면에서도 “자기소개 등 자료가 부족해 요약을 만들지 못했습니다”로 깔끔하게 처리된다. “스킬·학력만으로 gist를 쓸지”는 프롬프트 기준의 문제라 W3 튜닝 소재로 적어 뒀다.
프로필이 충실한 지원자(곽민재)는 3체인(요약+평가+추천)을 완주했고, gist·핵심 스킬·우려·추천·확인 질문까지 전부 스키마 상한(리스트 항목 40자) 안쪽으로 나왔다 — 어제 qwen에서 문제였던 부분이다.
부수 확인: 의도 라우터를 llm 모드로 둔 채 클라우드 백엔드를 쓰면 분류 호출(최대 64토큰)도 과금된다. 건당 극소액이지만, 코드 기본값이 rules인 이유가 이거다.
3. 인적성 설문 로컬 E2E — 메일 수신만 빼고 전부
어제 다른 세션에서 만든 기능(#164)을 아무도 실제 화면으로 돌려 본 적이 없었다 (프론트는 CI lint+build만 통과). 오늘 로컬에서 전체 흐름을 완주했다.
① 발송 — POST /applications/1/aptitude/send (김도현, 서류검토 단계) → 201. 단계 제한도 확인: 최종 합격자(곽민재)에게는 “접수·서류검토 단계에서만 발송할 수 있습니다” 422가 제대로 난다.
② 메일 감사 기록 — email_logs에 보낸 그대로 남는다. 제목 “[Arda] 백엔드 개발자 (Python/FastAPI) 사전 성향 설문 요청”, 본문에 ADR-0027 필수 문구(“응답하지 않으셔도 전형 진행에 불이익이 없습니다”)와 만료 안내(7일)까지.
③ 로컬의 한계 (설계된 것) — 발송 상태는 queued에서 멈춘다. 메일 시크릿(SES 자격·SQS 큐 URL)은 서버 .env가 유일한 원본이라 로컬에는 없고, 이건 07-deploy 문서에 적힌 그대로다. 실수신 검증은 운영 배포 후에. 본문의 설문 링크가 /aptitude/{token} 상대 경로로 찍히는 것도 로컬에 PUBLIC_APP_BASE_URL이 없어서인데, AI 면접·일정 제안 메일과 같은 의도된 처리다. 운영 배포 체크리스트에 “서버 .env의 PUBLIC_APP_BASE_URL 확인”을 얹어야 한다.
④ 지원자 경험 — 공개 링크를 열면 로그인 없이 설문 페이지가 뜬다. 인사말·공고명·”정답은 없습니다”·불이익 없음 안내, 리커트 5점 × 10문항, 응답 카운터(10/10), 제출 확인 화면까지 전부 정상.
⑤ 담당자 화면 — 제출하면 백그라운드로 관찰 요약이 생성되고, 지원자 상세 “성향 설문” 섹션에 카테고리 통계와 함께 붙는다:
협업 4.5 / 업무 방식 4.0 / 스트레스 대처 3.5 / 소통 3.5 / 성장 4.0 (각 2문항, 5점 만점)
아르의 관찰 요약(Haiku) 원문:
지원자는 협업 영역에서 높은 응답을 보였으며, 동료의 어려움에 도움을 주려는 의향(4점)과 비판적 피드백 수용(5점)에 모두 높게 응답했습니다. (…) 소통 영역에서는 의견 차이 시 직접 대화를 통한 조율(5점)에는 높게 응답했으나, 진행 상황을 먼저 공유하는 편에는 낮게 응답했습니다(2점).
일부러 상반되게 넣은 응답(조율 5점 vs 선제 공유 2점)을 정확히 “상반 관찰”로 잡아냈고, ADR-0027 경계도 지켰다 — 성격 유형 판정·점수·합불 의견이 한 줄도 없다. 통계는 코드가 계산하므로 LLM이 죽어도 표는 뜬다.
4. 오늘 걸린 잔 함정들
- 목데이터 폴백 + 만료 토큰: localStorage에 이전 세션의 만료 토큰이 남아 있으면 로그인 페이지가 대시보드로 튕기고, API 401 → 목데이터로 그럴싸한 가짜 화면이 뜬다. 콘솔의 “[arda] 서버 응답이 없어 로컬 목 데이터로 그립니다”가 유일한 단서.
- 콘솔 키 생성 기본값(위 1절) — identity 키.
- 로컬 dev의 상대 경로 링크(위 3절) — 버그가 아니라
PUBLIC_APP_BASE_URL미설정.
5. 남은 일
- 팀 공지: ERD v1.7(aptitude 2테이블, alembic 0004) + ADR-0027 확정 요청 + 프론트 접점 + 운영 복구 경로(새 키·재배포·PUBLIC_APP_BASE_URL)
- 회귀 하네스를 Haiku로 한 벌 돌려 qwen 실측과 3자 비교 (운영 방향 결정 근거)
- 운영 반영은 인프라 권한자 몫: 서버
.env키 교체 +alembic upgrade head(0004) + 재배포, 그 후 실메일 수신 테스트 - 내일 W2 게이트. 미뤄 둔 요약 필드 잘림(프롬프트 강화) 실험도 09/04.