Plano 0.4.3: когда AI-агенты перестали быть сплошным копипастом
Представьте: вы пишете пятого по счету AI-агента. Снова нужна аутентификация через Bearer Token. Снова логирование запросов. Снова обработка ошибок от API. Рука уже тянется к Ctrl+C, Ctrl+V из предыдущего проекта. Знакомо? Вот именно для этого и появился Plano 0.4.3 с его Filter Chains.
Plano — не очередной монолитный фреймворк вроде LangChain. Это скорее конструктор с Lego. Каждый фильтр — отдельный кубик. Аутентификация, логирование, трансформация запросов, кэширование — всё это становится переиспользуемыми модулями. И версия 0.4.3 наконец-то сделала эту идею рабочей в продакшене.
Актуальность на 20.01.2026: В Plano 0.4.3 полностью переработана система HTTP-фильтров, добавлена нативная поддержка MCP (Model Context Protocol) версии 2.1, и самое главное — появилась стабильная интеграция с OpenRouter API последней ревизии.
Что такое Filter Chains и почему они меняют всё
Фильтры в Plano — это middleware для ваших LLM-запросов. Как в Express.js или FastAPI, только для AI. Каждый фильтр получает запрос, что-то с ним делает (добавляет заголовки, логирует, модифицирует), и передает дальше по цепочке.
Вот типичная проблема без фильтров:
# Старый подход — дублирование кода везде
def call_llm_with_auth(prompt):
headers = {
"Authorization": f"Bearer {os.getenv('API_KEY')}",
"Content-Type": "application/json"
}
# Логируем начало
logger.info(f"Sending request: {prompt[:100]}...")
try:
response = requests.post(ENDPOINT, json={"messages": prompt}, headers=headers)
response.raise_for_status()
except requests.exceptions.RequestException as e:
logger.error(f"API error: {e}")
raise
# Логируем результат
logger.info(f"Response received: {response.status_code}")
return response.json()
# И этот же код в каждом агенте, в каждом сервисе...
Теперь посмотрите, как это выглядит с Filter Chains:
# Plano 0.4.3 — фильтры как отдельные компоненты
from plano.filters import (
BearerAuthFilter,
RequestLoggerFilter,
ErrorHandlerFilter,
RateLimitFilter
)
# Собираем цепочку один раз
llm_chain = FilterChain([
RequestLoggerFilter(level="INFO"),
BearerAuthFilter(api_key_env="OPENROUTER_KEY"),
RateLimitFilter(requests_per_minute=30),
ErrorHandlerFilter(retry_count=3)
])
# Используем везде
response = llm_chain.execute({
"model": "openai/gpt-4.5-turbo",
"messages": [{"role": "user", "content": prompt}]
})
# И не нужно таскать этот boilerplate по всем файлам
Разница очевидна. Фильтры становятся строительными блоками. Нужно добавить кэширование? Подключаем CacheFilter. Требуется валидация входных данных? ValidatorFilter. Всё это работает как модули, которые можно тестировать отдельно, версионировать и переиспользовать.
OpenRouter в Plano: один клиент для всех моделей
OpenRouter — это шлюз к десяткам моделей: от GPT-4.5-turbo и Claude-3.7-Sonnet до открытых моделей вроде Llama-4-90B и Command-R+. В Plano 0.4.3 интеграция с OpenRouter работает через те же фильтры, что дает невероятную гибкость.
Вот как выглядит переключение между моделями:
# Настраиваем цепочку для OpenRouter
openrouter_chain = FilterChain([
BearerAuthFilter(api_key_env="OPENROUTER_KEY"),
OpenRouterModelFilter(default_model="openai/gpt-4.5-turbo"),
CostTrackerFilter() # Следим за расходами!
])
# Используем GPT-4.5
response_gpt = openrouter_chain.execute({
"messages": messages,
"model": "openai/gpt-4.5-turbo" # Можно явно указать
})
# Или переключаемся на что-то подешевле
response_cheap = openrouter_chain.execute({
"messages": messages,
"model": "anthropic/claude-3.5-haiku" # Быстро и недорого
})
# Или на open-source вариант
response_oss = openrouter_chain.execute({
"messages": messages,
"model": "meta-llama/llama-4-90b-instruct"
})
Фильтр CostTrackerFilter — отдельная магия. Он автоматически считает стоимость каждого запроса, предупреждает о превышении лимитов и даже может динамически переключаться на более дешевые модели, если текущая слишком дорога для задачи.
Реальный кейс: система поддержки с тремя уровнями агентов
Давайте представим систему поддержки, где:
- Первый агент классифицирует запрос (техподдержка, продажи, жалоба)
- Второй агент извлекает нужную информацию из базы знаний
- Третий агент формулирует ответ
Без Plano это три отдельных сервиса с кучей повторяющегося кода. С Plano:
# Базовые фильтры для всех агентов
base_filters = FilterChain([
RequestLoggerFilter(),
BearerAuthFilter(api_key_env="OPENROUTER_KEY"),
TimeoutFilter(seconds=30),
RetryFilter(max_retries=2)
])
# Агент-классификатор
classifier_agent = Agent(
filters=base_filters + [
PromptTemplateFilter(template="Classify: {query}"),
ModelSelectorFilter(preferred_models=["gpt-4-turbo"])
],
post_processors=[ClassificationPostProcessor()]
)
# Агент поиска в базе знаний
knowledge_agent = Agent(
filters=base_filters + [
RAGFilter(vector_store="pinecone"),
ContextWindowFilter(max_tokens=4000)
]
)
# Агент-ответчик
responder_agent = Agent(
filters=base_filters + [
ToneAdjustmentFilter(tone="professional"),
LanguageFilter(language="ru")
]
)
# И связываем их в pipeline
support_pipeline = AgentPipeline([
classifier_agent,
knowledge_agent,
responder_agent
])
Обратите внимание: base_filters используется всеми тремя агентами. Изменили логику аутентификации? Правим в одном месте. Добавили кэширование? Подключаем CacheFilter к base_filters. Всё.
Если вам интересна архитектура с суб-агентами, посмотрите статью Как правильно использовать суб-агентов в AI-разработке: 3 реальных сценария — там подробно разбираются подобные схемы.
Plano vs. LangChain vs. LlamaIndex: что выбрать в 2026?
| Критерий | Plano 0.4.3 | LangChain 0.2.x | LlamaIndex 0.12.x |
|---|---|---|---|
| Модульность | Фильтры как независимые компоненты | Цепочки (Chains), менее гибкие | Специализирован на RAG |
| Переиспользование кода | Отличное (filter chains) | Среднее | Слабое |
| Производительность | Асинхронные фильтры, минимум overhead | Известные проблемы с памятью | Оптимизирован под поиск |
| MCP поддержка | Нативная, версия 2.1 | Через сторонние плагины | Ограниченная |
| Сложность входа | Низкая (чистый Python) | Высокая (свой DSL) | Средняя |
Plano не пытается быть всем для всех. Он решает конкретную проблему: как строить модульные AI-агенты без дублирования кода. Если вам нужен готовый RAG-фреймворк — берите LlamaIndex. Если хотите быстро собрать prototype — LangChain еще жив. Но если вы строите продакшен-систему из множества взаимодействующих агентов, Plano с его Filter Chains — самый разумный выбор.
Начинаем работать: первые 15 минут с Plano
1 Установка и настройка
Plano работает с Python 3.10+. Установка стандартная:
pip install plano==0.4.3
# Или через poetry, если вы современный человек
poetry add plano@0.4.3
2 Первый агент с OpenRouter
import os
from plano import Agent, FilterChain
from plano.filters import (
BearerAuthFilter,
RequestLoggerFilter,
OpenRouterModelFilter
)
# Получаем ключ от OpenRouter
# (регистрируемся на OpenRouter.ai)
os.environ["OPENROUTER_API_KEY"] = "ваш_ключ"
# Собираем цепочку фильтров
filters = FilterChain([
RequestLoggerFilter(level="DEBUG"),
BearerAuthFilter(api_key_env="OPENROUTER_API_KEY"),
OpenRouterModelFilter(default_model="openai/gpt-4.5-turbo")
])
# Создаем агента
assistant = Agent(
name="Помощник",
filters=filters,
system_prompt="Ты полезный AI-ассистент"
)
# Запускаем
response = assistant.ask("Привет! Как дела?")
print(response.content)
3 Добавляем свои фильтры
Вот где начинается магия. Создаем свой фильтр для цензуры:
from plano.filters import BaseFilter
class ProfanityFilter(BaseFilter):
"""Фильтр матерных слов"""
def __init__(self, bad_words=None):
self.bad_words = bad_words or ["плохое_слово1", "плохое_слово2"]
async def process(self, request, next_filter):
# Проверяем промпт
prompt = request.get("messages", [{}])[-1].get("content", "")
for word in self.bad_words:
if word in prompt.lower():
# Заменяем на звездочки
cleaned = prompt.replace(word, "*" * len(word))
request["messages"][-1]["content"] = cleaned
# Передаем дальше по цепочке
return await next_filter.process(request)
# И используем
safe_chain = FilterChain([
ProfanityFilter(),
BearerAuthFilter(api_key_env="OPENROUTER_API_KEY")
])
Фильтры могут быть асинхронными, синхронными, могут модифицировать запросы и ответы, прерывать цепочку, добавлять метаданные — полная свобода.
Кому подойдет Plano 0.4.3 (а кому нет)
Берите Plano, если:
- Строите систему из нескольких взаимодействующих AI-агентов
- Устали копировать код аутентификации и логирования между проектами
- Нужна гибкость в выборе моделей (OpenRouter идеален для этого)
- Хотите легко тестировать компоненты агентов по отдельности
- Работаете с MCP и нуждаетесь в стандартизированном интерфейсе
Не берите Plano, если:
- Нужен готовый RAG-фреймворк «из коробки» (смотрите в сторону Production-ready AI-агент с нуля для кастомных решений)
- Ищете максимально простой способ сделать чат-бота за 5 минут
- Работаете только с одной моделью (например, только GPT) и не планируете менять
- Предпочитаете «магические» фреймворки, где всё работает само (Plano требует понимания архитектуры)
Важный нюанс: Plano 0.4.3 всё еще имеет версию 0.x.x. API может меняться. Для критически важных продакшен-систем проверяйте changelog перед обновлениями. Но для новых проектов — стабильности хватает.
Что дальше? Прогнозы на 2026
Фильтры в Plano — это только начало. В ближайшие месяцы жду:
- Визуальный конструктор цепочек — перетаскивать фильтры как в n8n (кстати, о n8n и AI-агентах есть отличная статья: AI-агент 3-го уровня на n8n и OpenRouter)
- Готовые фильтры для популярных сервисов — Notion, Slack, GitHub, Jira
- Автоматическую оптимизацию цепочек — AI, который сам подбирает оптимальную последовательность фильтров
- Еще более тесную интеграцию с MCP — возможность превращать любой фильтр в MCP-сервер одной строкой
Пока остальные фреймворки пытаются быть «франкенштейнами», которые умеют всё (и поэтому ничего не умеют хорошо), Plano выбрал другой путь. Модульность. Переиспользование. Чистая архитектура.
И знаете что? Это работает. После того как вы соберете первую цепочку фильтров и поймете, что тот же код аутентификации теперь работает в десяти разных агентах без единого изменения — назад дороги нет.
Кстати, если хотите посмотреть на альтернативные подходы к архитектуре агентов, посмотрите Как спроектировать современного AI-агента — там разбираются planner/executor паттерны и stateful memory.
Мой совет: установите Plano 0.4.3 сегодня. Создайте простую цепочку с парой фильтров. Покопайтесь в исходниках — они читаемые. И через пару часов вы поймете, почему модульные агенты — это не будущее, а настоящее, которое уже здесь.
Только не забудьте про CostTrackerFilter, когда начнете экспериментировать с GPT-4.5-turbo. Trust me on this one.