Дата публикации
ai_products

Tendril: агент, который сам пишет себе инструменты и помнит их между сессиями

Что нового

Tendril — десктопный агент, который сам расширяет свои возможности. Он не получает сразу «мешок» инструментов. Вместо этого он умеет только три вещи:

  1. Искать существующие возможности в реестре.
  2. Регистрировать новые инструменты (способности).
  3. Исполнять код в песочнице Deno.

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

  • Первый запрос: «fetch the top stories from Hacker News».
    • Tendril не находит подходящий инструмент.
    • Пишет код fetch_url, регистрирует его, запускает.
  • Второй запрос: «now fetch Lobsters and compare».
    • Tendril уже видит fetch_url в реестре.
    • Просто вызывает его без пересборки.

Реестр возможностей растет с каждым использованием. Каждая следующая сессия работает с уже накопленным набором инструментов.

Под капотом Tendril использует:

  • AWS Bedrock с моделью Claude (через BedrockModel из @strands-agents/sdk).
  • Strands Agents SDK как агентный фреймворк.
  • Deno как изолированную песочницу для запуска кода.
  • Tauri 2.x (Rust) для десктопного приложения.
  • React 18 и TailwindCSS v4 для интерфейса.

Как это работает

Базовый цикл агента

В центре Tendril — агент Strands с минимальным набором инструментов. В agent.ts создают объект Agent с моделью Claude через AWS Bedrock и тремя основными инструментами:

import { Agent } from '@strands-agents/sdk';
import { BedrockModel } from '@strands-agents/sdk/models/bedrock';

const agent = new Agent({
  model: new BedrockModel({
    modelId: '...',
    region: '...'
  }),
  systemPrompt: TENDRIL_SYSTEM_PROMPT(workspacePath),
  printer: nullPrinter, // suppress SDK stdout — we own the protocol
  tools: [
    listCapabilities(registry),
    registerCapability(registry),
    executeCode(registry, workspacePath, config),
  ],
});

Эти инструменты отвечают за три ключевых действия:

  • listCapabilities / searchCapabilities — поиск в реестре способностей.
  • registerCapability — запись новой способности в реестр и на диск.
  • executeCode — запуск кода в песочнице Deno.

Автономное поведение через промпт

Файл loop/prompt.ts задает строгие правила поведения агента. Перед любым действием Tendril обязан:

  1. Вызвать searchCapabilities(query) и проверить, есть ли подходящий инструмент.
  2. Если инструмент найден — вызвать loadTool(name), затем execute(code, args).
  3. Если инструмента нет — сам написать код инструмента и зарегистрировать его.

Часть системного промпта:

BEFORE acting on any request:

  1. Call searchCapabilities(query) to check if a relevant tool exists
  2. If found: call loadTool(name) then execute(code, args)
  3. If NOT found: you MUST build the tool yourself.

RULES:

  • NEVER ask "would you like me to create a tool?" — just build it.
  • If a tool fails, read the error, fix the code, and retry.
  • NEVER answer from training data when a tool could get live information.

То есть Tendril не спрашивает разрешения на создание инструмента и не опирается на «знания из обучения», если задачу можно решить кодом и актуальными данными.

Агентный цикл и протокол

Файл index.ts связывает агентный цикл с протоколом ACP (Agent Integrator Specification), который использует, например, Claude Code. Агент запускает поток agent.stream(userText), а хост отслеживает фазы:

// The agentic loop runs inside agent.stream().
// We observe each phase and forward to the UI.

for await (const event of agent.stream(userText)) {
  const { phase, event: e } = classifyEvent(event);

  switch (phase) {
    case 'think':
      emitUpdate(handleThink(e));
      break; // text delta
    case 'act':
      emitUpdate(handleAct(e));
      break; // tool call
    case 'observe':
      emitUpdate(handleObserve(e));
      break; // tool result
  }
}

Фазы:

  • think — агент «думает» и генерирует текст.
  • act — вызывает инструменты.
  • observe — получает результаты и продолжает цикл.

Обмен с агентом идет по JSON-RPC 2.0 поверх NDJSON через stdin/stdout. Агент — отдельный процесс, который Tauri запускает как сайдкар.

Архитектура

Схема из проекта:

  • Tauri Shell (Rust)

    • ACP Host (acp.rs) — мост между UI и агентом по NDJSON.
    • Events (events.rs) — трансляция событий в Tauri Events.
    • React Frontend (TailwindCSS v4) — интерфейс.
  • Agent (Node.js SEA)

    • Strands SDK → BedrockModel → Claude.
    • 4 базовых инструмента в loop/tools.ts.
    • Реестр способностей (registry.ts) — index.json + файлы инструментов.
    • Песочница (sandbox.ts) — подпроцесс Deno с ограниченными правами.

