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:
@@ -6,10 +6,8 @@ import json
|
||||
import logging
|
||||
import re
|
||||
|
||||
import anthropic
|
||||
|
||||
from legal_mcp import config
|
||||
from legal_mcp.services import db
|
||||
from legal_mcp.services import db, claude_session
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -150,24 +148,16 @@ async def _analyze_single_pass(rows) -> dict:
|
||||
decisions_text += f"\n\n--- החלטה {row['decision_number'] or 'ללא מספר'} ---\n"
|
||||
decisions_text += row["full_text"]
|
||||
|
||||
client = anthropic.Anthropic(api_key=config.ANTHROPIC_API_KEY)
|
||||
message = client.messages.create(
|
||||
model="claude-opus-4-6",
|
||||
max_tokens=16384,
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": ANALYSIS_PROMPT.format(decisions=decisions_text),
|
||||
}
|
||||
],
|
||||
raw = claude_session.query(
|
||||
ANALYSIS_PROMPT.format(decisions=decisions_text),
|
||||
timeout=claude_session.LONG_TIMEOUT,
|
||||
)
|
||||
|
||||
return await _parse_and_store_patterns(message.content[0].text, len(rows))
|
||||
return await _parse_and_store_patterns(raw, len(rows))
|
||||
|
||||
|
||||
async def _analyze_multi_pass(rows) -> dict:
|
||||
"""Analyze each decision individually, then synthesize patterns."""
|
||||
client = anthropic.Anthropic(api_key=config.ANTHROPIC_API_KEY)
|
||||
all_patterns = []
|
||||
|
||||
# Pass 1: Analyze each decision individually
|
||||
@@ -175,18 +165,12 @@ async def _analyze_multi_pass(rows) -> dict:
|
||||
decision_text = f"--- החלטה {row['decision_number'] or 'ללא מספר'} ---\n"
|
||||
decision_text += row["full_text"]
|
||||
|
||||
message = client.messages.create(
|
||||
model="claude-opus-4-6",
|
||||
max_tokens=8192,
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": SINGLE_DECISION_PROMPT.format(decision=decision_text),
|
||||
}
|
||||
],
|
||||
raw = claude_session.query(
|
||||
SINGLE_DECISION_PROMPT.format(decision=decision_text),
|
||||
timeout=claude_session.LONG_TIMEOUT,
|
||||
)
|
||||
|
||||
patterns = _extract_json(message.content[0].text)
|
||||
patterns = _extract_json(raw)
|
||||
if patterns:
|
||||
all_patterns.extend(patterns)
|
||||
|
||||
@@ -194,21 +178,15 @@ async def _analyze_multi_pass(rows) -> dict:
|
||||
return {"error": "לא הצלחתי לחלץ דפוסים מההחלטות"}
|
||||
|
||||
# Pass 2: Synthesize across all decisions
|
||||
message = client.messages.create(
|
||||
model="claude-opus-4-6",
|
||||
max_tokens=16384,
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": SYNTHESIS_PROMPT.format(
|
||||
num_decisions=len(rows),
|
||||
patterns=json.dumps(all_patterns, ensure_ascii=False, indent=2),
|
||||
),
|
||||
}
|
||||
],
|
||||
raw = claude_session.query(
|
||||
SYNTHESIS_PROMPT.format(
|
||||
num_decisions=len(rows),
|
||||
patterns=json.dumps(all_patterns, ensure_ascii=False, indent=2),
|
||||
),
|
||||
timeout=claude_session.LONG_TIMEOUT,
|
||||
)
|
||||
|
||||
return await _parse_and_store_patterns(message.content[0].text, len(rows))
|
||||
return await _parse_and_store_patterns(raw, len(rows))
|
||||
|
||||
|
||||
def _extract_json(response_text: str) -> list | None:
|
||||
|
||||
Reference in New Issue
Block a user