feat(Ф2): llm_client.py — DI LLM (HttpxLLMClient + FakeLLMClient)
This commit is contained in:
+19
-18
@@ -27,6 +27,17 @@ LLM_URL = "https://api.aillm.ru/v1/chat/completions"
|
||||
LLM_KEY = os.environ.get("LLM_KEY") or os.environ.get("LLM_API_KEY", "")
|
||||
LLM_MODEL = "gpt-oss-120b"
|
||||
|
||||
# Ленивый singleton — обратная совместимость
|
||||
_classify_llm = None
|
||||
|
||||
|
||||
def _get_classify_client():
|
||||
global _classify_llm
|
||||
if _classify_llm is None:
|
||||
from .llm_client import HttpxLLMClient
|
||||
_classify_llm = HttpxLLMClient(url=LLM_URL, key=LLM_KEY, model=LLM_MODEL, max_tokens=1000, timeout=60)
|
||||
return _classify_llm
|
||||
|
||||
# ── Garbage filter (Stage 1: filename regex) ────────────────────
|
||||
_GARBAGE_FILENAME_RE = re.compile(
|
||||
r'(сч[её]т|акт|плат[её]ж|УПД|сверк|инвойс|invoice|payment|act)',
|
||||
@@ -53,29 +64,19 @@ def _is_garbage_by_header(text: str) -> bool:
|
||||
return any(marker in header for marker in _GARBAGE_HEADER_MARKERS)
|
||||
|
||||
|
||||
def _call_llm_classify(header_text):
|
||||
def _call_llm_classify(header_text, llm_client=None):
|
||||
"""
|
||||
Прямой вызов LLM для классификации ОДНОГО документа.
|
||||
Возвращает (parsed_dict, raw_text, needed_fix).
|
||||
llm_client: LLMClient (optional). Default — HttpxLLMClient.
|
||||
"""
|
||||
prompt, _ = build_classify_prompt(header_text)
|
||||
payload = {
|
||||
"model": LLM_MODEL,
|
||||
"messages": [{"role": "user", "content": prompt}],
|
||||
"max_tokens": 1000,
|
||||
"temperature": 0.1,
|
||||
}
|
||||
with httpx.Client(http2=True, timeout=60) as client:
|
||||
resp = client.post(
|
||||
LLM_URL, json=payload,
|
||||
headers={"Authorization": f"Bearer {LLM_KEY}", "Content-Type": "application/json"},
|
||||
)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
if llm_client is None:
|
||||
llm_client = _get_classify_client()
|
||||
|
||||
raw = data.get("choices", [{}])[0].get("message", {}).get("content", "")
|
||||
parsed, needed_fix = _safe_json_parse(raw)
|
||||
return parsed, raw, needed_fix
|
||||
prompt, _ = build_classify_prompt(header_text)
|
||||
raw_text = llm_client.complete(prompt)
|
||||
parsed, needed_fix = _safe_json_parse(raw_text)
|
||||
return parsed, raw_text, needed_fix
|
||||
|
||||
|
||||
def classify_batch(batch_id):
|
||||
|
||||
Reference in New Issue
Block a user