Legal Code
632 subscribers
1 file
87 links
Навчання програмуванню. Вирішення юридичних задач за допомогою IT-навичок. Технічний світогляд юриста.

Рекламу не пропонувати :)
Download Telegram
🍯 Как юристу заработать на автоматизации
часть 4 — финансовая формула автоматизации юриста

Обещал рассказать о джинне 🧞‍♀️, но сначала ещё немного математики. По итогам предыдущих трёх постов я предлагаю вам такую формулу финансовой оценки автоматизации работы отдельно взятого юриста:

y = hoursBefore * hourCost : (hoursAfter * hourCost + hoursWasted * hourCost + spendings)

Составляющие этой формулы описаны на веб-сайте канала. Вы там можете даже вписать свои расчётные данные и увидеть вердикт, насколько хороша будет такая автоматизация в финансовом плане. Прокомментировать это всё вы можете в "гуманитарном" чате, в "кодерском", и даже на Facebook, Axon Partners тоже запостили это.

Кто будет тестить, там вы увидите кнопку "показать удачный кейс". Она проиллюстрирует довольно неплохую, на мой взгляд, ситуацию:
💰 стоимость часа: 70 у.е. (в данном случае я подразумевал доллары, оценив час работы юриста в 70$)
кол-во часов до автоматизации: 400
⌛️ кол-во часов после автоматизации: 80
кол-во часов, затраченных на автоматизацию: 52
💸 стоимость автоматизации: 900 у.е. (важно не забыть включить сюда расходы на софт, хостинг, доменное имя и разные подписки на весь расчётный период, если таковые будут иметь место)

🌡 Получаем коэффициент: 2.761. Так как это больше единицы, это значит, что проект выходит в плюс. Кроме этого, интерфейс выведет вам другие полезные данные. И ещё есть кнопка с "плохим кейсом".

В общем, прошу потестить. Как вам оно?
🍯 Как юристу заработать на автоматизации
часть 5 — глядим не на деньги, а в свою бездну

💻 На том интерфейсе кнопка "показать плохой кейс" покажет, как вы теряете за год 3 570 долларов. Причина: автоматизация не делает вашу работу значительно быстрее, стоит ощутимо много и "съедает" ваше время.

🎽 Но нужно ли считать себя неудачником/неудачницей после этого? Зависит от того, насколько лично вы были вовлечены в эту автоматизацию, стали ли вы понимать логику алгоритмов и вычислительной техники, научились ли вы находить автоматизируемые закономерности в вашей работе, поняли ли, где и насколько компьютер может вас заменить в вашей работе, стать вашим "стажёром" или даже "джуном".

Если да — то вы приобрели современное, пока не очень распространённое знание, которое может сыграть хорошую роль в вашем юридическом будущем. Потому что ваши конкуренты уже используют разные технические решения, позволяющие им экономить своё время и снижать цены на ваши услуги. Возможно, это пока не касается некоторых специфических отраслей, таких как уголовное право. Хотя представители Сьерра-Леоне (солнечная Африка ☀️) в этом году показали обнадёживающую инновацию в сфере уголовного права/процесса, за что получили первое место на международном конкурсе HiiL, обойдя крутой проект AxDraft, который сейчас оценён больше, чем некоторые топовые украинские юрфирмы. Видите, жюри поставили выше не деньги.

🌱 Не всегда ваши первые попытки что-то автоматизировать будут удачны. Из моих трёх первых лигалинженерских проектов один был заморожен, а два других — закрыты. Но на всех трёх я научился кодить, и это теперь моя профессия. Истории известно, что люди не сразу раскрывают потенциал того знания, с которым сталкиваются. Поэтому нельзя точно назначить цену для знаний на момент их получения. 4-6 лет обучения на юрфаке на многотысячном контракте могут принести человеку меньше, чем два ивента по 10-15 баксов, на которых ему что-то западёт в душу и затем прорастёт.

💥 В эту субботу в Киеве прошёл сочный ивент — Coding 4 Lawyers. На протяжении 6 часов десятки юристов смотрели презентации о:
▫️ расширениях браузеров и как кодить прямо на чужих веб-сайтах;
▫️ написании JavaScript-кода на codepen.io, убивающего вашу рутину;
▫️ предназначении и структуре JSON;
▫️ проверке контрагентов ботом и других способах уменьшить концентрацию дичи в работе;
▫️ кодерских приёмах в праве и в чём договор должен быть похож на программу;
▫️ блокчейнизации и хэшировании;
▫️ автоматизации судебки Приватбанка;
▫️ сути лигалинженерии;
▫️ входе в айтишную профессию/экосистему.

Думаю, подробнее можно будет усмотреть здесь.
Channel photo updated
🍯 Автоматизация рутины и заработок юриста: выводы

Итак, какие выводы можно сделать из цикла постов на тему заработка от автоматизации своей рутины? У меня получились такие:

