Каналы
Каналы позволяют взаимодействовать с агентом Qwen Code через мессенджеры, такие как Telegram, WeChat, QQ, DingTalk, WeCom или Feishu, вместо терминала. Вы отправляете сообщения с телефона или десктопного чат-клиента, а агент отвечает так же, как в CLI.
Платформы хостинга кода (начиная с GitHub) также поддерживаются через адаптеры опроса — агент отслеживает уведомления и отвечает на @упоминания в issues и pull requests.
Как это работает
При запуске qwen channel start Qwen Code:
- Читает конфигурации каналов из вашего
settings.json - Запускает единый процесс агента, используя Agent Client Protocol (ACP)
- Подключается к каждому мессенджеру и начинает прослушивать сообщения
- Направляет входящие сообщения агенту и отправляет ответы в нужный чат
Все каналы используют один процесс агента с изолированными сессиями для каждого пользователя. У каждого канала может быть свой рабочий каталог, модель и инструкции.
Быстрый старт
- Настройте бота в вашем мессенджере (см. руководства для конкретных каналов: Telegram, WeChat, QQ Bot, DingTalk, WeCom, Feishu, GitHub)
- Добавьте конфигурацию канала в
~/.qwen/settings.json - Выполните
qwen channel start, чтобы запустить все каналы, илиqwen channel start <name>для одного канала
Хотите подключить платформу, которая не встроена? См. Плагины, чтобы добавить пользовательский адаптер в качестве расширения.
Конфигурация
Каналы настраиваются в ключе channels файла settings.json. Каждый канал имеет имя и набор параметров:
{
"channels": {
"my-channel": {
"type": "telegram",
"token": "$MY_BOT_TOKEN",
"senderPolicy": "allowlist",
"allowedUsers": ["123456789"],
"sessionScope": "user",
"cwd": "/path/to/working/directory",
"instructions": "Optional system instructions for the agent.",
"groupPolicy": "disabled",
"dmPolicy": "open",
"groups": {
"*": { "requireMention": true }
}
}
}
}Параметры
| Параметр | Обязательный | Описание |
|---|---|---|
type | Да | Тип канала: telegram, weixin, qq, dingtalk, wecom, feishu, github или пользовательский тип из расширения (см. Плагины) |
token | Telegram | Токен бота. Поддерживается синтаксис $ENV_VAR для чтения из переменных окружения. Не требуется для WeChat, DingTalk, WeCom или Feishu |
clientId | DingTalk, Feishu | AppKey для DingTalk или App ID для Feishu. Поддерживается синтаксис $ENV_VAR |
clientSecret | DingTalk, Feishu | AppSecret для DingTalk или App Secret для Feishu. Поддерживается синтаксис $ENV_VAR |
botId | WeCom | ID интеллектуального робота WeCom. Поддерживается синтаксис $ENV_VAR. См. WeCom |
secret | WeCom | Секрет интеллектуального робота WeCom. Поддерживается синтаксис $ENV_VAR. См. WeCom |
model | Нет | Модель для этого канала (например, qwen3.5-plus). Переопределяет модель по умолчанию. Полезно для мультимодальных моделей, поддерживающих ввод изображений |
senderPolicy | Нет | Кто может общаться с ботом: allowlist (по умолчанию), open или pairing |
allowedUsers | Нет | Список ID пользователей, которым разрешено использовать бота (используется политиками allowlist и pairing) |
sessionScope | Нет | Область действия сессий: user (по умолчанию), chat_thread или single. Устаревший thread остаётся совместимым, если уже настроен, но не предлагается для новых конфигураций Web Shell |
cwd | Нет | Рабочий каталог для агента. По умолчанию используется текущий каталог |
approvalMode | Нет | Режим одобрения инструментов для сессий канала. Автономные задачи вебхуков требуют yolo; настройка применяется к каждой сессии канала |
instructions | Нет | Пользовательские инструкции, добавляемые в начало первого сообщения каждой сессии |
webhooks | Нет | Источники вебхуков и цели доставки для каналов под управлением демона. См. Задачи, запускаемые вебхуками |
groupPolicy | Нет | Доступ к групповым чатам: disabled (по умолчанию), allowlist, pairing или open. См. Групповые чаты |
dmPolicy | Нет | Доступ к личным сообщениям: open (по умолчанию) или disabled (молча отбрасывать все ЛС). Полезно для ботов только для групп |
groupHistoryLimit | Нет | Включаемая загрузка истории группы. 0 или отсутствие значения отключает её. Положительное число сохраняет указанное количество не упомянутых сообщений группы от авторизованных отправителей или участников одобренных сопряжённых групп для следующего упоминания/ответа бота. |
groups | Нет | Настройки для каждой группы. Ключи — это ID групповых чатов или "*" для значений по умолчанию. См. Групповые чаты |
dispatchMode | Нет | Что происходит при отправке сообщения, пока бот занят: steer (по умолчанию), collect или followup. См. Режимы диспетчеризации |
blockStreaming | Нет | Прогрессивная доставка ответов: on или off (по умолчанию). См. Блочный стриминг |
blockStreamingChunk | Нет | Границы размера чанка: { "minChars": 400, "maxChars": 1000 }. См. Блочный стриминг |
blockStreamingCoalesce | Нет | Сброс при простое: { "idleMs": 1500 }. См. Блочный стриминг |
Политика отправителя
Определяет, кто может взаимодействовать с ботом:
allowlist(по умолчанию) — Только пользователи из спискаallowedUsersмогут отправлять сообщения. Остальные игнорируются без уведомления.pairing— Неизвестные отправители получают код сопряжения. Оператор бота одобряет их через CLI, и они добавляются в постоянный список разрешенных. Пользователи изallowedUsersполностью пропускают этап сопряжения. См. Сопряжение в личных сообщениях ниже.open— Любой может отправлять сообщения. Используйте с осторожностью.
Область действия сессии
Определяет, как управляются сессии диалога:
user(по умолчанию) — Одна сессия на пользователя. Все сообщения от одного пользователя находятся в одном диалоге.thread— Одна сессия на тред/тему. Полезно для групповых чатов с тредами.single— Одна общая сессия для всех пользователей. Все участники ведут один общий диалог.
Память канала
Память канала хранит долговременный контекст для одного чата или треда. Записи имеют стабильные ID, поэтому ответ списка может использоваться для детерминированных последующих операций.
记住:默认使用 staging 环境— детерминированная форма, сохраняющая ровно одну скалярную запись для текущего чата или треда.- Чтобы сохранить несколько отдельных фактов в одном запросе, используйте естественную фразу, маршрутизируемую через классификатор. Например:
请记住这三条约定:使用 staging;发布前测试;优先中文回复создаёт записи, которыми можно управлять независимо. Точные дубликаты фактов пропускаются и сообщаются без создания новой записи. Запросы, содержащие текст, похожий на учётные данные, отклоняются; удалите секреты и сохраните неконфиденциальные факты отдельно. 查看记忆выводит записи и их стабильные ID. Используйте查看第 2 页记忆для просмотра следующей страницы,查看记忆 <id>для просмотра одной записи или естественный запрос с фильтрацией, например只看中文偏好, для вывода совпадающих записей.查看刚才那条记忆,把关于 staging 的记忆改成默认使用 productionи忘掉刚才那条работают, когда естественная ссылка разрешается ровно в одну запись. Естественные обновления и удаления сначала показывают предложенное изменение. Подтвердите обновление с помощью确认更新记忆илиconfirm memory update, или удаление с помощью确认删除记忆илиconfirm memory removalв течение 60 секунд. Обновления и удаления по точному ID остаются немедленными и не требуют подтверждения.清空记忆запускает процесс подтверждения полной очистки;确认清空记忆завершает его.
Когда естественный запрос на просмотр, обновление или удаление соответствует нескольким записям, бот возвращает ID кандидатов и превью без изменения памяти. Нет отложенного выбора для неоднозначного результата: повторите запрос с одним точным ID, например 忘掉 m-a31f0d82c7e4. Операции по точному ID остаются детерминированным быстрым путём. Естественный запрос без совпадений сообщает, что ни одна запись не найдена.
Ожидающие подтверждения обновлений, удалений и полной очистки применяются только к отправителю и чату или треду, создавшему их. Более новое предложение полной очистки, естественного обновления или естественного удаления заменяет более старое ожидающее для того же отправителя и цели. Ожидающие подтверждения отменяются при перезапуске процесса канала.
Устаревшие слеш-алиасы /remember-channel, /channel-memory и /forget-channel удалены. Они больше не являются командами памяти канала.
Память канала следует за гейтами доступа канала. Любое сообщение, принятое senderPolicy, dmPolicy, groupPolicy, настройками группы, сопряжением и требованиями упоминания, может читать, записывать, обновлять или очищать память для этого чата или треда. Принятые участники одной группы используют общее хранилище целей этой группы. Используйте политики allowlist или pairing, когда память группы должна быть ограничена доверенными отправителями.
Устаревшая память CHANNEL.md автоматически мигрирует в структурированное хранилище CHANNEL.json при первой мутации. Структурированная память сохраняется между перезапусками автономного канала и канала под управлением демона и внедряется при запуске новой сессии с целевой областью, в том числе после /clear.
После начального внедрения каждое принятое сообщение также вспоминает до трёх релевантных записей для этого сообщения. Это сохраняет долговременные факты доступными во время длительной сессии без добавления каждой сохранённой записи в каждый ход. Воспоминание основано на текущем сообщении и не изменяет сохранённую память.
Память привязана к текущему чату или треду. Она не внедряется и не вспоминается в сессии sessionScope: single, потому что эта сессия используется всем каналом, а не привязана к одной цели.
Память канала автоматически не изучает факты из обычного разговора и не принимает 第一个 как подтверждение для неоднозначной естественной ссылки. Используйте чёткий запрос запоминания и точный ID записи, когда естественная ссылка неоднозначна.
Безопасность токенов
Токены ботов не следует хранить непосредственно в settings.json. Вместо этого используйте ссылки на переменные окружения:
{
"token": "$TELEGRAM_BOT_TOKEN"
}Установите реальный токен в окружении вашей оболочки или в файле .env, который загружается перед запуском канала.
Сопряжение в личных сообщениях
Когда senderPolicy установлен в "pairing", неизвестные отправители проходят процесс одобрения:
- Неизвестный пользователь отправляет сообщение боту
- Бот отвечает 8-символьным кодом сопряжения (например,
VEQDDWXJ) - Пользователь передает код вам (оператору бота)
- Вы одобряете его через CLI:
qwen channel pairing approve my-channel VEQDDWXJПосле одобрения ID пользователя сохраняется в allowlist канала с областью рабочего пространства (~/.qwen/channels/<workspace-scope>/<name>-allowlist.json), и все последующие сообщения проходят без препятствий. Состояние сопряжения привязано к рабочему пространству, поэтому два рабочих пространства, использующих одно имя канала, хранят отдельные одобрения.
CLI-команды для сопряжения
# Вывести список ожидающих запросов на сопряжение
qwen channel pairing list my-channel
# Одобрить запрос по коду
qwen channel pairing approve my-channel <CODE>Выполняйте эти команды из рабочего каталога канала (или передайте --cwd <dir>) — состояние сопряжения хранится для каждого рабочего пространства.
Правила сопряжения
- Коды состоят из 8 символов в верхнем регистре, используя однозначный алфавит (без
0/O/1/I) - Срок действия кодов истекает через 1 час
- Максимум 3 ожидающих запроса на канал одновременно, и не более одного на отправителя — дополнительные запросы отклоняются, пока один из них не истечёт или не будет одобрен
- Пользователи, указанные в
allowedUsersвsettings.json, пропускают сопряжение пользователя; приgroupPolicy: "pairing"группа всё равно должна быть одобрена - Одобренные пользователи сохраняются для каждого рабочего пространства в
~/.qwen/channels/<workspace-scope>/<name>-allowlist.json— относитесь к этому файлу как к конфиденциальному
Групповые чаты
По умолчанию бот работает только в личных сообщениях. Чтобы включить поддержку групповых чатов, установите для groupPolicy значение "allowlist", "pairing" или "open".
Политика групп
Определяет, участвует ли бот в групповых чатах в принципе:
disabled(по умолчанию) — Бот игнорирует все сообщения в группах. Самый безопасный вариант.allowlist— Бот отвечает только в группах, явно указанных вgroupsпо ID чата. Ключ"*"задает настройки по умолчанию, но не действует как разрешающий шаблон.pairing— Осознанное упоминание или ответ от неизвестной группы создаёт один запрос на сопряжение для группы. После одобрения каждый участник может использовать бота в этой группе;senderPolicyпродолжает управлять личными сообщениями.open— Бот отвечает во всех группах, в которые он добавлен. Используйте с осторожностью.
Группа одобряется той же CLI-командой, что и сопряжение пользователей. Ожидающий запрос идентифицирует группу и участника, который её инициировал:
qwen channel pairing approve my-channel <CODE>Одобрения групп сохраняются по chat ID группы в рабочем пространстве канала. На GitHub и GitLab chat ID — это путь репозитория/проекта, поэтому переименование или перенос отсоединяет сохранённое одобрение — повторно одобрите группу после переименования. Репозиторий или проект, созданный заново под тем же путём, наследует устаревшее одобрение — отзовите одобрения группы после любого переименования, переноса или удаления.
Неупомянутое сообщение никогда не создаёт запрос на сопряжение группы, даже когда в группе установлено requireMention в false; после одобрения применяется настроенная политика упоминаний.
Запросы на сопряжение групп используют ту же очередь ожидающих запросов, что и запросы на сопряжение в личных сообщениях: канал хранит максимум 3 ожидающих запроса, а отправитель — максимум один ожидающий запрос между пользовательскими и групповыми запросами (см. Правила сопряжения).
Фильтрация по упоминаниям
В группах бот по умолчанию требует @упоминания или ответа на одно из своих сообщений. Это предотвращает ответы бота на каждое сообщение в групповом чате.
Настройка для каждой группы через параметр groups:
{
"groups": {
"*": { "requireMention": true },
"-100123456": { "requireMention": false }
}
}"*"— Настройки по умолчанию для всех групп. Задает только значения по умолчанию, не является записью в списке разрешенных.- ID группового чата — Переопределяет настройки для конкретной группы. Имеет приоритет над значениями по умолчанию из
"*". requireMention(по умолчанию:true) — Еслиtrue, бот отвечает только на сообщения, в которых его @упоминают или которые являются ответом на его сообщения. Еслиfalse, бот отвечает на все сообщения (полезно для специализированных рабочих групп).
Загрузка истории группы
По умолчанию Qwen игнорирует сообщения группы без упоминаний и не сохраняет их как ходы сессии. Чтобы следующее @упоминание включало недавний контекст группы, установите для groupHistoryLimit положительное число.
{
"channels": {
"my-dingtalk": {
"type": "dingtalk",
"clientId": "$DINGTALK_CLIENT_ID",
"clientSecret": "$DINGTALK_CLIENT_SECRET",
"groupPolicy": "open",
"groupHistoryLimit": 50,
"groups": {
"*": { "requireMention": true },
"sensitive-group-id": {
"requireMention": true,
"groupHistoryLimit": 0
}
}
}
}
}- Если параметр опущен или равен
0, загрузка истории отключена. groupHistoryLimitна уровне группы переопределяет значение на уровне канала.- Сохраняются только сообщения от авторизованных отправителей или участников одобренной сопряжённой группы.
- Сообщения, отклоненные
groupPolicyили списком разрешенных групп, не сохраняются. - Ожидающая обработки история группы хранится в виде локального JSONL в
~/.qwen/channels/<channel-name>-group-history.jsonlили$QWEN_HOME/channels/<channel-name>-group-history.jsonl. - Кэшированные сообщения внедряются как ненадежный контекст при следующем реальном триггере и не записываются как отдельные ходы сессии.
Как оцениваются сообщения в группах
1. groupPolicy — эта группа отключена, в списке, сопряжена или открыта? (нет → игнорировать/процесс сопряжения)
2. dmPolicy — это ЛС разрешено? (disabled → игнорировать)
3. requireMention — бот был упомянут/ответили на него? (нет → игнорировать)
4. senderPolicy — этот отправитель одобрен? (пропускается для сопряжённой группы; иначе нет → процесс сопряжения пользователя)
5. Направить в сессиюНастройка Telegram для групп
- Добавьте бота в группу
- Отключите privacy mode в BotFather (
/mybots→ Bot Settings → Group Privacy → Turn Off) — иначе бот не будет видеть сообщения без команд - Удалите и повторно добавьте бота в группу после изменения privacy mode (Telegram кэширует эту настройку)
Поиск ID группового чата
Чтобы найти ID чата группы для allowlist groups:
- Остановите бота, если он запущен
- Отправьте сообщение с упоминанием бота в группу
- Используйте Telegram Bot API для проверки обновлений в очереди:
curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates" | python3 -m json.toolНайдите message.chat.id в ответе — ID групп представляют собой отрицательные числа (например, -5170296765).
Поддержка медиа
Каналы поддерживают отправку изображений и файлов агенту, а не только текста.
Изображения
Отправьте фото боту, и агент его увидит — это удобно для обмена скриншотами, сообщениями об ошибках или диаграммами. Изображение отправляется модели напрямую в качестве визуального ввода.
Чтобы использовать поддержку изображений, настройте мультимодальную модель для канала:
{
"channels": {
"my-channel": {
"type": "telegram",
"model": "qwen3.5-plus",
...
}
}
}Файлы
Отправьте документ (PDF, файл с кодом, текстовый файл и т.д.) боту. Файл скачивается и сохраняется во временную директорию, а агенту передается путь к файлу, чтобы он мог прочитать его содержимое с помощью своих инструментов для чтения файлов.
Файлы работают с любой моделью — мультимодальная поддержка не требуется.
Отличия платформ
| Возможность | Telegram | DingTalk | Feishu | |
|---|---|---|---|---|
| Изображения | Прямая загрузка через Bot API | Загрузка через CDN с AES-дешифрованием | downloadCode API (двухэтапный) | Эндпоинт ресурсов Open API (аутентифицированный GET, лимит 50 МБ) |
| Файлы | Прямая загрузка через Bot API (лимит 20 МБ) | Загрузка через CDN с AES-дешифрованием | downloadCode API (двухэтапный) | Эндпоинт ресурсов Open API (лимит 50 МБ) |
| Подписи | Подписи к фото/файлам включаются как текст сообщения | Не применимо | Rich text: смешанный текст + изображения в одном сообщении | Rich text (post): текст извлекается; встроенные изображения игнорируются |
QQ Bot не обрабатывает входящие медиа — сообщения с изображениями и стикерами игнорируются, поэтому для него нет строки обработки медиа в таблице выше.
WeCom принимает текст, изображения, смешанный текст с изображениями, файлы, видео и голосовые сообщения (транскрибированные). Изображения передаются агенту как вложения; файлы и видео загружаются во временные локальные пути. См. WeCom для подробностей.
Режимы диспетчеризации
Определяет, что происходит, когда вы отправляете новое сообщение, пока бот еще обрабатывает предыдущее.
steer(по умолчанию) — Бот отменяет текущий запрос и начинает работать с вашим новым сообщением. Лучше всего подходит для обычного чата, где последующее сообщение обычно означает, что вы хотите исправить или перенаправить бота.collect— Ваши новые сообщения буферизуются. Когда текущий запрос завершается, все буферизованные сообщения объединяются в один последующий промпт. Хорошо подходит для асинхронных рабочих процессов, где вы хотите накапливать мысли.followup— Каждое сообщение ставится в очередь и обрабатывается как свой отдельный ход по порядку. Полезно для пакетных рабочих процессов, где каждое сообщение независимо.
{
"channels": {
"my-channel": {
"type": "telegram",
"dispatchMode": "steer",
...
}
}
}Вы также можете установить режим диспетчеризации для каждой группы, переопределяя значение по умолчанию для канала:
{
"groups": {
"*": { "requireMention": true, "dispatchMode": "steer" },
"-100123456": { "dispatchMode": "collect" }
}
}Блочный стриминг
По умолчанию агент работает некоторое время, а затем отправляет один большой ответ. При включенном блочном стриминге ответ поступает в виде нескольких более коротких сообщений, пока агент еще работает — аналогично тому, как ChatGPT или Claude показывают прогрессивный вывод.
{
"channels": {
"my-channel": {
"type": "telegram",
"blockStreaming": "on",
"blockStreamingChunk": { "minChars": 400, "maxChars": 1000 },
"blockStreamingCoalesce": { "idleMs": 1500 },
...
}
}
}Как это работает
- Ответ агента разбивается на блоки по границам абзацев и отправляется в виде отдельных сообщений
minChars(по умолчанию 400) — не отправлять блок, пока он не достигнет хотя бы этой длины, чтобы избежать спама крошечными сообщениямиmaxChars(по умолчанию 1000) — если блок достигает этой длины без естественного разрыва, все равно отправить егоidleMs(по умолчанию 1500) — если агент делает паузу (например, запускает инструмент), отправить то, что накопилось в буфере- Когда агент завершает работу, любой оставшийся текст отправляется немедленно
Требуется только blockStreaming. Настройки chunk и coalesce необязательны и имеют разумные значения по умолчанию.
Запланированные циклы канала
Каналы имеют постоянный планировщик для промптов, которые должны выполняться позже и отправлять результат обратно в тот же чат. Вы можете попросить агента естественным образом, например, Every 15 minutes, check the deployment and report any change, или использовать локальные команды напрямую:
/loop add "*/15 * * * *" check the deployment and report any change
/loop list
/loop inspect <id>
/loop cancel <id>Агент использует инструменты channel_loop_create, channel_loop_list и channel_loop_cancel при управлении этими задачами для вас. Расписания используют стандартные cron-выражения с пятью полями в локальном времени машины. Задача выполняется автономно, и её финальный ответ автоматически доставляется в чат, создавший её.
Циклы канала отличаются от задач по расписанию, описанных в разделе Выполнение промптов по расписанию:
- Они хранятся в
$QWEN_HOME/channels/— автономные каналы используютcron.jsonнапрямую, а каналы под управлением демона используют файл рабочего пространства вdaemon/. Оба варианта переживают перезапуск канала. - Они привязаны к текущему чату или треду канала. Каждая цель может иметь до 10 включённых циклов, и каждый промпт ограничен 4 000 символами.
- Они требуют адаптер и цель, поддерживающую проактивную доставку. Telegram, DingTalk, Feishu и WeCom явно включают её, с учётом ограничений целей конкретной платформы.
- Они недоступны при
sessionScope: "single", потому что эта область не привязана к одной цели чата. - Сохранённый цикл отключается, если его цель больше не авторизована к моменту выполнения.
Результаты фонового агента
Когда агент делегирует работу фоновому субагенту или форку, результат завершения доставляется обратно в чат канала, которому принадлежит сессия. Доставка может произойти после завершения оригинального хода, поэтому держите сервис канала или демон запущенным, пока активна фоновая работа.
Слэш-команды
Каналы поддерживают слэш-команды. Они обрабатываются локально (без обращения к агенту):
/help— Список доступных команд/clear— Очистить сессию и начать заново (алиасы:/reset,/new)/status— Показать информацию о сессии и политике доступа/loop add "<cron>" <prompt>— Создать постоянный запланированный цикл канала/loop list— Список циклов для текущего чата/loop inspect <id>— Показать статус и детали выполнения цикла/loop cancel <id>— Отключить цикл
Все остальные слэш-команды (например, /compress, /summary) перенаправляются агенту.
Эти команды работают во всех типах каналов (Telegram, WeChat, QQ, DingTalk, WeCom, Feishu, GitHub), хотя создание циклов также требует поддержки проактивной доставки для текущего адаптера и цели.
Запуск
# Запуск всех настроенных каналов (общий процесс агента)
qwen channel start
# Запуск одного канала
qwen channel start my-channel
# Проверка статуса работы сервиса
qwen channel status
# Остановка работающего сервиса
qwen channel stopБот запускается в активном режиме (foreground). Нажмите Ctrl+C для остановки или используйте qwen channel stop из другого терминала.
Экспериментальный режим управления через демон
Вы также можете запускать настроенные каналы через qwen serve:
# Запуск одного канала в жизненном цикле демона
qwen serve --channel my-channel
# Запуск всех настроенных каналов
qwen serve --channel all
# Или включите каналы позже на демоне с защитой по токену
QWEN_SERVER_TOKEN=secret qwen serve
qwen channel set my-channel --token secret
# Запрос или остановка выбора, управляемого демоном
qwen channel status --daemon-url http://127.0.0.1:4170 --token secret
qwen channel stop --daemon-url http://127.0.0.1:4170 --token secretЭтот режим запускает рабочие процессы каналов, сгруппированные по рабочим пространствам, принадлежащие qwen serve. Воркеры подключаются к демону через SDK и используют те же адаптеры каналов. Они отделены от процесса демона, поэтому сбой адаптера канала не приводит к сбою демона. Демон, запущенный без --channel, не загружает адаптеры каналов и не резервирует PID-лизинг сервиса каналов до первого qwen channel set.
qwen serve --channel — это не тот же сервис, что и qwen channel start. Автономный qwen channel start по-прежнему использует сервис каналов на базе ACP и может запускать конфигурации каналов с разными значениями cwd. Каналы, управляемые демоном, требуют, чтобы cwd каждого выбранного канала указывал на рабочее пространство, зарегистрированное демоном. В режиме множественных рабочих пространств замена выбора сохраняет воркеров для рабочих пространств, чей упорядоченный список каналов не изменился; all остаётся только для основного рабочего пространства.
Без --daemon-url, qwen channel status и qwen channel stop сохраняют поведение автономного pidfile. Их варианты с --daemon-url запрашивают или останавливают менеджер демона. Выбор времени выполнения не записывается в настройки и не переживает перезапуск демона. Если готовый воркер неожиданно завершает работу, демон продолжает работать и сообщает о предупреждении channel-worker в /daemon/status.
Задачи, запускаемые вебхуками {#webhook-triggered-tasks}
Каналы под управлением демона также могут принимать аутентифицированные вебхук-события. Qwen получает событие как контекст, суммирует его и определяет, что важно, а затем доставляет финальный ответ настроенной цели чата. Это не простая ретрансляция уведомлений.
Задачи вебхуков требуют approvalMode: "yolo", потому что они выполняются без интерактивного одобрения. Эта настройка применяется ко всему каналу, а не только к ходам вебхуков, поэтому используйте выделенный канал вебхуков или строго ограничьте обычных отправителей чата для этого канала.
Пример конфигурации канала:
{
"channels": {
"dingtalk-main": {
"type": "dingtalk",
"clientId": "$DINGTALK_CLIENT_ID",
"clientSecret": "$DINGTALK_CLIENT_SECRET",
"cwd": "/repo",
"senderPolicy": "allowlist",
"allowedUsers": ["12345"],
"approvalMode": "yolo",
"sessionScope": "user",
"webhooks": {
"sources": {
"github-ci": {
"secretEnv": "QWEN_CHANNEL_GITHUB_CI_SECRET",
"targets": {
"operator": {
"chatId": "DINGTALK_USER_ID",
"senderId": "webhook:github-ci",
"isGroup": false
},
"team": {
"chatId": "OPEN_CONVERSATION_ID",
"senderId": "webhook:github-ci",
"isGroup": true
}
}
}
}
}
}
}
}Для DingTalk явно установите isGroup для каждой цели. Цель личного сообщения использует ID пользователя DingTalk как chatId с isGroup: false; цель группы использует openConversationId группы с isGroup: true. Другие адаптеры могут требовать свою собственную форму проактивной цели.
Каналы DingTalk, Feishu, Telegram и WeCom под управлением демона динамически наблюдают контакты из авторизованных входящих сообщений. Просмотрите контакты, наблюдаемые в основном рабочем пространстве, в стандартное семидневое окно актуальности:
curl -H "Authorization: Bearer $QWEN_SERVER_TOKEN" \
http://127.0.0.1:4170/workspace/channel/observed-contactsИспользуйте GET /workspaces/:workspace/channel/observed-contacts для выбора другого зарегистрированного, доверенного рабочего пространства. Добавьте ?freshWithinSeconds=N, чтобы выбрать окно от одной секунды до 365 дней. Демон рекламирует этот API с помощью capability workspace_channel_observed_contacts.
Ответ возвращает полные ID платформ и метки. Метки групп используют имена, уже присутствующие в принятых входящих сообщениях, когда они доступны: DingTalk предоставляет conversationTitle, а Telegram предоставляет chat.title. Метки групп Feishu и WeCom в настоящее время возвращают полные ID; ни каталог платформ, ни API деталей групп не запрашиваются. Метки тем также возвращают полные ID. Каждый lastObservedAt — это каноническая метка времени ISO 8601 UTC с миллисекундной точностью; клиенты могут преобразовать её в локальный часовой пояс пользователя для отображения. Верхнеуровневый users содержит пользователей, наблюдаемых в личных сообщениях. groups содержит наблюдаемые групповые беседы, groups[].users содержит пользователей, наблюдаемых в каждой группе, а groups[].topics[].users содержит пользователей, наблюдаемых в темах Feishu или Telegram:
{
"users": [
{
"channelName": "feishu-main",
"label": "Example User",
"id": "ou_complete_user_id",
"lastObservedAt": "2026-07-17T08:00:00.000Z"
}
],
"groups": [
{
"channelName": "feishu-main",
"label": "oc_complete_chat_id",
"id": "oc_complete_chat_id",
"lastObservedAt": "2026-07-17T08:05:00.000Z",
"users": [
{
"label": "Example User",
"id": "ou_complete_user_id",
"lastObservedAt": "2026-07-17T08:05:00.000Z"
}
],
"topics": []
}
]
}Эти вложенные пользователи — наблюдаемые участники, а не авторитарное членство в группе. Записываются только сообщения, прошедшие гейты личных/групповых, упоминаний, отправителей и сопряжения. Повторные наблюдения обновляют метки и временные метки; пассивное наблюдение не может обнаружить выход или удаление, пока отношение не устареет. Содержимое сообщений никогда не сохраняется. Ограниченный реестр хранится в $QWEN_HOME/channels/daemon/<workspaceHash>/observed-contacts.json, вне рабочего пространства checkout и разделён по рабочим пространствам. Его лимит в 500 наблюдений является общим для всех каналов и бесед в этом рабочем пространстве, а наблюдения старше 365 дней удаляются при следующей принятой записи. Если реестр становится повреждённым или использует неподдерживаемую версию, удалите этот файл для сброса; принятый трафик воссоздаст его. Конфигурация и доставка вебхуков не изменяются.
Запустите qwen serve с включённым воркером канала:
QWEN_SERVER_TOKEN="$QWEN_SERVER_TOKEN" qwen serve --require-auth --channel dingtalk-mainПример запроса:
curl -X POST "http://127.0.0.1:4170/channels/dingtalk-main/webhooks/github-ci" \
-H "x-qwen-webhook-secret: $QWEN_CHANNEL_GITHUB_CI_SECRET" \
-H "Content-Type: application/json" \
-d '{
"eventType": "push",
"targetRef": "operator",
"title": "CI pipeline finished",
"payload": {
"targetRef": "refs/heads/main",
"repository": "qwen-code",
"status": "success"
}
}'Маршруты вебхуков аутентифицируются с помощью заголовка секрета вебхука, даже когда qwen serve работает с включённой bearer-аутентификацией. Не передавайте токен bearer демона провайдерам вебхуков. Конфигурация вебхуков и значения secretEnv загружаются при запуске демона; перезапустите qwen serve после изменения источников вебхуков или ротации секретов. Ответ 202 {"accepted": true} означает, что воркер канала принял владение задачей, а не что финальный ответ уже доставлен в чат. Проверьте логи демона и воркера канала, а также /daemon/status, при устранении неполадок доставки.
Мультиканальный режим
Когда вы запускаете qwen channel start без указания имени, все каналы, определенные в settings.json, запускаются вместе, используя единый процесс агента. Каждый канал поддерживает свои собственные сессии — пользователь Telegram и пользователь WeChat получают отдельные диалоги, даже если они используют одного и того же агента.
Каждый канал использует свой собственный cwd из конфигурации, поэтому разные каналы могут работать над разными проектами одновременно.
Управление сервисом
Сервис каналов использует PID-файл (~/.qwen/channels/service.pid) для отслеживания запущенного экземпляра:
- Предотвращение дубликатов: Запуск
qwen channel startпри уже работающем сервисе приведет к ошибке вместо запуска второго экземпляра qwen channel stop: Корректно останавливает работающий сервис из другого терминалаqwen channel status: Показывает, запущен ли сервис, его время работы и количество сессий для каждого канала
Восстановление после сбоев
Если процесс агента неожиданно завершается с ошибкой, сервис каналов автоматически перезапускает его и пытается восстановить все активные сессии. Пользователи могут продолжить свои диалоги без необходимости начинать заново.
- Сессии сохраняются в
~/.qwen/channels/sessions.jsonво время работы сервиса - При сбое: агент перезапускается в течение 3 секунд и перезагружает сохраненные сессии
- После 3 последовательных сбоев сервис завершает работу с ошибкой
- При штатном завершении работы (Ctrl+C или
qwen channel stop): данные сессий очищаются — следующий запуск всегда начинается с чистого состояния