had
This commit is contained in:
@@ -1,80 +1,184 @@
|
||||
# AgentUI Project Overview
|
||||
# НадTavern (AgentUI): объясняем просто
|
||||
|
||||
## Цель проекта
|
||||
AgentUI — это прокси‑сервер с визуальным редактором пайплайнов (на базе Drawflow), который нормализует запросы от различных клиентов в единый формат и выполняет их через цепочку узлов (nodes). Это позволяет гибко собирать пайплайны обработки текстовых/LLM‑запросов без необходимости вручную интегрировать каждый провайдер.
|
||||
Это инструмент, который помогает слать запросы к ИИ (OpenAI, Gemini, Claude) через простой конвейер из блоков (узлов). Вы кликаете мышкой, соединяете блоки — и получаете ответ в том же формате, в каком спрашивали.
|
||||
|
||||
Коротко: было сложно — стало просто.
|
||||
|
||||
---
|
||||
|
||||
## Основные компоненты
|
||||
Что вы можете сделать
|
||||
|
||||
### Фронтенд: Визуальный редактор
|
||||
- Построен на **Drawflow**.
|
||||
- Поддерживает узлы, входы/выходы и соединения.
|
||||
- Реализована надёжная сериализация/десериализация:
|
||||
- `toPipelineJSON()` сохраняет структуру + все соединения.
|
||||
- `fromPipelineJSON()` восстанавливает узлы и соединения с учётом времени рендера DOM (retry‑логика).
|
||||
- Исправлены баги исчезающих соединений.
|
||||
- В инспекторе узлов отображается оригинальный ID узла, а не runtime ID от Drawflow.
|
||||
- UI подсказки: макрохинты в синтаксисе `[[...]]` (например `[[VAR:system.prompt]]`, `[[OUT:node1.text]]`).
|
||||
|
||||
### Бэкенд: Исполнение пайплайна
|
||||
- Основной код: [`agentui/pipeline/executor.py`](agentui/pipeline/executor.py).
|
||||
- Выполняется **топологическая сортировка** графа для правильного порядка исполнения и предотвращения циклов.
|
||||
- Узлы:
|
||||
- **RawForwardNode**:
|
||||
- Прямой HTTP‑форвардинг с макросами в `base_url`, `override_path`, `headers`.
|
||||
- Автоопределение провайдера.
|
||||
- **ProviderCallNode**:
|
||||
- Унифицированный вызов LLM‑провайдеров.
|
||||
- Преобразует внутренний формат сообщений в специфический формат для OpenAI, Gemini, Anthropic.
|
||||
- Поддерживает параметры `temperature`, `max_tokens`, `top_p`, `stop` (или аналоги).
|
||||
- Поддержка **макросов**:
|
||||
- `{{ path }}` — Jinja‑подобный.
|
||||
- `[[VAR:...]]` — доступ к данным контекста (system, chat, params).
|
||||
- `[[OUT:nodeId(.attr)]]` — ссылки на вывод других узлов.
|
||||
- `{{ OUT.node.* }}` — альтернативная форма.
|
||||
|
||||
### API сервер (`agentui/api/server.py`)
|
||||
- Нормализует запросы под форматы `/v1/chat/completions`, Gemini, Anthropic.
|
||||
- Формирует контекст макросов (vendor, model, params, incoming).
|
||||
- Принять запрос от клиента как есть (OpenAI/Gemini/Claude).
|
||||
- При желании подменить его или дополнить.
|
||||
- Отправить к нужному провайдеру (или прямо «пробросить» как есть).
|
||||
- Склеить финальный ответ в том формате, который ждёт клиент.
|
||||
|
||||
---
|
||||
|
||||
## Текущий прогресс
|
||||
- Исправлены баги сериализации соединений во фронтенде.
|
||||
- Добавлены подсказки по макросам.
|
||||
- Реализована топологическая сортировка исполнения.
|
||||
- Создан универсальный рендер макросов `render_template_simple`.
|
||||
- Интегрирован RawForward с макроподстановкой.
|
||||
- ProviderCall теперь преобразует сообщения под формат конкретного провайдера.
|
||||
Как это работает в 5 шагов
|
||||
|
||||
1) Клиент шлёт HTTP‑запрос на ваш сервер.
|
||||
2) Сервер понимает формат (OpenAI/Gemini/Claude) и делает «унифицированный» вид.
|
||||
3) Загружается ваш пайплайн (схема из узлов) из файла pipeline.json.
|
||||
4) Узлы запускаются по очереди «волнами» и обмениваются результатами.
|
||||
5) Последний узел отдаёт ответ клиенту в нужном формате.
|
||||
|
||||
Если страшно — не бойтесь: всё это уже настроено из коробки.
|
||||
|
||||
---
|
||||
|
||||
## Текущая задача (для нового разработчика)
|
||||
Быстрый старт
|
||||
|
||||
В проекте мы начинаем реализацию **Prompt Manager**, который станет частью узла `ProviderCall`.
|
||||
Вариант А (Windows):
|
||||
- Откройте файл [`run_agentui.bat`](run_agentui.bat) — он сам поставит зависимости и откроет редактор.
|
||||
|
||||
**Что уже решено:**
|
||||
- Архитектура пайплайна, сериализация/десериализация, макросная система, базовые конвертеры форматов.
|
||||
Вариант Б (любой ОС):
|
||||
- Установите Python 3.10+ и выполните:
|
||||
- pip install -r [`requirements.txt`](requirements.txt)
|
||||
- python -m uvicorn agentui.api.server:app --host 127.0.0.1 --port 7860
|
||||
|
||||
**Что нужно сделать:**
|
||||
- [ ] Спроектировать структуру prompt‑менеджера: массив блоков `{ name, role, prompt, enabled, order }`.
|
||||
- [ ] Добавить универсальный рендер макросов, который применяется ко всем блокам перед конвертацией.
|
||||
- [ ] Доработать конвертеры форматов под OpenAI, Gemini, Anthropic, чтобы они учитывали эти блоки.
|
||||
- [ ] Интегрировать prompt‑менеджер в `ProviderCallNode`:
|
||||
- Сборка последовательности сообщений.
|
||||
- Подстановка макросов.
|
||||
- Конвертация в провайдерский формат.
|
||||
- [ ] Реализовать UI prompt‑менеджера во фронтенде:
|
||||
- CRUD операций над блоками.
|
||||
- Drag&Drop сортировку.
|
||||
- Возможность включать/выключать блок.
|
||||
- Выбор роли (`user`, `system`, `assistant`, `tool`).
|
||||
Откройте в браузере:
|
||||
- http://127.0.0.1:7860/ui/editor.html — визуальный редактор узлов
|
||||
- http://127.0.0.1:7860/ui/pipeline.html — редактор «сырых» JSON настроек пайплайна
|
||||
- http://127.0.0.1:7860/ — простая страница с примером запроса
|
||||
|
||||
---
|
||||
|
||||
## Важные файлы
|
||||
- [`static/editor.html`](static/editor.html) — визуальный редактор пайплайнов.
|
||||
- [`agentui/pipeline/executor.py`](agentui/pipeline/executor.py) — логика исполнения пайплайнов, макросов и узлов.
|
||||
- [`agentui/api/server.py`](agentui/api/server.py) — REST API для внешних клиентов.
|
||||
- [`pipeline.json`](pipeline.json) — сохранённый пайплайн по умолчанию.
|
||||
Где лежат важные файлы
|
||||
|
||||
- API сервер: [`agentui/api/server.py`](agentui/api/server.py)
|
||||
- Исполнитель узлов: [`agentui/pipeline/executor.py`](agentui/pipeline/executor.py)
|
||||
- Шаблоны и макросы: [`agentui/pipeline/templating.py`](agentui/pipeline/templating.py)
|
||||
- Определение провайдера (OpenAI/Gemini/Claude): [`agentui/common/vendors.py`](agentui/common/vendors.py)
|
||||
- Активный пайплайн: [`pipeline.json`](pipeline.json)
|
||||
- Пресеты (готовые пайплайны): папка [`presets`](presets/)
|
||||
- Визуальный редактор (страница): [`static/editor.html`](static/editor.html)
|
||||
- Логика сериализации/соединений: [`static/js/serialization.js`](static/js/serialization.js)
|
||||
- Настройка Prompt Manager UI: [`static/js/pm-ui.js`](static/js/pm-ui.js)
|
||||
- Справка по переменным: [`docs/VARIABLES.md`](docs/VARIABLES.md)
|
||||
|
||||
---
|
||||
|
||||
Что такое «узлы»
|
||||
|
||||
Представьте конструктор Лего. Узел — это кубик. Соединяете кубики — получаете конвейер (пайплайн).
|
||||
В проекте есть 4 базовых узла:
|
||||
|
||||
1) SetVars — завести свои переменные.
|
||||
- Пример: MY_KEY, REGION, MAX_TOKENS.
|
||||
- Потом в шаблонах вы можете писать [[MY_KEY]] или {{ MAX_TOKENS }}.
|
||||
|
||||
2) RawForward — «пробросить» входящий запрос как есть дальше (reverse‑proxy).
|
||||
- Полезно, когда вы не хотите ничего менять.
|
||||
|
||||
3) ProviderCall — аккуратно собрать JSON для провайдера (OpenAI/Gemini/Claude) из «кусочков текста» (Prompt Blocks) и отправить.
|
||||
- Это удобно, если вы хотите дописать системное сообщение, переписать текст пользователя и т.п.
|
||||
|
||||
4) Return — оформить финальный ответ под тот формат, который ждёт клиент.
|
||||
- Если клиент прислал в стиле OpenAI, вернём в стиле OpenAI; можно принудительно выбрать формат.
|
||||
|
||||
Узлы соединяются линиями «из выхода в вход». Так вы задаёте порядок.
|
||||
|
||||
---
|
||||
|
||||
Простые «заклинания» (макросы), которые работают в шаблонах
|
||||
|
||||
- [[VAR:путь]] — взять значение из входящего запроса.
|
||||
- Например: [[VAR:incoming.headers.authorization]]
|
||||
- [[OUT:n1.что‑то]] — взять кусочек результата из узла n1.
|
||||
- [[OUT1]] — взять «самый понятный текст» из узла n1 (короткая форма).
|
||||
- [[PROMPT]] — умный фрагмент JSON, который автоматически соберётся из ваших Prompt Blocks для выбранного провайдера.
|
||||
- {{ путь }} — вставка без кавычек (подходит для чисел/массивов/объектов).
|
||||
- {{ путь|default(значение) }} — вставка с безопасным дефолтом.
|
||||
|
||||
Пример 1 (OpenAI, фрагмент шаблона тела запроса):
|
||||
{
|
||||
"model": "{{ model }}",
|
||||
[[PROMPT]],
|
||||
"temperature": {{ incoming.json.temperature|default(0.7) }}
|
||||
}
|
||||
|
||||
Пример 2 (вставим токен из заголовка в заголовки запроса):
|
||||
{"Authorization":"Bearer [[VAR:incoming.headers.authorization]]"}
|
||||
|
||||
Подробная шпаргалка — в файле [`docs/VARIABLES.md`](docs/VARIABLES.md).
|
||||
|
||||
---
|
||||
|
||||
Первый рабочий пайплайн за 3 минуты
|
||||
|
||||
Цель: взять сообщение пользователя, немного «пригладить» его и вернуть ответ в стиле OpenAI.
|
||||
|
||||
1) Добавьте узел SetVars (можно пропустить).
|
||||
2) Добавьте узел ProviderCall.
|
||||
- В инспекторе выберите провайдера (например, openai).
|
||||
- В Prompt Blocks создайте блоки:
|
||||
- system: «Ты — помощник. Отвечай коротко.»
|
||||
- user: «[[VAR:chat.last_user]] — перепиши текст красивее.»
|
||||
- В шаблоне тела (template) не трогайте структуру — там уже есть [[PROMPT]].
|
||||
3) Добавьте узел Return.
|
||||
- Оставьте «auto», чтобы формат ответа совпал с входящим.
|
||||
4) Соедините ProviderCall → Return.
|
||||
5) Нажмите «Сохранить пайплайн».
|
||||
6) Отправьте запрос на POST /v1/chat/completions (можно со страницы `/`).
|
||||
|
||||
Если что‑то не работает — смотрите журнал (консоль) и всплывающие подсказки в UI.
|
||||
|
||||
---
|
||||
|
||||
Полезные адреса (админка)
|
||||
|
||||
- GET /admin/pipeline — получить текущий пайплайн.
|
||||
- POST /admin/pipeline — сохранить пайплайн.
|
||||
- GET /admin/presets — список пресетов.
|
||||
- GET/POST /admin/presets/{name} — загрузить/сохранить пресет.
|
||||
- GET /admin/trace/stream — «живой» поток событий исполнения. Редактор подсвечивает узлы (начал/успешно/ошибка).
|
||||
|
||||
Это уже настроено в [`agentui/api/server.py`](agentui/api/server.py).
|
||||
|
||||
---
|
||||
|
||||
Где смотреть логи
|
||||
|
||||
- Сервер пишет в консоль шаги узлов и ответы провайдеров.
|
||||
- В UI редакторе видно подсветку состояний узлов (события из /admin/trace/stream).
|
||||
- При необходимости включите/отключите подробность логов в коде узлов [`agentui/pipeline/executor.py`](agentui/pipeline/executor.py).
|
||||
|
||||
---
|
||||
|
||||
Важная безопасность (прочитайте!)
|
||||
|
||||
- Никогда не храните реальные ключи в файлах в репозитории (pipeline.json, пресеты).
|
||||
- Передавайте ключи через заголовки запроса клиента:
|
||||
- OpenAI: Authorization: Bearer XXXXXX
|
||||
- Anthropic: x-api-key: XXXXXX
|
||||
- Gemini: ?key=XXXXXX в URL
|
||||
- В шаблонах используйте подстановки из входящего запроса: [[VAR:incoming.headers.authorization]], [[VAR:incoming.headers.x-api-key]], [[VAR:incoming.api_keys.key]].
|
||||
- В логах при разработке печатаются заголовки и тело. Для продакшена выключайте или маскируйте их.
|
||||
|
||||
---
|
||||
|
||||
Частые ошибки и быстрые решения
|
||||
|
||||
- «Соединения между узлами пропадают»
|
||||
- Нажмите «Загрузить пайплайн» ещё раз: редактор терпеливо дождётся DOM и восстановит линии.
|
||||
- «Шаблон JSON ругается на запятые/скобки»
|
||||
- Убедитесь, что [[PROMPT]] стоит без лишних запятых вокруг; числа/массивы вставляйте через {{ ... }}.
|
||||
- «Нет ответа от провайдера»
|
||||
- Проверьте ключ и URL/endpoint в конфигурации узла ProviderCall (инспектор справа).
|
||||
- «Нужен просто прокси без изменений»
|
||||
- Используйте узел RawForward первым, а потом Return.
|
||||
|
||||
---
|
||||
|
||||
Для любопытных (необязательно)
|
||||
|
||||
Код устроен так:
|
||||
- Сервер создаётся здесь: [`agentui/api/server.py`](agentui/api/server.py)
|
||||
- Исполнение узлов и «волны» — здесь: [`PipelineExecutor.run()`](agentui/pipeline/executor.py:136)
|
||||
- Провайдерный вызов и Prompt Blocks — здесь: [`ProviderCallNode.run()`](agentui/pipeline/executor.py:650)
|
||||
- Простой шаблонизатор (две скобки): [`render_template_simple()`](agentui/pipeline/templating.py:187)
|
||||
|
||||
Этого достаточно, чтобы понимать, куда заглянуть, если захотите кое‑что подкрутить.
|
||||
|
||||
Удачи! Запускайте редактор, соединяйте узлы и получайте ответы без боли.
|
||||
|
||||
Reference in New Issue
Block a user