РозробкаБудь-який рівень

Основи LLM

Велика мовна модель (LLM) робить рівно одну річ: маючи наявний текст, вона оцінює кожен можливий наступний токен, а щось один із них обирає. Чат, виклики інструментів, міркування й агенти — усе це та сама операція, повторена багато разів. На цій сторінці — що таке токен, скільки насправді коштує контекстне вікно, чому модель вигадує факти з цілковитою впевненістю і які налаштування справді змінюють відповідь.

Одиниця роботи
Один токен за раз
Памʼять
Лише контекстне вікно
Відповіді
Згенеровані, не знайдені

Одна операція, повторена багато разів

Модель не читає слів. Текст спершу ріжеться на токени — фрагменти приблизно з трьох-чотирьох символів в англійській і часто з одного-двох символів в українській, і саме тому те саме речення коштує в українській помітно більше токенів. Кожен токен має номер, і модель бачить лише цю послідовність номерів. Спитайте її, скільки літер у слові, — вона гадає про те, чого не бачить, і саме тому такі питання виходять хибними.

Маючи цю послідовність, модель видає одне: оцінку для кожного токена у своєму словнику — наскільки добре кожен продовжив би текст. Вона не видає відповіді, речення чи думки: вона видає розподіл приблизно по ста тисячах кандидатів. Далі семплер обирає одного, дописує його до входу, і весь обрахунок запускається знову для наступного токена. Відповідь на чотириста слів — це той самий цикл, прокручений кількасот разів, і саме тому вивід повільніший і дорожчий за ввід: ввід обробляється за один прохід, а кожен токен виводу — це окрема подорож крізь модель.

Мовна модель виконує одну операцію й повторює її. Промпт ріжеться на токени, модель робить один прохід і видає оцінку для кожного токена свого словника, а семплер обирає один із них за налаштуваннями на кшталт temperature і top_p. Обраний токен дописується до входу, і весь прохід повторюється — саме тому токени виводу коштують більше часу й грошей, ніж токени входу. Усе задіяне — вказівки, історія, документи й відповідь, що пишеться, — ділить одне контекстне вікно, і між викликами не зберігається ніщо: історію щоразу надсилає застосунок.

Семплер — це те місце, де живуть налаштування, які ви справді можете змінювати, і їх менше, ніж підказує інструментарій. Вони визначають, як розподіл перетворюється на вибір: додати знань вони не можуть і уважнішою модель не зроблять. Більшість команд чіпає два з них, а решту лишає як є.

НалаштуванняЩо робитьПрактична порада
temperatureЗгладжує або загострює розподіл перед вибіркою. Вище значення — малоймовірні токени дістають справжній шанс.Низька — для видобування, класифікації й коду. Вища — лише для чернеток та ідей, де різноманіття і є метою.
top_pЛишає лише найімовірніші токени, чиї ймовірності разом дають p, і робить вибірку серед них.Змінюйте одне з двох, а не обидва: вони взаємодіють, і підкручування обох одночасно робить результат незбагненним.
Ліміт токенів виводуЖорстка стеля відповіді. Модель про неї не знає — генерацію просто обрізають.Ставте достатньо високо, щоб коректна відповідь помістилася, і вважайте обрізану відповідь помилкою, а не результатом.
Стоп-послідовностіРядки, що завершують генерацію тієї миті, коли зʼявляються.Корисні, коли ви генеруєте по одному елементу списку. Здебільшого зайві, якщо просите структурований вивід.

Контекстне вікно — це вся памʼять

Контекстне вікно — це максимальна кількість токенів, яку модель може мати перед собою на одному виклику, і воно вміщує все одразу: системні вказівки, розмову дотепер, будь-які вставлені документи, описи інструментів і саму відповідь, що генерується. Це не сховище. Між двома викликами модель не зберігає геть нічого: API не має стану, точно як HTTP.

Велике вікно — це не те саме, що увага до всього, що в ньому. Моделі надійно використовують те, що ближче до початку й до кінця промпту, а середину — гірше: довгий документ, вкинутий у центр запиту, — класичний спосіб отримати відповідь, яка ігнорує половину його. Ставте вказівку й саме питання в кінець, найближче до місця, де починається генерація, а зайве не кладіть узагалі. Заповнювати мільйонне вікно лише тому, що воно є, — це рішення про вартість і затримку не менше, ніж про якість.

Тут же кешування промптів змінює економіку, і це та єдина оптимізація, яку варто зрозуміти рано. Постачальники можуть кешувати оброблену форму префікса вашого запиту, тож повторюваний префікс тарифікується часткою звичайної ціни входу й обробляється швидше. Заковика в тому, що збіг має бути саме префіксним: один змінений байт будь-де перед кінцем кешованої ділянки знецінює її всю. Практично це означає, що стабільний матеріал іде першим — системні вказівки, описи інструментів, довгий документ, — а все мінливе останнім. Позначка часу чи ідентифікатор запиту на початку системного промпту тихо руйнує кеш на кожному виклику, і в самій відповіді про це не скаже ніщо, крім лічильників використання.

