title: OpenRouter L2 구현 런북 (즉시 실행용) date: 2026-02-26 parent_plan: "openrouter-migration-l1.md"
OpenRouter L2 구현 런북 (즉시 실행용)
L1 설계 플랜 기반, PL이 copy-paste로 즉시 실행할 수 있도록 정리.
Step 1: 의존성 교체
cd /Users/nbs22/(Claude)/(claude).projects/business-builder/projects/content-pipeline
npm uninstall @google/generative-ai
npm install openai@^4.77.0
Step 2: 파일별 수정 목록
2-1. src/pipeline/generate.ts (뉴스레터 생성, 457줄)
수정 4곳:
| 위치 | Before | After |
|---|---|---|
| L1 import | import { GoogleGenerativeAI } from "@google/generative-ai"; | import OpenAI from "openai"; |
| L251~253 mock fallback | process.env.GOOGLE_API_KEY 체크 + 로그 | process.env.OPENROUTER_API_KEY 체크 + 로그 |
| L257~262 AI 호출 | GoogleGenerativeAI → generateContent(fullPrompt) | new OpenAI({ baseURL, apiKey }) → chat.completions.create({ model: "google/gemini-2.0-flash-exp", messages: [{ role: "user", content: fullPrompt }] }) |
| L267, L284, L375 로그 | Gemini / GOOGLE_API_KEY 참조 | OpenRouter / OPENROUTER_API_KEY 참조 |
핵심 코드 (L257~262 대체):
console.log("[generate] Calling OpenRouter API (google/gemini-2.0-flash-exp)...");
const client = new OpenAI({
baseURL: process.env.OPENROUTER_BASE_URL || "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY,
});
const completion = await client.chat.completions.create({
model: "google/gemini-2.0-flash-exp",
messages: [{ role: "user", content: fullPrompt }],
});
const responseText = completion.choices[0]?.message?.content || "";
2-2. src/pipeline/generate-blog.ts (블로그 포스트 생성, 615줄)
수정 4곳:
| 위치 | Before | After |
|---|---|---|
| L1 import | import { GoogleGenerativeAI } from "@google/generative-ai"; | import OpenAI from "openai"; |
| L374, L392 mock fallback | GOOGLE_API_KEY 체크 + 로그 | OPENROUTER_API_KEY 체크 + 로그 |
| L415~423 AI 호출 (가장 중요) | GoogleGenerativeAI + systemInstruction → generateContent(userPrompt) | new OpenAI(...) → chat.completions.create with messages: [{ role: "system", content: systemPrompt }, { role: "user", content: userPrompt }] |
| L428~433, L580 로그 | Gemini 참조 | OpenRouter 참조 |
핵심 코드 (L415~423 대체 -- systemInstruction 전환 주의):
console.log(`[generate-blog] OpenRouter API 호출 중 (google/gemini-2.0-flash-exp)... (필라: ${pillar || "미지정"})`);
const client = new OpenAI({
baseURL: process.env.OPENROUTER_BASE_URL || "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY,
});
const completion = await client.chat.completions.create({
model: "google/gemini-2.0-flash-exp",
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: userPrompt },
],
});
const responseText = completion.choices[0]?.message?.content || "";
2-3. src/pipeline/stage-generate.ts (생성 스테이지, 209줄)
수정 1곳:
| 위치 | Before | After |
|---|---|---|
| L192 모델명 로깅 | process.env.GOOGLE_API_KEY ? 'gemini-2.0-flash' : 'mock' | process.env.OPENROUTER_API_KEY ? 'google/gemini-2.0-flash-exp' : 'mock' |
2-4. .env.example (환경변수 템플릿)
수정 1곳 (L17~24):
# -----------------------------------------------------------------------------
# OpenRouter API (선택 - 없으면 mock 모드)
# -----------------------------------------------------------------------------
# AI 콘텐츠 생성에 사용됩니다 (OpenRouter 경유, OpenAI 호환 API).
# 미설정 시: mock 콘텐츠를 생성합니다.
# 설정 시: google/gemini-2.0-flash-exp로 고품질 한국어 콘텐츠를 자동 생성합니다.
# 발급: https://openrouter.ai > Settings > API Keys
# 정책: openrouter-policy.md 참조 (CEO 확정 — 모든 AI API는 OpenRouter 경유)
OPENROUTER_API_KEY=sk-or-v1-...
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
Step 3: 빌드 검증
cd /Users/nbs22/(Claude)/(claude).projects/business-builder/projects/content-pipeline
npm run build
기대 결과: TypeScript 컴파일 에러 0건.
Step 4: import 잔재 확인
cd /Users/nbs22/(Claude)/(claude).projects/business-builder/projects/content-pipeline
grep -r "@google/generative-ai" src/
grep -r "GOOGLE_API_KEY" src/
기대 결과: 매칭 0건 (schema/backup 등 제외).
Step 5: mock 모드 테스트
cd /Users/nbs22/(Claude)/(claude).projects/business-builder/projects/content-pipeline
npx tsx src/pipeline/generate-blog.ts "소상공인 ChatGPT 활용법" AI도구리뷰
기대 결과:
[generate-blog] OPENROUTER_API_KEY 미설정. Mock 블로그 포스트를 생성합니다.로그 출력- Mock 포스트 JSON 정상 출력
Step 6: git commit + push
cd /Users/nbs22/(Claude)/(claude).projects/business-builder/projects/content-pipeline
git add -A
git commit -m "feat: migrate content-pipeline to OpenRouter (openai SDK)"
git pull --rebase origin production
git push origin production
변경하지 않는 파일 (확인 완료)
| 파일 | 이유 |
|---|---|
src/pipeline/collect.ts | RSS 수집, AI API 미사용 |
src/pipeline/publish.ts | 발행, AI API 미사용 |
src/pipeline/publish-blog.ts | 블로그 발행, AI API 미사용 |
src/pipeline/run.ts | 오케스트레이터, generate 함수 호출만 |
src/pipeline/run-blog-pipeline.ts | 오케스트레이터, SDK 미사용 |
src/lib/ | 유틸리티, AI API 미사용 |
prompts/ | 프롬프트 템플릿, 변경 불필요 |
JSON 파싱 호환성
기존 robust JSON 파싱 로직(escapeNewlinesInJsonStrings, extractField, regex 파싱)은 변경 없이 유지. OpenRouter 경유 Gemini Flash 응답 형식 동일.