🔸 Чем более длительный период, который вы берёте за основу, тем более выгодна автоматизация. Тут простая логика: строишь дом один раз, живёшь в нём всю жизнь. Время от времени что-то отваливается, и ты чинишь, но всё равно большее время ощущается профит. Это пример так называемой инфраструктурной задачи, которая не является самоцелью, а создаёт благоприятные условия для достижения ваших истинных целей в жизни. Поэтому нет смысла требовать прибыль за первый месяц, если процесс автоматизации занял три недели.

🔸 Но у юристов отваливается чаще, чем у остальных профессий. Ведь в любой момент может измениться законодательство, повлияв на смену алгоритма автоматизации — придётся тратить ресурсы на доработку. А в худшем для вас случае банально может исчезнуть та работа, которую вы автоматизировали. И тогда архив с продуктом придётся закинуть куда-нибудь подальше. Или подумать, где ещё он может быть применён.

🔸 Ещё у автоматизации есть предел: всегда останется часть времени, которую вы не можете выкинуть из своего графика. В примерах ранее это те самые 6 минут на одну задачу. Поэтому стоит помнить, что продукт не заменит вас полностью, не выйдет вместо вас во время отпуска/больничного. Если только вы не найдёте способ даровать ему такую силу, в чём, по сути, и заключается суть истинно tech-нологичного legaltech.

🧞‍♀️ Но в любом случае у ваших опытов с автоматизацией ещё может быть нераскрытый потенциал: точка перехода к автономности. Сейчас сложно кого-то удивить тем, что компьютер быстрее человека находит искомое, быстрее считает, быстрее заполняет шаблоны. Но вы почувствуете бо́льшую силу, когда начнёте автономизировать ваши разработки, то есть когда вашему продукту не нужно будет ваше присутствие, чтобы выполнять какие-то задачи. Поэтому далее я расскажу о своём примере автономизирования при помощи чатбота.
🤖 Чатботы — пустышки: крюки да корзины

Наверняка, вы наслышаны о чатботах. Они всё чаще используются в бизнесе, в образовании, для поиска билетов и т.д. И я не раз слышал от людей что-то типа "Чатбот — это искусственный интеллект? Как он устроен?". Отвечаю.

Моё определение
Чатбот — доверенная создателю (вам) мессенджером сущность, которая в рамках интерфейса мессенджера по отношению к создателю (вам) и третим лицам занимает место собеседника, при этом способна связывать этих лиц со внешней интернет-средой по установленным мессенджером правилам.

При создании чатбота вам выдаётся токен (например, 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11), при помощи которого вы можете связать чатбота с нужным вам сервисом, как чужим, так и самописным. Например, в Telegram чатботы создаются при помощи @Botfather. Но в момент создания чатбот является пустышкой: в нём нет никакого содержания. Возможности чатботов целесообразно делить на две группы (хотя аналогичные возможности принадлежат и телеграм-аккаунтам самих людей). Условно называю их Корзина и Крюк.

🧺 Корзина
Когда появляется чатбот, он прежде всего становится одиноким слушателем в пустыне тишины. Для него большую часть времени ничего не происходит. А когда вдруг что-то происходит, он передаёт это своим подписавшимся слушателям (всем доступным или конкретному). Это и есть то, что именуется "пуш". Например, так выглядит простенький GET-запрос (его достаточно ввести в адресной строке браузера), который скидывает в корзину телеграм-чатботу текст "привет" с требованием передать его конкретному юзеру:
https://api.telegram.org/bot{TOKEN}/sendMessage?text=привет&chat_id={CHAT}, где:
🔹 вместо {TOKEN} подставляем токен чатбота, выданный @Botfather-ом;
🔹 вместо {CHAT} подставляем id чата, который был создан с этим чатботом интересующим нас юзером.

🏹 Крюк
Также чатботу можно подключить вебхук (от англ. webhook, где "hook" пришло от hooking в информатике, а буквально в конечном итоге переводится как "крюк"). Это означает, что все попадающее в чатбота со стороны юзеров-собеседников будет отправляться на указанный вами адрес в Интернете. Там эти запросы уже должен поджидать ваш скрипт, который с ними сделает то, что вам нужно. Этот же скрипт может вернуть некие данные в корзину чатбота, то есть "пропушить" в ответ.

Собственно, процесс программирования чатбота и заключается в том, чтобы на вашем сервере принимать от него (а точнее, от пишущих ему людей) входящие запросы (текст, файлы, картинки), обрабатывать их по нужной вам логике (NLP-алгоритмами, нейросетями, простым деревом решений, в общем, как хотите) и возвращать ответы. Причём можно возвращать как конкретному собеседнику чатбота, так и всем собеседникам. А сам чатбот является пустышкой, бессодержательным посредником между армией юзеров и вашими скриптами/алгоритмами, которые и должны, если вам этого хочется, изо всех сил имитировать "разум", "интеллект" и "эмоции". 🎅

