checked / search_errors_logic.py
bvd757's picture
backup
3b89fa8
import openai
from openai import OpenAI
import difflib
prompt_check_error_message = """
Ты — лингвистический анализатор. Тебе будут дано описание ошибки в тексте.
Задача:
- Если в сообщении говорится что ошибки нет или что это ошибка форматирования - верни 0
- В остальных случаях возвращай 1
Обрати внимаение, если ты бы охарактеризовал ошибку в тексте, как ошибку форматирования или оформления, то нужно вернуть 0!!!
Сообщение об ошибке:
{}
Вывод В ФОРМАТЕ JSON без комментариев:
{{"result": 0|1}}
"""
prompt_is_there_error = """
Ты — лингвистический анализатор. Тебе будут даны две текстовые строки:
1. Оригинальный текст (точно без ошибок)
2. Текст для проверки (может содержать ошибку или альтернативное написание)
Задача:
- Сравни второй текст с оригиналом на предмет наличия ошибок (орфографических, пунктуационных, грамматических)
- Если во втором тексте есть орфографическая, пунктуационная или грамматическая ошибка(отличается от оригинала и это не допустимый вариант написания) — верни 1
- Если текст совпадает с оригиналом или отличается только допустимыми вариантами написания (синонимы, альтернативная пунктуация и т.п.) или же присутствует ошибка формативарования — верни 0
Обрати внимаение, если ты бы охарактеризовал ошибку в тексте, как ошибку форматирования или оформления, то нужно вернуть 0!!!
Оригинальный текст:
{}
Текст для проверки:
{}
Вывод В ФОРМАТЕ JSON без комментариев:
{{"result": 0|1}}
"""
prompt_fix_text_gpt = """
Исправь ошибки в данном тексте. Текст в makrdown и должен в результате остаться в markdown.
Исправляй грамматические, пунктуационные и орфоргафические ошибки.
Логические, лексические, стилистические ошибки, а также ошибки форматирования (напрмер неправильные переносы строки) ошибками не считаются!!! Их исправлять не надо
Буква "е" вместо буквы "ё" не считается ошибкой.
Не исправляй ошибки форматрирования!!! В текст заранее удалены все ненужны переносы, это сделано осознанно!
Верни только текст, никаких комментариев от себя не оставляй.
### Пример 1:
input text:
Это все мое, чашки вилки и ложи
Твой ответ:
Это все мое: чашки, вилки и ложки
Теперь твоя очередь:
input text:
{}
"""
prompt_compare_get_comment = """
Ты должен писать комментарий об ошибке в тексте.
Тебе дан кусок текст, в котором есть одна или несколько ошибок и этот же кусок текста с исправленными ошибками.
Твоя задача - кратко описать все ошибки, которые есть в тексте.
Пиши кратко, не больше одного-двух предложений. Отвечай на русском языке.
### Пример 1:
original text:
"кросивую, сабаку"
corrected text:
"красивую собаку"
Твой ответ:
Орфографические ошибки: "кросивую" -> "красивую", "сабаку" -> "собаку", лишняя запятая после "красивую".
### Пример 2:
original:
"я решил пойти, в"
corrected text:
"я решил пойти в"
Твой ответ:
Опечатка: повтор пробела, лишняя запятая после слова "пойти".
Теперь твоя очередь:
original:
"{}"
corrected text:
"{}"
"""
prompt = """
Ты должен писать комментарии об ошибках в тексте.
Тебе дан кусок текст, в котором есть ошибка, контекст, в котором стоит это слово и сообщение об ошибке. Твоя задача - кратко описать суть ошибки и, если необходимо, исправить её.
Исправляй только ту ошибку, на которую указывает сообщение. Отвечай на русском языке.
### Пример 1:
Кусок текста:
"кросивую"
Сообщение об ошибке:
"Возможно найдена орфографическая ошибка."
Текст:
"...т! Сегодня я был в парке и встретил там кросивую собаку. Она повиляла хвостом и побежа..."
Твой ответ:
Орфографическая ошибка в слове "кросивую" - правильно "красивую".
### Пример 2:
Кусок текста:
" "
Сообщение об ошибке:
"Повтор пробела."
Текст:
"...ретил там кросивую собаку. Она повиляла хвостом и побежала к речке. Я решил что ..."
Твой ответ:
Обнаружен повтор пробела между словами.
Теперь твоя очередь:
Кусок текста:
"{}"
Сообщение об ошибке:
"{}"
Текст:
"{}"
"""
def get_gpt_response_openai(inp):
response = openai.ChatCompletion.create(
model="openai/gpt-4.1-mini",
messages=[
{"role": "user", "content": inp}
]
)
return response.choices[0].message['content']
def get_gpt_response_vsegpt(inp):
client = OpenAI(
api_key='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',
base_url='https://openrouter.ai/api/v1'
)
response = client.chat.completions.create(
model="openai/gpt-4.1-mini",
messages=[{"role": "user", "content": inp}]
).choices[0].message.content
return response
def get_gpt_response(inp, client_name="vsegpt"):
if client_name == "openai":
return get_gpt_response_openai(inp)
elif client_name == "vsegpt":
return get_gpt_response_vsegpt(inp)
else:
raise ValueError(f"Unsupported client: {client_name}")
def find_corrected_positions(original, corrected):
matcher = difflib.SequenceMatcher(None, original, corrected)
changes = []
for opcode in matcher.get_opcodes():
tag, i1, i2, j1, j2 = opcode
if tag != 'equal':
changes.append({
'original': (i1, i2),
'corrected': (j1, j2),
'operation': tag
})
return changes
def get_piece_of_text_bounds(s, start, end):
if start != 0: start -= 1
while start != 0 and s[start] not in [' ', "\n", '\t']:
start -= 1
if s[start] in [' ', "\n", '\t']: start += 1
if end < len(s) - 1: end += 1
while end < len(s) - 1 and s[end] not in [' ', "\n", '\t']:
end += 1
if end == len(s) - 1: end += 1
return start, end
def add_comments_to_text(text, errors, add_errors=False):
errors = sorted(errors, key=lambda x: x['end'])
shift = 0
for i, error in enumerate(errors, 1):
error['start'] += shift
error['end'] += shift
inp = f"({i})"
end_place = error["end"]
for i in range(end_place, end_place - 5, -1):
symbol = text[i - 1]
if symbol.isalpha() or symbol in ",.!?:;":
break
error["end"] -= 1
if add_errors:
inp = inp[:-1] + ' - ' + error['message'] + ')'
text = text[:error['end']] + inp + text[error['end']:]
error["end"] += len(inp)
shift += len(inp)
return text
def check_text(text, tool, mode="chat_gpt", highlight_mode=False, add_errors=False):
if mode == "tool":
return check_text_with_tool(text, tool, add_errors=add_errors)
else:
if highlight_mode:
return check_text_chat_gpt_highlight_mode(text, add_errors=add_errors)
else:
return check_text_chat_gpt(text, add_errors=add_errors)
def check_text_chat_gpt(text, fixed_text=None, add_errors=False, *args, **kwargs):
if fixed_text is None:
fixed_text = get_gpt_response(prompt_fix_text_gpt.format(text), "vsegpt")
changes = find_corrected_positions(text, fixed_text)
errors = []
for change in changes:
start_orig, end_orig = get_piece_of_text_bounds(text, change['original'][0], change['original'][1])
start_corr, end_corr = get_piece_of_text_bounds(fixed_text, change['corrected'][0], change['corrected'][1])
inp = prompt_compare_get_comment.format(text[start_orig:end_orig], fixed_text[start_corr:end_corr])
errors.append({
'start': start_orig,
'end': end_orig,
'message': get_gpt_response(inp, client_name="vsegpt"),
})
text_with_comments = add_comments_to_text(text, errors, add_errors=add_errors)
return text_with_comments, errors
def check_text_chat_gpt_highlight_mode(text, fixed_text=None, add_errors=False, *args, **kwargs):
if fixed_text is None:
fixed_text = get_gpt_response(prompt_fix_text_gpt.format(text), "vsegpt")
text = text.replace("ё", "е")
fixed_text = fixed_text.replace("ё", "е")
changes = find_corrected_positions(text, fixed_text)
bounds_init = []
for change in changes:
start_orig, end_orig = get_piece_of_text_bounds(text, change['original'][0], change['original'][1])
start_corr, end_corr = get_piece_of_text_bounds(fixed_text, change['corrected'][0], change['corrected'][1])
bounds_init.append({"start_orig": start_orig,
"end_orig": end_orig,
"start_corr": start_corr,
"end_corr": end_corr})
bounds_init = sorted(bounds_init, key=lambda x: x["start_orig"])
bounds_result = [bounds_init[0]] if len(bounds_init) > 0 else []
for bound in bounds_init[1:]:
if bounds_result[-1]["end_orig"] >= bound["start_orig"]:
bounds_result[-1]["end_orig"] = max(bounds_result[-1]["end_orig"], bound["end_orig"])
bounds_result[-1]["end_corr"] = max(bounds_result[-1]["end_corr"], bound["end_corr"])
else:
bounds_result.append(bound.copy())
errors = []
for bound in bounds_result:
orig_piece = text[bound["start_orig"]:bound["end_orig"]]
fixed_piece = fixed_text[bound["start_corr"]:bound["end_corr"]]
if "0" in get_gpt_response(prompt_is_there_error.format(orig_piece, fixed_piece)):
continue
inp = prompt_compare_get_comment.format(orig_piece, fixed_piece)
error = {
'start': bound["start_orig"],
'end': bound["end_orig"],
'message': get_gpt_response(inp, client_name="vsegpt"),
}
#if "1" in get_gpt_response(prompt_check_error_message.format(error["message"])):
errors.append(error)
text_with_comments = add_comments_to_text(text, errors, add_errors=add_errors)
return text_with_comments, errors
def check_text_with_tool(text, tool, add_errors=False):
matches = tool.check(text)
errors = []
for match in matches:
inp = prompt.format(text[match.offset:match.offset + match.errorLength],
match.message, match.context)
error_info = {
'start': match.offset,
'end': match.offset + match.errorLength,
'message': get_gpt_response(inp, client_name="vsegpt"),
}
errors.append(error_info)
text_with_comments = add_comments_to_text(text, errors, add_errors=add_errors)
return text_with_comments, errors