v3.3.0: чат с договором — задать вопрос по spec_rows
This commit is contained in:
+57
-2
@@ -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", "Нет ответа")})
|
||||
|
||||
Reference in New Issue
Block a user