- BrainTools - https://www.braintools.ru -

В компании не было юриста, охраны труда, лишних рук в бухгалтерии. Их заменил один программист

Статья написана на основе интервью с Фаритом Аглиуллиным, программистом строительной компании.

В строительную компанию приходит претензия от генподрядчика: работы сделаны не так, сроки сорваны, платить не будем. Чтобы ответить, кто-то должен перелопатить сотни документов по объекту, понять, прав ли заказчик, и собрать ответ.

Штатного юриста в компании нет. На претензию отвечает человек без юридического образования. Он советуется с приходящим юристом-консультантом и нейросетью DeepSeek.

А теперь добавьте, что таких объектов десять. И на каждом свои кипы документов: договоры, письма, графики работ. Удержать это в голове невозможно, и человек начинает ошибаться там, где ошибка [1] стоит денег.

Меня зовут Фарит, мне 21 год. Я программист в строительной компании, и историю выше я в итоге переложил на нейросеть.

По первому образованию я монтажник холодильного оборудования, на программиста доучиваюсь заочно. Почти доучился в Школе 21 от Сбера, но последний уровень пройти не смог и стажировку там не получил. Диплома разработчика у меня нет.

В строительную компанию я попал не сразу программистом. Сначала работал там ещё студентом-практикантом, был и инженером, и мастером, а параллельно умел программировать. Когда компании понадобился человек под нейросети, задача досталась мне.

Дальше будет много про то, как всё устроено внутри: векторы, распознавание текста, агенты. Школьную математику [2] вспоминать [3] не придётся, сложные места я разбираю на бытовых примерах.

Некому было заниматься бумагами

Два года назад в компании не было ни специалиста по охране труда, ни постоянного юриста. Работа за них никуда не девалась, и её делали люди, которым по-хорошему было не до неё.

Прорабы вручную вели заявки на обучение [4] строителей: кого отправить учиться работе на высоте, кого на технику безопасности. Когда приходили готовые удостоверения, кто-то их сканировал, глазами вычитывал, руками вбивал в CRM, а потом складывал бумажки в папку. Каждый день кто-то отписывался, сколько человек и какие именно вышли на объект.

Отдельная боль [5] была с документами по проектам. Бухгалтеры вручную перебивали номенклатуру из накладных в 1С, строчку за строчкой. А ещё юридическая сфера: претензии от генподрядчика, с которых начался этот рассказ, разбирать тоже было некому.

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

С чего я начал

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

Оставалось два пути, дёргать GPT или Gemini напрямую либо искать что-то поудобнее. Напрямую — это отдельный аккаунт под каждую модель, оплата зарубежной картой из России и риск, что доступ в любой момент отвалится. А я уже понимал, что под разные задачи мне понадобятся разные модели: одна лучше распознаёт сканы, другая пишет тексты.

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

Так я и вышел на Polza AI. На тот момент там обещали около 200 нейронок под один API плюс агентскую систему от OpenAI. На фоне конструкторов и голого GPT это выглядело заметно интереснее, а какую модель дёрнуть под задачу, я решаю сам.

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

Работаю я с Polza только по API. Это значит, что я не захожу на сайт и ничего не нажимаю руками: из моего кода на Python уходит запрос, обратно приходит ответ.

Боты для охраны труда

Первые мои боты были про охрану труда. Их три, все работают в Телеграме, в рабочей супергруппе по объектам.

Бот первый я назову «заявщик удостоверений». Прораб пишет в группу, тегает бота, и тот по сообщению оформляет заявку: кого из строителей отправить на обучение и на какое именно. Кажется, будто иишка тут лишняя, ведь заявку можно собирать и без неё, по строгому шаблону. Но у прораба нет на это времени, он занят на стройке. Он не будет писать по форме с полями и галочками, он пишет так, как написал бы живому человеку. Вот это живое сообщение нейросеть и приводит в строгий JSON для нашей CRM по сотрудникам и их документам.

Прораб пишет всё, что ему нужно, бот сам собирает из этого карточку сотрудника и заводит её в систему 

