aiw-ru 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiw_ru-2.0.0/.gitignore +234 -0
- aiw_ru-2.0.0/CHANGELOG.md +169 -0
- aiw_ru-2.0.0/LICENSE +22 -0
- aiw_ru-2.0.0/NOTICE.md +29 -0
- aiw_ru-2.0.0/PKG-INFO +337 -0
- aiw_ru-2.0.0/README.md +303 -0
- aiw_ru-2.0.0/pyproject.toml +124 -0
- aiw_ru-2.0.0/skills/antiplagiat/SKILL.md +158 -0
- aiw_ru-2.0.0/skills/avoid-ai-writing-russian/SKILL.md +320 -0
- aiw_ru-2.0.0/skills/avoid-ai-writing-russian/references/chat.md +74 -0
- aiw_ru-2.0.0/skills/avoid-ai-writing-russian/references/profiles.md +101 -0
- aiw_ru-2.0.0/skills/avoid-ai-writing-russian/references/review.md +63 -0
- aiw_ru-2.0.0/skills/avoid-ai-writing-russian/references/rhetoric.md +141 -0
- aiw_ru-2.0.0/skills/avoid-ai-writing-russian/references/sentences.md +100 -0
- aiw_ru-2.0.0/skills/avoid-ai-writing-russian/references/structure.md +70 -0
- aiw_ru-2.0.0/skills/avoid-ai-writing-russian/references/typography.md +33 -0
- aiw_ru-2.0.0/skills/avoid-ai-writing-russian/references/vocabulary.md +211 -0
- aiw_ru-2.0.0/src/aiw_ru/__init__.py +74 -0
- aiw_ru-2.0.0/src/aiw_ru/__main__.py +3 -0
- aiw_ru-2.0.0/src/aiw_ru/antiplagiat.py +360 -0
- aiw_ru-2.0.0/src/aiw_ru/categories.py +118 -0
- aiw_ru-2.0.0/src/aiw_ru/cli.py +1087 -0
- aiw_ru-2.0.0/src/aiw_ru/compat.py +145 -0
- aiw_ru-2.0.0/src/aiw_ru/data/models.json +124 -0
- aiw_ru-2.0.0/src/aiw_ru/detect.py +1058 -0
- aiw_ru-2.0.0/src/aiw_ru/features.py +121 -0
- aiw_ru-2.0.0/src/aiw_ru/lexicon.py +1013 -0
- aiw_ru-2.0.0/src/aiw_ru/models.py +353 -0
- aiw_ru-2.0.0/src/aiw_ru/py.typed +0 -0
- aiw_ru-2.0.0/src/aiw_ru/skills.py +167 -0
- aiw_ru-2.0.0/src/aiw_ru/text.py +508 -0
- aiw_ru-2.0.0/src/aiw_ru/types.py +73 -0
- aiw_ru-2.0.0/src/aiw_ru/validate.py +770 -0
aiw_ru-2.0.0/.gitignore
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# Шаблон GitHub для Python: https://github.com/github/gitignore/blob/52f5a2bf5785a851e69936a6f5c54a734b828046/Python.gitignore
|
|
2
|
+
# Проектные правила — в конце файла.
|
|
3
|
+
|
|
4
|
+
# Byte-compiled / optimized / DLL files
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[codz]
|
|
7
|
+
*$py.class
|
|
8
|
+
|
|
9
|
+
# C extensions
|
|
10
|
+
*.so
|
|
11
|
+
|
|
12
|
+
# Distribution / packaging
|
|
13
|
+
.Python
|
|
14
|
+
build/
|
|
15
|
+
develop-eggs/
|
|
16
|
+
dist/
|
|
17
|
+
downloads/
|
|
18
|
+
eggs/
|
|
19
|
+
.eggs/
|
|
20
|
+
lib/
|
|
21
|
+
lib64/
|
|
22
|
+
parts/
|
|
23
|
+
sdist/
|
|
24
|
+
var/
|
|
25
|
+
wheels/
|
|
26
|
+
share/python-wheels/
|
|
27
|
+
*.egg-info/
|
|
28
|
+
.installed.cfg
|
|
29
|
+
*.egg
|
|
30
|
+
MANIFEST
|
|
31
|
+
|
|
32
|
+
# PyInstaller
|
|
33
|
+
# Usually these files are written by a python script from a template
|
|
34
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
35
|
+
*.manifest
|
|
36
|
+
*.spec
|
|
37
|
+
|
|
38
|
+
# Installer logs
|
|
39
|
+
pip-log.txt
|
|
40
|
+
pip-delete-this-directory.txt
|
|
41
|
+
|
|
42
|
+
# Unit test / coverage reports
|
|
43
|
+
htmlcov/
|
|
44
|
+
.tox/
|
|
45
|
+
.nox/
|
|
46
|
+
.coverage
|
|
47
|
+
.coverage.*
|
|
48
|
+
.cache
|
|
49
|
+
nosetests.xml
|
|
50
|
+
coverage.xml
|
|
51
|
+
*.cover
|
|
52
|
+
*.py.cover
|
|
53
|
+
*.lcov
|
|
54
|
+
.hypothesis/
|
|
55
|
+
.pytest_cache/
|
|
56
|
+
cover/
|
|
57
|
+
|
|
58
|
+
# Translations
|
|
59
|
+
*.mo
|
|
60
|
+
*.pot
|
|
61
|
+
|
|
62
|
+
# Django stuff:
|
|
63
|
+
*.log
|
|
64
|
+
local_settings.py
|
|
65
|
+
db.sqlite3
|
|
66
|
+
db.sqlite3-journal
|
|
67
|
+
|
|
68
|
+
# Flask stuff:
|
|
69
|
+
instance/
|
|
70
|
+
.webassets-cache
|
|
71
|
+
|
|
72
|
+
# Scrapy stuff:
|
|
73
|
+
.scrapy
|
|
74
|
+
|
|
75
|
+
# Sphinx documentation
|
|
76
|
+
docs/_build/
|
|
77
|
+
|
|
78
|
+
# PyBuilder
|
|
79
|
+
.pybuilder/
|
|
80
|
+
target/
|
|
81
|
+
|
|
82
|
+
# Jupyter Notebook
|
|
83
|
+
.ipynb_checkpoints
|
|
84
|
+
|
|
85
|
+
# IPython
|
|
86
|
+
profile_default/
|
|
87
|
+
ipython_config.py
|
|
88
|
+
|
|
89
|
+
# pyenv
|
|
90
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
91
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
92
|
+
# .python-version
|
|
93
|
+
|
|
94
|
+
# pipenv
|
|
95
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
96
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
97
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
98
|
+
# install all needed dependencies.
|
|
99
|
+
# Pipfile.lock
|
|
100
|
+
|
|
101
|
+
# UV
|
|
102
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
103
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
104
|
+
# commonly ignored for libraries.
|
|
105
|
+
# uv.lock
|
|
106
|
+
|
|
107
|
+
# poetry
|
|
108
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
109
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
110
|
+
# commonly ignored for libraries.
|
|
111
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
112
|
+
# poetry.lock
|
|
113
|
+
# poetry.toml
|
|
114
|
+
|
|
115
|
+
# pdm
|
|
116
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
117
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
118
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
119
|
+
# pdm.lock
|
|
120
|
+
# pdm.toml
|
|
121
|
+
.pdm-python
|
|
122
|
+
.pdm-build/
|
|
123
|
+
|
|
124
|
+
# pixi
|
|
125
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
126
|
+
# pixi.lock
|
|
127
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
128
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
129
|
+
.pixi/*
|
|
130
|
+
!.pixi/config.toml
|
|
131
|
+
|
|
132
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
133
|
+
__pypackages__/
|
|
134
|
+
|
|
135
|
+
# Celery stuff
|
|
136
|
+
celerybeat-schedule*
|
|
137
|
+
celerybeat.pid
|
|
138
|
+
|
|
139
|
+
# Redis
|
|
140
|
+
*.rdb
|
|
141
|
+
*.aof
|
|
142
|
+
*.pid
|
|
143
|
+
|
|
144
|
+
# RabbitMQ
|
|
145
|
+
mnesia/
|
|
146
|
+
rabbitmq/
|
|
147
|
+
rabbitmq-data/
|
|
148
|
+
|
|
149
|
+
# ActiveMQ
|
|
150
|
+
activemq-data/
|
|
151
|
+
|
|
152
|
+
# SageMath parsed files
|
|
153
|
+
*.sage.py
|
|
154
|
+
|
|
155
|
+
# Environments
|
|
156
|
+
.env
|
|
157
|
+
.envrc
|
|
158
|
+
.venv
|
|
159
|
+
env/
|
|
160
|
+
venv/
|
|
161
|
+
ENV/
|
|
162
|
+
env.bak/
|
|
163
|
+
venv.bak/
|
|
164
|
+
|
|
165
|
+
# Spyder project settings
|
|
166
|
+
.spyderproject
|
|
167
|
+
.spyproject
|
|
168
|
+
|
|
169
|
+
# Rope project settings
|
|
170
|
+
.ropeproject
|
|
171
|
+
|
|
172
|
+
# mkdocs documentation
|
|
173
|
+
/site
|
|
174
|
+
|
|
175
|
+
# mypy
|
|
176
|
+
.mypy_cache/
|
|
177
|
+
.dmypy.json
|
|
178
|
+
dmypy.json
|
|
179
|
+
|
|
180
|
+
# Pyre type checker
|
|
181
|
+
.pyre/
|
|
182
|
+
|
|
183
|
+
# pytype static type analyzer
|
|
184
|
+
.pytype/
|
|
185
|
+
|
|
186
|
+
# Cython debug symbols
|
|
187
|
+
cython_debug/
|
|
188
|
+
|
|
189
|
+
# PyCharm
|
|
190
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
191
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
192
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
193
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
194
|
+
# .idea/
|
|
195
|
+
|
|
196
|
+
# Abstra
|
|
197
|
+
# Abstra is an AI-powered process automation framework.
|
|
198
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
199
|
+
# Learn more at https://abstra.io/docs
|
|
200
|
+
.abstra/
|
|
201
|
+
|
|
202
|
+
# Visual Studio Code
|
|
203
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore that
|
|
204
|
+
# can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
205
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer, you
|
|
206
|
+
# could uncomment the following to ignore the entire vscode folder
|
|
207
|
+
# .vscode/
|
|
208
|
+
# Temporary file for partial code execution
|
|
209
|
+
tempCodeRunnerFile.py
|
|
210
|
+
|
|
211
|
+
# Ruff stuff:
|
|
212
|
+
.ruff_cache/
|
|
213
|
+
|
|
214
|
+
# PyPI configuration file
|
|
215
|
+
.pypirc
|
|
216
|
+
|
|
217
|
+
# Marimo
|
|
218
|
+
marimo/_static/
|
|
219
|
+
marimo/_lsp/
|
|
220
|
+
__marimo__/
|
|
221
|
+
|
|
222
|
+
# Streamlit
|
|
223
|
+
.streamlit/secrets.toml
|
|
224
|
+
|
|
225
|
+
# ─── aiw-ru ───
|
|
226
|
+
|
|
227
|
+
# Калибровка antiplagiat: модель и признаки фрагментов пользователя.
|
|
228
|
+
.aiw-ru.json
|
|
229
|
+
|
|
230
|
+
# Ответы агентов из поведенческих проверок и черновая запись демо.
|
|
231
|
+
evals/results/
|
|
232
|
+
docs/demo/demo-raw.gif
|
|
233
|
+
|
|
234
|
+
.DS_Store
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# История изменений
|
|
2
|
+
|
|
3
|
+
Формат — [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/), версии — [семантические](https://semver.org/lang/ru/).
|
|
4
|
+
|
|
5
|
+
## [Не выпущено]
|
|
6
|
+
|
|
7
|
+
## [2.0.0] — 2026-09-25
|
|
8
|
+
|
|
9
|
+
Стабильный выпуск 2.0. Вместе с предварительными выпусками 2.0.0rc1–2.0.0rc4 в него вошли детектор на Python и пакет `aiw-ru` на PyPI вместо TypeScript и Bun, `aiw-ru skill` для агентов без плагина, четыре необязательные модели с Hugging Face (ModernBERT, трансформер на rubert-tiny2, mini-frida и LightGBM) со справкой `models info` и сравнением `classify --all`, каталог примет по темам и сверка фактов в `validate`. Подробности в разделах этих rc в [CHANGELOG.md](https://github.com/ormeilu/avoid-ai-writing-russian/blob/master/CHANGELOG.md).
|
|
10
|
+
|
|
11
|
+
### Изменено
|
|
12
|
+
|
|
13
|
+
- Свежее демо в README: к `scan`, `validate` и `antiplagiat` добавился `classify --all`, где на правке четыре модели расходятся во мнении, в выводе видна вероятность модели. `scripts/demo.py` собирает запись terminalizer из настоящего вывода команд и сжимает gif до ширины README.
|
|
14
|
+
- Раздел «Какую модель выбрать» в карточках трансформеров на Hugging Face и в отчётах `docs/models/`: вместо сплошного абзаца попарных сравнений таблица всех моделей в порядке, в котором их выбирает aiw-ru, строка «когда брать» на каждую модель (та же, что в `aiw-ru models info`) и правило выбора. У mini-frida вместо «промежуточного варианта» её место по ROC AUC и по доле людей, принятых за ИИ.
|
|
15
|
+
|
|
16
|
+
## [2.0.0rc4] — 2026-09-25
|
|
17
|
+
|
|
18
|
+
### Исправлено
|
|
19
|
+
|
|
20
|
+
- `aiw-ru skill` не находил файлы скилла, если пакет стоял под скрытой папкой, то есть почти всегда: в `.venv` или в кэше uv (`~/.cache/uv`) при запуске через `uvx`. Выводился только SKILL.md, а `aiw-ru skill avoid-ai-writing-russian references/review.md` отвечал «других файлов нет». Скрытые файлы теперь отсеиваются только внутри папки скилла.
|
|
21
|
+
- Трансформер, ModernBERT и mini-frida падали с `AttributeError: … no attribute 'no_truncation'` на tokenizers 1.0: в нём нет методов `no_truncation` и `no_padding`, обрезку и дополнение снимают присваиванием `None`. Поддерживаются обе версии, токены и вероятности на них совпадают. Версию 1.0.0rc2 ставит, например, `uvx --prerelease allow`.
|
|
22
|
+
|
|
23
|
+
## [2.0.0rc3] — 2026-09-25
|
|
24
|
+
|
|
25
|
+
### Добавлено
|
|
26
|
+
|
|
27
|
+
- `aiw-ru classify --all` показывает вероятности всех установленных моделей рядом и пишет, выше порога они все, ниже или расходятся. В JSON у вероятности теперь есть порог (`threshold`) и признак `nearThreshold`: вероятность ближе 15 пунктов к порогу, модель не уверена; в выводе это «близко к порогу».
|
|
28
|
+
- Правило в скиллах: вероятность модели — тоже сигнал. Агент смотрит на само число, сверяет его с находками и своим чтением, при сомнении сравнивает модели через `classify --all`, не правит текст ради цифры и не пишет «написан ИИ» по одной вероятности. Повод: человеческое письмо из тестов проекта все четыре модели отнесли к ИИ.
|
|
29
|
+
- `aiw-ru models info [имя]` сравнивает модели до скачивания: ROC AUC и accuracy на test LLMTrace, доля людей, принятых за ИИ, скорость, память и размер. Числа лежат в пакете (`aiw_ru/data/models.json`), их собирает `scripts/models_catalog.py` перед выпуском. Скилл смотрит эту справку, прежде чем предложить модель.
|
|
30
|
+
- Третья необязательная модель, самая точная: дообученный RuModernBERT-small в ONNX fp32 ([toiletsandpaper/russian-ai-text-detector-modernbert](https://huggingface.co/toiletsandpaper/russian-ai-text-detector-modernbert)). Весит около 140 МБ и в несколько раз медленнее трансформера на rubert-tiny2, поэтому ставится только по имени: `aiw-ru models install modernbert`. Если она установлена, вероятность даёт она; `--model` выбирает другую.
|
|
31
|
+
- Четвёртая необязательная модель: дообученный `sergeyzh/rubert-mini-frida` в ONNX fp32 ([toiletsandpaper/russian-ai-text-detector-mini-frida](https://huggingface.co/toiletsandpaper/russian-ai-text-detector-mini-frida)). На test ROC AUC 0.991 и accuracy 0.948, между ModernBERT (0.993) и трансформером на rubert-tiny2 (0.987), но при пороге 50 % принимает за ИИ 9.5 % человеческих текстов против 7.2 % у трансформера. Весит около 130 МБ и в 3 раза медленнее трансформера, поэтому ставится только по имени: `aiw-ru models install mini-frida`. Если стоят несколько моделей, вероятность даёт первая из установленных в порядке ModernBERT, трансформер, mini-frida, LightGBM: по доле людей, принятых за ИИ на test, а не по ROC AUC. Ошибиться в человеке дороже, поэтому mini-frida рядом с трансформером работает только через `--model mini-frida`.
|
|
32
|
+
- `scan` называет файлы каталога скилла с разделами, где описаны условия и исключения найденных примет: под таблицей и в поле `catalog` JSON.
|
|
33
|
+
- После правки скилл сверяет итог с источником по утверждениям: действия, условия, уверенность, числа, причинные связи и рамка (как выглядят названные клиенты и люди до и после). Если среда позволяет, итог проверяет свежий агент по `references/review.md`: он видит только исходник, итог и задание, без рассуждений редактора, и блокирует выдумку, сдвиг смысла, потерянный довод и чужой голос. Тест на переносимость убирает предложения, которые встанут в любой чужой текст без правки. Идея из [humanizer-ru](https://github.com/ilyautov/humanizer-ru), текст свой.
|
|
34
|
+
- Раздел каталога про оторванные деепричастия и сбитое согласование, в том числе в собственных правках редактора.
|
|
35
|
+
- `aiw-ru validate` сверяет факты. Нарушения: снятая оговорка («обычно», «примерно», «около 40», «от 5000», «вероятно», «не всегда») и появившиеся имя или название (слово с заглавной не в начале предложения, латиница, аббревиатура), число словами, месяц, которых нет в исходнике. Стопку оговорок свести к одной можно, синонимы внутри семейства («обычно» → «как правило», «от 0,15 до 0,40» → «0,15–0,40») и падежи имён («Москва» → «Москве») нарушением не считаются. Предупреждения идут в новое поле `warnings` и код выхода не меняют: снятое одиночное «может», новые слова-претензии («впервые», «единственный», «всегда», «доказали») и мелкие числа словами («один», «оба»). Морфологии нет, только словари и регистр букв; идея из [humanizer-ru](https://github.com/ilyautov/humanizer-ru).
|
|
36
|
+
- Тест `tests/test_examples.py`: примеры замен в файлах скилла и эталонные ответы из `evals/golden` проходят ту же сверку фактов без нарушений и предупреждений, а плохие эталоны на ней падают. Один эталон её не прошёл (придуманные «видео и звук» и механизм с двумя каналами), он исправлен.
|
|
37
|
+
- Новые приметы в детекторе, идеи из [humanizer-ru](https://github.com/ilyautov/humanizer-ru), словари и замеры свои. «Почерк модели» (`model-idiolect`): восемь оборотов свежих моделей («подчёркивает», «важность», «что делает его…», «Это позволяет…» в начале предложения, «может привести к», «символом», «незабываемый», «важный шаг» вне шаблона «важный шаг к…»). Находка появляется, когда в тексте два разных оборота и больше. На русской части LLMTrace так пишут 1,47 % сгенерированных текстов и 0,12 % человеческих; из 22 кандидатов остались те, у кого lift не меньше 3 и доля у людей не больше 1 %. «Обвязка ответа чата» (`chat-wrapper`): предложение доработать ответ («Хотите, я сокращу его?», «Могу также подготовить более официальную версию») и подводка «Вот вариант поста:». «Текст оборван на полуслове» (`truncated`): последний абзац кончается запятой или предлогом, как ответ, оборванный на лимите длины; 1,14 % сгенерированных текстов против 0,07 % человеческих. Разделы в `vocabulary.md`, `chat.md` и `structure.md`. ROC AUC оценки правил на test LLMTrace выросла с 0,610 до 0,615 (люди против всего ИИ), доля людей с оценкой 40 и выше осталась 5,9 %. Признаки модели LightGBM не меняются: новые типы в них не входят.
|
|
38
|
+
- Разметка из чатов, которую ловит `chat-markup`: `:::writing{variant=`, `[cite: N]` и `[span_N](start_span)` из Gemini, переадресация `vertexaisearch.cloud.google.com/grounding-api-redirect`, `grok_render_citation_card_json`, `](sandbox:/mnt/data/`, `[citation:N]`, `attributableIndex`, теги `<think>`.
|
|
39
|
+
- Невидимые символы: знаки направления текста (U+200E, U+200F, U+061C, U+202A–U+202E, U+2066–U+2069) и U+180E удаляются перед поиском и делают документ подозрительным. Рядом с ивритом и арабским знак направления законен, узкий неразрывный пробел U+202F не трогается.
|
|
40
|
+
- Разделы каталога на суждение, без детектора: «Финальная мораль», «Псевдотерапия», «Запятая после обстоятельства в начале предложения». На LLMTrace эти формулы не отделяют людей от моделей: «мораль этой истории» у людей встречается не реже, самопомощь пишет «вполне нормально чувствовать…», а запятую после «В 2024 году» люди ставят чаще моделей.
|
|
41
|
+
|
|
42
|
+
### Изменено
|
|
43
|
+
|
|
44
|
+
- Каталог примет разбит на тематические файлы: `vocabulary.md`, `typography.md`, `sentences.md`, `rhetoric.md`, `chat.md`, `structure.md` и `profiles.md` вместо одного `patterns.md` на 87 КБ. Агент больше не читает каталог целиком. Кандидатов он ищет по краткому каталогу в SKILL.md (уровни P0–P2 и частые ложные находки), а файл темы открывает перед правкой находки из неё. Все файлы нужны только для полного аудита. Поводом стал слепой тест проекта [humanizer-ru](https://github.com/ilyautov/humanizer-ru): компактная инструкция дала смысловые ошибки в 1 правке из 65, полный каталог — в 15.
|
|
45
|
+
|
|
46
|
+
### Исправлено
|
|
47
|
+
|
|
48
|
+
- `aiw-ru validate` не замечал изменённый инлайн-код: бэктики вырезались до сравнения.
|
|
49
|
+
- Фрагмент находки в `scan` показывался после нормализации: «подчеркивает» вместо «подчёркивает», без невидимых символов и с исправленной подменой букв. Теперь это текст исходника как есть, и его можно найти в файле поиском.
|
|
50
|
+
- `models info` печатал число текстов test без разрядов («52521 текст»).
|
|
51
|
+
- «Играет всё более важную роль» давало две пересекающиеся находки («играет всё» и «всё более важную»), теперь одну на весь оборот.
|
|
52
|
+
- Разбор ответа в `evals/grade.py` захватывал в итоговый текст раздел «Проверка», если его текст шёл на той же строке, что и подпись (`**Проверка:** …`).
|
|
53
|
+
|
|
54
|
+
## [2.0.0rc2] — 2026-09-25
|
|
55
|
+
|
|
56
|
+
### Добавлено
|
|
57
|
+
|
|
58
|
+
- Вторая необязательная модель: дообученный русский трансформер в ONNX ([toiletsandpaper/russian-ai-text-detector-bert](https://huggingface.co/toiletsandpaper/russian-ai-text-detector-bert)). Работает на CPU через onnxruntime, без torch. Если стоят обе модели, вероятность в `scan`, `antiplagiat` и `classify` даёт трансформер. В основе `cointegrated/rubert-tiny2` в int8, файл около 30 МБ. На test русской части LLMTrace ROC AUC 0.987 и accuracy 0.945 (у LightGBM 0.943 и 0.868), человеческих текстов, принятых за ИИ, 7.2 %; замеры относятся к ревизии `a05ddce` на Hugging Face. Отчёт об обучении в `docs/models/russian-ai-text-detector-bert.md`, скрипты `scripts/train_transformer.py` и `scripts/colab_transformer.py`.
|
|
59
|
+
- `--model transformer|lightgbm` выбирает модель в `scan`, `antiplagiat` и `classify`; `aiw-ru models install [имя…]` ставит одну модель или обе.
|
|
60
|
+
|
|
61
|
+
### Изменено
|
|
62
|
+
|
|
63
|
+
- Вероятность от модели в JSON `scan` и `antiplagiat` лежит в поле `classifier` с именем модели. В 2.0.0rc1 она была в поле `model` и в `antiplagiat` затирала имя модели калибровки.
|
|
64
|
+
- `aiw-ru models --json` отдаёт `ready` (готова хотя бы одна модель) и список `models` с состоянием каждой.
|
|
65
|
+
- extra `ml` ставит и onnxruntime с tokenizers для трансформера; на Mac с Intel onnxruntime не ставится, там работает только LightGBM.
|
|
66
|
+
|
|
67
|
+
### Исправлено
|
|
68
|
+
|
|
69
|
+
- На Windows `aiw-ru scan … | head` завершался с кодом 120: закрытый канал там приходит как OSError с EINVAL.
|
|
70
|
+
- На macOS без libomp LightGBM падал с трассировкой при загрузке; теперь `aiw-ru models` просит `brew install libomp`.
|
|
71
|
+
|
|
72
|
+
## [2.0.0rc1] — 2026-09-25
|
|
73
|
+
|
|
74
|
+
### Добавлено
|
|
75
|
+
|
|
76
|
+
- Пакет `aiw-ru` на PyPI: `uvx aiw-ru scan статья.md` запускает детектор без клонирования репозитория, `pip install aiw-ru` ставит его как библиотеку (`from aiw_ru import analyze`).
|
|
77
|
+
- `aiw-ru skill` выводит скиллы, если стоит только пакет, без плагина: список, SKILL.md с командами через `aiw-ru` и файлы скилла вроде `references/patterns.md`. Скиллы входят в пакет.
|
|
78
|
+
- `aiw-ru scan --jsonl` и `aiw-ru antiplagiat --jsonl` проверяют пачку документов: на входе по JSON-строке с полем `text`, на выходе по строке результата на документ. Так корпус в сотни тысяч текстов проходит за несколько запусков, а не за сотни тысяч.
|
|
79
|
+
- Необязательная модель LightGBM поверх признаков детектора. `aiw-ru models install` скачивает её с Hugging Face ([toiletsandpaper/russian-ai-text-detector-lightgbm](https://huggingface.co/toiletsandpaper/russian-ai-text-detector-lightgbm)), `aiw-ru classify` даёт вероятность, что текст написала модель, а `scan` и `antiplagiat` показывают её рядом с оценкой, если модель установлена. Зависимости модели ставятся отдельно (extra `ml`), без них всё остальное работает как раньше. Скиллы предлагают модель пользователю и ставят её только с его согласия. На test русской части LLMTrace у модели accuracy 0.868 и ROC AUC 0.943, у оценки правил ROC AUC 0.610; человеческих текстов, принятых за ИИ, 16.5 %. Замеры относятся к ревизии `6b80454` на Hugging Face; `aiw-ru models install` берёт последнюю ревизию.
|
|
80
|
+
- `scripts/llmtrace.py` меряет детектор на русской части LLMTrace: `fetch` скачивает корпус и продолжает загрузку после обрыва связи, `eval` считает ROC AUC, accuracy и F1 по порогам и частоту каждого правила у людей и у моделей, `spans` сверяет фрагменты `antiplagiat` с разметкой по знакам. Данные и кэш ответов детектора лежат в `~/.cache/aiw-ru/llmtrace`, в репозиторий не попадают.
|
|
81
|
+
- `scripts/train.py` обучает LightGBM на признаках языка (сработавшие правила, длина предложений и слов, пунктуация, частоты служебных слов), сравнивает его с оценкой детектора и выкладывает модель на Hugging Face. Карточка модели собирается из замеров: `model-index` с результатами на LLMTrace и таблицы по жанрам, длине текста, типу задания и модели-генератору. Отчёт об обучении с описанием всех признаков и командами для воспроизведения пишется в `docs/models/russian-ai-text-detector-lightgbm.md`.
|
|
82
|
+
|
|
83
|
+
### Изменено
|
|
84
|
+
|
|
85
|
+
- Детектор, CLI, скрипты выпуска и поведенческие проверки переписаны с TypeScript на Python: пакет uv, ruff, ty, pydantic, rich. Ответы детектора те же, что у версии на TypeScript, а работает он примерно втрое быстрее.
|
|
86
|
+
- Смещения, номера столбцов и доля знаков в `antiplagiat` считаются по символам Python, а не по единицам UTF-16: эмодзи теперь один знак, а не два. Для текстов без эмодзи и других символов вне BMP ничего не изменилось.
|
|
87
|
+
- Скиллы вызывают детектор через `uv run --project ../.. aiw-ru`. Вместо Bun нужен [uv](https://docs.astral.sh/uv/), Python 3.12 или новее он поставит сам.
|
|
88
|
+
- В JSON целые значения дробных полей печатаются с точкой: `12.0`, а не `12`.
|
|
89
|
+
- Версии по PEP 440: предварительные выпуски пишутся как `2.0.0rc1` и выходят на GitHub с пометкой pre-release.
|
|
90
|
+
|
|
91
|
+
### Удалено
|
|
92
|
+
|
|
93
|
+
- Бинарники `aiw-ru` под Linux, macOS и Windows в выпусках: вместо них пакет на PyPI.
|
|
94
|
+
- API на TypeScript (`import { analyze } from "avoid-ai-writing-russian"`); вместо него `from aiw_ru import analyze`.
|
|
95
|
+
|
|
96
|
+
## [1.0.0] — 2026-09-24
|
|
97
|
+
|
|
98
|
+
### Изменено
|
|
99
|
+
|
|
100
|
+
- Невидимые символы и подмена букв больше не входят в оценку ИИ-стиля и в плотность примет у `antiplagiat`. Находки P0 и флаг «подозрительный документ» остаются. На русской части LLMTrace подмена встречается в 1,2 % человеческих документов и в 0,5 % сгенерированных: это гигиена документа, а не признак модели.
|
|
101
|
+
- Подмена букв определяется по смене алфавитов внутри слова, а алфавит слова выдаёт буква без двойника. Теперь ловятся кириллические двойники внутри английских слов и латинские в заглавных русских словах. Латинская основа с русским окончанием («PHPшник», «OKей», «CEOшный») больше не P0. Не считаются подменой латинская i в украинских словах, «х» как знак умножения между буквами и ударение латинской буквой с акутом.
|
|
102
|
+
- NOTICE.md и CITATION.cff называют данные и источники, по которым проверялись правила: LLMTrace, GigaCheck, технический отчёт Pangram 4, раздел Википедии о признаках ИИ-текста. Раздел «Ограничения» в README приводит замер на LLMTrace: сколько человеческих и сгенерированных текстов детектор отмечает.
|
|
103
|
+
- Под-скилл antiplagiat объясняет, почему в нём нет приёмов обхода: опубликованный приём закрывают и превращают в улику, а спрятанный всё равно выдаёт общий стиль.
|
|
104
|
+
|
|
105
|
+
### Исправлено
|
|
106
|
+
|
|
107
|
+
- SKILL.md антиплагиата и README писали, что `.aiw-ru.json` хранит фрагменты текста. В файле только модель и числовые признаки; текст есть в выписанных из отчёта файлах.
|
|
108
|
+
- Латинское сокращение через дефис с русским словом («HTTP-запрос», «PHP-скрипт», «OK-кодом») считалось подменой букв P0, и технический текст получал до 100/100. Теперь алфавиты сравниваются внутри каждой части слова.
|
|
109
|
+
- Один мягкий перенос (U+00AD) из Word или PDF делал документ подозрительным и давал короткому тексту 71/100. Теперь это отдельная находка P2 «Мягкие переносы» без веса в оценке.
|
|
110
|
+
- Соединитель U+200D внутри составного эмодзи и BOM в начале текста при вызове `analyze()` считались невидимыми вставками.
|
|
111
|
+
- Слова с неразрывным дефисом U+2011 или дефисом U+2010 («по-настоящему») выпадали из словарей. Теперь они читаются как обычный дефис.
|
|
112
|
+
- Разметка цитирования ChatGPT не ловилась в виде служебных символов U+E200–U+E204, голого `turn0search12` и `【4:0†source】`.
|
|
113
|
+
- Подсказка писала «1 невидимых символов».
|
|
114
|
+
- Детектор зависал на длинном слове без пробелов (вырожденный вывод модели в LLMTrace, около 18 тысяч знаков): регулярка пассива без привязки к началу слова работала кубически. Длинное отточие разбивалось на предложения квадратично. Обе регулярки теперь линейные.
|
|
115
|
+
|
|
116
|
+
## [0.3.0] — 2026-09-23
|
|
117
|
+
|
|
118
|
+
### Изменено
|
|
119
|
+
|
|
120
|
+
- Вывод `scan`, `antiplagiat` и `validate` переделан для людей: сводка сверху, находки и фрагменты таблицей по ширине терминала с переносом внутри ячеек, P0 выше P1. Цвет только в терминале, `NO_COLOR` и `FORCE_COLOR` работают.
|
|
121
|
+
- Под-скилл antiplagiat сам просит у пользователя отчёты «Антиплагиата» для калибровки, если модель не откалибрована, и предлагает несколько способов их передать: PDF отчёта или скриншоты (фрагменты агент выпишет сам), скопированные фрагменты, номера абзацев, итоговая доля.
|
|
122
|
+
- Вывод `calibrate` — таблица отчётов и сводка калибровки.
|
|
123
|
+
|
|
124
|
+
### Исправлено
|
|
125
|
+
|
|
126
|
+
- Ручной перенос строки внутри абзаца больше не считается концом предложения: у Markdown с переносами врала статистика ритма.
|
|
127
|
+
- `aiw-ru … | head` падал с EPIPE.
|
|
128
|
+
- Детектор пропускал «В заключение,» и «будущее за инновационными…», хотя каталог их описывает.
|
|
129
|
+
|
|
130
|
+
### Добавлено
|
|
131
|
+
|
|
132
|
+
- `calibrate --share N`: калибровка по итоговой доле ИИ-текста из отчёта, когда разметки фрагментов нет. Подстраивает общую строгость модели; несколько отчётов передаются парами `--doc … --marked …` и `--doc … --share …` в одном вызове.
|
|
133
|
+
- Демо в README (`docs/demo.gif`): `scan`, `validate` и `antiplagiat` на примерах из `docs/demo/`; там же запись terminalizer, из которой gif собирается заново.
|
|
134
|
+
|
|
135
|
+
## [0.2.0] — 2026-09-23
|
|
136
|
+
|
|
137
|
+
### Исправлено
|
|
138
|
+
|
|
139
|
+
- Тесты командной строки и проверка невидимых символов падали на Windows из-за путей вида `/D:/…`.
|
|
140
|
+
- Шапки SKILL.md были невалидным YAML (двоеточие внутри `description`), строгие парсеры не читали скилл.
|
|
141
|
+
- Квадратичная сложность в научном и техническом режимах: на 38 тыс. знаков проверка шла 6,8 с, теперь 0,4 с.
|
|
142
|
+
|
|
143
|
+
### Изменено
|
|
144
|
+
|
|
145
|
+
- TypeScript 7 (нативный компилятор), actions/checkout v7, j178/prek-action v2.
|
|
146
|
+
|
|
147
|
+
### Добавлено
|
|
148
|
+
|
|
149
|
+
- Хуки prek: гигиена файлов, gitleaks, Biome (линтер и форматтер), проверка типов, невидимые символы, синхронность версий, самопроверка документации детектором, сообщения коммитов на русском, тесты перед отправкой.
|
|
150
|
+
- Система выпусков: `bun run release X.Y.Z` переносит «Не выпущено» в раздел версии, обновляет версию во всех манифестах, скиллах и `CITATION.cff`, делает коммит и тег; по тегу GitHub Actions собирает бинарники под Linux, macOS и Windows и публикует выпуск с заметками из CHANGELOG.
|
|
151
|
+
- Тесты скилла: фронтматтер, ссылки, согласованность профилей и категорий детектора с каталогом, примеры из каталога.
|
|
152
|
+
- Поведенческие проверки скилла (`bun run eval`): набор случаев с автоматической оценкой ответа агента.
|
|
153
|
+
- Метаданные: расширенные шапки скиллов (ссылки на проект, апстрим, теги), манифесты плагинов Claude Code и Codex с описанием для каталога, `CITATION.cff`, `SECURITY.md`, CODEOWNERS, Dependabot.
|
|
154
|
+
- CLAUDE.md с правилами для Claude Code: проверка плагина, установка из рабочей копии, поведенческие проверки, ловушки при разработке.
|
|
155
|
+
- Тесты кода: разбиение на предложения и блоки, маскирование, стилометрия, корпус живых текстов разных жанров без ложных срабатываний, калибровка через командную строку.
|
|
156
|
+
|
|
157
|
+
## [0.1.0] — 2026-09-23
|
|
158
|
+
|
|
159
|
+
Первый выпуск русской адаптации [avoid-ai-writing](https://github.com/conorbronsdon/avoid-ai-writing) (за основу взята версия 3.36.0).
|
|
160
|
+
|
|
161
|
+
### Добавлено
|
|
162
|
+
|
|
163
|
+
- Скилл `avoid-ai-writing-russian`: режимы `rewrite`, `detect`, `edit`, договор о правке, уровни P0–P2, правило «никогда не добавляй» — на русском.
|
|
164
|
+
- Каталог русских примет: словарь в три уровня с отдельной группой канцелярита (1Б), кальки с английского, цепочки родительного падежа, пассив без деятеля, русская типографика (тире как грамматика, «ёлочки», десятичная запятая, ГОСТ-списки), социальные хуки и следы чат-ботов.
|
|
165
|
+
- Профили контекста `vak`, `docs`, `blog`, `telegram`, `business-email`, `chat` с матрицей строгости и исключениями для научного текста.
|
|
166
|
+
- Под-скилл `antiplagiat`: подготовка к проверке системой «Антиплагиат», оценка по фрагментам, чистка артефактов, оформление заимствований как цитирований.
|
|
167
|
+
- Детектор на TypeScript для Bun: команды `scan`, `antiplagiat`, `validate`, `calibrate`; нормализация невидимых символов и подмены букв с картой смещений; маскирование цитат, кода, формул, ссылок `[12]` и `[@key]`.
|
|
168
|
+
- Калибровка модели `antiplagiat` по реальным отчётам с накоплением образцов в `.aiw-ru.json`.
|
|
169
|
+
- Манифесты плагинов для Claude Code и Codex, CI на GitHub Actions.
|
aiw_ru-2.0.0/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Conor Bronsdon
|
|
4
|
+
Copyright (c) 2026 Ilya Lubenets
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
aiw_ru-2.0.0/NOTICE.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Происхождение и авторство
|
|
2
|
+
|
|
3
|
+
Проект — русская адаптация [avoid-ai-writing](https://github.com/conorbronsdon/avoid-ai-writing) Конора Бронсдона (Conor Bronsdon), распространяемого по лицензии MIT. Copyright (c) 2026 Conor Bronsdon.
|
|
4
|
+
|
|
5
|
+
Из исходного проекта взяты устройство скилла (режимы `rewrite`, `detect`, `edit`; договор о правке; уровни серьёзности P0–P2; трёхуровневый словарь; профили контекста и голоса; правило «никогда не добавляй»; самоисключение для текстов о приметах) и значительная часть каталога примет, которые переведены и переосмыслены для русского языка.
|
|
6
|
+
|
|
7
|
+
Написано заново для этой адаптации:
|
|
8
|
+
|
|
9
|
+
- каталог русских примет: канцелярит, кальки с английского, цепочки родительного падежа, русская типографика (тире как грамматика, «ёлочки», десятичная запятая, ГОСТ-списки);
|
|
10
|
+
- профили `vak`, `telegram`, `business-email`, `chat` и исключения для научного текста;
|
|
11
|
+
- детектор на Python (исходный детектор на JavaScript рассчитан на английский и сюда не переносился);
|
|
12
|
+
- под-скилл `antiplagiat` с оценкой по фрагментам и калибровкой по отчётам.
|
|
13
|
+
|
|
14
|
+
Исходный проект, в свою очередь, ссылается на работы, из которых взяты отдельные приметы: `blader/humanizer`, `brandonwise/humanizer`, `Aboudjem/humanizer-skill`, `isatimur/de-slop`, `welttowelt/stop-slop-refined`, LLM cliché highlighter Саймона Уиллисона и tropes.fyi. Благодарности им переходят и сюда.
|
|
15
|
+
|
|
16
|
+
## Данные и источники
|
|
17
|
+
|
|
18
|
+
Правила детектора проверялись и уточнялись по этим работам:
|
|
19
|
+
|
|
20
|
+
- LLMTrace: A Corpus for Classification and Fine-Grained Localization of AI-Written Text (Irina Tolstykh, Aleksandra Tsybina, Sergey Yakubson, Maksim Kuprashevich; Findings of EMNLP 2026, [arXiv:2509.21269](https://arxiv.org/abs/2509.21269)). Корпус текстов людей и моделей на русском и английском, [датасет](https://huggingface.co/datasets/iitolstykh/LLMTrace_classification) под лицензией Apache 2.0. На русской части тестового набора (21 417 человеческих текстов и 14 064 сгенерированных) мы мерили, как часто правила срабатывают на людях. Отсюда новое правило подмены букв и решение не учитывать технические отпечатки в оценке. Данные в репозиторий не входят: человеческие тексты корпуса собраны из сторонних источников со своими лицензиями.
|
|
21
|
+
- GigaCheck: Detecting LLM-generated Content via Object-Centric Span Localization (те же авторы, Aleksandr Gordeev, Vladimir Dokholyan; Findings of ACL 2026, [arXiv:2410.23728](https://arxiv.org/abs/2410.23728)). Работа, из которой мы узнали о LLMTrace и о разметке ИИ-фрагментов с точностью до знака.
|
|
22
|
+
- [Технический отчёт Pangram 4](https://pangram-public.s3.us-east-1.amazonaws.com/pdf/pangram_4_technical_report.pdf) (Pangram Labs, 2026). Идея держать технический мусор (невидимые символы, следы PDF и распознавания) отдельно от оценки стиля.
|
|
23
|
+
- [Wikipedia: Signs of AI writing](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing), раздел о разметке ссылок ChatGPT (`turn0search0`, `oaicite`, `contentReference`), и [описание служебных символов U+E200–U+E204](https://github.com/sanand0/openai-conversations/blob/main/private-unicode-control-characters.md) из репозитория sanand0/openai-conversations.
|
|
24
|
+
|
|
25
|
+
## Идеи из других проектов
|
|
26
|
+
|
|
27
|
+
- [humanizer-ru](https://github.com/ilyautov/humanizer-ru) Ильи Утова (Ilya Utov), лицензия MIT, Copyright (c) 2026 Ilya Utov. Из его «факт-замка» (`facts.py`) взята идея сверки фактов в `aiw-ru validate`: снятые оговорки, новые имена, числа словами, месяцы и слова-претензии. Код написан заново и без морфологии (pymorphy3 и razdel детектору недоступны): на словарях и регистре букв, со стопками оговорок и семействами синонимов.
|
|
28
|
+
|
|
29
|
+
«Антиплагиат» — товарный знак АО «Антиплагиат». Проект с ним не связан, использует только публично известные сведения о том, как устроен отчёт, и не воспроизводит его классификатор.
|