thoughts on building LLM based apps

сейчас у меня каждый проект каким-то образом завязан на LLM. и я заметил что как клиенты так и коллеги не особо видят LLM-ки вне рамок какого-то чата.

то есть, приходит заказ, и либо клиент хочет чтобы была LLM, либо коллеги решают что это идеальный кейс для LLM. и строят прототип где всё завязано вокруг чата. все используют LLM как intelligence двигатель: чтобы он чатился, думал, делал и выдавал результаты.

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

люди как будто не видят LLM кроме как чат. имхо, это слишком усложняет код и мышление о проекте.

llm + embeddings + bm25 + агенты стали современным молотком.

но я заметил две другие идеи которые работают. LLM чаще всего кидают на задачи где проблема что данные не структурированные: открытые поля, текстовые документы, мнения, комментарии.

моё видение того что работает: использовать LLM не как intelligence двигатель, которому через промпты пытаешься объяснить как что-то сделать и молишься что так и произойдёт всегда. а как инструмент для того чтобы выводить структуры из неструктурированных документов. типичный structured output.

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

это напоминает то что говорил Dijkstra:

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

хороший пример этого принципа это hooks в Claude code и других инструментах. это кусок кода который запускается при каком-то event и делает что-то автоматически. например, LLM пытается вызвать npm install или pip install, а у вас надо использовать pnpm или uv. hook останавливает вызов если видит паттерн и сообщает LLM как правильно. таким образом оно всегда будет знать как правильно сделать, а не забывать в длинном разговоре.

второй метод это auto research, но о нём в следующем посте.