Прораб пишет всё, что ему нужно, бот сам собирает из этого карточку сотрудника и заводит её в систему 

JSON тут можно представить как анкету, где по полям разложено, кто, на что и когда. Программе с такой анкетой работать легко, а человеку заполнять её вручную лень.

Бот второй разбирается с удостоверениями, которые приходят после обучения. Раньше их сканировали и вбивали в CRM руками. Теперь бот сам распознаёт скан и достаёт из таблицы людей и то, какое удостоверение каждый получил. Тут впервые появляется распознавание текста с картинки, но подробно про него расскажу на бухгалтерии, там оно дошло до ума.

Бот третий считает, сколько человек и кто именно каждый день на объекте. Прораб опять же пишет по-человечески, а иишка нормализует это в тот же JSON и отправляет в CRM. Совсем простой бот, один-два промпта, и готово.

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

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

Раньше на проверку по охране труда уходило около часа в день, теперь хватает минуты.

Распознавание документов для бухгалтерии

Самый показательный для меня кейс — распознавание документов для бухгалтеров. Бухгалтер не должен вручную перебивать номенклатуру из накладных и счетов-фактур в 1С, пусть это делает машина.

OCR — это распознавание текста с картинки или скана. Сфотографировали страницу книги, а на выходе получили текст, который можно копировать и искать. Только нам мало текста целиком. Из накладной надо достать нужные строки и разложить их по полям.

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

Дальше я месяц игрался: менял промпты, менял количество страниц в одном запросе, сравнивал, что вышло. Точность падает, если отправлять на распознавание несколько страниц сразу. Стоит дать две и больше, качество уже хуже. Поэтому если важна точность, отправляйте по одной странице. Денег так уходит чуть больше, но если точность критична, это того стоит.

В итоге я добился точности 99,5% на своих тестах.

Обычный счёт от поставщика

Обычный счёт от поставщика

Раньше бухгалтер вычитывал его глазами и по строчке вбивал в 1С.

А это то, что из него достаёт нейросеть. Наименование, количество, цена — каждая строка разложена по полям. Отсюда данные уходят в 1С автоматически 

А это то, что из него достаёт нейросеть. Наименование, количество, цена — каждая строка разложена по полям. Отсюда данные уходят в 1С автоматически 

Не всякий документ можно вот так отправить в облачную нейросеть, потому что в накладной есть персональные данные. Для этого есть обезличивание, когда вся личная информация перед отправкой шифруется. Фамилия, имя и отчество превращаются в условный FIO1, корреспондентский счёт в Корсчёт1, и так далее. Нейросеть работает с обезличенным документом, а настоящие данные мы возвращаем уже у себя. 

Тут логичный вопрос, зачем писать своё, если готовые решения есть. Я и сам так спрашивал. У 1С есть своё распознавание счетов-фактур, ещё есть Entera и НТР, и все их я смотрел.

В компании не было юриста, охраны труда, лишних рук в бухгалтерии. Их заменил один программист - 4

В итоге экономия и денег, и времени всё решила. Готовое оказывалось либо медленным, либо неточным, либо дорогим, а чаще всё сразу. .

Пробовал я и локальные решения, PaddleOCR и подобные. Это то же распознавание, только крутится на своём железе. На бумаге звучит хорошо, ведь данные никуда не уходят. На практике локальное у меня всегда проигрывало облачному. И железо под него нужно мощнее, и работает оно медленнее. Кстати, Entera и 1С как раз и используют локальные решения, потому что не всякий документ юридически можно загружать в облако. Им приходится, а я эту проблему закрываю обезличиванием.

Само распознавание считаю не я: запрос уходит в OpenAI через Polza, считают там, а я получаю готовый ответ. На моей стороне нужна только оперативная память [6] под веб-запросы. Когда грузишь по одной странице, через Polza уходит около 15 страниц в секунду, а больше 20 запросов в секунду на один ключ уже не пропустить. На одну компанию хватает 16 гигабайт памяти.

Бухгалтерскую программу я доводил до ума месяц, но она того стоила. После неё я умел доставать данные из любого документа дёшево и точно. Дальше нужно было, чтобы нейросеть не только читала документы, но и отвечала по ним.

