- BrainTools - https://www.braintools.ru -

Привет, хабр, меня зовут Кияшева Екатерина. Вообще я из QA, но сегодня сделаю шаг в сторону и разберу архитектуру агентов на базе языковых моделей.
За последний год встречалась масса литературы об AI, она, или теоретическая — не ясно, как это пощупать, или углубленная в одну тему — не сразу ясно какую задачу решает. Эта статья — обзор теоретической базы, но с прикладным характером. Интересно открыть капот агента, извелечь основные компоненты, покрутить и подумать над каждым.
На ур. QA важно знать «как эта штука работает», чтоб осмысленно применять паттерны тест‑дизайна. На человеческом ур. надоела маска «волшебства» вокруг ИИ, хочется смахнуть ее и рассмотреть инструмент предметно: как устроен, какой бывает, через что с ним работать, как подобрать модель.
Модели бывают:
языковые;
аудио;
компьютерное зрение [12] (Computer Vision – CV);
мультимодальные.
Как ясно из названий, они отличаются по типу модальностей, с которыми работают. Языковые – берут на вход текст, аудио – звуковую дорожку, CV – картинку. Мультимодальные умеют работать больше, чем с одним типом информации.
Примеры:
Оцифровка текста с фотографий – мультимодальная (CV + Языковая);
Генерация видео по фото – мультимодальная (CV + Аудио/Видео);
Генерация картинки по текстовому описанию – мультимодальная (Языковая + CV);
Генерация программного кода по текстовому описанию – языковая модель (LLM).
Отдельное направление работы с моделями – их обучение [13] (Model Learning – ML). Берем данные, семейство функций по которым будет рассуждать модель, измеритель ошибок этих рассуждений, алгоритм отбора наилучшего рассуждения, запускаем процесс отбора. На тему ML есть отличная серия статей от автора @ysrgsyn [14], излагает доступно, по полочкам, небольшими частями.
Большие языковые модели (Large Language Model – LLM), всем известные GPT, Gemini, DeepSeek, Claude, Kimi, Qwen, Llama, и т.д. – предобученные языковые модели от разных производителей.
Классифицировать модели можно по функциям и по возможностям:
Функциональную классификацию удобно смотреть на Hugging Face [15]: это “старая” площадка, задуманная, как аналог GitHub. Создана, когда модели имели свою специализацию: генерировать, суммаризировать, анализировать, работать с таблицами и т.д. Эти и многие др. функции со временем вобрали в себя LLM.
Инструментальную классификацию удобно смотреть на Ollama [16]: более новая площадка, работает как менеджер моделей. В ее реестре есть всего три фильтра:
thinking – LLM функция мыслительного процесса Chain-of-Thought. Когда модель думает по цепочке, проверяет каждый вывод, прежде чем дать ответ.
tool – LLM функция вызова действия. Когда модель самостоятельно вызывает выданные ей инструменты, например пушить код или открывать браузер.
embeddings – тип модели, нацеленный на извлечение смыслов из текста. В отличие от LLM – эти модели возвращают на выход не текст, а координаты смысла.
На сегодня есть целая линейка моделей с полным набором функциональностей и инструментов. Они конкурируют между собой: по интеллекту [17], стоимости, стабильности, ресурсоемкости. Ситуация непрерывно меняется, так что невозможно сказать, какая модель лучше. Но можно отслеживать динамику развития по лидербордам: следить за трендами изменений последних лет, оценивать на что упирает производитель; подбирать модель под свои нужды, опираясь на прогноз.
|
Лидерборд |
Тип модели |
Фокус сравнения |
|
Artificial Analysis [18] |
Генеративная |
Бизнес-ориентированный. Динамика инвестиций в модели, их развитие, стоимость токенов, интеллектуальность, предсказуемость и т.д. Информация, чтобы подобрать баланс между стоимостью и возможностями модели. |
|
benchlm.ai [19] |
Генеративная |
Прикладной. Рейтинг моделей в разрезе способностей – Agentic, Coding, Multimodal, Reasoning и т.д. Информация, чтобы подобрать баланс между стоимостью, скоростью вместительностью в контексте прикладной задачи. |
|
MTEB [20] |
Векторная |
Функциональный. Сравнение моделей по качеству понимания смыслов. Информация, чтобы подобрать баланс между точностью поиска, скоростью обработки и объемом векторных данных для построения систем RAG. |
Итак, современные нейронки умеют мыслить, кодировать, выполнять любые команды за человека, полностью самостоятельно. Рассмотрим подкапотное пространство: что, кроме модели, необходимо для этой деятельности.
LLM – форвард AI-активностей, она берет задачу пользователя, генерирует решение, что-то отвечает. Все модели живут одним действием. Осмысленный диалог, связный код, согласованная цепочка действий получается за счет агентных механизмов. Это специальная прослойка, которая вызывает LLM в цикле:
отправляет запрос,
записывает ответ в историю диалога,
на каждом круге дополняет историю последним запросом юзера и ответом LLM,
отправляет новый запрос с накопленной историей и доп. инструкциями – контекстом.
В простом виде взаимодействие с генеративной моделью выглядит как-то так:

