Replace all Anthropic API calls with Claude Code session (claude -p)

New module claude_session.py provides query() and query_json() that
run prompts via `claude -p` CLI — uses the claude.ai session, zero API cost.

Converted 6 services:
- claims_extractor.py: extract_claims_with_ai
- brainstorm.py: brainstorm_directions
- block_writer.py: write_block (was streaming+thinking, now simple)
- qa_validator.py: claims_coverage check
- style_analyzer.py: 3 API calls (single pass, multi pass, synthesis)
- learning_loop.py: extract_lessons

Only extractor.py still uses Anthropic API (for PDF OCR with Vision).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-04 14:14:08 +00:00
parent e5dc037088
commit bacb330a2a
7 changed files with 115 additions and 192 deletions

View File

@@ -1,7 +1,7 @@
"""חילוץ טענות מכתבי טענות (ערר, תשובה) באמצעות Claude API.
"""חילוץ טענות מכתבי טענות (ערר, תשובה) באמצעות Claude Code session.
שתי גישות:
1. extract_claims_with_ai — חילוץ עם Claude (לכתבי טענות קלט)
1. extract_claims_with_ai — חילוץ עם Claude Code headless (לכתבי טענות קלט)
2. extract_claims_from_block — חילוץ regex (מבלוק ז של החלטות סופיות)
"""
@@ -11,23 +11,12 @@ import logging
import re
from uuid import UUID
import anthropic
from legal_mcp import config
from legal_mcp.config import parse_llm_json
from legal_mcp.services import db
from legal_mcp.services import db, claude_session
logger = logging.getLogger(__name__)
_anthropic_client: anthropic.Anthropic | None = None
def _get_anthropic() -> anthropic.Anthropic:
global _anthropic_client
if _anthropic_client is None:
_anthropic_client = anthropic.Anthropic(api_key=config.ANTHROPIC_API_KEY)
return _anthropic_client
EXTRACT_CLAIMS_PROMPT = """אתה מנתח מסמכים משפטיים בתחום תכנון ובניה. תפקידך לחלץ טענות מכתב טענות.
@@ -93,27 +82,15 @@ async def extract_claims_with_ai(
chunks = [text]
all_claims = []
client = _get_anthropic()
for i, chunk in enumerate(chunks):
chunk_label = f" (חלק {i+1}/{len(chunks)})" if len(chunks) > 1 else ""
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=8192,
messages=[
{
"role": "user",
"content": (
f"{EXTRACT_CLAIMS_PROMPT}\n\n"
f"{context}{chunk_label}\n\n"
f"--- תחילת מסמך ---\n{chunk}\n--- סוף מסמך ---"
),
}
],
prompt = (
f"{EXTRACT_CLAIMS_PROMPT}\n\n"
f"{context}{chunk_label}\n\n"
f"--- תחילת מסמך ---\n{chunk}\n--- סוף מסמך ---"
)
raw = message.content[0].text.strip()
claims = parse_llm_json(raw)
claims = claude_session.query_json(prompt, timeout=120)
if claims is None:
logger.warning("Failed to parse claims for chunk %d: %s", i, raw[:200])
continue