Но почему тогда я разделяю эти возможности на две группы, если это составляющие единого процесса "запрос — ответ"? Да потому, что на практике можно использовать только одну возможность — "корзину", что я и делаю. Об этом расскажу дальше.

📑 Документация API чатботов Telegram
🙋‍♀️ Элина — чатбот-доносчик или чат-лог

Подзаголовок: как сделать чатбота, который будет полезен тем, что он тебе пишет, а ты ему нет.

За три года я сделал несколько разных сервисов, которыми приходится пользоваться другим людям. На этих сервисах есть формы по типу "оставить отзыв", "сообщение админу" или просто мониторинг активности юзеров. Один из них — наша база знаний в Axon Partners (далее — БЗ). В ней есть поле поиска результатов. Когда любой юзер вводит в поиск нечто, на что БЗ выдает ноль результатов или мало результатов, данные об этом событии сохраняются в отдельную таблицу базы данных.

И чтобы не лазить туда вручную с некоторой периодичностью (а значит — нечасто), я решил создать чатбота в Телеграме, назвать его Элиной и соорудить следующую штуку:
▫️ добавляем в эту таблицу колонку "wasChecked", значение по умолчанию — "no";
▫️ создаём на сервере cron-задачу с периодом срабатывания 10 минут, эта задача запускает скрипт, например, "checkBadRequestsLog.php";
▫️ этот скрипт выгружает из таблицы все строки, где наша колонка "wasChecked" равна "no", обрабатывает их, формируя текстовый пакет такого вида:
Неудавшихся запросов в БЗ – 2:
"proposal Каліфорнія" от Сергей Шевч., результатов 1;
"Estonia NDA" от Катя Нест., результатов 0.
▫️ далее отправляет этот текст чатботу (т.е. пушит) примерно тем образом, что я показывал выше;
▫️ и в конце ставим этим строкам отметку "yes" в колонке "wasChecked", чтобы через 10 минут эта информация не прилетела нам снова.

Вот и всё. Вышеописанное я повторил для 4-5 разных сервисов и один чатбот держит меня в курсе важных событий в разных точках. Если мои юзеры будут бедствовать или начнётся хакерская активность, которую смогут детектировать мои скрипты, я об этом узнаю быстро, ведь для этого достаточно быть онлайн в Телеграме. Такой механизм можно прикрутить почти ко всему, у чего есть API или что можно вменяемо парсить.

Вот поэтому я и полюбил метафору с корзиной 🧺, в которую сыплются плоды 🍎 (и личинки 🐛) с выращенных мной деревьев. Берите на вооружение. :)

Лигалинженеры, юзаете ли вы что-то подобное? Можем обсудить в чате.
​​🍎🍏 Как задать два вопроса в одном

Во многих лигалтек-решениях нам нужно строить алгоритм, задающий вопросы клиенту или другому собеседнику (далее — юзер). Нередко это происходит в чатботе.

🐢 Правилом хорошего тона (а также условием хорошей конверсии) является составление алгоритма таким образом, чтобы юзер совершал как можно меньше лишних действий. Например, не нужно спрашивать его номер телефона дважды, когда можно с первого раза сохранить эту информацию в привязке к аккаунту.

И разумеется, нужно оптимизировать порядок вопросов таким образом, чтобы не вытягивать из юзера те ответы, которые при некоторых дальнейших условиях могут не понадобиться. Но кроме этого, есть ещё один неочевидный приём, позволяющий сократить количество утомляющих ситуаций "вопрос-ответ".

1️⃣ Например, у нас может возникнуть ситуация такого типа:

вопрос А. Есть ли у вас ФЛП?
ответ А1. да
ответ А2. нет

вопрос Б (если был дан ответ А1). Он находится на 3-й группе налогообложения?
ответ Б1. да, на 3-й
ответ Б2. нет, не на 3-й

По результатам этого диалога мы заполняем свои переменные userHasFLP ( true / false ) и isTaxGroup3 ( true / false ), каждая заполняется в "своём", отведённом для этого вопросе.

2️⃣ Но того же результата можно достичь всего одним вопросом:

вопрос. Есть ли у вас ФЛП, и на какой группе налогообложения?
ответ 1. есть, 3-я группа
ответ 2. есть, не 3-я группа
ответ 3. нету

Как заполняются переменные в обоих сценариях, смотрите на схеме ниже. Думаю, в чатботе такой подход сделал бы этот участок более приятным для юзера, особенно в условиях, когда диалог приходится запускать заново.
🥅 Добавим немного интерактива в монолог?

// код (JavaScript):
let a = 5;
let b = 2;
let c = a + a;
let x = c / b;
let y = b-1;

// выводим в консоль:
console.log(x);

Вопрос:
каково значение переменной x?
x = ...
Anonymous Poll
3%
10
89%
5
2%
55
6%
27.5
5️⃣ Правильный ответ — 5. И немного о приведении типов.

