타입 힌트를 도입했는데 디버깅이 빨라졌다: 파이썬에서 “조사 속도”를 올리는 고정점들 그날은 로그가 있었다. 경고도 있었고, 에러도 있었다. 그런데 원인은 없었다. 재현이 안 되는 버그는 아니었다. 오히려 잘 재현됐다. 문제는 “어디서부터 잘못됐는지”를 못 찾는 거였다. 요청은 API에서 들어오고, DB에서 데이터를 꺼내고, 중간에 여러 함수가 거친 뒤에야 예외가 났다. 마지막 스택트레이스는 친절했지만, 팀이 궁금한 건 늘 그거다. 그래서 이 값은 언제부터 이상했지? 타입 힌트를 ‘정확성’의 이야기로만 들으면 도입이 늘 늦어진다. “동적 언어인데 굳이?” “mypy 설정부터 해야 하나?” 같은 얘기만 남는다. 나는 타입 힌트를 조사 속도 의 도구로 받아들이기 시작하면서부터 도입이 쉬워졌다. 코드가 덜 틀리게 만드는 도구가 아니라, 사고가 났을 때 조사를 빨리 끝내는 도구. 오늘은 그 관점에서 타입 힌트를 도입할 때 고정하면 좋은 것들을 적는다. 체크리스트로 늘어놓기보다, 한 번 터진 장애를 기준으로 어디를 고정하면 조사 시간이 줄어드는지의 이야기다. 본문에는 링크를 넣지 않고, 읽을거리는 맨 아래 참고자료로만 모았다. 타입은 ‘정답’이 아니라 조사 비용을 줄이는 장치다 Talk Python의 Typing Council 에피소드(참고자료)를 들으면, 타입은 단순히 문법 논쟁이 아니라 “파이썬 생태계가 어떻게 합의를 쌓아가는지”에 대한 이야기로 들린다. 그 합의는 성능보다도, 협업과 유지보수의 현실에서 나온다. 내가 실무에서 타입 힌트를 좋아하게 된 이유도 비슷하다. 타입이 있으면 코드가 100% 맞아지진 않는다. 대신 이런 질문이 빨라진다. 이 함수는 뭘 받아야 하지? 이 값은 None 이 될 수 있나? 여기서 문자열이 들어오는 게 맞나? 중요한 건 질문이 “리뷰 타이밍”에만 나오지 않는다는 거다. 장애 조사에서 이 질문들이 늦게 나오면, 팀은 로그를 뒤지고 DB를 뒤지고 결국 사람의 기억을 ...
OpenRouter를 붙였는데 더 불안해졌다: 파이썬에서 LLM 호출 동선을 한 군데로 모으는 법 그날 장애는 모델이 아니라 “재시도”에서 시작했다. 응답이 늦어지자 타임아웃이 났고, 타임아웃이 나자 재시도가 돌았다. 재시도가 도니 요청이 더 밀렸다. 로그에는 같은 에러가 쌓였고, 비용 대시보드는 새로고침할 때마다 숫자가 튀었다. 누군가가 “모델만 바꾸면 되는 거 아니었어?”라고 물었는데, 그 질문이 제일 아팠다. OpenRouter 같은 라우터 API를 붙이는 이유는 보통 “여러 모델을 쉽게 바꿔 쓰려고”다. 그런데 실무에서 더 큰 이점은 따로 있다. 호출 동선을 한 군데로 강제할 수 있다는 것 이다. 키, 타임아웃, 리트라이, 로그, 비용. 이 다섯 가지가 프로젝트 여기저기에 흩어져 있으면, 모델이 아무리 좋아도 운영이 먼저 망가진다. 오늘은 그걸 한 파일로 모으는 이야기다. 본문에는 링크를 넣지 않고, 읽을거리는 맨 아래 참고자료로만 모았다. 라우터 API의 장점은 ‘모델 선택’이 아니라 ‘동선 통일’이다 Real Python의 OpenRouter 글(참고자료)을 보면, 접근은 단순하다. 라우터를 붙이면 여러 모델을 한 API로 호출할 수 있다. 여기까지는 누구나 한다. 하지만 팀이 진짜로 얻고 싶은 건 “모델 바꾸기”가 아니라 “규칙을 바꾸기”다. 타임아웃은 몇 초로 둘지 재시도는 몇 번까지 허용할지 실패하면 어떤 예외로 올릴지 로그는 어떤 태그로 남길지 비용은 어디에서 상한을 걸지 이 다섯 가지는 기능 개발보다 운영에 가깝다. 그리고 운영 규칙은 문서로 써놓으면 대개 깨진다. 코드로 박아야 한다. Armin Ronacher가 AI를 ‘테세우스의 배’로 비유한 글(참고자료)을 읽고 떠오른 것도 비슷한 감각이었다. 모델이 바뀌고, 프롬프트가 바뀌고, 정책이 바뀌어도 “이 시스템이 같은 배인가”를 유지하려면 결국 형태(구조)가 아니라 동선(운영)이 남아 있어야 한다. 그래서 우리는 라우...