feat(skills): vision-subagent + web-search v0.2.0 — dual-mechanism (pi tool + claude script)
- vision-subagent: describe_image tool (pi) / describe-image script (claude, routerai, standard OpenAI image_url — pi-legacy format NOT accepted) - web-search: search_web tool (pi) / search-web script (claude, llm-web-proxy); pro-search (Expert Mode) does not live-search — default is flash-search (Instant Mode) Sources synced to ~/.claude/skills + ~/.agents/skills via install.sh; dist rebuilt. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
BIN
dist/vision-subagent.skill
vendored
BIN
dist/vision-subagent.skill
vendored
Binary file not shown.
BIN
dist/web-search.skill
vendored
Normal file
BIN
dist/web-search.skill
vendored
Normal file
Binary file not shown.
@@ -1,20 +1,20 @@
|
||||
---
|
||||
name: vision-subagent
|
||||
author: ours
|
||||
version: 0.1.0
|
||||
version: 0.2.0
|
||||
description: >
|
||||
Use when you need to SEE an image (photo, screenshot, PCB render, diagram,
|
||||
picture file) but your model does not support images — e.g. a read tool
|
||||
result was omitted with "tool image omitted: model does not support images",
|
||||
or the user asks what is shown in a picture / asks you to look at a
|
||||
screenshot / render. Delegate the vision work to a vision-capable subagent
|
||||
via the describe_image tool instead of guessing or saying you can't.
|
||||
instead of guessing or saying you can't.
|
||||
---
|
||||
|
||||
# Vision Subagent
|
||||
|
||||
Твоя модель не видит изображения — картинки выбрасываются из контекста.
|
||||
Не угадывай содержимое и не отказывайся: делегируй зрение сабу с видящей моделью.
|
||||
Не угадывай содержимое и не отказывайся: делегируй зрение видущему субагенту.
|
||||
|
||||
## Когда вызывать
|
||||
|
||||
@@ -27,7 +27,9 @@ description: >
|
||||
|
||||
## Как вызывать
|
||||
|
||||
Вызови тул `describe_image`:
|
||||
### Через тул `describe_image` (pi)
|
||||
|
||||
Если у тебя доступен тул `describe_image`:
|
||||
|
||||
```
|
||||
describe_image:
|
||||
@@ -35,8 +37,19 @@ describe_image:
|
||||
question: "точечный вопрос" # опционально
|
||||
```
|
||||
|
||||
### Через скрипт describe-image (Claude Code на deepseek и любой агент)
|
||||
|
||||
Если тула нет — запусти субагента-скрипт через Bash:
|
||||
|
||||
```
|
||||
node ~/projects/.common/lib/describe-image/describe-image.mjs --path "<абсолютный путь|URL>" [--question "точечный вопрос"]
|
||||
```
|
||||
|
||||
Скрипт печатает в stdout описание от видящей модели — этот текст и есть
|
||||
результат «зрения», верни его пользователю/в свой ответ.
|
||||
|
||||
Пример точечного вопроса:
|
||||
`path: "C:\Users\vitya\Downloads\screen.png"`, `question: "Какое сообщение об ошибке в красной рамке сверху?"`
|
||||
`node ~/projects/.common/lib/describe-image/describe-image.mjs --path "C:\Users\vitya\Downloads\screen.png" --question "Какое сообщение об ошибке в красной рамке сверху?"`
|
||||
|
||||
## Правила
|
||||
|
||||
@@ -44,23 +57,29 @@ describe_image:
|
||||
если ты её не видел — это галлюцинация.
|
||||
2. **Задавай точечные вопросы.** Не соглашайся на generic-описание, если тебе
|
||||
нужны конкретные детали (текст, координаты, цвета, что на заднем плане).
|
||||
Если ответа не хватило — вызови `describe_image` ещё раз с уточнением.
|
||||
3. **Если `describe_image` упал** (нет vision-модели, ошибка сети) — честно скажи
|
||||
пользователю, что зрение сейчас недоступно, и предложи путь дальше
|
||||
(например, переключить модель на видящую через `/model`).
|
||||
Если ответа не хватило — вызови ещё раз с уточнением.
|
||||
3. **Если зрение недоступно** (упал тул/скрипт: нет vision-модели, ошибка сети) —
|
||||
честно скажи пользователю, что зрение сейчас недоступно, и предложи путь дальше.
|
||||
|
||||
## Настройка vision-модели
|
||||
|
||||
Модель задаётся ЯВНО (по приоритету):
|
||||
1. env `PI_VISION_MODEL` — например `routerai/minimax-m3`
|
||||
2. файл `~/.pi/vision-model.json` — `{ "model": "routerai/minimax-m3" }`
|
||||
1. env `PI_VISION_MODEL` — например `routerai/meta/muse-glimmer-30b`
|
||||
2. файл `~/.pi/vision-model.json` — `{ "model": "routerai/meta/muse-glimmer-30b" }`
|
||||
|
||||
Авто-выбора нет — если модель не задана, `describe_image` вернёт ошибку с подсказкой.
|
||||
Авто-выбора нет — если модель не задана, зрение вернёт ошибку с подсказкой.
|
||||
Конфиг общий для pi и Claude Code (единый источник правды).
|
||||
|
||||
## Реализация тула
|
||||
## Реализация
|
||||
|
||||
Тул `describe_image` — pi-расширение:
|
||||
`~/projects/pi-extensions/extensions/vision-subagent.ts` (репо
|
||||
`OpeItcLoc03/pi-extensions`, дом pi-расширений). Правки — в клоне репо →
|
||||
- **Скрипт (Claude Code / любой агент):** `~/projects/.common/lib/describe-image/describe-image.mjs`
|
||||
— субагент на клиенте OpenAI API (пакет `openai`), зовёт routerai
|
||||
(`https://routerai.ru/api/v1`). Модель — из `PI_VISION_MODEL`/`~/.pi/vision-model.json`,
|
||||
ключ — `~/.pi/agent/auth.json` (провайдер и base URL — из префикса модели, напр. `routerai/…`).
|
||||
**Формат картинки — стандартный OpenAI `image_url`** (`data:<mime>;base64,…`).
|
||||
pi-legacy `{type:"image",data,mimeType}` routerai НЕ принимает (модель отвечает
|
||||
«no image data») — не «чинить» обратно по комментарию в pi-расширении.
|
||||
- **pi-расширение (тул `describe_image`):** `~/projects/pi-extensions/extensions/vision-subagent.ts`
|
||||
(репо `OpeItcLoc03/pi-extensions`, дом pi-расширений). Правки — в клоне репо →
|
||||
`commit + push` → `just install` (затирает home-копию). Конфиг-example:
|
||||
`~/projects/pi-extensions/config/vision-model.json.example`.
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
---
|
||||
name: web-search
|
||||
author: ours
|
||||
version: 0.1.0
|
||||
version: 0.2.0
|
||||
description: >
|
||||
Use when the user asks for fresh or external information — news, prices,
|
||||
versions, dates, current facts — or says «поищи», «найди актуальное»,
|
||||
"search for", "look up". Search the web via the `search_web` tool (a
|
||||
search-capable model from llm-web-proxy with live citations) instead of
|
||||
guessing from training data, refusing, or scraping by hand. Search is ON by
|
||||
default — the agent decides when to call it; the user can turn it OFF for
|
||||
the rest of the session by saying «без поиска» / "no search".
|
||||
"search for", "look up". Search the web via a search-capable model from
|
||||
llm-web-proxy with live citations (`search_web` tool or the `search-web`
|
||||
script) instead of guessing from training data, refusing, or scraping by
|
||||
hand. Search is ON by default — the agent decides when to call it; the user
|
||||
can turn it OFF for the rest of the session by saying «без поиска» / "no search".
|
||||
---
|
||||
|
||||
# Web Search
|
||||
|
||||
Твоя основная модель не имеет веб-поиска. `search_web` — тул, который
|
||||
отправляет запрос search-модели (веб-поиск DeepSeek с цитатами) на чистом
|
||||
контексте и возвращает ответ с [1][2]-источниками. **Поиск включён по
|
||||
умолчанию** — не отказывайся и не выдумывай, когда нужны свежие данные.
|
||||
Твоя основная модель не имеет веб-поиска. Поиск идёт через search-модель
|
||||
(веб-поиск DeepSeek с цитатами) на чистом контексте и возвращает ответ с
|
||||
[1][2]-источниками. **Поиск включён по умолчанию** — не отказывайся и не
|
||||
выдумывай, когда нужны свежие данные.
|
||||
|
||||
## Когда вызывать search_web
|
||||
## Когда вызывать поиск
|
||||
|
||||
- Юзер просит «поищи X», «найди актуальное про Y», "search for", "look up".
|
||||
- Вопрос про свежие/внешние данные: новости, цены, версии, даты релизов,
|
||||
@@ -30,17 +30,30 @@ description: >
|
||||
|
||||
- Вопросы по коду/проекту, дизайн, рефакторинг — ответ в репо и контексте.
|
||||
- Уже загруженные доки/файлы сессии — не ищи то, что уже прочитано.
|
||||
- **Юзер сказал «без поиска» в этой сессии** — тул не вызывать до конца сессии.
|
||||
- **Юзер сказал «без поиска» в этой сессии** — поиск не вызывать до конца сессии.
|
||||
|
||||
## Как вызывать
|
||||
|
||||
### Через тул `search_web` (pi)
|
||||
|
||||
```
|
||||
search_web:
|
||||
query: "последняя версия Rust — что нового в релизе"
|
||||
```
|
||||
|
||||
Один запрос = **один вызов** тула. Не спамить серией поисков — если ответа
|
||||
не хватило, уточни запрос один раз.
|
||||
### Через скрипт search-web (Claude Code и любой агент)
|
||||
|
||||
Если тула нет — запусти субагента-скрипт через Bash:
|
||||
|
||||
```
|
||||
node ~/projects/.common/lib/search-web/search-web.mjs --query "последняя версия Rust — что нового в релизе"
|
||||
```
|
||||
|
||||
Скрипт печатает в stdout ответ search-модели (с [1][2]-цитатами и списком
|
||||
источников) — это и есть результат поиска.
|
||||
|
||||
Один запрос = **один** вызов (тула/скрипта). Не спамить серией поисков —
|
||||
если ответа не хватило, уточни запрос один раз.
|
||||
|
||||
## Правила ответа
|
||||
|
||||
@@ -52,29 +65,40 @@ search_web:
|
||||
## Механизм «без поиска»
|
||||
|
||||
- **Default**: поиск включён — сам решаешь, когда нужны свежие данные.
|
||||
- Юзер: «без поиска» / "no search" → **перестань вызывать search_web до конца
|
||||
- Юзер: «без поиска» / "no search" → **перестань вызывать поиск до конца
|
||||
сессии**. Подтверди одной строкой. Не искать даже если запрос «поисковый».
|
||||
- Юзер снова: «поищи» → верни поиск (повторный грант, до конца сессии).
|
||||
- Следующая сессия — снова поиск включён (грант не переживает сессии).
|
||||
|
||||
## Ошибки тула
|
||||
## Ошибки
|
||||
|
||||
`search_web failed: ...` — честно скажи юзеру, что поиск недоступен
|
||||
(модель не настроена: `/search-status`, или сервер llm-web-proxy не запущен:
|
||||
`lwp serve`), и предложи путь дальше.
|
||||
`search_web failed: ...` (или ненулевой exit скрипта) — честно скажи юзеру,
|
||||
что поиск недоступен (модель не настроена, или сервер llm-web-proxy не
|
||||
запущен: `lwp serve`), и предложи путь дальше.
|
||||
|
||||
## Настройка
|
||||
|
||||
Search-модель (default `lwp/deepseek-pro-search-web`, pro-search):
|
||||
Search-модель (default `lwp/deepseek-flash-search-web`):
|
||||
1. env `PI_SEARCH_MODEL` — например `lwp/deepseek-flash-search-web`
|
||||
2. файл `~/.pi/search-model.json` — `{ "model": "..." }`
|
||||
|
||||
Тул `search_web` — pi-расширение `~/projects/pi-extensions/extensions/search-web.ts`
|
||||
⚠️ `lwp/deepseek-pro-search-web` (pro-search, Expert Mode) живой поиск НЕ
|
||||
выполняет — отвечает из обучения («unavailable in Expert Mode»). Рабочая —
|
||||
flash-search (Instant Mode). Не «чинить» дефолт обратно на pro.
|
||||
|
||||
## Реализация
|
||||
|
||||
- **Скрипт (Claude Code / любой агент):** `~/projects/.common/lib/search-web/search-web.mjs`
|
||||
— субагент на клиенте OpenAI API (пакет `openai`), зовёт локальный
|
||||
llm-web-proxy (`http://127.0.0.1:8788/v1`, `stream:false`). Модель — из
|
||||
`PI_SEARCH_MODEL`/`~/.pi/search-model.json`, ключ+baseUrl — из
|
||||
`~/.pi/agent/models.json` → `providers["llm-web"]` (общий конфиг с pi).
|
||||
- **pi-расширение (тул `search_web`):** `~/projects/pi-extensions/extensions/search-web.ts`
|
||||
(репо `OpeItcLoc03/pi-extensions`). Правки — commit + push → `just install` → `/reload`.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- НЕ автоматический поиск в каждом сообщении — тул зовётся, когда запрос
|
||||
- НЕ автоматический поиск в каждом сообщении — поиск зовётся, когда запрос
|
||||
реально требует внешних данных.
|
||||
- НЕ скрейпинг страниц (это browser-cdp): search_web ищет и отвечает с цитатами,
|
||||
- НЕ скрейпинг страниц (это browser-cdp): поиск ищет и отвечает с цитатами,
|
||||
а не открывает конкретные URL.
|
||||
|
||||
Reference in New Issue
Block a user