한 줄 요약: 어제 만든 PRD를 “하루에 하나씩 될 만한 크기”로 쪼갠 다음, 그중 두 조각(Finnhub 데이터 가져오기, Claude API로 AI 판단 받기)을 오늘 직접 만들고 실행해서, 프로젝트가 처음으로 “진짜로 작동하는” 상태가 됐다.
이런 분께 도움돼요: PRD·계획은 세웠는데 “그래서 코드는 어디서부터 짜지” 막막한 분, 또는 Claude API로 구조화된 판단을 받고 싶은 분.
Before
PRD엔 “가격+뉴스를 AI에게 줘서 매수/매도/보유 판단을 받는다”고만 적혀 있었지, 실제로 그걸 코드 몇 줄로 어떻게 짜는지는 하나도 안 정해져 있었다. 게다가 Claude API를 스크립트에서 부르는 건 처음이라, 어떤 모델을 써야 할지도 몰랐다.
어떻게 했나
1. PRD를 하루 단위로 쪼개기
이렇게 물어봤다.
어제 만든 PRD를 바탕으로 세부계획을 세우고 싶어.
단, 계획을 짜기 전에 먼저 조사부터 해줘 —
이걸 지금 만든다면 요즘 제일 쉽고 많이 쓰는 방법이 뭔지 최신 기준으로 찾아봐.
나는 코딩을 잘 몰라. 4주 안에 진짜 만들 수 있게, 작은 단계로 잘게 쪼개서
순서대로 정리해줘. 각 단계는 "하루 안에 될 만한 크기"로.
AI가 모델 선택(비용 대비 성능), Node.js에서 Claude API를 부르는 방법, “판단+이유”를 안정적인 JSON으로 받는 방법까지 조사한 뒤, 1~9단계로 쪼갠 세부계획을 만들어줬다.
2. 데이터 하나 가져오기 (2단계)
Finnhub API로 AAPL의 오늘 가격과 최신 뉴스를 가져오는 짧은 스크립트를 만들어 바로 실행해봤다. 콘솔에 진짜 숫자(현재가 336.91, 전일 대비 +1.17%)와 뉴스 제목이 찍히는 걸 보고서야 “아, 이게 실제로 되는구나” 싶었다.
3. AI 판단 연결하기 (3단계)
여기서부터가 이번 사례의 핵심이다. @anthropic-ai/sdk를 설치하고, 가격·뉴스를 프롬프트로 만들어서 Claude에게 넘긴 뒤, “구조화된 출력”이라는 기능으로 판단을 강제된 JSON 형태로 받게 만들었다.
const DecisionSchema = z.object({
판단: z.enum(['매수', '매도', '보유']),
이유: z.string(),
});
const response = await client.messages.parse({
model: 'claude-sonnet-5',
messages: [{ role: 'user', content: 프롬프트 }],
output_config: { format: zodOutputFormat(DecisionSchema) },
});
막힘 → 해결
코드를 처음 돌렸을 때 Cannot read properties of undefined (reading 'def')라는 에러가 났다. 원인은 설치된 zod 라이브러리가 v3→v4 과도기 버전이라, import { z } from 'zod'로 쓰면 옛날 방식이 되고, 구조화된 출력은 새 방식을 기대해서 생긴 충돌이었다. 'zod/v4'에서 가져오도록 한 줄 고치니 바로 해결됐다.
After
- PRD가 1~9단계 세부계획으로 쪼개졌다
- Finnhub에서 실제 가격·뉴스를 가져오는 스크립트 완성
- Claude API로 “매수/매도/보유 + 이유”를 안정적인 JSON으로 받는 스크립트 완성 — 실제로 AAPL에 대해 “보유” 판단과 그 이유를 받아냄
- 새로 나온 개념들은 개념페이지로 정리해둠
배운 점 / 재사용 자산
- “조사 먼저, 계획은 그 다음” — 계획부터 짜지 말고 “지금 제일 쉬운 방법이 뭔지” 먼저 물어보면, 계획 자체가 훨씬 실전적으로 나온다.
- **구조화된 출력(structured output)**은 AI 판단을 코드에 안정적으로 연결할 때 재사용할 수 있는 패턴 — 이번에 쓴 Zod 스키마 방식은 앞으로 다른 판단(예: 종목별 반복 처리)에도 그대로 가져다 쓸 수 있다.
- zod 버전 충돌 해결법(
zod/v4에서 import)도 기억해둘 것 — SDK 버전이 올라가도 같은 문제가 또 나올 수 있다.