Claude API 호출 시 시스템 프롬프트에 현재 날짜를 포함하여 2024년이 아닌 실제 날짜 기준으로 콘텐츠가 생성되도록 수정. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
86 lines
2.4 KiB
Python
86 lines
2.4 KiB
Python
"""Claude API 기반 블로그 글 품질 리뷰 — 6기준 × 10점, 42/60 통과."""
|
||
|
||
import json
|
||
import logging
|
||
from datetime import date
|
||
from typing import Any, Dict, Optional
|
||
|
||
import anthropic
|
||
|
||
from .config import ANTHROPIC_API_KEY, CLAUDE_MODEL
|
||
from .db import get_template
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
PASS_THRESHOLD = 42 # 60점 만점 중 42점 이상이면 통과 (70%)
|
||
|
||
_client: Optional[anthropic.Anthropic] = None
|
||
|
||
|
||
def _get_client() -> anthropic.Anthropic:
|
||
global _client
|
||
if _client is None:
|
||
_client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
|
||
return _client
|
||
|
||
|
||
def review_post(title: str, body: str) -> Dict[str, Any]:
|
||
"""블로그 글 품질 리뷰.
|
||
|
||
Returns:
|
||
{
|
||
"scores": {
|
||
"empathy": N, "click_appeal": N, "conversion": N,
|
||
"seo": N, "format": N, "link_natural": N
|
||
},
|
||
"total": N,
|
||
"pass": bool,
|
||
"feedback": str
|
||
}
|
||
"""
|
||
template = get_template("quality_review")
|
||
if not template:
|
||
raise RuntimeError("quality_review 템플릿이 없습니다")
|
||
|
||
prompt = template.format(title=title, body=body[:6000])
|
||
|
||
client = _get_client()
|
||
today = date.today().isoformat()
|
||
resp = client.messages.create(
|
||
model=CLAUDE_MODEL,
|
||
max_tokens=2048,
|
||
system=f"현재 날짜는 {today}입니다.",
|
||
messages=[{"role": "user", "content": prompt}],
|
||
)
|
||
raw = resp.content[0].text
|
||
|
||
try:
|
||
text = raw.strip()
|
||
if text.startswith("```"):
|
||
lines = text.split("\n")
|
||
lines = [l for l in lines if not l.strip().startswith("```")]
|
||
text = "\n".join(lines)
|
||
result = json.loads(text)
|
||
|
||
scores = result.get("scores", {})
|
||
total = sum(scores.values())
|
||
passed = total >= PASS_THRESHOLD
|
||
|
||
return {
|
||
"scores": scores,
|
||
"total": total,
|
||
"pass": passed,
|
||
"feedback": result.get("feedback", ""),
|
||
}
|
||
except (json.JSONDecodeError, KeyError, TypeError) as e:
|
||
logger.warning("Quality review JSON parse failed: %s", e)
|
||
return {
|
||
"scores": {
|
||
"empathy": 0, "click_appeal": 0, "conversion": 0,
|
||
"seo": 0, "format": 0, "link_natural": 0,
|
||
},
|
||
"total": 0,
|
||
"pass": False,
|
||
"feedback": f"리뷰 파싱 실패. 원본 응답:\n{raw[:500]}",
|
||
}
|