В проектах программирующих на JavaScript юристов часто будут возникать ситуации с проблемой приведения типов. Поэтому об этом важно знать.

Понимаю тех, кто выбрал 27.5. Ведь моё указание на JavaScript могло навести на мысль о том, что тут должно некорректно сработать приведение типа данных, и сложение "пятёрок" приведёт к результату 55.

В случае с JavaScript подобный казус возникнет, когда мы получим в переменной не само число, а его строковое представление. То есть не 8, а '8'. Например, '8'+5 будет равно 85. И 8+'5' будет тоже равно 85.

Где можно внезапно получить строковое представление числа и нарваться на такую ошибку? Например, когда мы парсим текст в поисках подстрок с цифрами. Или когда получаем число от юзера из простого поля ввода.

Чтобы избежать казуса, нужно пользоваться специальной функцией Number(). Если вы не уверены в чистоте данных, можно использовать parseInt(), но нужно чётко понимать механику работы этих функций.

А в Python строки вообще можно умножать на числа:
'га' * 3 = 'гагага'.
🐵 Как ошибаются программисты
1️⃣ Синтаксис

Программисты ошибаются часто. Точнее, часто совершают действия, которые приводят к ошибкам того или иного вида. Довольно распространены мемы о том, что кодер за полчаса создаёт кучу ошибок и затем целый день их исправляет. На разных языках программирования и в разных средах (сервер, браузер, операционная система типа Windows, iOs или Android) ошибки выглядят по-разному, приводят к разным последствиям. Но все их можно поделить на несколько больших групп.

1️⃣ Синтаксические — ошибки кодерского "правописания". Их легко совершить, легко найти, легко исправить.

Возникают, когда написанный вами код компьютер жёстко не одобряет, как правило, непосредственно перед его запуском. Дело в том, что компьютер запрограммирован исполнять ваш исходный код буквально, а для этого он его предварительно анализирует. Когда в процессе такого анализа компьютер не находит, например, нужную закрывающую скобку, точку с запятой, обнаруживает неправильно написанную команду (например, fnuction вместо function), он вынужден остановиться и объявить ошибку.

Параллель с человеком: представьте, что собеседник вам скажет "я хочу, чтобы ты напрлвивглур". Вы, скорее всего, попросите повторить. А компьютер безо всякой этики скажет прямо: "тут ошибка".

🧳 Частые примеры таких ошибок из моей практики:
1) непоставленная точка с запятой в PHP;
2) несовпадение количеств открывающих и закрывающих фигурных скобок в сложных многоуровневых блоках кода (и JS, и PHP);
3) несовпадение количеств открывающих и закрывающих круглых скобок во многовложенных конструкциях, например: Math.floor(Number($(".row_costs:eq("+i+")").text()+5);


🔎 Поиск таких ошибок весьма лёгок: компьютер сам подскажет, где и что не так. Но не всегда он тыкает прямо в больное место. Например, если вы в JavaScript напишете fnuction do_something(){ }
вместо
function do_something(){ }

то браузер Chrome выведет вам следующее:
Uncaught SyntaxError: Unexpected identifier, а подчёркивать будет do_something, а не неверно записанное fnuction. Но это не смертельно.
🐵 Как ошибаются программисты
2️⃣ Ошибки выполнения

Итак, компьютер успешно проанализировал код, и начал его выполнять. Но и теперь может произойти событие, которое приведёт к аварийной остановке. Это происходит, как правило, в пределах конкретной инструкции (грубо говоря, строчки кода), которую компьютер не может исполнить, а "переступить" через неё и пойти дальше компьютер по умолчанию не запрограммирован (этого можно добиться, читайте о try...catch). Если это происходит в браузере у вашего юзера, то, если вы не предусмотрели такой случай, он скорее всего увидит, что не происходит то, что нужно (например, не удаляется товар из корзины). Если юзер догадается открыть консоль браузера (например, кнопкой F12), то увидит описание ошибки. В ОС Windows такие ошибки — классика жанра. Критические ошибки вызывают тот самый Синий Экран Смерти.

Примеры ошибок выполнения:
▪️ арифметическая ошибка (известное деление на ноль, которое возникает, когда в переменную-делитель вписан ноль);
▪️ ошибка доступа к указанной сущности (например, вы пытаетесь распарсить JSON там, где его нет или просто обращаетесь к несуществующей переменной);
▪️ исчерпание ресурсов компьютера (например, если вы запустили рекурсию, какой-нибудь бесконечный процесс и т.д.);
▪️ до боли знакомое "память не может быть read".

🧳 Частые примеры таких ошибок из моей практики:
1) попытка обратиться к JSON-у, которого в указанной переменной нет;
2) вызов локальной переменной изнутри функции, в которую эта переменная не была передана.

🔎 Поиск таких ошибок для новичка также несложен: компьютер и в этом случае объясняет, что и где произошло. И, кроме вывода ошибок в момент их появления, уведомления о них могут записываться в специальные логи ошибок на сервере.
🐵 Как ошибаются программисты
3️⃣ Логика

