diff --git a/CHANGELOG.md b/CHANGELOG.md index 59f9dbc..81c98b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Не выпущено +- Backend обновлён до `0.10.3`: запрос о налоге на прибыль поднимает действующий + Налоговый кодекс; релевантность текста и названия оценивается раздельно. - Backend обновлён до `0.10.2`: действующие документы ранжируются выше, а утратившие силу — после остальных; из лаборатории удалён пустой блок фрагмента. - Backend обновлён до `0.10.1`: поисковая выдача по регистрации больше не diff --git a/README.md b/README.md index 6be416c..2e4cf24 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,13 @@ Telegram-бот — только часть рабочего окружения ## Текущее состояние Сейчас реализованы Telegram-бот-секретарь версии `0.2.2` и backend версии -`0.10.2`. Поиск расширяет аббревиатуры организационно-правовых форм и поднимает -положение о регистрации 2026 года, закон об обществах и ГК КР для запросов об -открытии ОсОО/ЖЧК. +`0.10.3`. Поиск расширяет аббревиатуры организационно-правовых форм и поднимает +действующий Налоговый кодекс для запросов о налоге на прибыль. | Компонент | Версия | Состояние | |---|---:|---| | Telegram-бот | `0.2.2` | на Synology работает `0.2.1`; обновление после слияния | -| Backend | `0.10.2` | расширение терминов и приоритет действующих актов о регистрации ОсОО/ЖЧК | +| Backend | `0.10.3` | приоритет кодекса для темы налога на прибыль; тематический поиск ОсОО/ЖЧК | | Frontend | — | ещё не создан | | Сбор и обработка правовых данных | `0.8.0` | добавлены relevance set и оценка выдачи | | RAG и база знаний | — | ещё не созданы | @@ -60,4 +59,4 @@ python3 -m unittest discover -s tools/telegram-bot -v --- -Акылдаш · Telegram-бот v0.2.2 · Backend v0.10.2 · Frontend — не создан +Акылдаш · Telegram-бот v0.2.2 · Backend v0.10.3 · Frontend — не создан diff --git a/backend/README.md b/backend/README.md index b7993c5..9713de9 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,6 +1,6 @@ # Backend Акылдаш -Версия: `0.10.2` +Версия: `0.10.3` Первая backend-область проекта — загрузка правовых документов из официального Open Data API ЦБД Минюста Кыргызской Республики. Код расположен в @@ -240,4 +240,4 @@ PYTHONPATH=backend python3 -m search.query "ЖЧК ачуу тартиби" --la --- -Акылдаш · Backend v0.10.2 · Frontend — не создан +Акылдаш · Backend v0.10.3 · Frontend — не создан diff --git a/backend/search/api.py b/backend/search/api.py index 0014984..7659d50 100644 --- a/backend/search/api.py +++ b/backend/search/api.py @@ -17,7 +17,7 @@ from search.reviews import ReviewSnapshots, ReviewStore API_VERSION = "v1" -SEARCH_ALGORITHM_VERSION = "search-4" +SEARCH_ALGORITHM_VERSION = "search-5" LANGUAGES = {"ru", "ky"} CODE = re.compile(r"^[0-9]+$") MAX_PAGE_SIZE = 100 diff --git a/backend/search/minjust_opensearch.py b/backend/search/minjust_opensearch.py index 196701f..fa8f9a4 100644 --- a/backend/search/minjust_opensearch.py +++ b/backend/search/minjust_opensearch.py @@ -17,7 +17,7 @@ from typing import Iterator from search.catalog import authority_codes, legal_force_code, source_code -APP_VERSION = "0.10.2" +APP_VERSION = "0.10.3" LANGUAGES = {"ru", "ky"} DEFAULT_MAPPING = Path(__file__).with_name("minjust-fragments-index.json") diff --git a/backend/search/query.py b/backend/search/query.py index c06d5df..ce95748 100644 --- a/backend/search/query.py +++ b/backend/search/query.py @@ -23,6 +23,7 @@ LEGAL_FORM_ALIASES = { }, } COMPANY_REGISTRATION_DOCUMENTS = (("230044970", 3000), ("667", 2000), ("4", 1000)) +TAX_PROFIT_DOCUMENTS = (("112340", 3000),) def query_variants(language: str, query: str) -> list[str]: @@ -34,6 +35,26 @@ def query_variants(language: str, query: str) -> list[str]: return list(dict.fromkeys(variants)) +def document_priority_clauses(language: str, documents: tuple[tuple[str, int], ...]) -> list[dict]: + status = {"ru": "Действует", "ky": "Күчүндө"}[language] + return [ + { + "constant_score": { + "filter": { + "bool": { + "filter": [ + {"term": {"document_code": code}}, + {"term": {f"status_{language}": status}}, + ] + } + }, + "boost": boost, + } + } + for code, boost in documents + ] + + def company_registration_clauses(language: str, query: str) -> list[dict]: non_registration_context = { "ru": (r"\bсч[её]т\w*", r"\bбанк\w*", r"\bфилиал\w*", r"\bпредставительств\w*"), @@ -66,38 +87,28 @@ def company_registration_clauses(language: str, query: str) -> list[dict]: if not any(re.search(pattern.format(form=forms), normalized_query) for pattern in patterns): return [] - status = {"ru": "Действует", "ky": "Күчүндө"}[language] - # ponytail: curated legal mapping; replace with a reviewed intent catalog when coverage expands. - def clause(document_code: str, boost: int) -> dict: - return { - "constant_score": { - "filter": { - "bool": { - "filter": [ - {"term": {"document_code": document_code}}, - {"term": {f"status_{language}": status}}, - ] - } - }, - "boost": boost, - } - } + return document_priority_clauses(language, COMPANY_REGISTRATION_DOCUMENTS) - return [clause(code, boost) for code, boost in COMPANY_REGISTRATION_DOCUMENTS] + +def tax_profit_clauses(language: str, query: str) -> list[dict]: + if language != "ru" or not re.search(r"\bналог\w*\s+(?:на\s+)?прибыл\w*\b", query.casefold()): + return [] + # ponytail: exact topic anchor; expand only with verified tax-code sources. + return document_priority_clauses(language, TAX_PROFIT_DOCUMENTS) def build_search_query(language: str, query: str) -> dict: - intent_clauses = company_registration_clauses(language, query) + registration_clauses = company_registration_clauses(language, query) + intent_clauses = [*registration_clauses, *tax_profit_clauses(language, query)] + operator = "OR" if registration_clauses else "AND" full_text = [ - { - "multi_match": { - "query": variant, - "fields": [f"document_name_{language}^4", f"text_{language}"], - "type": "cross_fields", - "operator": "OR" if intent_clauses else "AND", - } - } + clause for variant in query_variants(language, query) + for clause in ( + {"match": {f"text_{language}": {"query": variant, "operator": operator}}}, + {"match": {f"document_name_{language}": {"query": variant, "operator": operator, "boost": 4}}}, + {"match_phrase": {f"text_{language}": {"query": variant, "boost": 3}}}, + ) ] planned = {"should": [*full_text, *intent_clauses], "minimum_should_match": 1} return {"bool": planned} diff --git a/backend/search/review.html b/backend/search/review.html index 51254de..f5d4316 100644 --- a/backend/search/review.html +++ b/backend/search/review.html @@ -117,7 +117,7 @@

Документ

Короткое знакомство

- +