fix(hermes): 改用 anthropic Python SDK 直呼,棄用需要 claude CLI 的 claude-agent-sdk
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
根因:claude-agent-sdk 需要 spawn claude CLI,prod pod 沒有 CLI 所以 SDK 回空。 修法:改用 anthropic.AsyncAnthropic().messages.create() 直呼 API。 model: claude-haiku-4-5-20251001(快速低成本,適合 Telegram QA) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,19 +1,20 @@
|
||||
"""Hermes 自然語言閘道 — ADR-094
|
||||
|
||||
Layer 1 意圖路由(關鍵字正則)→ Claude Agent SDK 呼叫 → Telegram 格式化輸出。
|
||||
Layer 1 意圖路由(關鍵字正則)→ Anthropic Python SDK 直呼 → Telegram 格式化輸出。
|
||||
|
||||
2026-04-24 Claude Sonnet 4.6 (WS4 Hermes NL)
|
||||
2026-04-24 Claude Sonnet 4.6 (WS4 Hermes NL T1+T2+T3): hermes_dispatch_log DB 寫入 /
|
||||
Redis per-chat_id 速率限制 / Multi-turn session (Redis Hash TTL=300s)
|
||||
2026-04-25 Claude Sonnet 4.6: 改用 anthropic Python SDK 直呼,棄用需要 CLI 的
|
||||
claude-agent-sdk(prod pod 無 claude CLI,sdk call 回傳空字串)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import asyncio
|
||||
import re
|
||||
import time
|
||||
|
||||
import anthropic as _anthropic
|
||||
import structlog
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions
|
||||
from claude_agent_sdk.types import ResultMessage
|
||||
from sqlalchemy import text
|
||||
|
||||
from src.core.config import settings
|
||||
@@ -43,8 +44,6 @@ _ROUTING_RULES: list[tuple[re.Pattern, str]] = [
|
||||
(re.compile(r"(實作|implement|develop|功能|feature)", re.IGNORECASE), "fullstack-engineer"),
|
||||
]
|
||||
|
||||
_HERMES_BUDGET_USD = 0.05
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# T2:速率限制常數(ADR-094)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -222,25 +221,18 @@ async def process_nl_message(
|
||||
|
||||
t0 = time.monotonic()
|
||||
|
||||
# 呼叫 Claude Agent SDK
|
||||
# 呼叫 Anthropic Python SDK(直呼 messages.create,不依賴 claude CLI)
|
||||
success = False
|
||||
error_type: str | None = None
|
||||
try:
|
||||
sdk_env: dict[str, str] = {}
|
||||
if settings.CLAUDE_API_KEY:
|
||||
sdk_env["ANTHROPIC_API_KEY"] = settings.CLAUDE_API_KEY
|
||||
options = ClaudeAgentOptions(
|
||||
system_prompt=system_prompt,
|
||||
max_turns=3,
|
||||
permission_mode="dontAsk",
|
||||
max_budget_usd=_HERMES_BUDGET_USD,
|
||||
env=sdk_env,
|
||||
_client = _anthropic.AsyncAnthropic(api_key=settings.CLAUDE_API_KEY or None)
|
||||
_msg = await _client.messages.create(
|
||||
model="claude-haiku-4-5-20251001",
|
||||
max_tokens=1500,
|
||||
system=system_prompt,
|
||||
messages=[{"role": "user", "content": prompt_with_ctx}],
|
||||
)
|
||||
result_text = ""
|
||||
async for event in query(prompt=prompt_with_ctx, options=options):
|
||||
if isinstance(event, ResultMessage):
|
||||
result_text = getattr(event, "result", "") or ""
|
||||
break
|
||||
result_text = _msg.content[0].text if _msg.content else ""
|
||||
|
||||
if not result_text:
|
||||
result_text = "_Agent 回應為空,請稍後再試。_"
|
||||
|
||||
Reference in New Issue
Block a user