🦇 Эти ошибки – чёрный лебедь программирования. Это самое страшное, что может случиться как с опытными гуру, так и неокрепшими новичками. Они – бич IT-гигантов, их наперегонки ищут хакеры и специалисты по безопасности. В каком-то смысле это даже не ошибки, ведь ваша программа выполняется, но она выполняется не так, как нужно вам или вашему клиенту. Поэтому компьютер не выделит вам строки с такими ошибками. Чуть позже я расскажу о том, как их искать в своём проекте. А сейчас несколько примеров таких ошибок, которые могут встретиться в лигалтек-проектах.

🔹 Непредсказуемые данные от юзера
Например, у вас есть поле для ввода суммы, которая подставится в текст документа. Затем ваш алгоритм должен высчитать 5% от суммы и вписать в отдельном месте. Например, юзер укажет 200 гривен, тогда алгоритм впишет 10 гривен в это место. А вы знаете ответ на вопрос, что будет, когда юзер введёт туда 0? А 000? А если -100? А если отправит пустой ответ? Всё вышеперечисленное не обязательно должно быть проявлением злого умысла. Это может произойти случайно, и ваша программа должна грамотно реагировать на подобное.

🔹 Вместо сравнения влепить присваивание
Иногда вместо оператора сравнения в условии:
if( variable == "value" ){ … }
можно не допечатать один символ:
if( variable = "value" ){ … }.
И это по факту не является синтаксической ошибкой. Значение "value" присвоится переменной "variable", и вся эта конструкция благополучно выдаст true. Ваша проверка обесценится. Если это проверка какого-нибудь пароля, токена или ключа с кукисов, то у вас серьёзная брешь в защите.

🔹 Неучтённый диапазон
Помните, на школьных уроках алгебры была тема с диапазонами, "строго больше", "нестрого больше", выколотыми точками и т.д.? Такую точку можно "выколоть" и в коде. Например, в вашем чатбот-проекте есть зависимость от времени суток. Если сообщение от юзера приходит до 10:00 утра, вы выдаёте ему решение КСУ. Если сообщение приходит с 10:01 утра, вы выдаете ему решение ВСУ. Но если оно приходит в промежуток между 10:00 и 10:01, алгоритм не попадает ни в один из сценариев и ничего не происходит.

Интересно узнать больше о логических ошибках?
Новости: устав на 71 байт и ЗНО

📑 Вчера в канале "Юрня, дно і нелогічність" я увидел новость о том, что теперь модельные уставы можно кодировать в строку на 71 символ. Если верить скриншоту, то ваш модельный устав будет выглядеть как-то так:
01000000000000000000000999000000011111990000000000009901119999999990000.
Говорят, что зарегистрировать это счастье можно здесь.

Это значит, что такой устав:
- будет занимать 71 байт на накопителе, что меньше, чем занимает словосочетание "Товариство з обмеженою відповідальністю" (75 байт);
- вы можете переслать его по SMS, пока едете в метро.

🤯 На днях прошло ЗНО, где свежие бакалавры права сражались с тестами по логике. Точнее, речь идёт о секциях "Аналитическое мышление" и "Логическое мышление" в рамках ТЗНПК. На этом канале логическое и аналитическое мышление в почёте (ведь это ключевой хардскилл для программиста, юриста и лигалинженера). Поэтому считаю своим долгом проанализировать те задания и поделиться мыслями. Также поищем разницу между этими двумя мышлениями.

А как вы считаете, отображает ли такое ЗНО нужные навыки юриста в алгоритмизации своей работы?
"Код, который пишется человеком, будет содержать человеческие ошибки."

👄 Например, делаете вы автоматический "цензор матов" (известен в народе как матфильтр) для своего проекта, где юзеры могут размещать свои тексты. И хотите литературное слово "суки" во всех падежах заменять на **** (для соблюдения неких приличий). Вот вам сразу три проблемы в этом благородном занятии.

1️⃣ По умолчанию заменяться будут не только обозначения собачек, но и веток:
"На торчащие снизу суки деревьев коммунальные службы должны обращать особое внимание".
Чтобы заставить компьютер перед бездумной заменой хотя бы с 80-процентной вероятностью определить заложенный автором смысл этого слова, нужно уже подключать более сложные алгоритмы — по сути NLP, и это отдельная тема.

2️⃣ Есть нюанс, когда вам нужно заставить алгоритм не заменять это буквосочетание в словах "сукалки" и "барсуки", но при этом заменять в ",суки", ".суки" без потери соответствующего знака. Это уже вопрос к регулярным выражениям, тоже отдельная тема.