Нейросеть-юрист

Боты охраны труда просто причёсывали сообщения. Здесь нейросети нужно понимать содержание десятков документов и принимать по ним решения. 

Почему обычные боты тут не годятся

Постоянного юриста в компании не было, был приходящий консультант. На претензии и уведомления от генподрядчика отвечал человек без юридического образования, советуясь с консультантом и с DeepSeek. Невозможно держать в голове десять объектов, на каждом по десятку с лишним документов. Чтобы ответить на одну претензию, надо прошерстить все документы, понять, прав ли заявитель, составить ответ, и снова прошерстить все документы, чтобы ответ был корректным.

Сначала кажется, что можно скормить нейросети все документы разом. Так не получится: у любой нейросети есть лимит контекста, то есть предел, сколько текста она удержит в «голове» за один раз. Целую книгу в неё не запихнёшь и не скажешь «перескажи». Влезет от силы документ страниц на десять, дальше упираешься в лимит. А у нас этих страниц тысячи.

Значит, нужен способ из тысяч страниц быстро доставать только те куски, которые относятся к делу, и показывать нейросети уже их. Так я и решил собрать отдельный продукт, свою нейросеть-юриста. Назвал его LawyerAI, а в его основе лежит векторный поиск, он же RAG.

Так выглядит наша нейросеть-юрист. Слева документы по объекту, разложенные по папкам и проиндексированные. Справа чат, который отвечает по ним

Так выглядит наша нейросеть-юрист. Слева документы по объекту, разложенные по папкам и проиндексированные. Справа чат, который отвечает по ним

Два поиска вместо одного

У человека в голове есть базы знаний по математике, по литературе, по своей работе. У нас тоже есть такая база, по документам объекта. Задача в том, чтобы нейросеть могла в неё заглядывать, не держа всё разом в контексте.

Сначала я режу текст на куски. Можно по предложениям, по абзацам, по страницам, размер любой. Для документов мне удобнее резать по пунктам или по абзацам. Дальше каждый кусок переводится в вектор.

Что такое вектор, проще всего вспомнить из школьной геометрии. На плоскости вектор — это точка с координатами по x и по y. Наш абзац тоже точка, только координат у неё не две, а от 300 до 3000 с лишним. Специальная нейросеть берёт абзац и превращает его в набор таких чисел: один абзац, одна точка. Добавили второй абзац, получили ещё одну. Так весь документ раскладывается точками в многомерном пространстве. Перевод абзацев в векторы я тоже делаю через Polza AI.

Нужно это затем, что расстояние между точками показывает похожесть текста. Чем ближе две точки друг к другу, тем больше похожи куски текста за ними, чем дальше, тем меньше общего. Сама по себе векторная база не нейросеть, у неё нет мозга [7]. Она раскладывает тексты по похожести, и по ней можно быстро найти соседей.

Мы написали себе простой чат, в нём я задаю вопрос. Поначалу я искал только по смыслу и не сразу понял, что этого мало. Смысловой поиск по векторам хорош на общих вопросах вроде «какие у нас риски по срокам». А с точными вещами он промахивается. Спросишь про пункт 7.13, а по смыслу он почти не отличается от пункта 7.12 и десятка соседних, так что нужное может и не всплыть.

Поэтому я ищу сразу двумя способами. Первый работает по смыслу, через векторы, как я описал выше. Второй ищет по словам, это обычный поиск точных совпадений в тексте, как Ctrl+F, только поумнее. Потом я соединяю обе выдачи в один список и ставлю выше то, что вероятнее подходит. Главный у меня поиск по смыслу, а по словам я добираю точные номера и пункты.

Сверху ещё фильтры: искать только по нужному объекту, только по нужному типу документов, а служебные файлы из выдачи выкидывать. Из готового списка беру топ-5 самых подходящих кусков, или топ-10, топ-15, топ-20.

Запрос идёт двумя ветками сразу. По смыслу (kNN) и по словам (BM25),  а фильтры отсекают чужие объекты и служебные файлы