Коммуникация:

  • JSON-RPC 2.0 / NDJSON по stdin/stdout.
  • Агент запускается Tauri-хостом как отдельный бинарь (SEA — Single Executable Application для Node.js).

Реестр способностей

Tendril хранит все способности в рабочей директории пользователя. Структура:

~/tendril-workspace/
  index.json      ← реестр (name, triggers, suppression rules)
  tools/
    fetch_url.ts      ← реализация инструмента (TypeScript, Deno)
    summarize_text.ts
    parse_json.ts

Каждая способность содержит:

  • name — идентификатор в snake_case.
  • capability — одно предложение с описанием.
  • triggers — фразы и сигналы в диалоге, которые должны вызывать инструмент.
  • suppression — условия, при которых инструмент вызывать не нужно.

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

Ограничение количества инструментов

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

Поверхность инструментов не растет, растут только способности, описанные в файлах и index.json.

Технологический стек

Проект делится на две части:

  • tendril-agent/ — TypeScript-агент на Strands SDK.

    • src/ — исходники агента:
      • agent.ts — конфигурация агента (модель + инструменты).
      • index.ts — оркестратор, связывает цикл и транспорт.
      • loop/ — логика агентного цикла:
        • tools.ts — 4 базовых инструмента.
        • prompt.ts — системный промпт.
        • registry.ts — CRUD для index.json.
        • sandbox.ts — запуск Deno с сэндбоксингом.
      • transport/ — протокол общения:
        • protocol.ts — ACP JSON-RPC по stdio.
        • stream.ts — маппинг событий SDK на фазы цикла.
        • errors.ts — классификация ошибок провайдера.
    • tests/ — тесты на vitest.
    • sea-config.json — конфигурация сборки SEA-бинаря Node.js.
  • tendril-ui/ — десктопное приложение.

    • src/ — React-компоненты и хуки.
    • src-tauri/ — Rust-бэкенд Tauri (ACP-хост, события).

Таблица из проекта:

| Компонент | Технология | |------------------|--------------------------------------------------| | Desktop shell | Tauri 2.x (Rust) | | Frontend | React 18 + TailwindCSS v4 | | Agent | TypeScript (Node.js SEA binary) | | Agent framework | @strands-agents/sdk | | Inference | AWS Bedrock (Claude через Strands BedrockModel)| | Code sandbox | Deno (бандлится, подпроцесс с permission flags) | | Protocol | JSON-RPC 2.0 / NDJSON по stdio |

Что это значит для вас

Когда Tendril полезен

Tendril имеет смысл рассматривать, если вы:

  • Разрабатываете собственных агентов и хотите посмотреть, как реализовать «саморасширяющийся» набор инструментов.
  • Пишете десктопные приложения и интересуетесь интеграцией агента через ACP-протокол.
  • Хотите, чтобы агент запоминал, какие инструменты уже писал для вас, и не тратил токены на повторную генерацию кода.
  • Планируете строить внутренние тулкиты: агент пишет скрипты под ваши задачи, вы их ревьюите, правите и оставляете в проекте.

Хорошие сценарии использования:

  • Автоматизация рутинных действий с вебом и файлами: парсинг страниц, загрузка данных, простые ETL-пайплайны.
  • Быстрая генерация мелких утилит: парсеров, конвертеров форматов, анализаторов логов.
  • Эксперименты с агентными циклами: как вести журнал способностей, как управлять сэндбоксом и правами.

Где лучше не применять

  • Продакшен-критичные системы, где безопасность кода критична. Код генерирует модель Claude, он запускается в Deno с ограничениями, но вам все равно нужно ревьюить логику и права доступа.
  • Сценарии без доступа к AWS Bedrock. Tendril опирается на Bedrock и требует корректно настроенные AWS credentials.
  • Пользовательские сценарии «из коробки». Tendril — это больше референс-реализация и песочница для разработчиков, чем готовый ассистент для широкой аудитории.

Доступность и ограничения

  • Нужен аккаунт AWS с доступом к Bedrock и модели Claude (например, us.anthropic.claude-sonnet-4-5-20250514).
  • Нужны корректно настроенные креды в ~/.aws/credentials.
  • Проект — десктопный, на Tauri, без отдельного облачного сервиса.
  • Если AWS Bedrock недоступен из вашей сети, понадобится VPN или работа через инфраструктуру, которая уже имеет доступ к AWS.

Место на рынке

Tendril конкурирует не с потребительскими ассистентами, а с инструментами для разработчиков агентов и IDE-агентами.

