Проблема: Зачем отказываться от LangChain?
LangChain стал де-факто стандартом для создания AI-агентов, но у этого подхода есть серьезные недостатки. Фреймворк превратился в монолита с сотнями зависимостей, где даже простой агент требует подключения десятков пакетов. Это приводит к:
- Раздутым бандлам — ваш проект весит сотни мегабайт
- Сложности отладки — когда что-то ломается, непонятно, в каком слое фреймворка искать проблему
- Низкой производительности — много слоев абстракции замедляют выполнение
- Vendor lock-in — ваш код становится привязанным к конкретной реализации
Если вам нужен простой агент для конкретной задачи (парсинг сайтов, обработка документов, автоматизация рутинных действий), LangChain — это избыточно. Как в статье про Cogitator, мы ищем минималистичные альтернативы.
Решение: Bun + простые библиотеки = легковесный агент
Bun — это не просто быстрый JavaScript-рантайм. Это целая экосистема с нативной поддержкой TypeScript, встроенным пакетным менеджером и тест-раннером. Вместо того чтобы тянуть за собой весь LangChain, мы соберем агента из:
- Bun — как среда выполнения
- OpenAI API (или любой другой провайдер) — для LLM
- Cheerio — для парсинга DOM (альтернатива LangChain's document loaders)
- Свой собственный код — 100% контроль над логикой
Пошаговый план: от нуля до работающего агента
1 Установка и настройка окружения (5 минут)
Сначала установите Bun, если еще не сделали этого:
curl -fsSL https://bun.sh/install | bash
Создайте новый проект:
mkdir my-ai-agent
cd my-ai-agent
bun init
Установите необходимые зависимости:
bun add openai cheerio
bun add -D @types/node typescript
Обратите внимание: мы устанавливаем только 2 основные зависимости! Сравните это с десятками пакетов в типичном LangChain-проекте.
2 Создание базового агента (10 минут)
Создайте файл agent.ts с простейшей реализацией:
import OpenAI from 'openai';
class SimpleAgent {
private openai: OpenAI;
constructor(apiKey: string) {
this.openai = new OpenAI({ apiKey });
}
async think(prompt: string): Promise {
const completion = await this.openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{ role: "system", content: "Ты полезный AI-агент. Отвечай кратко и по делу." },
{ role: "user", content: prompt }
],
temperature: 0.7,
});
return completion.choices[0].message.content || "Нет ответа";
}
}
// Использование
const agent = new SimpleAgent(process.env.OPENAI_API_KEY!);
const response = await agent.think("Какая погода в Москве?");
console.log(response);
Запустите агента:
OPENAI_API_KEY=your_key_here bun run agent.ts
3 Добавляем DOM парсинг (10 минут)
Теперь расширим функциональность, добавив возможность анализа веб-страниц. Создайте файл web-agent.ts:
import OpenAI from 'openai';
import * as cheerio from 'cheerio';
class WebAgent {
private openai: OpenAI;
constructor(apiKey: string) {
this.openai = new OpenAI({ apiKey });
}
async fetchAndParse(url: string): Promise {
const response = await fetch(url);
const html = await response.text();
const $ = cheerio.load(html);
// Удаляем скрипты и стили для чистого текста
$('script, style, nav, footer').remove();
// Берем основной контент
const text = $('body').text()
.replace(/\s+/g, ' ') // Убираем лишние пробелы
.trim()
.substring(0, 4000); // Ограничиваем длину для токенов
return text;
}
async analyzeWebsite(url: string, question: string): Promise {
const websiteContent = await this.fetchAndParse(url);
const prompt = `На основе содержимого сайта ответь на вопрос.
Содержимое сайта:
${websiteContent}
Вопрос: ${question}`;
return this.think(prompt);
}
private async think(prompt: string): Promise {
const completion = await this.openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
role: "system",
content: "Ты специалист по анализу веб-контента. Отвечай только на основе предоставленной информации."
},
{ role: "user", content: prompt }
],
temperature: 0.5,
});
return completion.choices[0].message.content || "Не могу проанализировать";
}
}
// Пример использования
const agent = new WebAgent(process.env.OPENAI_API_KEY!);
const answer = await agent.analyzeWebsite(
"https://example.com",
"Какие услуги предлагает этот сайт?"
);
console.log(answer);
4 Добавляем цепочку вызовов (5 минут)
Чтобы агент мог выполнять последовательность действий, реализуем простую цепочку:
class SequentialAgent extends WebAgent {
async processMultiple(urls: string[], question: string): Promise {
const results: string[] = [];
for (const url of urls) {
try {
const result = await this.analyzeWebsite(url, question);
results.push(`Результат для ${url}: ${result}`);
} catch (error) {
results.push(`Ошибка для ${url}: ${error}`);
}
}
return results;
}
async summarizeResults(results: string[]): Promise {
const prompt = `Суммируй следующие результаты анализа:
${results.join('\n\n')}`;
return this.think(prompt);
}
}
Нюансы и возможные ошибки
| Проблема | Решение | Пояснение |
|---|---|---|
| Превышение лимита токенов | Обрезать контент до 3000-4000 символов | GPT-4o-mini имеет контекст 128K, но для скорости лучше ограничиться |
| Медленная загрузка страниц | Добавить timeout и retry логику | Используйте AbortController для контроля времени |
| Проблемы с кодировкой | Конвертировать текст в UTF-8 | Bun автоматически обрабатывает кодировки, но проверьте |
| Слишком частые запросы к API | Добавить rate limiting | Используйте p-limit или простой счетчик |
Важный нюанс: Bun использует свой собственный fetch API, который может отличаться от Node.js. Всегда проверяйте, что ваши HTTP-запросы работают корректно в продакшене.
Что дальше? Развитие вашего агента
Теперь, когда у вас есть базовый агент, можно добавить более сложные функции:
- Память агента — сохраняйте контекст между вызовами (см. статью про Agent Skills)
- Инструменты (Tools) — дайте агенту доступ к API, базам данных, файловой системе
- Планировщик задач — разбивайте сложные задачи на подзадачи
- Локальные модели — вместо OpenAI используйте локальные LLM (как в статье про 7 маленьких LLM на ноутбуке)
Преимущество нашего подхода в том, что вы контролируете каждую часть системы. Нет черного ящика, как в LangChain. Вы точно знаете, какой код выполняется и почему.
Заключение
Создание AI-агента на Bun за 30 минут — это не только возможно, но и практично. Вы получаете:
- Минимальные зависимости — 2 пакета вместо 200
- Полный контроль — ваш код, ваша логика
- Высокую производительность — Bun работает быстрее Node.js
- Простоту отладки — меньше слоев абстракции
Этот подход особенно хорош для:
- Прототипирования идей
- Специфических задач (парсинг, анализ, автоматизация)
- Образовательных целей (чтобы понять, как работают агенты на низком уровне)
- Продакшена, где важны контроль и производительность
Как показано в статье про Claude Opus, будущее за агентами, которые могут работать автономно. Начните с простой реализации на Bun, и постепенно расширяйте функциональность по мере необходимости.