Обмеження, які структурні, а не помилки

Модель, яка завжди видає найправдоподібніше продовження, видасть правдоподібне продовження й тоді, коли правдивого просто немає. Ось що таке галюцинація: не збій, а той самий механізм, застосований до питання, під яке у вагах немає нічого твердого. Окремого стану «я не знаю» в неї немає, тож упевнений тон хибної відповіді нічим не відрізняється від упевненого тону правильної, і впевненість не несе інформації, якою можна користуватися.

Запит до бази даних

  • Повертає рядки, які існують, або порожній результат. Третього варіанта немає.
  • Той самий запит до тих самих даних щоразу дає ту саму відповідь.
  • Хибний результат означає, що хибні дані або запит, — і можна показати, що саме.
  • Масштабується здешевленням пошуку.

Виклик моделі

  • Завжди щось повертає. Порожній результат — це поведінка, яку треба спроєктувати.
  • Той самий промпт може дати різні відповіді, а самі промпти переналаштовують, коли змінюється модель.
  • Хибний результат зазвичай означає, що в промпті бракувало факту, а сигналізувати про це модель не мала як.
  • Масштабується витрачанням більшої кількості токенів — а це прямий і видимий кошт.

Ще два обмеження випливають із того, як роблять модель. Її ваги заморожені на межі навчання, тож усе пізніше — реліз, зміна цін, інцидент, ваша ж документація з минулого тижня — просто не всередині, і питання про це дає описану вище правдоподібну вигадку, а не зізнання. І той самий промпт не гарантує тієї самої відповіді двічі: вибірка випадкова за побудовою, а навіть за найнижчої температури пакетування й відмінності заліза на боці постачальника лишають точну відтворюваність недосяжною. Будь-який тест, що звіряє точний рядок відповіді, рано чи пізно впаде з причини, ніяк не повʼязаної з вашою зміною.

Як це виявляється в реальній поставці

Вибір моделі — це діапазон, а не рішення, ухвалене один раз. Постачальники дають потужний рівень і дешевий швидкий рівень, і корисна звичка така: довести, що задача взагалі розвʼязна, на найсильнішій доступній моделі, а тоді спробувати спуститися діапазоном, маючи в руках фіксований набір тестових випадків. Без цього набору ви не обираєте модель, а вгадуєте її — і дешевша модель виглядатиме пристойно на тих трьох прикладах, які ви навмання спробували.

Рядок витрат на LLM-функцію — це майже завжди токени на запит, помножені на кількість запитів, і непомітно росте саме перший множник. Промпти накопичуються: вказівка, додана після кожного інциденту, довший приклад, ще три знайдені документи — а під усім цим історія розмови. Логуйте кількість токенів кожного виклику з першого дня, поруч із затримкою: це єдиний спосіб побачити зростання, і він перетворює туманне «AI-функція подорожчала» на конкретний промпт, який можна підрізати.

Затримка поводиться не так, як будь-яка інша ваша залежність. Час до першого токена приблизно сталий, а все після нього пропорційне тому, скільки модель пише, — тож запит із довгою відповіддю повільний саме тому, що вона довга, і жодне налаштування інфраструктури цього не змінить. Звідси дві речі: віддавайте відповідь потоком, щоб користувач бачив поступ, а не крутилку, і просіть коротший вивід, коли вам справді потрібна менша затримка, бо це та змінна, яка на неї впливає.

Де це вироджується

  • Ставлення до моделі як до бази знань про ваш власний продукт замість того, щоб класти свої документи в промпт.
  • Тести, що звіряють точний рядок відповіді: вони падають від зміни вибірки, а не від зміни поведінки.
  • Позначка часу чи ідентифікатор запиту на початку системного промпту: вони знецінюють кеш промптів на кожному виклику.
  • Підняття температури, щоб відповіді стали «розумнішими», хоча воно лише робить малоймовірні токени ймовірнішими.
  • Дозвіл чату рости, доки бібліотека тихо обріже початок — разом із системними вказівками.
  • Заповнення величезного контекстного вікна лише тому, що воно є: ви платите за токени, які радше псують відповідь, ніж покращують.
  • Реліз без метрик токенів і затримки: перша ознака проблеми — рахунок.

Коли це застосовувати

Застосовуйте, коли

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

Уникайте, коли

  • Усе, що потребує точної, перевірюваної відповіді: арифметика, підсумки, правила відповідності. Для цього викликайте код — і дайте моделі викликати саме його.
  • Факти про вашу власну галузь без нічого знайденого в промпті: очікуваним результатом є впевнена вигадка.
  • Шляхи, де хибна відповідь діє негайно й безповоротно — платежі, видалення, вихідні повідомлення — без людського контролю.
  • Численні дешеві виклики, де правило, таблиця відповідностей чи маленький класифікатор роблять те саме за тисячну частку вартості.

Було корисно?

Поділіться з тим, хто працює над тією ж задачею.