Ближайшие по духу решения:

  • Claude Code и другие хосты, реализующие ACP-протокол.
  • Агентные фреймворки, которые дают большой набор инструментов и позволяют модели выбирать их.

Конкретные отличия Tendril:

  • Малый фиксированный набор инструментов. Модель всегда видит только три базовых операции, а все остальное хранится в реестре и подгружается по запросу.
  • Постоянный реестр способностей на диске. Инструменты не теряются между сессиями, их можно редактировать руками.
  • Жесткий системный промпт. Агент обязан сначала искать существующий инструмент, и только потом писать новый.

В проекте нет чисел по скорости или стоимости запросов, поэтому сравнивать производительность или цену с GPT-4o, Claude 3.5 Sonnet или другими моделями некорректно. С точки зрения архитектуры Tendril интересен как показательный пример:

  • Как строить агента поверх AWS Bedrock и Claude.
  • Как оформлять протокол ACP и JSON-RPC по stdio.
  • Как организовать накапливаемый реестр инструментов.

Установка

Предварительные требования

Для сборки и запуска Tendril нужны:

  • Node.js 22+ — для сборки агента.
  • Rust toolchain — для сборки Tauri-приложения.
  • AWS credentials с доступом к Bedrock — файл ~/.aws/credentials.

Быстрый старт

Полные команды из проекта:

git clone https://github.com/serverless-dna/tendril.git
cd tendril
make dev

Эта команда:

  • Установит зависимости (npm install для агента и UI).
  • Соберет агента (бандл через esbuild).
  • Скачает Deno и положит его как сайдкар.
  • Создаст шими сайдкара с учетом платформы.
  • Запустит Tauri в dev-режиме.

При первом запуске Tendril попросит выбрать рабочую папку. После этого:

  • Зайдите в Settings.
  • Укажите AWS-профиль и модель Bedrock.

Конфигурация

Все настройки Tendril лежат в ~/.tendril/config.json. Пример:

{
  "workspace": "/Users/you/tendril-workspace",
  "model": {
    "provider": "bedrock",
    "modelId": "us.anthropic.claude-sonnet-4-5-20250514",
    "region": "us-east-1",
    "profile": "your-aws-profile"
  },
  "sandbox": {
    "denoPath": "deno",
    "timeoutMs": 45000,
    "allowedDomains": []
  },
  "agent": {
    "maxTurns": 100
  }
}

Параметры:

  • workspace — путь к директории, где Tendril хранит реестр и инструменты.
  • model — настройки Bedrock:
    • providerbedrock.
    • modelId — идентификатор модели Claude, например us.anthropic.claude-sonnet-4-5-20250514.
    • region — регион AWS, например us-east-1.
    • profile — имя AWS-профиля из ~/.aws/credentials.
  • sandbox:
    • denoPath — путь к бинарю Deno.
    • timeoutMs — таймаут выполнения кода в миллисекундах (по умолчанию 45000).
    • allowedDomains — список доменов, к которым разрешен сетевой доступ из песочницы. Пустой массив означает неограниченный доступ.
  • agent.maxTurns — максимальное число ходов агентного цикла за одну сессию.

Если хотите ограничить сеть для сэндбокса, укажите, например:

"allowedDomains": ["api.example.com"]

Как запустить и собрать

Проект использует Makefile с готовыми целями. Полный список команд из репозитория:

make dev       # Build agent + sidecars, launch Tauri dev
make build     # Build agent (esbuild bundle)
make test      # Run agent tests (vitest)
make lint      # tsc --noEmit + cargo clippy
make fmt       # cargo fmt --check
make check     # Full quality gate (fmt + lint + test)
make release   # Quality gate + cargo tauri build
make clean     # Remove all build artifacts

Рекомендуемый порядок для локальной разработки:

  1. make dev — собрать все и запустить в dev-режиме.
  2. make test — проверить агентные тесты.
  3. make check — полный прогон форматирования, линтеров и тестов.
  4. make release — собрать релизный билд Tauri после прохождения всех проверок.

Структура проекта

Проект организован так:

tendril/
  tendril-agent/       # TypeScript Strands sidecar
    src/               # исходники агента (см. "The Agent Loop")
    tests/             # vitest-тесты
    package.json
    sea-config.json    # Node.js SEA build config

  tendril-ui/          # Tauri + React desktop app
    src/               # React-компоненты и хуки
    src-tauri/         # Rust backend (ACP host, event forwarding)
    package.json

  docs/                # спецификации и референс-реализации
    specs/             # планы и описания фич

  Makefile

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


Читайте также