3️⃣ Когда вы замените все формы этого слова (или, что ещё хуже, куски других слов) на ****, вы не сможете с полученным текстом проделать аналогичную операцию в обратном направлении, т.е. восстановить содержание. Это похоже на идею энтропии: смешав кетчуп и майонез, вы не сможете их разделить. Поэтому нужно позаботиться о том, чтобы сохранить в базе данных отдельно изначальную версию присланного текста и отдельно "очищенную".

🗣 На самом деле, тема NLP и регулярных выражений гораздо более связана с инновациями в праве, нежели в приведённом примере. Например, в работе с текстами судебных решений, на чём съел не одну собаку лигалтек-проект "Суд на долоні".
🛠 Что такое лигалинженер?
часть 1 — постановка вопроса и LISS 2019

⌨️ Фокус этого канала всё так же — программирование для юристов. Большая часть постов должна быть посвящена кодингу, всяким техническим приёмам, концепциям, визуализациям алгоритмов в разрезе права. И вот я уже который месяц думаю, достаточно ли этого, чтобы стать лигалинженером?

В пятницу закончилась замечательная недельная Legal Innovations Summer School. Скоро опубликую свою рефлексию на Медиуме. Сейчас же можно глянуть пост Дениса Иванова, обзор Минюста и статью Loyer.

🏛 Это событие более чем косвенно связано с обучением лигалинженеров. Только представьте, что где-то в 2020-е годы на бакалаврате вашего ВУЗа будет дисциплина примерно с такими темами:
🔹 диджитализация права: практика и перспективы;
🔹 дизайн-мышление юриста;
🔹 чатботы в работе юриста: как создать и применить;
🔹 блокчейн в праве;
🔹 фандрейзинг и монетизация лигалтек-продуктов;
🔹 возможности нейросетей и теоремы Байеса в решении правовых задач;
🔹 предиктивная аналитика;
и т.д.

🛶 Ну прям идеальное начало для входа в эту нишевую профессию! Но станут ли выпускники такого бакалаврата лигалинженерами автоматически? Для начала нужно разобраться с этим термином. Поэтому хочу узнать ваше мнение:
▪️ может ли лигалинженер не уметь кодить вовсе?
▪️ как следует понимать частицу "-инженер" в этом термине? Как умение различать sql, js, py, css и применять хоть что-то из этого? Или как умение выстраивать работу фирмы/госоргана с CRM и чатботами? Или и то, и то?

Го обсуждать.
​​Робот, как подать иск в хозяйственный суд?

🌠 Иногда кодинг представляется несколько романтизированно: ведь ты можешь создавать самостоятельные мирки, живущие по придуманным тобой законам. И, поддаваясь азарту, начинаешь мечтать о создании чего-то великого. Ну или хотя бы некоего виртуального помощника, распознающего твои вопросы и дающего релевантные ответы.

🏛 Например, задаёшь ты ему вопрос "Как подать иск в хозяйственный суд?", а он, не зная ответ напрямую, выдаёт структурированный ответ на базе соответствующих статей процессуального кодекса.

🛤 Однако, когда хочешь перейти от мечт к действию, задаёшься холодными вопросами "как это работает?", "с чего начать?". Ок, сделаем эскиз логики происходящего с человеческой точки зрения. В нашем мозгу это происходит очень быстро, а при алгоритмизации нужно уметь выделять и выстраивать стадии, где результат первой стадии становится отправной точкой (а иногда и ресурсами) для следующей и т.д.

1️⃣ Начинаем с того, чтобы детектировать сам вопрос (см. жёлтые стрелки на картинке). Можем презюмировать, что в конце вопроса стоит "?". Конечно, бывает всякое, но мы пока что тяжёлые случаи опустим.

2️⃣ Далее нужно установить тип вопроса ("как", "что", "где", "когда", "истинно ли" и т.д.), т.е. какой род данных вопрошающий хочет получить ("способ", "объект", "место", "время", "да/нет" и т.д.). (см. жёлтые стрелки на картинке)

3️⃣ Теперь нужно установить наличие и характер данных в самом вопросе. То есть тупо распознать слова. В нашем случае это "подать", "иск", "в", "хозяйственный", "суд".

4️⃣ Ищем связи между словами, выявляя термины и отношения между ними. Здесь должно стать ясно, что:
🔸 "подать иск" — это целостное действие (правовой термин),
🔸 "хозяйственный суд" — целостное явление (правовой термин),
🔸 "в" связывает действие с явлением (образуя правовую ситуацию).
На этой стадии нужно исходить из типа языка. Например, украинский и русский — это синтетические языки, а английский — преимущественно аналитический. Работа с ними строится по-разному. Хотя на картинке видно, что конечная цель вполне достижима для обоих типов.