Запрос идёт двумя ветками сразу. По смыслу (kNN) и по словам (BM25),  а фильтры отсекают чужие объекты и служебные файлы

Но похожее не значит нужное. Совпадение по вектору может быть на 90%, а кусок окажется не тем, что нам надо. А может совпасть на 10% и подойти. База находит похожее, но ответа на вопрос в ней нет.

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

Баз знаний у нас пока две. Первая по документам нашего объекта. Вторая по судебной практике в строительном подряде. Вторую я загружал ночью, там было 460 документов, это примерно 2500 страниц. Поставил вечером, а утром всё загрузилось.

Так нейросеть получила доступ к любому объёму документов в обход лимита контекста. Но обрабатывать все документы одинаково неправильно: договор, письмо и график работ читаются по-разному.

Оркестратор раздаёт документы

Когда документов и задач становится много, один промпт на всё уже не годится. Договор надо анализировать одними правилами, письмо другими, график производства работ третьими.

За это отвечает агент-оркестратор. Он работает как диспетчер: сам ничего не разбирает, а смотрит на документ и передаёт его нужному агенту. На этом построена риск-аналитика. Мы загружаем пачку документов, а оркестратор раскидывает каждый на свой разбор.

Разбор договора, система сама метит его критическим, вытаскивает опасные условия с привязкой к пунктам и подсказывает, что поправить в свою пользу 

Разбор договора, система сама метит его критическим, вытаскивает опасные условия с привязкой к пунктам и подсказывает, что поправить в свою пользу 

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

Каждый аргумент подкреплен пунктом договора и статьей ГК

Каждый аргумент подкреплен пунктом договора и статьей ГК

Снизить процент ошибок помогают точные промпты и повторные запросы, когда один и тот же вопрос прогоняется несколько раз, а ответы сверяются. Совсем убрать ошибку нельзя, но удержать её на приемлемом уровне реально.

Так из трёх простых ботов выросла мультиагентная система, которая читает документы и отвечает по ним под присмотром человека.

Сам LawyerAI мы ещё дорабатываем, но поиском по документам пользуемся уже сейчас. Раньше, чтобы найти нужный пункт по объекту, приходилось перечитывать весь архив.

Что я понял за два года

Сегодня на компанию работают три бота охраны труда, распознавание первички для бухгалтерии и нейросеть-юрист, последняя пока в разработке и тестах. Всё это собрано на самописном коде на Python и держится на API Polza AI. Платформы вроде n8n я не использую, потому что мне важнее писать своё и не упираться в чужие ограничения.

Юриста мы хотим довести до ума и уже потом вывести на рынок, на продажу. Для внешнего рынка понадобится и железо помощнее, но это следующий шаг. Пока же мы обкатываем его на своих объектах и ставим эксперимент: сможет ли человек без юридического образования вести строительный объект с нейросетью в помощь. Ошибки в юридической сфере возможны, мы это понимаем, поэтому и проверяем всё на себе, прежде чем предлагать другим.

Вот что я вынес из этих двух лет.

Не усложняй без нужды. Сложное решение не равно хорошее, и на первом же боте я в этом убедился.

Проверяй готовое, прежде чем брать. Иногда своё на одном API выходит выгоднее.

Контролируй нейросеть. Она может уверенно сослаться на пункт, которого нет, поэтому важные ответы всегда проверяет человек.

Если захотите расспросить про любой из этих ботов или про распознавание подробнее, пишите, расскажу и покажу, что смогу.

Автор: polza_ai

Источник [8]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/33275

URLs in this post:

[1] ошибка: http://www.braintools.ru/article/4192

[2] математику: http://www.braintools.ru/article/7620

[3] вспоминать: http://www.braintools.ru/article/3999

[4] обучение: http://www.braintools.ru/article/5125

[5] боль: http://www.braintools.ru/article/9901

[6] память: http://www.braintools.ru/article/4140

[7] мозга: http://www.braintools.ru/parts-of-the-brain

[8] Источник: https://habr.com/ru/companies/polzaai/articles/1060806/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1060806

www.BrainTools.ru

Rambler's Top100