← Усі статті

Семантичний контекст для ШІ: як LSP допомагає моделі зрозуміти код

Четверта частина серії про автодоповнення: Language Server Protocol дає типи, визначення й посилання — шар поверх текстового пошуку по репозиторію.

Семантичний контекст для ШІ: як LSP допомагає моделі зрозуміти код
Зміст

Коротко

Текстовий пошук по репозиторію знаходить схожі рядки, але не відповідає, який тип у змінної і де оголошено імпорт. Нотатка на Хабрі показує, як система автодоповнення на LLM запитує в Language Server Protocol визначення, типи й місця використання — і збирає з відповідей контекст для моделі.

Що сталося

Автор продовжує серію про автодоповнення: після текстового пошуку BM25 по коду біля курсора лишається дірка. Імпорт посилається на конкретне оголошення, у сервісу є інтерфейс, у методу — поля аргументу. Збіг слів ReturnRequest ще не означає зв’язок у програмі.

LSP стандартизує обмін між редактором і мовним сервером через JSON-RPC: initialize, синхронізація документа, далі запити на кшталт textDocument/definition, typeDefinition, references, hover. Сервер не «розуміє TypeScript сам по собі» — якість дає конкретний мовний сервер, а протокол задає формат. В IDE дані іноді приходять через PSI або API редактора, але сенс той самий: граф визначень і типів замість мішка рядків.

На прикладі returnService ланцюжок такий: definition → оголошення з типом → typeDefinition → інтерфейс із submitdefinition аргументу SubmitReturnCommandreferences методу → реальний виклик у проєкті, звідки брати requestedBy. Контракт API і звичний спосіб ним користуватися потрапляють у промпт разом.

Чому це важливо

LLM без семантики вгадує за сусіднім текстом. LSP дає відбір за зв’язками програми: що допустимо в позиції курсора — задача completion; що має намір написати розробник — уже ранжування кандидатів і збирання промпту заповнення середини (FIM). Для майбутніх агентів той самий шар стане навігацією по коду: семантичні інструменти ведуть відомими ребрами, пошук по репозиторію — за сенсом і словами.

Якість підказки складається не лише з моделі: момент запуску генерації, склад контексту, ранжування, розмір у токенах і встигнути до наступного натискання клавіші.

На практиці

  1. Для автодоповнення запитуйте definition і typeDefinition у символів біля курсора до генерації.
  2. Додавайте 1–2 живих references із прод-коду, а не лише сигнатуру з інтерфейсу.
  3. Ранжуйте кандидатів: збіг типів, свіжість файлу, тест vs прод, вартість токенів.
  4. Не плутайте textDocument/completion (допустимі символи) з генерацією цілого виразу — це різні задачі.
  5. Закладіть таймаут: повільний мовний сервер гірший за порожній контекст, якщо зриває інтерактивність.

Підсумок

Семантичний шар поверх BM25 перетворює автодоповнення з «вгадай за рядками» на «спирайся на контракт проєкту». LSP — не заміна моделі, а спосіб дати їй ті самі зв’язки, якими вже користується IDE.