v3.3.0: чат с договором — задать вопрос по spec_rows

This commit is contained in:
2026-06-18 09:23:09 +04:00
parent e3b7f283f0
commit 958865c397
3 changed files with 115 additions and 3 deletions
+57 -2
View File
@@ -1,13 +1,14 @@
"""routes/llm.py — LLM-извлечение + сравнение: один SSE-поток."""
"""routes/llm.py — LLM-извлечение + сравнение + чат."""
import json as _json
import time as _time
from flask import Response
from flask import Response, request, jsonify
import db
import extractor
import differ
import llm_client
def process(cid):
@@ -137,3 +138,57 @@ def process(cid):
yield f"data: {_json.dumps({'type': 'done', 'total_time_s': total_time, 'all_changes': all_changes})}\n\n"
return Response(generate(), mimetype="text/event-stream")
def chat(cid):
"""
POST /llm/chat/<cid> — задать вопрос по договору.
Тело: {"question": "..."}
Контекст: все строки spec_rows этого договора.
Ответ: {"answer": "..."}
"""
data = request.get_json(silent=True) or {}
question = data.get("question", "").strip()
if not question:
return jsonify({"error": "Введите вопрос"}), 400
# ── Собрать контекст: все строки спецификации ──────────
rows_res, _ = db.query(
"SELECT s.type, s.number, d.filename, sr.row_num, sr.name, sr.price, sr.qty, sr.sum, sr.date_start "
"FROM spec_rows sr "
"JOIN supplements s ON sr.supplement_id = s.id "
"JOIN documents d ON s.document_id = d.id "
"WHERE s.contract_id = %s ORDER BY s.created_at, sr.row_num",
(cid,),
)
if not rows_res or not rows_res["rows"]:
return jsonify({"answer": "Нет извлечённых данных. Сначала запустите сравнение."})
# Форматируем контекст
lines = []
for r in rows_res["rows"]:
row = dict(zip(rows_res["columns"], r))
lines.append(
f"[{row['filename']}] строка {row['row_num']}: {row['name']} | "
f"цена={row['price']} | объём={row['qty']} | сумма={row['sum']} | начало={row['date_start']}"
)
context = "\n".join(lines)
# ── Промпт ──────────────────────────────────────────────
prompt = f"""Ты — анализатор договоров облачного провайдера. У тебя есть извлечённые строки спецификации услуг.
ДАННЫЕ:
{context}
ВОПРОС ПОЛЬЗОВАТЕЛЯ:
{question}
Ответь кратко и по делу, опираясь ТОЛЬКО на данные выше. Если данных недостаточно — скажи об этом."""
# ── Вызов LLM ───────────────────────────────────────────
result = llm_client.ask(prompt, max_tokens=1000)
if "error" in result:
return jsonify({"answer": f"Ошибка LLM: {result['error']}"})
return jsonify({"answer": result.get("text", "Нет ответа")})