Цыкл наступнага токена: псіхалогічны модэль LLM-ў прыямо перад тым, як вы пачнёте викорыстоўваць агентаў.
Дазнаецеся, як працуюць токены, акна контэксту, выбір прымероў і цыкл генеравання, за дапамогай невялікіх прымероў на Python, якія адказваюць на пытанне, чаму існуюць RAG, ReAct і LangGraph.
Інжынеры, які працуюць з LLM-амі через такі фрэймворкі, як LangChain, частаў не можуць з’ясавіць, калі ўтворыўся проблема, чыя це віна — фрэймворка, API, які ў яго ўключаны, чы сама модель. Рашэнням являецца чыстая ментальная модель: LLM — это функцыя прагнозавання наступнага токена, якая вызываецца паўтароўна ў цікле. Калі такая канцэпцыя ўсвядомлена, RAG — это спосаб выбору таго, што будзе падацца ў функцыю, ReAct — спосаб аналізу таго, што выходзіць, а LangGraph — спосаб коордынацыі багацькох вызоваў. Прыклады нижэй працуюць локальна з Python і адной маленькай бібліятэкай, ключа API не патрэбна.
Генераванне — это прагнозавання наступнага токена ў цікле
Пры наявнасці серыі токенаў модель вяртае верыгоднасць кожнага можлівага наступнага токена. Выбираецца адны, яго дадаюць да серыі, а сама дужэйшая серыя зноў вводзіцца ў працэс. Гэта павтарываецца, пакуль не будзе досягнуты токен зупінкі або ліміт дужжыны. Стрімаванне выходных дадзенняў проста прадстаўляе гэты цікл токен за токенам.
Выліваецца два наследкія:
- Няма плану. Кожны токен залежыць толькі ад токенаў, якія ўжо былі.
- Няма памяці между вызваннямі. Кожны запит пачынаецца ад самэх токенаў, якія вы адправляеце, і самэ гэта є прычыной існавання генеравання з падтрымкай выкарыстоўвання ранейшых дадзеных.
Токены — это часткі слова, а не самыя слова
Модель бачыць цэлыя числа, а не текст. Токенізатор ператварае строкі на ID токенаў і назад. Часта вжываемыя словы зазвычай становяць адзін токен, тады як рэдкасці і код дзелююцца на калькі токенаў. Прыблізны показнік: адзін токен — цэлае трохце часткі слова.
Фрагмент завантажыць o200k_base, кодаванне з сямейства gpt-4o, через tiktoken, кодавае рэченне і выдрукоўвае кожны ID разам з фрагментам тексту. Заўважыце, што "LangGraph" становіць два токены, а прасторы пад словамі належаць да наступнага токена.
import tiktoken
# tokenizer of the gpt-4o model family
enc = tiktoken.get_encoding("o200k_base")
ids = enc.encode("LangGraph orchestrates agents.")
print(ids)
# [30741, 9922, 109873, 1381, 19297, 13]
for i in ids:
print(i, repr(enc.decode([i])))
# 'Lang' 'Graph' ' orchestr' 'ates' ' agents' '.'
Адаптаванне і выконання — гэта разныя фазы
Падчас адаптавання вагі корэктуецца праз прыказванне наступных токенаў у вялікіх колькасцях тексту. Пад час выконання викорыстоўваецца зашчытаны модэль. Ваш запит ніколі не зменяе вагі, таму інфармацыю, якой не хапае модэлю, трэба падаць у запит пад час выконання. Самэ гэта і робіць RAG.
Вікна контэкста — гэта весь свет модэля
Одна вызова може обрабатваць толькі певную колькасць токенаў, і гэты ліміт, вікна контэкста, абягае як запит, так і створаны выход. Усё, што знаходзіцца за межамі, для той вызовы не існуе. Чат здаецца безперывным толькі таму, што прыложэнне ў кожны раз перасылае паказаныя раней поведамленні, а RAG існуе таму, што зборы дакументаў не пасвядчаюць, таму замест таго адбіраецца калькі актуальных фрагментаў.
Бюджетаванне — это простая арымэтыка. Адказчык після падрахавання токэнаў за дапамойкай токенізатора вырахоўвае ўсё гэта, плюс резерв для адказу, з дыяпазона 128 000 токэнаў, які заданы для gpt-4o-mini. Ліміты разлічаюцца ў залежнасці ад модэляў і версый, таму пераканайцеся ў актуальной дасягледзе вашага прадаўцы.
def count_tokens(text: str) -> int:
return len(enc.encode(text))
prompt = "Summarize the attached design doc."
window = 128_000 # e.g. gpt-4o-mini
reserve = 1_000 # room for the answer
used = count_tokens(prompt)
print("left:", window - reserve - used)
Тэмпература кантролюе выбіранне наступнага токэна
Метод адбору выбірае аднаго токэна з распаду модэля, а тэмпература перакаштоввае гэты распад. Калі тэмпература близкая да нуля, паўтараючыся токэн практычна завжды выграўвае. Пры значэнні 1,0 і вышэ менавіта токэны, якія раней былі малаямо верагодныя, атрымаюць рэальную шанс. Для экстракцыі, структураванага выходу і агентаў для вызову інструментаў вярны ўжыць тэмпературу 0, а для прадрафтавання і брейнстармінгу — прыблізна 0,7–1,0. Наша інструкцыя па тэмпературе, top-k і top-p раскрывае іншыя параметры адбору.
Стварэнне ціклу ў мініятуры
Наступны прыклад спаўнюе рэальны токенайзер з фальшывым моделлю, створаным на адной табліцы пашуку. Ён маленькі, але выконвае той самы цикл, што і справжній LLM: кодаванне, прыказанне, дадзенне да адной табліцы, зупнэнне.
Спачатку маленькі корпус токенайзуецца, і працуецца з кожной суседней парой ID. Для кожнага токена табліца зберагае толькі яго найчастэйшаг наступніка, што робіць гэты прыказчык „жаднамудрый“, ў той жа час, што це эквівалент тэмпературы нуля.
CORPUS = (
"the agent calls the model. "
"the model returns a token. "
"the agent calls the tool. "
"the tool returns a result."
)
ids = enc.encode(CORPUS)
counts = {}
for a, b in zip(ids, ids[1:]):
counts.setdefault(a, {})
counts[a][b] = counts[a].get(b, 0) + 1
# greedy "model": token -> likeliest successor
table = {
a: max(s, key=s.get)
for a, s in counts.items()
}
Цікл кодавае запит, шукае найбольш верагодны наступнік апошньага токена, дадзеў яго да адной табліцы і выведае декодаваны текст. Якщо наступніка няма, вяртаецца None, які выступае ў ролі токена зупнэння. Саме дадзенне да адной табліцы ёсьць ключовай ступенём: выходны данные станавяцца вхіднымі.
seq = enc.encode("the agent calls")
for _ in range(3):
nxt = table.get(seq[-1])
if nxt is None: # our toy "stop token"
break
seq.append(nxt) # output becomes input
print(enc.decode(seq))
Прылічэнне расте на адны токен за кожны крок:
the agent calls the
the agent calls the model
the agent calls the model.
Адзін дакладны момант ёсць павучы. У корпусе слова „the“ частаюць пасля „model“ і „tool“ аднакова частота, а max застаўляе тое, што пазнаў першы. Рэальныя моделі сталквуюцца з такімі майже равнымі распадамі постаўна, таму так важлівы настройкі выбору прымэроў.
Адкліканне прымэроў
Зберагуйце фрагменты ў аднам скрыптэ, напрыклад examples/part01_tokens.py, разам з файлам requirements.txt, у якім перыядначаны tiktoken. Ён выводзіць распад токэнаў, выконвае расчыткі бюджету і запускае простую петлю за адну секунду, у автонамны режым пасля таго, як данні токенайзера будуць зберагнутыя у кэш. Потым зменіце корпус і старайцесь, каб выходныя данні таксама змениліся.
pip install -r requirements.txt
python examples/part01_tokens.py
Ключовыя выводы
- LLM — это зафіксаваная функцыя, якая ператварае последовальнась токэнаў у распад наступных токэнаў, і якая працуе ў цыклі зворотнага зв’язку.
Спадневаная літэратура
- Розумеўце AI-агентаў: цялі, інструменты, память і цыкл агента — простае поясненне таго, чым AI-агенты адрозніццаятся ад чатботаў, з акцэнам на ключовыя складовы, цыкл прыняцтва рашэнняў, рывень автонаміі і практычныя прыклады выкарыстання.
- LangGraph протык Pydantic AI: Чаму самэй модель, а не фрэймворк, вялічыню точнасці — Контрольваныя тэсты, якія адбыліся 160 разоў з LangGraph і Pydantic AI, паказваюць аднаковую тачнасць выканання задаў, і паказвае, што выбор модэлі і спосаб експертызы маюць набагато большое значэнне.
- Дэбаггін малог GPT у PyTorch: Тэсты, якія ізолююць кожную памылку — Этапавы процес дэбаггіну GPT на рывень симвалаў у PyTorch, ад ідэнтыфікацыі ID токенаў і змены цэлей да вычыслення градыянтав, значэнняў NaN і чекпоінтаў.
- Token Budgets vs. Semantic Boundaries: Getting RAG Chunk Splits Right — Дазвольце дазнацься, як разлічаецца токенізацыя і чанкаванне, яе месца ў процэсе RAG, а таксама як правільна разбіваць дакументы па значэннях, выкарыстоўваючы рэальны токенізатор і вылічаючы ўжоўшчыну.