5️⃣ Теперь идём к общего к частному. Если презюмируем, что ответ на вопрос должен браться из законодательства, ищем там. "хозяйственный суд" + "иск" должны вывести нас (например, чисто контекстуально) на конкретный кодекс (для начала берём его как наиболее "сильный" и обширный источник), действие "подать иск" — на его конкретные главы, а тип вопроса вместе с выявленной нами правовой ситуацией позволяет сфокусироваться на двух нужных статьях (для полноты ответа можно задействовать и статью 170). Градус сложности происходящего тут резко возрастает, ведь компьютер должен, по сути, сопоставить смыслы в вопросе и в тексте закона, выявить соотвествие между ними. Если текст закона не был предварительно размечен, то тут начинается грязное NLP. И здесь теоретически можно испытать несколько алгоритмов машинного обучения, с разными особенностями. Но вам придётся решить, будет компьютер мыслить категориями вероятностей (например, при помощи нейросетей или теоремы Байеса) или же будет ездить по дедуктивным рельсам, упираясь в тупики лингвистической неопределённости.

6️⃣ Далее начинается ещё более утончённая процедура, которая не уместится в этот пост. Ведь мы хотим получить не просто текст статей, а структурированный ответ, не так ли?

Продолжать эту тему? 🧐
🖇 Машиночтение немашиночитабельного закона
часть 2: наша первая гипотеза

Итак, давайте подумаем: чему нужно научить робота, чтобы он на поставленный вопрос готовил структурированный, не перегруженный лишней информацией ответ из статей закона?

Не погружаясь в теорию и опыт компьютерной лингвистики (мы же хотим научиться алгоритмизировать, а не брать готовые решения?), предположим следующее:

🔹 Нужно выделять в тексте предложения (sentences) и оценивать их. В законодательстве предложение часто содержит некоторую идею (ситуацию, правоотношение, право, обязанность и т.д.), и выше среднего вероятность, что следующее предложение будет содержать уже другую идею. Робот должен оценивать каждое предложение отдельно. И не выдавать те предложения, которые "не подходят".

🔹 В каждом предложении нужно найти слова (и их производные формы), которые присутствуют в поставленном вопросе. Например, для нашего вопроса "як подати позов до господарського суду" это будут такие формы:
▫️ подати, подавати (можно добавить ещё подав [позивач], подала [особа]);
▫️ подання, поданню, поданням, поданні;
▫️ позов, позову, позовом, позові;
▫️ суд, суду, судом, суді.
Для полноты анализа можно ещё докинуть это:
▫️ позовний, позовного, позовному, позовним + позовна, позовної, позовній, позовну, позовною + позовне;

🔹 Что касается слова "господарський", то искать его здесь не надо (если мы уже находимся в нужном процессуальном кодексе). То есть на более ранней стадии нужно было заключить, что это слово является определяющим для выбора закона, но не выбора норм в нём. Служебные слова "як" и "до" мы пока тоже опустим.

Ну а дальше можно действовать по-разному. Простенький подход, который первый пришёл в голову — тупо подсчитать найденные слова/корни в предложениях, и выбрать предложения, где находок больше.

Сработает ли это? 🧐
1. Это наша гипотеза (предположение, надежда, ожидание и т.д.).
2. Значит, её нужно проверить.
3. Значит, напишем алгоритм, который поможет её проверить (ну или хотя бы оценить конкретно в этом кейсе).

Кодинг мне нравится тем, что любую дурную мысль, если она поддаётся логическому изложению, можно проверить на практике и даже извлечь из неё пользу.
Оставайтесь с нами. 🎷
🖇 Машиночтение немашиночитабельного закона
часть 3: проверка первой гипотезы

🎯 Итак, я начал проверять гипотезу на практике. Сначала предельно уточнил её, что важно технически:
"Ожидается, что ответом на поставленный вопрос будет предложение, которое содержит как минимум по одному слову, принадлежащему каждой из трёх групп слов, состоящих из неслужебных слов в поставленном вопросе и некоторых производных от них (далее — ключевые слова)".

🍽 Далее готовлю алгоритм:

1. Скопировал текст кодекса в переменную.

2. Сделал три массива для каждого из ключевых слов вопроса. Это нужно, чтобы удостовериться, что в найденном предложении есть как минимум по одному слову из каждой "словесной группы". Дополнительно добавил форму "подається", так как в этом состоянии глаголы часто используются в текстах законов.

3. Для определения "границы предложения" использую регулярку /(?<=\D)\./. То есть наш робот будет считать, что точка стоит в конце предложения, если перед ней находятся "нецифры". Это грубое допущение, но для наших целей пока сойдёт. ?<= — это квантификатор, о них надо будет рассказать отдельно.

4. Для поиска ключевых слов использую паттерн регулярки '(?<![а-яіїє])'+текущее слово+'(?![а-яіїє])'.

🎳 Наметим KPI для алгоритма:
1.
обязательно (на мой взгляд) должен найти предложения из ч. 1 ст. 171, ч. 1 ст. 172, ч. 2, 3 ст. 162, ч. 1, 2 ст. 164 ХПК Украины;
2. допускаются находки других предложений по теме, например из ч. 1 ст. 173, ч. 3, 5 ст. 164;
3. не должно найти ничего лишнего.

