fix: раздельные промпты для initial (ADD) и ДС (diff) (v1.0.75)
This commit is contained in:
@@ -0,0 +1,83 @@
|
|||||||
|
"""llm_prompt.py — Формирование промпта для LLM-анализа ДС."""
|
||||||
|
|
||||||
|
|
||||||
|
def build_prompt(current_spec: list, doc_text: str) -> str:
|
||||||
|
is_first = len(current_spec) == 0
|
||||||
|
if is_first:
|
||||||
|
return _build_initial(doc_text)
|
||||||
|
else:
|
||||||
|
return _build_diff(current_spec, doc_text)
|
||||||
|
|
||||||
|
|
||||||
|
def _build_initial(doc_text: str) -> str:
|
||||||
|
return f"""Ты — анализатор договоров облачного провайдера.
|
||||||
|
|
||||||
|
Ниже текст спецификации услуг из ПЕРВОГО документа (базовый договор).
|
||||||
|
Извлеки ВСЕ строки спецификации в JSON-массив.
|
||||||
|
|
||||||
|
Верни СТРОГО JSON без пояснений. Не используй markdown-блоки.
|
||||||
|
|
||||||
|
ФОРМАТ:
|
||||||
|
{{
|
||||||
|
"mode": "partial",
|
||||||
|
"ops": [
|
||||||
|
{{"action": "ADD", "new_row": {{"name": "полное наименование", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}}, "comment": ""}}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
|
||||||
|
ПРАВИЛА:
|
||||||
|
1. Извлеки КАЖДУЮ строку таблицы спецификации как отдельную ADD-операцию.
|
||||||
|
2. Пропускай итоговые строки ("Итого...") и строки с подписями.
|
||||||
|
3. Если ячейка пустая — ставь null (не пиши 0).
|
||||||
|
4. price, qty, sum — ЧИСЛА, не строки.
|
||||||
|
|
||||||
|
ТЕКСТ ДОКУМЕНТА:
|
||||||
|
---
|
||||||
|
{doc_text}
|
||||||
|
---"""
|
||||||
|
|
||||||
|
|
||||||
|
def _build_diff(current_spec: list, doc_text: str) -> str:
|
||||||
|
lines = []
|
||||||
|
for r in current_spec:
|
||||||
|
lines.append(
|
||||||
|
f"[hash: {r.get('hash', '?')}] {r.get('name', '?')} | "
|
||||||
|
f"цена={r.get('price', '')} | объём={r.get('qty', '')} | "
|
||||||
|
f"сумма={r.get('sum', '')} | начало={r.get('date_start', '')}"
|
||||||
|
)
|
||||||
|
spec_text = "\n".join(lines)
|
||||||
|
|
||||||
|
return f"""Ты — анализатор допсоглашений к договорам облачного провайдера.
|
||||||
|
|
||||||
|
У тебя есть текущая спецификация услуг и текст нового допсоглашения (ДС).
|
||||||
|
Твоя задача — определить, какие изменения вносит ДС в текущую спецификацию.
|
||||||
|
|
||||||
|
Верни СТРОГО JSON без пояснений. Не используй markdown-блоки.
|
||||||
|
|
||||||
|
ФОРМАТ:
|
||||||
|
{{
|
||||||
|
"mode": "partial" | "full_replace",
|
||||||
|
"ops": [
|
||||||
|
{{"action": "ADD", "new_row": {{"name": "...", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}}, "comment": "..."}},
|
||||||
|
{{"action": "UPDATE", "target_hash": "hash_строки", "new_values": {{"price": число}}, "comment": "..."}},
|
||||||
|
{{"action": "DELETE", "target_hash": "hash_строки", "comment": "..."}},
|
||||||
|
{{"action": "UNRESOLVED", "new_values": {{"name": "...", "price": число, ...}}, "reason": "почему не смог сопоставить"}}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
|
||||||
|
ПРАВИЛА:
|
||||||
|
1. mode = "full_replace" — если в тексте есть фразы: «в следующей редакции», «заменить приложение», «излагается в следующей редакции». При full_replace — опиши ВСЕ новые строки как ADD.
|
||||||
|
2. mode = "partial" — если ДС меняет только отдельные строки.
|
||||||
|
3. Для UPDATE/DELETE — находи соответствующую строку по target_hash.
|
||||||
|
4. new_values в UPDATE — только ИЗМЕНЁННЫЕ поля (не все).
|
||||||
|
5. Если не можешь однозначно сопоставить строку — action: UNRESOLVED с reason.
|
||||||
|
6. Пропускай итоговые строки и подписи.
|
||||||
|
7. price, qty, sum — ЧИСЛА (не строки).
|
||||||
|
|
||||||
|
ТЕКУЩАЯ СПЕЦИФИКАЦИЯ:
|
||||||
|
{spec_text}
|
||||||
|
|
||||||
|
ТЕКСТ ДОПСОГЛАШЕНИЯ:
|
||||||
|
---
|
||||||
|
{doc_text}
|
||||||
|
---"""
|
||||||
Reference in New Issue
Block a user