v1.0.174: fix \n → real newlines в seed-промптах (parameterized queries)
This commit is contained in:
+62
-18
@@ -28,20 +28,53 @@ def seed_defaults():
|
||||
if count[0]["cnt"] > 0:
|
||||
return
|
||||
|
||||
execute("""
|
||||
INSERT INTO prompts (role, name, body, is_active, notes) VALUES (
|
||||
'extract', 'default-v1',
|
||||
'Ты — анализатор договоров облачного провайдера.\n\nНиже текст спецификации услуг из ПЕРВОГО документа (базовый договор).\nИзвлеки ВСЕ строки спецификации в JSON-массив.\n\nВерни СТРОГО JSON без пояснений. Не используй markdown-блоки.\n\nФОРМАТ:\n{\n "mode": "partial",\n "ops": [\n {"action": "ADD", "new_row": {"name": "полное наименование", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}, "comment": ""}\n ]\n}\n\nПРАВИЛА:\n1. Извлеки КАЖДУЮ строку таблицы спецификации как отдельную ADD-операцию.\n2. Пропускай итоговые строки ("Итого...") и строки с подписями.\n3. Если ячейка пустая — ставь null (не пиши 0).\n4. price, qty, sum — ЧИСЛА, не строки.\n\nТЕКСТ ДОКУМЕНТА:\n---\n{doc_text}\n---',
|
||||
true, 'Авто-создан из llm_prompt.py _build_initial'
|
||||
extract_body = (
|
||||
"Ты — анализатор договоров облачного провайдера.\n\n"
|
||||
"Ниже текст спецификации услуг из ПЕРВОГО документа (базовый договор).\n"
|
||||
"Извлеки ВСЕ строки спецификации в JSON-массив.\n\n"
|
||||
"Верни СТРОГО JSON без пояснений. Не используй markdown-блоки.\n\n"
|
||||
"ФОРМАТ:\n"
|
||||
'{\n "mode": "partial",\n "ops": [\n'
|
||||
' {"action": "ADD", "new_row": {"name": "полное наименование", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}, "comment": ""}\n'
|
||||
" ]\n}\n\n"
|
||||
"ПРАВИЛА:\n"
|
||||
"1. Извлеки КАЖДУЮ строку таблицы спецификации как отдельную ADD-операцию.\n"
|
||||
'2. Пропускай итоговые строки ("Итого...") и строки с подписями.\n'
|
||||
"3. Если ячейка пустая — ставь null (не пиши 0).\n"
|
||||
"4. price, qty, sum — ЧИСЛА, не строки.\n\n"
|
||||
"ТЕКСТ ДОКУМЕНТА:\n---\n{doc_text}\n---"
|
||||
)
|
||||
""")
|
||||
execute("""
|
||||
INSERT INTO prompts (role, name, body, is_active, notes) VALUES (
|
||||
'diff', 'default-v1',
|
||||
'Ты — анализатор допсоглашений к договорам облачного провайдера.\n\nУ тебя есть текущая спецификация услуг и текст нового допсоглашения (ДС).\nТвоя задача — определить, какие изменения вносит ДС в текущую спецификацию.\n\nВерни СТРОГО JSON без пояснений. Не используй markdown-блоки.\n\nФОРМАТ:\n{\n "mode": "partial" | "full_replace",\n "ops": [\n {"action": "ADD", "new_row": {"name": "...", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}, "comment": "..."},\n {"action": "UPDATE", "target_id": "rN", "new_values": {"price": число}, "comment": "..."},\n {"action": "DELETE", "target_id": "rN", "comment": "..."},\n {"action": "UNRESOLVED", "new_values": {"name": "...", "price": число, ...}, "reason": "почему не смог сопоставить"}\n ]\n}\n\nПРАВИЛА:\n1. mode = "full_replace" — если в тексте есть фразы: «в следующей редакции», «заменить приложение», «излагается в следующей редакции». При full_replace — опиши ВСЕ новые строки как ADD.\n2. mode = "partial" — если ДС меняет только отдельные строки.\n3. Для UPDATE/DELETE — укажи target_id (r1, r2...) из списка текущей спецификации. НЕ придумывай новые id.\n4. new_values в UPDATE — только ИЗМЕНЁННЫЕ поля (не все).\n5. Если не можешь однозначно сопоставить строку — action: UNRESOLVED с reason.\n6. Пропускай итоговые строки и подписи.\n7. price, qty, sum — ЧИСЛА (не строки).\n\nТЕКУЩАЯ СПЕЦИФИКАЦИЯ:\n{spec_current}\n\nТЕКСТ ДОПСОГЛАШЕНИЯ:\n---\n{doc_text}\n---',
|
||||
true, 'Авто-создан из llm_prompt.py _build_diff'
|
||||
execute(
|
||||
"INSERT INTO prompts (role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s)",
|
||||
("extract", "default-v1", extract_body, True, "Авто-создан из llm_prompt.py _build_initial"),
|
||||
)
|
||||
diff_body = (
|
||||
"Ты — анализатор допсоглашений к договорам облачного провайдера.\n\n"
|
||||
"У тебя есть текущая спецификация услуг и текст нового допсоглашения (ДС).\n"
|
||||
"Твоя задача — определить, какие изменения вносит ДС в текущую спецификацию.\n\n"
|
||||
"Верни СТРОГО JSON без пояснений. Не используй markdown-блоки.\n\n"
|
||||
"ФОРМАТ:\n"
|
||||
'{\n "mode": "partial" | "full_replace",\n "ops": [\n'
|
||||
' {"action": "ADD", "new_row": {"name": "...", "price": число, "qty": число, "sum": число, "date_start": "YYYY-MM-DD"}, "comment": "..."},\n'
|
||||
' {"action": "UPDATE", "target_id": "rN", "new_values": {"price": число}, "comment": "..."},\n'
|
||||
' {"action": "DELETE", "target_id": "rN", "comment": "..."},\n'
|
||||
' {"action": "UNRESOLVED", "new_values": {"name": "...", "price": число, ...}, "reason": "почему не смог сопоставить"}\n'
|
||||
" ]\n}\n\n"
|
||||
"ПРАВИЛА:\n"
|
||||
'1. mode = "full_replace" — если в тексте есть фразы: «в следующей редакции», «заменить приложение», «излагается в следующей редакции». При full_replace — опиши ВСЕ новые строки как ADD.\n'
|
||||
'2. mode = "partial" — если ДС меняет только отдельные строки.\n'
|
||||
"3. Для UPDATE/DELETE — укажи target_id (r1, r2...) из списка текущей спецификации. НЕ придумывай новые id.\n"
|
||||
"4. new_values в UPDATE — только ИЗМЕНЁННЫЕ поля (не все).\n"
|
||||
"5. Если не можешь однозначно сопоставить строку — action: UNRESOLVED с reason.\n"
|
||||
"6. Пропускай итоговые строки и подписи.\n"
|
||||
"7. price, qty, sum — ЧИСЛА (не строки).\n\n"
|
||||
"ТЕКУЩАЯ СПЕЦИФИКАЦИЯ:\n{spec_current}\n\n"
|
||||
"ТЕКСТ ДОПСОГЛАШЕНИЯ:\n---\n{doc_text}\n---"
|
||||
)
|
||||
execute(
|
||||
"INSERT INTO prompts (role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s)",
|
||||
("diff", "default-v1", diff_body, True, "Авто-создан из llm_prompt.py _build_diff"),
|
||||
)
|
||||
""")
|
||||
_ensure_classify_prompt()
|
||||
|
||||
|
||||
@@ -95,10 +128,21 @@ def _ensure_classify_prompt():
|
||||
existing = query("SELECT id FROM prompts WHERE role = 'classify' AND is_active = true LIMIT 1")
|
||||
if existing:
|
||||
return
|
||||
execute("""
|
||||
INSERT INTO prompts (role, name, body, is_active, notes) VALUES (
|
||||
'classify', 'default-v1',
|
||||
'Ты — система классификации договорных документов. Проанализируй текст и верни СТРОГО ВАЛИДНЫЙ JSON ОДНОЙ СТРОКОЙ (без переносов строк, без markdown, без лишних пробелов в начале/конце).\n\nПоля:\n- doc_type: "contract" (договор) / "supplement" (допсоглашение) / "specification" (спецификация/приложение) / "other"\n- own_number: номер ЭТОГО документа, строка без лишних пробелов (или null)\n- parent_number: номер родительского договора из фраз «к Договору №...» (или null)\n- doc_date: дата в YYYY-MM-DD. «27 февраля 2026» → 2026-02-27 (или null)\n- counterparty: полное название контрагента (Заказчик/Арендатор), без сокращений (или null)\n\nПример вывода:\n{"doc_type":"supplement","own_number":"1","parent_number":"01300_2","doc_date":"2026-02-27","counterparty":"АО XXX003"}\n\nДОКУМЕНТ:\n---\n{header_text}\n---',
|
||||
true, 'Авто-создан: classify prompt v2 — LLM сам предложил'
|
||||
body = (
|
||||
"Ты — система классификации договорных документов. "
|
||||
"Проанализируй текст и верни СТРОГО ВАЛИДНЫЙ JSON ОДНОЙ СТРОКОЙ "
|
||||
"(без переносов строк, без markdown, без лишних пробелов в начале/конце).\n\n"
|
||||
"Поля:\n"
|
||||
'- doc_type: "contract" (договор) / "supplement" (допсоглашение) / "specification" (спецификация/приложение) / "other"\n'
|
||||
"- own_number: номер ЭТОГО документа, строка без лишних пробелов (или null)\n"
|
||||
'- parent_number: номер родительского договора из фразы «к Договору №...» (или null)\n'
|
||||
'- doc_date: дата в YYYY-MM-DD. «27 февраля 2026» → 2026-02-27 (или null)\n'
|
||||
"- counterparty: полное название контрагента (Заказчик/Арендатор), без сокращений (или null)\n\n"
|
||||
"Пример вывода:\n"
|
||||
'{"doc_type":"supplement","own_number":"1","parent_number":"01300_2","doc_date":"2026-02-27","counterparty":"АО XXX003"}\n\n'
|
||||
"ДОКУМЕНТ:\n---\n{header_text}\n---"
|
||||
)
|
||||
execute(
|
||||
"INSERT INTO prompts (role, name, body, is_active, notes) VALUES (%s, %s, %s, %s, %s)",
|
||||
("classify", "default-v1", body, True, "Авто-создан: classify prompt v2 — LLM сам предложил"),
|
||||
)
|
||||
""")
|
||||
|
||||
Reference in New Issue
Block a user