Пользователь написал свой запрос (user-prompt) ➔ агент взял запрос + контекст, сформировал все в промпт и отправил ➔ LLM сгенерировала ответ ➔ агент, получив ответ, пополнил контекст и вернул ответ пользователю.
О правилах и практиках составления промтов есть отличный ресурс Prompt Engineering Guide [21]. Там доступно и по шагам излагаются паттерны промптинга, актуальные для любой модели. Паттерн-исключение “Chain-of-Thought”: неактуален и даже вреден в работе с thinking моделями, поскольку механизм “думать по шагам” в них встроен.
Агентные механизмы обогащают, суммаризируют, сегментируют, классифицируют накопленный контекст, чтобы каждый новый ответ казался продолжением предыдущего взаимодействия. Так что, когда говорят, у LLM короткая память [22], на самом деле это ошибка [23]. В реальности памяти нет вообще, короткая память у агентного механизма, которым выполняется работа с моделью.
Задача агентного механизма
проконтролировать заполненность контекстного окна, чтобы не получить ошибку переполнения вроде ‘400: “Request payload size exceeds the limit’,
сформировать такой промпт, чтобы ответ модели был предельно уместным с учетом предыдущего контекста.
Далее я буду использовать примеры кода, надерганные из личных экспериментов. Это фрагменты и винегрет из разных библиотек. Прошу воспринимать, как псевдокод, только для передачи мысли.
Уместность ответа регулируется не только контекстном, но и параметрами. Через параметры можно управлять ресурсоемкостью и софт характеристиками ответа. Рассмотрим типовой запрос в LLM с параметрами ответа.
# Формируем историю сообщений
messages = [
{"role": "system", "content": "<системная инструкция>"},
]
# Получаем и добавляем в историю user-prompt
query = "<запрос пользователя>"
messages.append({"role": "user", "content": query})
# Создаем финальный промпт с параметрами для запроса в LLM
payload = {
"model": "deepseek-v4-flash",
"messages": messages,
"stream": True,
"options": {
"temperature": 0.1,
"top_k": 400,
"top_p": 0.5,
"min_p": 0.05,
"repeat_penalty": 1.1,
"presence_penalty": 0.0,
"frequency_penalty": 0.0,
"num_predict": 2048,
"stop": ["Пользователь"]
}
}
# Отправляем финальный промпт в LLM
try:
response = requests.post(
"https://ollama.com/api/chat",
headers=headers,
json=payload,
timeout=120
)
# Извлекаем ответ модели и добавляем в историю
data = response.json()
answer = data["message"]["content"]
messages.append({"role": "assistant", "content": answer})
UX-параметры:
stream: True – модель будет набирать ответ в режиме реального времени, при false вернула бы его целиком;
Num_predict (или max_token): 2048 – ограничение длины ответа (токенов, шт.), позволяет управлять стоимостью работы с моделью;
stop: [“Пользователь”] – модель остановит набор и отправит ответ, как только напишет стоп-слово. Здесь дополнительная защита от бесконечной переписки самой с собой.
Модель набирает ответ, последовательно выбирая токены с наибольшей вероятностью. Вероятность – это производная величина, числовая оценка того, каким именно должно быть продолжение.
Вычисляется вероятность примерно так: сначала модель определяет смысловой “вес” токенов (логиты), потом Softmax-функцией пересчитывает вес в вероятности. По ходу вычисления, можно подкручивать веса, так чтоб модель увеличивала и уменьшала диапазон вероятных продолжений.
Штраф-параметры (подкручивают логиты):
repeat_penalty: 1.1 – “мягкий цензор”: уменьшает вес слов, уже встречавшихся в контексте, в 1,1 раза. При repat_penalty = 1, никакого воздействия, при repat_penalty меньше 1 слово-дубликат увеличивает вес;
presence_penalty: 0.0 – “штраф за факт”: уменьшает вес слова-дубликата на 0,1;
frequency_penalty: 0.0 – “штраф за частоту”: уменьшает вес слова-дубликата пропорционально количеству повторений. Если слово встречается 5 раз, штраф будет 0,5.
Параметр креативности (подкручивает логиты):
temperature: 0,1 – управляет “азартом”: здесь модель заостряет вероятности выбора, возводит их в 10 степень (=1/0,1), так что разница между вариантами ответов становится более видимой. При температуре больше 1 наоборот бы сглаживала в сторону уравнения.
Параметры адекватности (фильтрует вероятности):
top_k: 400 – ограничивает выборку “штуками”: модель смотрит только на 400 самых релевантных вариантов;
top_p: 0.5 – ограничивает выборку “качеством”: оставляет варианты, чья суммарная вероятность достигает 50%;
min_p: 0.05 – отсекает «мусор»: выбрасывает токены, вероятность которых меньше 5% от вероятности самого лучшего варианта.
Параметры работают друг за другом, сначала группа штрафов, потом температура, и в конце осечка по адекватности.
Комбинации на примерах: top_p: 0,1 и temperature:2 – вернет самые необычные ответы из самых адекватных; temperature:0 вернет самый логичный ответ; temperature:1,2 и min_p: 0,4 вернет что-то на грани безумия, но без откровенной дичи.
LLM с функцией tool, умеет вызывать действие. Для этого программируем в агентной прослойке обертки для выполнения действий – тулы, передаем в модель набор тулов вместе с промптом. В ответ нейронка сама будет выбирать инструмент и возвращать команды для активации того или иного действия.
MCP (Model Context Protocol) – способ пакетировать тулы в комплекты: унифицированные, переносимые, безопасные. Собираем комплект, запускаем на сервере и юзаем его различными моделям по API.
# Формируем список доступных инструментов для LLM с call-to-action инструкцией
tools = []
for t in mcp_tools:
tools.append({
"type": "function",
"function": {
"name": t["<название инструмента>"],
"description": t.get("<инструкция, когда использовать>"),
"parameters": t.get("inputSchema", {"type": "object", "properties": {}, "required": []}),
},
})
# Формируем финальный промпт со списком доступных инструментов
payload = {
"model": "deepseek-v4-flash",
"messages": messages,
"tools": tools, # Передача перечня инструментов
"stream": False,
"options": {
"temperature": 0.1,
"num_predict": 2048,
"num_ctx": 16000
},
}
# Отправляем финальный промпт в LLM
try:
resp = requests.post(
"https://ollama.com/api/chat",
headers=headers,
json=payload,
timeout=120
)
resp.raise_for_status()
msg = resp.json()["message"]
# Если модель вызвала инструмент - исполняем его
if msg.get("tool_calls"):
for tc in msg["tool_calls"]:
name = tc["function"]["name"]
args = tc["function"]["arguments"]
result = mcp_client.call_tool(name, args)
RAG (Retrieval-Augmented Generation) – LLM дает ответы не из своей нейросети, а какие-то конкретные, из кастомной базы знаний. Актуально, когда база знаний существенно больше, чтоб влезть в один промпт целиком и существенно отличается, чтобы удовлетвориться предобученным ответом LLM.
Общая схема работы: агентный механизм получает запрос юзера ➔ делает выборку из БД ➔ добавляет в промпт результат выборки ➔ отправляет обогащенный промпт в генеративную модель.
Центральное звено в схеме занимает векторная база данных. База может быть любой, но векторная получила большое распространение благодаря функции семантического поиска. Данные в ней хранятся в виде коллекций, есть поддержка функции “перевода” текста в смыслы (эмбеддинг). Рассмотрим типовую схему данных векторной БД.
Ids – идентификатор элемента в коллекции;
Embeddings – массив чисел, смысловой вектор элемента, чтобы искать кусок текста по смыслу;
Metadatas – служебная информация, любой набор маркеров текста, чтобы искать текст по кастомным значимым признакам;
Documents – исходный кусок текста сохраненный в БД, именно он эмбедится в вектора и потом передается в LLM в виде промпта.
Непосредственный перевод текста в смыслы выполняет векторная модель. На вход она получает текст в виде токенов ➔ определяет координаты этого текста на каждой своей оси ➔ возвращает массив координат (вектор).
Например, на вход имеем слово “кот”. Векторная модель ищет его в осях координат:
Живое – неживое,
Пушистое – гладкое,
Сладкое – соленое,
Мягкое – твердое,
И т.д.
Размерность модели = количество измерительных осей. Чем больше размерность, тем больше признаков, по которым модель будет оценивать слово.
Работа с векторной БД глобально состоит из 2 частей:
# Режем текст на куски, каждый кусок - один элемент коллекции в ChromaDB
…..
# Создаем/вызываем коллекцию и передаем в нее функцию эмбеддинга
embed_fn = LocalEmbeddingFunction(embed_model)
chroma_client = chromadb.PersistentClient(path=vector_store_path)
try:
collection = chroma_client.get_collection(name=collection_name, embedding_function=embed_fn)
logger.info(" Reusing existing collection '%s'", collection_name)
except Exception:
collection = chroma_client.create_collection(
name=collection_name,
embedding_function=embed_fn,
metadata={"hnsw:space": "cosine"},
)
# Добавляем элементы в коллекцию, эмбеддинг происходит автоматически
collection.add(ids=ids, metadatas=metadatas, documents=documents)
# Получаем запрос пользователя
query = "<текст вопроса пользователя>"
n_results = 600 #орграничитель первичной выборки в шт.
# Эмбеддим запрос пользователя и выбираем n_result с наиближайшими векторами
results = collection.query(query_texts=[query], n_results=n_results, include=["documents", "distances"])
# Фильтруем полученную выборку по дистанции м-у векторами запроса и выборки
# отбрасываем все, что больше max_distance
filtered_docs = []
for doc, dist in zip(results['documents'][0], results['distances'][0]):
if dist <= max_distance:
filtered_docs.append(doc)
# Фильтруем вектора в оставшейся выборке по релевантности
final_context = filtered_docs[:top_k]
# Добавляем в итоговый промпт текст Documents из выборки
context_text = "nn--- {{заголовок ответа}} ---nn".join(final_context)
prompt = f"""
КОНТЕКСТ:
{context_text}
ВОПРОС:
{query}
"""
# Отправляем промпт в LLM
...
NLP (Natural Language Processing) – извлечение из текста непрямых посланий. Возможно замечали, как LLM меняет тон разговора, когда ей пишешь весело или грубо – это проявление NLP.
Небольшой пример из жизни: на скрине финальное сообщение из цепочки запросов о стандартах ISO (perplexity).