Алгоритм нашёл 46 предложений, которые удовлетворяют требованиям гипотезы.

🔬 Оценим по нашему KPI:
1.1.
алгоритм нашёл:
ч. 2 ст. 162 (№28 в списке находок), ч. 3 ст. 162 (№ 29), ч. 1 ст. 171 (№ 30)

1.2. алгоритм не нашёл:
ч. 1 ст. 172, ч. 1, 2 ст. 164.

2. дополнительных полезных находок нет.

3. алгоритм нашёл много лишнего, а именно 43 предложения.

🧪 Делаем вывод. Эта гипотеза:
1) недостаточно точна, ведь алгоритм нашёл примерно половину из искомого;
2) поверхностна, ведь намеченный "критерий ответоспособности" слабо соотносится со смыслом искомого.

🙂 Для тех, кто дочитал сюда: протестировать прототип можно ЗДЕСЬ.

🤷‍♂️ Примерно так и выглядят некоторые лигалтек-эксперименты. Имею некоторые идеи, как эту гипотезу улучшить. А что думаете вы? Продолжать эту тему?
​​✂️ Зачем юристам регулярки?

На тему регулярок здесь ещё не было постов, только упоминания: №1, №2. И перед тем, как продолжить нашу тему, хочу остановиться на них подробнее.

🏛 Представьте, что вам нужно просмотреть в кодексе все предложения со словом "суд", но при этом вас не интересуют такие слова, как "судебный", "досудебный" и т.д. Что бы мы сделали, используя стандартный Ctrl+F?

Первое, что приходит в голову — искать по каждому падежу отдельно, но с нюансами:
1) именительный и винительный — "суд " (с пробелом, чтобы избежать "судебный" и "досудебный");
2) родительный — "суда";
3) дательный — "суду";
4) творительный — "судом";
5) предложный — "суде " (с пробелом, чтобы избежать "судебный" и "досудебный").

🎢 То есть 5 раз мы меняем слово и проходим по всему тексту. А затем осознаём, что слово "суд" и "суде" могут также находиться не только перед пробелом, а и перед точкой (.), запятой (,), точкой с запятой (;) и двоеточием (:). И вместо 5 прохождений получаем 13: наши 5 + "суд.", "суд,", "суд;", "суд:" + "суде.", "суде,", "суде;", "суде:".

Гемор? Гемор. И вот тут появляются регулярки.
Вот как сделать то же самое всего за один раз:
✂️ /((суд|суде)(\s|\.|,|;|:)|суда|суду|судом)/gi

Или даже так:
✂️ /(?<![а-яєіїґ])суд(|а|у|ом|е)(?![а-яєіїґ])/gi

Вторая регулярка круче тем, что не пропустит слово "судомы". Но она может работать не во всех браузерах. Однако можно и первую допилить для этого.

📕 Сделал для вас такой справочник на базе слова "суд":
https://legaltech.org.ua/legalcode/regexp
​​🖇 Машиночтение немашиночитабельного закона
часть 4: углубление гипотезы и проверка

Как можно развить гипотезу и улучшить лежащее в её основе решение? Надо рассмотреть, чем же отличаются "подходящие" и "неподходящие" предложения, а именно — за какое отличие между ними можно зацепиться технически. И оно есть: в "подходящих" предложениях ключевые слова расположены взаимно ближе.

🏃‍♂️ Введём условный термин – "расстояние".
В предложении "Суд работает до обеда":
1) слово "суд" находится на расстоянии 1 до слова "работает", на расстоянии 3 до слова "обеда";
2) и наоборот, слово "обеда" находится на расстоянии 3 до слова "суд".

Итак, я выдвигаю новую гипотезу:
Предложение, возможно, подходит тогда, когда ключевые слова находятся на расстоянии не более 5 друг от друга (далее — max_distance).

Проверяем. Для этого я усовершенствовал прототип, добавив блок кода с такой логикой:
1) взять предложение, в котором есть все 3 ключевые слова (напомню, в прошлый раз этих предложений вышло 46);
2) убрать из него знаки препинания и превратить его в массив слов, используя метод .split(" ");
3) пройтись циклом по массиву и зафиксировать позиции, на которых находятся ключевые слова данного предложения;
4) вычислить расстояния между всеми словами (а именно между 1-м и 2-м, 2-м и 3-м, 1-м и 3-м), отрицательные значения фиксим функцией Math.abs();
5) если все три расстояния меньше нашей константы max_distance, тогда это предложение выводим в список результатов.

Результатов вышло 4. Среди них был только один однозначно желанный. Но среди трёх других были нормы насчёт обеспечения иска ("забезпечення позову"), что близко к тематике поставленного вопроса.

Увеличил max_distance с 5 до 7. Результатов стало 9, и среди них появился второй однозначно желанный. Остальные также касаются обеспечения иска.

Неидеально, но уже ощутимо лучше. Вот прототип.