Ваш комментарий, увы, продолжает прежнюю тенденцию — вы подменяете дискуссию по сути статьи на обсуждение второстепенных технических деталей, игнорируя её основную цель: демонстрацию практического подхода к семантической индексации текстов с использованием локальных LLM моделей и PostgreSQL / pgvector.
>>Примеры кода должны быть хорошими Статья не претендует на роль руководства по идеальному стилю кодирования. Она показывает рабочую реализацию концепции, где фокус — на логике работы системы, а не на соблюдении всех best practices Java-сообщества. Если бы цель была в демонстрации идеального кода, статья превратилась бы в курс по Java-паттернам, а не в разбор ИИ-задачи.
Я принимаю конструктивную обратную связь, но ваш комментарий больше похож на демагогию со сменой контекста обсуждения. Вы сами выбрали свое "соломенное чучело - идеальный код" и пытаетесь дискредитировать содержание этой статьи. Делаете это с помощью указаний на несоответствие кода вашим представлениям о прекрасном.
В итоге в ваших комментариях оффтоп о стиле кода, а не на семантическом поиске и запуске локальных LLM моделей с помощь Spring AI. Статью я написал для тех, кто хочет разобраться, как применить LLM в Java проекте без использования облачных сервисов - API нейросетей.
У меня возникает двоякое чувство, что оба критических комментария похожи на результаты сгенерированые не совсем хорошей моделью по стандартному промпту для критики кода на java. И это даже пока без анализа профилей коментаторов на экспертность в обсуждаемой теме, статистики комментариев по тону, наличию обесценивания и конструктивности.
Ваш комментарий рекомендует распространенную ошибку в разработке систем: слишком большое внимание к следованию предполагаемым «лучшим практикам» без учета конкретного контекста и целей проекта. Я и не претендовал здесь на абсолютную архитектурную чистоту примера и сделал все что считаю полезным написания этого кода.
Вашим советам тут не следует следовать по нескольким причинам...
Для работы с БД стоило использовать spring-jdbc с его пулом коннекций и jdbcTemplate.
Код здесь предназначен для демонстрации примера реализации семантического поиска, а не для готового к производству корпоративного приложения. Основное внимание уделяется иллюстрации концепции, а не соблюдению абсолютно всех практик разработки и модулей фреймворка. Поскольку я автор, то и выбор/баланс что мне использовать из Spring, а что не нужно в этом проекте за мной.
Если в проекте spring boot, почему приложение не построено как классическое boot приложение с разделением на сервисы / репозитории?
Предложение полной архитектуры Spring с сервисами/репозиториями добавит сюда избыточной сложности. Когда потребуется, то я добавлю все необходимые дополнительные абстракции и слои.
Работа с файлами через File устарела на лет 15, давно есть более удобный java.nio.file.Files
Утверждение, что "работа с файлами через File устарела на 15 лет", преувеличено. java.nio.file.Files предлагает определенные преимущества, но java.io.File по-прежнему широко используется и вполне подходит для тех операций с файлами, что используются в этом примере
Для логирования ошибок стоило использовать spring-logging / ломбоковский @slf4j
Вполне возможно, так же как можно подключить сбор стуртурированных логов в OpenTelemetry, добавить трейсинг и сбор метрик для улучшения observability. Тогда это будет совсем другая статья и уровень сложности. И главный вопрос зачем это мне сейчас.
зачем тут обертки? достаточно примитивов float[]
Преобразование упакованного массива необходимо при работе с массивами JDBC, поскольку метод createArrayOf требует массивы объектов, а не примитивные массивы.
Я уже объяснил в предыдущем комментарии, какой я сделал выбор, чтобы сосредоточиться на реализации семантического поиска и тем подходам к расширяемости прототипа что я считаю рациональными, а не на применении здесь всех лучших практик разработки на Java.
Комментарий оставляет двоякое впечатление. С первого взгляда похож на конструктивный вопрос о выборе технологий, но по своему тону и форме выражение больше на попытку обесценить работу автора и завязать спор на эмоциях.
"Тут технология X, а почему не Y?". Краткий мой ответ на вопросы такого типа - это личные предпочтения, основанные на опыте разработки прототипов систем. Бывает что код со временем прототипы превращаются в систему, где важнее читаемость и простота расширения, а не отсутствие фреймворков и внешних зависимостей.
Эта статья иллюстрирует подход, который можно адаптировать под конкретные задачи. Почти любой проект можно реализовать на разных технологиях в зависимости от целей, а в данном случае баланс между образовательной ценностью и "написанием с минимумом фреймворков" казался приоритетным в первом. ИИ для кодинга это вообще отдельная тема про агенты и RAG и совсем не gemma3.
Для минимального примера можно обойтись без Spring и Lombok. Однако цель этой публикации — демонстрация практической реализации с легкой повторяемостью и фокусе на сути идеи, а не на написании кода без использования фреймворков. Spring Boot уменьшает усилия на подключение Ollama в Spring AI и в логику индексации данных. Lombok сокращает boilerplate с сеттерами и try/catch, что важно в статье, где фокус на логике, а не на многословном синтаксисе языка программирования. В образовательных целей такой подход позволяет читателю сосредоточиться на главном.
Выбор TestContainers здесь для быстрого старта примера, без описаний инструкций как запустить и настроить PostgreSQL. Опять же фокус на сути, а не командах развертывания СУБД. Мне был нужен именно PostgreSQL c pgvector для долгосрочного хранения данных и написаний произвольных по сложности запросов, а не Sqlite/H2database итп
Спасибо, про семантический поиск ваш комментарий справедлив хоть и забежал в мою будущую публикацию по этой теме. В этой статье показана базовая реализация индексации текстов, вычисление эмбеддингов, но без интерфейса для пользовательского поиска. Добавление интерфейса — логичный следующий этап, который можно реализовать на основе предложенной архитектуры. Например, можно было бы расширить приложение методом вроде searchByQuery() с использованием этих же эмбеддингов. Дополнил эту статью примером получения вектора SELECT get_embedding('SQL final state machine') для ее логической завершенности.
Проект действительно начался как эксперимент и превратился в прототип, демонстрирующий потенциал локальных LLM для структурирования данных. Я показал, как интегрировать PostgreSQL, Ollama и Java для решения задачи, которая обычно требует облачных сервисов или отдельных pipeline с DS/DevOPS экспертизой. Для меня это комплимент, что сложный функционал удалось реализовать по виду как лабораторную работу, что говорит об умении делать сложное проще для понимания читателями без ущерба для цели проекта.
Конечно, я использую и другие модели в разных задачах, с учётом в том числе и лицензий. Но конкретно в этом сценарии gemma3 лучше всего показала себя, с учётом размера ее контекстного окна / числа параметров.
Т.е. для второй сетки, которая фомирует эмбеддинги, это просто отдельные слова и фразы.
Да, это так. Но верно если только генерировать эмбеддинги только для ключевых слов. В этом примере я подмешиваю ключевые слова к описанию темы.
Из плюсов отдельной LLM и эмбеддинг нейросети - высокая специализация каждой и производительность. А значит можно например убрать "подмешивание" ключевых слов и заменить на подмешивание краткого описания всей статьи в отдельную тему и быстро пересчитать.
Ваше предложение действительно рабочее для генерации эмбеддингов для исходных кодов программ, там также важно и большее контекстное окно, так как в отличии от обычного текста - без ущерба не разделить большой метод на независимые фрагменты.
у нас был лайфхак - ходить на спортивные площадки с резиновым покрытием, которые никто не занимает в осеннюю погоду вечерами. Но здесь таких площадок нет.
И это не единственный минус места где я живу, есть еще, но больше конечно плюсов. И этой информацией я бы мог делиться с людьми, которые ищут свое уютное место. Но как и где непонятно.
А проще было бы проставить в OpenStreetMap типы покрытия в городе спортивным площадкам и доставать потом запросом leisure=pitch AND surface=acrylic или же (tartan, clay) чем полагаться на отзывы.
Я не делал PR в osmosis. Не думаю что мой код с учетом статуса проекта приняли бы, там и внешние утилиты вызываются к тому же. Просто выложил openstreetmap_h3 на GitHub.
Данные о годах постройки домов и типовых проектов зданий, как оказалось, есть в OSM. Для спальных районов Москвы данных прилично, а в остальных зданиях start_date и design:ref редкость.
А так в других городах по РФ действительно для аналитики парсят ГИС ЖКХ. Так делали в параллельном проекте на одной из моих предыдущих работ.
К сожалению, только поддержка проекта. В 2020-2022 я провел много времени разбирая исходники этого проекта, чтобы написать запись PBF в PostGIS шустрее и с разбиением данных в таблицы по H3 index.
bash. Он полезнее будет в качестве повышения квалификации.
Мне надолго хватило воспоминаний от написания и поддержки bash скриптов в швейцарском инвестбанке - стирал их потом скотчем, который не в рулонах ??. Дам другим программистам отличиться и понаблюдаю в стороне!
Просто почитал с удовольствием, а ассемблер оставил в 2003 - во времена студенчества, вместе с другими теплыми воспоминаниями об учебе. К сожалению, работодатели эти знания не оплачивают - всем нужен результат быстрее и даже GC в большинстве проекто в не помеха.
Сегодня нашел разгадку зачем совершают небеги анонимов на статьи на Хабре.
Это "поисковая деоптимизация" когда ищешь в поисковике конкретную информацию, а в ответ под заголовком твоей статьи что-то невнятное про "кузнецов, гвозди и опята" из коментариев вместо программирования и запуска проекта из статьи.
Выгорание при потери времени страшнее ваших ведерок и примеров. Снова повторюсь"отличий много от материального производства и распространения товаров." и расходы хоть не материальные, но это не значит что они менее значимые.
Спасибо, статью отредактировал.
Ваш комментарий, увы, продолжает прежнюю тенденцию — вы подменяете дискуссию по сути статьи на обсуждение второстепенных технических деталей, игнорируя её основную цель: демонстрацию практического подхода к семантической индексации текстов с использованием локальных LLM моделей и PostgreSQL / pgvector.
>>Примеры кода должны быть хорошими
Статья не претендует на роль руководства по идеальному стилю кодирования. Она показывает рабочую реализацию концепции, где фокус — на логике работы системы, а не на соблюдении всех best practices Java-сообщества. Если бы цель была в демонстрации идеального кода, статья превратилась бы в курс по Java-паттернам, а не в разбор ИИ-задачи.
Я принимаю конструктивную обратную связь, но ваш комментарий больше похож на демагогию со сменой контекста обсуждения. Вы сами выбрали свое "соломенное чучело - идеальный код" и пытаетесь дискредитировать содержание этой статьи. Делаете это с помощью указаний на несоответствие кода вашим представлениям о прекрасном.
В итоге в ваших комментариях оффтоп о стиле кода, а не на семантическом поиске и запуске локальных LLM моделей с помощь Spring AI. Статью я написал для тех, кто хочет разобраться, как применить LLM в Java проекте без использования облачных сервисов - API нейросетей.
У меня возникает двоякое чувство, что оба критических комментария похожи на результаты сгенерированые не совсем хорошей моделью по стандартному промпту для критики кода на java. И это даже пока без анализа профилей коментаторов на экспертность в обсуждаемой теме, статистики комментариев по тону, наличию обесценивания и конструктивности.
Ваш комментарий рекомендует распространенную ошибку в разработке систем: слишком большое внимание к следованию предполагаемым «лучшим практикам» без учета конкретного контекста и целей проекта. Я и не претендовал здесь на абсолютную архитектурную чистоту примера и сделал все что считаю полезным написания этого кода.
Вашим советам тут не следует следовать по нескольким причинам...
Код здесь предназначен для демонстрации примера реализации семантического поиска, а не для готового к производству корпоративного приложения. Основное внимание уделяется иллюстрации концепции, а не соблюдению абсолютно всех практик разработки и модулей фреймворка. Поскольку я автор, то и выбор/баланс что мне использовать из Spring, а что не нужно в этом проекте за мной.
Предложение полной архитектуры Spring с сервисами/репозиториями добавит сюда избыточной сложности. Когда потребуется, то я добавлю все необходимые дополнительные абстракции и слои.
Утверждение, что "работа с файлами через File устарела на 15 лет", преувеличено. java.nio.file.Files предлагает определенные преимущества, но java.io.File по-прежнему широко используется и вполне подходит для тех операций с файлами, что используются в этом примере
Вполне возможно, так же как можно подключить сбор стуртурированных логов в OpenTelemetry, добавить трейсинг и сбор метрик для улучшения observability. Тогда это будет совсем другая статья и уровень сложности. И главный вопрос зачем это мне сейчас.
Преобразование упакованного массива необходимо при работе с массивами JDBC, поскольку метод createArrayOf требует массивы объектов, а не примитивные массивы.
Я уже объяснил в предыдущем комментарии, какой я сделал выбор, чтобы сосредоточиться на реализации семантического поиска и тем подходам к расширяемости прототипа что я считаю рациональными, а не на применении здесь всех лучших практик разработки на Java.
Комментарий оставляет двоякое впечатление. С первого взгляда похож на конструктивный вопрос о выборе технологий, но по своему тону и форме выражение больше на попытку обесценить работу автора и завязать спор на эмоциях.
"Тут технология X, а почему не Y?". Краткий мой ответ на вопросы такого типа - это личные предпочтения, основанные на опыте разработки прототипов систем. Бывает что код со временем прототипы превращаются в систему, где важнее читаемость и простота расширения, а не отсутствие фреймворков и внешних зависимостей.
Эта статья иллюстрирует подход, который можно адаптировать под конкретные задачи. Почти любой проект можно реализовать на разных технологиях в зависимости от целей, а в данном случае баланс между образовательной ценностью и "написанием с минимумом фреймворков" казался приоритетным в первом. ИИ для кодинга это вообще отдельная тема про агенты и RAG и совсем не gemma3.
Для минимального примера можно обойтись без Spring и Lombok. Однако цель этой публикации — демонстрация практической реализации с легкой повторяемостью и фокусе на сути идеи, а не на написании кода без использования фреймворков. Spring Boot уменьшает усилия на подключение Ollama в Spring AI и в логику индексации данных. Lombok сокращает boilerplate с сеттерами и try/catch, что важно в статье, где фокус на логике, а не на многословном синтаксисе языка программирования. В образовательных целей такой подход позволяет читателю сосредоточиться на главном.
Выбор TestContainers здесь для быстрого старта примера, без описаний инструкций как запустить и настроить PostgreSQL. Опять же фокус на сути, а не командах развертывания СУБД. Мне был нужен именно PostgreSQL c pgvector для долгосрочного хранения данных и написаний произвольных по сложности запросов, а не Sqlite/H2database итп
Спасибо, про семантический поиск ваш комментарий справедлив хоть и забежал в мою будущую публикацию по этой теме. В этой статье показана базовая реализация индексации текстов, вычисление эмбеддингов, но без интерфейса для пользовательского поиска. Добавление интерфейса — логичный следующий этап, который можно реализовать на основе предложенной архитектуры. Например, можно было бы расширить приложение методом вроде searchByQuery() с использованием этих же эмбеддингов. Дополнил эту статью примером получения вектора SELECT get_embedding('SQL final state machine') для ее логической завершенности.
Проект действительно начался как эксперимент и превратился в прототип, демонстрирующий потенциал локальных LLM для структурирования данных. Я показал, как интегрировать PostgreSQL, Ollama и Java для решения задачи, которая обычно требует облачных сервисов или отдельных pipeline с DS/DevOPS экспертизой. Для меня это комплимент, что сложный функционал удалось реализовать по виду как лабораторную работу, что говорит об умении делать сложное проще для понимания читателями без ущерба для цели проекта.
Spacy это библиотека NLP для Python?
Конечно, я использую и другие модели в разных задачах, с учётом в том числе и лицензий. Но конкретно в этом сценарии gemma3 лучше всего показала себя, с учётом размера ее контекстного окна / числа параметров.
Да, это так. Но верно если только генерировать эмбеддинги только для ключевых слов. В этом примере я подмешиваю ключевые слова к описанию темы.
Из плюсов отдельной LLM и эмбеддинг нейросети - высокая специализация каждой и производительность. А значит можно например убрать "подмешивание" ключевых слов и заменить на подмешивание краткого описания всей статьи в отдельную тему и быстро пересчитать.
Ваше предложение действительно рабочее для генерации эмбеддингов для исходных кодов программ, там также важно и большее контекстное окно, так как в отличии от обычного текста - без ущерба не разделить большой метод на независимые фрагменты.
leisure=pitch + surface объективные факты, которые любой может перепроверить.
Отзывы, как и комментарии, же штука иногда не соответствующая действительности. При этом автор отзыва всегда может возразить "это мое личное мнение".
А проще было бы проставить в OpenStreetMap типы покрытия в городе спортивным площадкам и доставать потом запросом leisure=pitch AND surface=acrylic или же (tartan, clay) чем полагаться на отзывы.
Спасибо, это я фильтр забыл включить во второй ревизии. Данные обновил!
Частота упоминания для городов, встречающихся минимум в 30 статьях Хабра 2023
Я не делал PR в osmosis. Не думаю что мой код с учетом статуса проекта приняли бы, там и внешние утилиты вызываются к тому же. Просто выложил openstreetmap_h3 на GitHub.
Данные о годах постройки домов и типовых проектов зданий, как оказалось, есть в OSM. Для спальных районов Москвы данных прилично, а в остальных зданиях start_date и design:ref редкость.
А так в других городах по РФ действительно для аналитики парсят ГИС ЖКХ. Так делали в параллельном проекте на одной из моих предыдущих работ.
К сожалению, только поддержка проекта. В 2020-2022 я провел много времени разбирая исходники этого проекта, чтобы написать запись PBF в PostGIS шустрее и с разбиением данных в таблицы по H3 index.
Спасибо за подробный разбор
osmosis
это действительно "швейцарский нож" для OSM дампов, только его больше не развивают.
Из примеров задач - поиск лучшего места для жилья, по моему мнению, отличное применение для геоданных из OpenStreetMap
Мне надолго хватило воспоминаний от написания и поддержки bash скриптов в швейцарском инвестбанке - стирал их потом скотчем, который не в рулонах ??. Дам другим программистам отличиться и понаблюдаю в стороне!
Спасибо что потратили время!
Просто почитал с удовольствием, а ассемблер оставил в 2003 - во времена студенчества, вместе с другими теплыми воспоминаниями об учебе. К сожалению, работодатели эти знания не оплачивают - всем нужен результат быстрее и даже GC в большинстве проекто в не помеха.
Сегодня нашел разгадку зачем совершают небеги анонимов на статьи на Хабре.
Это "поисковая деоптимизация" когда ищешь в поисковике конкретную информацию, а в ответ под заголовком твоей статьи что-то невнятное про "кузнецов, гвозди и опята" из коментариев вместо программирования и запуска проекта из статьи.
Опять какие-то выдуманные опята, гвозди и разбойники. Узнается чистой воды артамоновщина...
вы сами выдумали этот заговор, я лишь говорю о контроле средств распространения информации и дороговизне продвижения нематериальных товаров
Приятно познакомиться, вот и проявилась ваша истинная личина) Напомню, что аудитория ресурса не на вашей стороне.
Выгорание при потери времени страшнее ваших ведерок и примеров. Снова повторюсь
"отличий много от материального производства и распространения товаров."
и расходы хоть не материальные, но это не значит что они менее значимые.