В сообщении нет прямой информации, только подтекст. Что тут видно: подтекст считали LLM и агентный механизм:
LLM пересобрала смысловые акценты и выдала, наконец, точный ответ,
Агентный механизм проверил культуру взаимодействия.
Базовая утилитарная функция NLP в агентах – собирать данные о пользователе: как зовут, где находится, чем занимается, что умеет, чем интересуется, и т.д. Все это позволяет формировать по-настоящему персонифицированные промпты, так чтобы LLM буквально видела, кому отвечает.
Общая схема работы: агентный механизм парсит сообщение юзера ➔ извлекает из сообщения важный подтекст ➔ маркирует его и сохраняет в базу данных ➔ берет из базы информацию с наибольшим весом и добавляет ее в промпт в виде инструкции ➔ отправляет промт в LLM.
Центральное звено в схеме занимают NLP-экстракторы: паттерны и NER модели, которые могут разбивать и нормализовать текст, маркировать в нем важную информацию о пользователе.
# Инициализируем NER нейронку Natasha
segmenter = Segmenter() # функция разбивки на предложения и слова
morph_vocab = MorphVocab() # словарь словоформ
emb = NewsEmbedding() # функция-эмбеддер текста
morph_tagger = NewsMorphTagger(emb) # морфологический словарь
ner_tagger = NewsNERTagger(emb) # NER экстрактор
NER_TYPES = {"PER": "person", "ORG": "company", "LOC": "place"} #словарь маркеров
# Получаем запрос пользователя
texts = [
"Привет! Меня зовут Маша, я — frontend-разработчик.",
"Работаю в Яндексе, интересуюсь React.",
"Сейчас делаю проект Grafika.",
"React — это библиотека для UI.",
"Кстати, переезжаю в новый офис, буду ближе к команде.",
]
# Разбираем и маркируем запрос по NER признакам
for text in texts:
doc = Doc(text)
doc.segment(segmenter) # разбиваем текст на слова
doc.tag_morph(morph_tagger) # извелкаем ключевые слова
doc.tag_ner(ner_tagger) # ищем слова про персону, компанию, локацию
seen = set()
entities = []
for span in doc.spans: # перебираем все слова
ntype = NER_TYPES.get(span.type) # получаем NER маркер слова
if not ntype:
continue
span.normalize(morph_vocab) # приводим слово к начальной форме
key = (span.normal.lower(), ntype)
if key not in seen: # дополняем массив словом и его маркером
seen.add(key)
entities.append({"name": span.normal, "type": ntype})
В качестве хранилища – используются графовые базы данных. В отличие от реляционных (SQL) и документ-ориентированных (NoSQL), они умеют в нелинейные связи: позволяют связывать между собой объекты любого типа и легко доставать эти объекты по коротким описаниям связей.
Ниже пример-представление статьи “Чит-лист функционального тестирования, памятка тестировщику [24]” в графовой базе. Здесь:
“Статья” главное звено, от нее идут связи к векторам – слоям тестирования: Данные, Операции, Функциональности, Технология,
“Вектора” связаны с сетами: группами тестов с общим признаком в конкретном слое,
“Сеты” связаны с “Тестами”: конкретными проверками внутри сета
“Теги” воспроизводят нелинейные связи к любым объектом из иерархии.

Резюмируем:
LLM живет одним запросом, она генерирует ответ ровно на тот запрос, какой получила, каждый раз, как в первый раз,
Уместность ответов и эффект связанного диалога создается через промпт, который обогащается после каждого взаимодействия (запроса – ответа),
Промпт – это инструкция с запросом юзера И контекстом (информацией о юзере, историей диалога, кастомными данными юзера, параметрами генерации ответа, системными инструкциями для LLM о форме, тоне и ограничениях ведения диалога).
Промпт должен быть достаточно точным, чтобы создавать эффект связанного процесса и не слишком большой, чтобы уместиться в контекстное окно модели.
Рассмотрим несколько известных подходов сокращения длины контекста:
Buffer Memory – хранит последние N сообщений истории диалога, при достижении границ контекстного окна старая история стирается в пользу новой.
Summary Memory – раз в N сообщений суммаризирует историю диалога в краткий пересказ. За счет этого может хранить более длинную историю, но не очень конкретную – детали и полутона стираются.
Buffer + Summary – свежую историю диалога хранит в исходном виде, а старые сообщения суммаризирует в конспект. Компромисс между длинной контекста и его точностью.
Vector Memory – сохраняет ключевые участки диалога в векторную базу данных, по запросу пользователя может найти их семантическим поиском и добавить в контекст фрагментарно.
Graph Memory – управляет данными о пользователе через структуру связей. Извлекает характеристики юзера из подтекста, сохраняет факты в графовую БД, связывает их между собой и ранее добавленным фактами, назначает связям веса. Чем актуальней информация – тем больше связей с бОльшим весом она имеет. В промпт отправляет факты с наибольшим весом. Для поддержания актуальности – у фактов, в которым долго не обращались, переписывает веса в меньшую сторону или совсем обрывает связи.
Episodic vs Semantic – ранжирует данные о пользователе на постоянные характеристики и события. Постоянные характеристики всегда имеют высокий вес, событийные данные со временем теряют в весе и перестают добавляться в контекст.
Сейчас наблюдается чехарда с терминами, поэтому здесь изложу свою логику [25] и классификацию. Споры, вопросы, уточнения – приветствуются.
Агентное ПО – программа, которая взаимодействует с моделью и организовывает контекст. Глобально выделяется 2 класса:
бизнес-приложения – модель подключается для выполнения бизнес – функции, например записи в парикмахерскую, консультирование, на простые служебные операции.
сервисные “приложения” – модель подключается для автоматизации производственных процессов, разработки другого ПО или других агентов. Слово “приложение” здесь условно, поскольку это ПО активно прорастает в операционные системы и железо.
Оба типа под капотом содержат агентные механизмы, различаются по цели использования, арсеналу и сложности агентных механик. Отдельного внимания [26] требуют сервисные приложения.
|
Тип |
Комментарии |
Примеры |
|
Чат асисстент |
Чаты с функциями настройки диалога, внешней памятью RAG, действиями в интернете. Автоматизируют работу с информацией: ее поиском, анализом, преобразованием, позволяют кастомизировать контекст под себя. |
Чат-ассистенты Perplexity [27] |
|
Конструктор-среда |
Среда разработки в виде конструктора. Содержит пред подготовленные модули-коннекторы для интеграции с нейронкой, различными корпоративными системами и между собой. Упрощает автоматизацию производственных процессов: проверку, преобразование, передачу информацию по цепочке. Действия реализуются через API. |
LangFlow [28] n8n [29] |
|
CLI-среды |
Открытая среда разработки, заточенная под создание агентов. Из коробки: подстраивается под пользователя (формирует контекст), содержит инструменты bash и web (MCP), знает известные языки разработки (механизм LSP). Позволяет: донастраивать контекст (AGENTS.md [30], SKILLS, COMMAND) подключать собственные инструменты (MCP, LSP) чтобы создавать ролевую модель из агентов и делегировать им любые операции. Арсенал позволяет делать любые агентные механизмы, разрабатывать агентный слой любой сложности. |
OpenCode [31] Hermes [32] |
|
IDE-среды |
Среда разработки с GUI интерфейсом, изначально заточенная под написание кода. Теперь IDE- среды перенимают все больше функциональностей CLI-среды и вероятно станут одним и тем же. |
Cursor [33] OpenCode Hermes |
Все сервисные приложения имеют собственную базу подключенных нейронок: покупаешь подписку на использование и получаешь доступ ко всему реестру моделей (из России и в некоторых инструментах почти ко всему).
Бизнес-приложениям необходимо специальное подключение. Нужно выбрать модель, определиться, где она будет хоститься, оценить на перспективу, сколько это будет стоить. Ценообразование напрямую зависит от хостинга:
Локальное – требует покупки и обслуживания своих стоек, важна ресурсоемкость модели;
Облачное – плата за использование серверов хостера;
Онлайн – оплата потраченных токенов.
|
Провайден |
Комментарий |
|
Hugging Face [15] |
Площадка – экосистема. Модели можно скачать, использовать удаленно на ресурсах Huggin Face или онлайн. Варианты использования зависят от провайдера и модели. |
|
Ollama [16] |
Площадка – аппстор. Модели можно скачать в локаль или использовать облачное хранилище олламы. |
|
Open Router [34] |
Провайдер моделей. Подписка позволяет использовать модели из реестра онлайн, плата взимается за токены. |
Автор: ekiyasheva
Источник [35]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/32534
URLs in this post:
[1] Модели: #model
[2] Определения и классификация: #type
[3] Выбор модели: #choise
[4] Агенты: #agent
[5] Агентные механизмы: #mechanizm
[6] Генеративная функция: #generative
[7] MCP: выполнение действий: #mcp
[8] RAG: внешняя память и семантический поиск: #rag
[9] NLP: дешифровка подтекста: #nlp
[10] Контекст: #context
[11] Агентное ПО: #po
[12] зрение: http://www.braintools.ru/article/6238
[13] обучение: http://www.braintools.ru/article/5125
[14] @ysrgsyn: https://habr.com/ru/users/ysrgsyn/
[15] Hugging Face: https://huggingface.co/models
[16] Ollama: https://ollama.com/search
[17] интеллекту: http://www.braintools.ru/article/7605
[18] Artificial Analysis: https://artificialanalysis.ai/trends#open-source
[19] benchlm.ai : http://benchlm.ai
[20] MTEB: https://mteb-leaderboard.hf.space/benchmarks?mods=text
[21] Prompt Engineering Guide: https://www.promptingguide.ai/ru
[22] память: http://www.braintools.ru/article/4140
[23] ошибка: http://www.braintools.ru/article/4192
[24] Чит-лист функционального тестирования, памятка тестировщику: https://habr.com/ru/articles/715262/
[25] логику: http://www.braintools.ru/article/7640
[26] внимания: http://www.braintools.ru/article/7595
[27] Perplexity : https://www.perplexity.ai/
[28] LangFlow : https://www.langflow.org/
[29] n8n: https://n8n.io/
[30] AGENTS.md: http://AGENTS.md
[31] OpenCode : https://opencode.ai/
[32] Hermes : https://hermes-agent.nousresearch.com/docs/
[33] Cursor: https://cursor.com/
[34] Open Router: https://openrouter.ai/models
[35] Источник: https://habr.com/ru/articles/1054412/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1054412
Нажмите здесь для печати.