🚀 Эффективное использование Qwen Code

Интерактивный CLI агент для разработки программного обеспечения с поддержкой многозадачности, субагентов и продвинутых инструментов.

📋 Что такое Qwen Code?

Qwen Code — это интеллектуальный агент, разработанный Alibaba Group, специализирующийся на задачах разработки ПО. Он умеет безопасно и эффективно помогать пользователям, строго следуя инструкциям и используя доступные инструменты.

🎯 Основные возможности

🔍

Поиск и чтение

Поиск по кодовой базе, чтение файлов, glob-паттерны

✏️

Редактирование

Запись и редактирование файлов, создание структур

🤖

Субагенты

Делегирование сложных задач специализированным агентам

🌐

Web доступ

Поиск в интернете и получение контента с URL

📦

Навыки (Skills)

Специализированные модули для конкретных задач

📝

Планирование

Управление задачами через todo списки

🛠️ Доступные инструменты

📁 Работа с файлами

read_file Чтение

Читает содержимое файла. Для больших файлов поддерживает пагинацию через offset и limit.

{
  "absolute_path": "/path/to/file.txt",
  "offset": 0,
  "limit": 100
}
write_file Запись

Записывает содержимое в файл по указанному пути.

{
  "file_path": "/path/to/file.txt",
  "content": "Содержимое файла..."
}
edit Редактирование

Заменяет текст в файле. Требует точного совпадения old_string с контекстом.

{
  "file_path": "/path/to/file.py",
  "old_string": "def old():\n    pass",
  "new_string": "def new():\n    return True",
  "replace_all": false
}
💡 Совет: Включайте минимум 3 строки контекста до и после изменяемого текста для точного совпадения.
list_directory Список файлов

Показывает файлы и поддиректории в указанной директории.

🔍 Поиск

glob Поиск по имени

Быстрый поиск файлов по glob-паттернам (например, **/*.js).

{
  "pattern": "**/*.py",
  "path": "/home/project"
}
grep_search Поиск по содержимому

Мощный поиск по содержимому файлов на основе ripgrep. Поддерживает regex.

{
  "pattern": "function\\s+\\w+",
  "glob": "*.js",
  "path": "/src",
  "limit": 50
}

🖥️ Выполнение команд

run_shell_command Shell команды

Выполняет shell команды в persistente сессии. Поддерживает фоновый режим.

{
  "command": "npm install",
  "description": "Установка зависимостей",
  "is_background": false,
  "timeout": 120000
}
⚠️ Важно: Не используйте find, grep, cat, head, tail, sed, awk — для этого есть специализированные инструменты.

🌐 Web инструменты

web_search Поиск в интернете

Поиск актуальной информации в интернете для данных за пределами training cutoff.

{
  "query": "Python 3.12 new features",
  "provider": "google"
}
web_fetch Получение URL

Получает контент с URL и обрабатывает его AI моделью.

{
  "url": "https://example.com/docs",
  "prompt": "Извлеки информацию об API endpoints"
}

🤖 Субагенты: Делегирование задач

📌 Что такое субагенты?

Субагенты — это специализированные агенты, которые могут автономно выполнять сложные многошаговые задачи. Они идеальны для задач, требующих множественных итераций поиска, анализа или исследований.

Типы субагентов

🎯

general-purpose

Универсальный агент для:

  • Исследования сложных вопросов
  • Поиска кода в большой кодовой базе
  • Выполнения многошаговых задач автономно

Когда использовать:

Когда вы ищете ключевое слово или файл и не уверены, что найдете с первой попытки — используйте этот агент для автономного поиска.

📝 Как использовать task инструмент

{
  "description": "Поиск всех обработчиков auth",
  "prompt": """
    Найди все файлы и функции, связанные с аутентификацией пользователей.
    
    1. Используй grep_search для поиска паттернов "auth", "login", "authenticate"
    2. Для каждого найденного файла прочитай содержимое
    3. Составь список всех функций с их путями и кратким описанием
    4. Верни результат в виде структурированного отчета
    
    Важно: Верни полные пути к файлам и номера строк где найдены совпадения.
  """,
  "subagent_type": "general-purpose"
}

🎯 Best Practices для субагентов

1

Детальное описание задачи

prompt должен содержать максимально подробное описание задачи, включая ожидаемый формат результата и конкретные шаги.

2

Указывайте тип задачи

Четко обозначьте, ожидаете ли вы код или только исследование (research, file reads).

3

Запускайте параллельно

Для независимых задач запускайте несколько агентов одновременно для максимизации производительности.

4

Агент stateless

Каждый вызов агента не сохраняет состояние. Вы не можете отправлять дополнительные сообщения агенту — весь контекст должен быть в initial prompt.

📋 Пример сценария использования

Задача: Рефакторинг модуля аутентификации

  1. Шаг 1: Запустить general-purpose агента для поиска всех файлов auth
  2. Шаг 2: Параллельно запустить агента для поиска тестов auth
  3. Шаг 3: Получить отчеты от обоих агентов
  4. Шаг 4: Использовать review skill для проверки плана изменений
  5. Шаг 5: Внести изменения с помощью edit инструмента

📚 RAG (Retrieval-Augmented Generation)

🔍 Что такое RAG в контексте Qwen Code?

RAG (Retrieval-Augmented Generation) — это подход, при котором AI получает доступ к внешней базе знаний (вашей кодовой базе) для генерации более точных и контекстуально релевантных ответов.

📊 Как работает RAG в Qwen Code

1

Запрос пользователя

2

Поиск релевантных файлов (glob/grep)

3

Чтение содержимого (read_file)

4

Анализ и генерация ответа

🛠️ Инструменты для RAG

🔎 grep_search

Основной инструмент для поиска по содержимому. Поддерживает regex.

// Поиск всех импортов React
{
  "pattern": "import.*from.*['\"]react['\"]",
  "glob": "**/*.{js,jsx,ts,tsx}"
}

📁 glob

Поиск файлов по имени. Быстрее чем grep для поиска по именам.

// Найти все тестовые файлы
{
  "pattern": "**/*.test.ts"
}

📖 read_file

Чтение содержимого найденных файлов с пагинацией.

// Читать файл частями
{
  "absolute_path": "/src/app.ts",
  "offset": 0,
  "limit": 100
}

🤖 task (subagent)

Делегирование сложного поиска субагенту для автономной работы.

📝 Стратегии эффективного RAG

1. Постепенное уточнение

Начните с широкого поиска, затем уточняйте:

// Шаг 1: Найти все файлы конфигурации
glob: "**/*.{json,yaml,yml}"

// Шаг 2: Найти конкретные настройки
grep_search: "database.*host"

// Шаг 3: Прочитать релевантные файлы
read_file: "/config/database.yml"

2. Параллельный поиск

Запускайте несколько поисков одновременно:

// Параллельно:
- grep_search: "class.*Controller" (контроллеры)
- grep_search: "@Controller" (декораторы)
- glob: "**/controllers/**"

3. Использование субагентов для сложного RAG

Для комплексного анализа кодовой базы:

task:
  description: "Анализ архитектуры"
  prompt: """
    Исследуй структуру проекта и определи:
    1. Основные модули и их ответственность
    2. Зависимости между модулями
    3. Паттерны проектирования
    
    Используй glob, grep_search и read_file 
    для сбора информации.
  """

⚠️ Ограничения RAG в Qwen Code

  • Нет векторной базы данных: Поиск осуществляется через текстовые паттерны (grep/glob), а не через семантический поиск.
  • Нет встроенной индексации: Каждый поиск выполняется в реальном времени по файловой системе.
  • Контекст ограничен: Большие файлы нужно читать частями через offset/limit.
  • Stateless: Каждый запрос не помнит предыдущие搜索结果, нужно явно передавать контекст.

🔌 MCP (Model Context Protocol)

📌 Что такое MCP?

Model Context Protocol (MCP) — это открытый протокол от Anthropic, который позволяет AI-агентам безопасно взаимодействовать с внешними системами, базами данных, API и инструментами через стандартизированный интерфейс.

🎯 Зачем нужен MCP в Qwen Code?

🔗

Интеграции

Подключение к базам данных, файловым хранилищам, внешним API

🛡️

Безопасность

Изолированное выполнение через sandbox с контролем доступа

🔧

Расширяемость

Добавление новых инструментов без изменения кода агента

📡

Универсальность

Единый протокол для любых внешних систем

🏗️ Архитектура MCP

1

Qwen Code (Host)

2

MCP Client

3

MCP Server

4

Внешняя система

Компоненты:

  • Host — приложение (Qwen Code), которое использует MCP
  • Client — библиотека, управляющая соединениями
  • Server — сервис, предоставляющий инструменты и ресурсы
  • Resources/Tools — данные и функции, доступные через MCP

⚙️ Настройка MCP серверов

Конфигурационный файл

MCP серверы настраиваются через JSON-конфигурацию:

# ~/.qwen/mcp.json или .qwen/mcp.json в проекте
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/data"],
      "env": {
        "ALLOWED_ORIGINS": "*"
      }
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "ghp_..."
      }
    },
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "postgresql://user:pass@localhost:5432/db"
      }
    },
    "slack": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-slack"],
      "env": {
        "SLACK_BOT_TOKEN": "xoxb-...",
        "SLACK_TEAM_ID": "T01234567"
      }
    }
  }
}

📦 Официальные MCP серверы

📁 Filesystem

@modelcontextprotocol/server-filesystem

Безопасный доступ к файловой системе с контролем путей. Чтение, запись, поиск файлов.

🐙 GitHub

@modelcontextprotocol/server-github

Работа с репозиториями: issues, PR, файлы, создание коммитов через GitHub API.

🗄️ PostgreSQL

@modelcontextprotocol/server-postgres

Выполнение SQL-запросов, чтение схем, безопасная работа с БД.

💬 Slack

@modelcontextprotocol/server-slack

Отправка сообщений, чтение каналов, управление workspace через Slack API.

🌐 Fetch

@modelcontextprotocol/server-fetch

Получение и парсинг веб-страниц, извлечение контента с URL.

🔍 Google Drive

@modelcontextprotocol/server-google-drive

Доступ к файлам Google Drive, поиск, чтение документов.

💡 Совет: Полный список MCP серверов смотрите на GitHub Model Context Protocol

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

Шаг 1: Создание конфигурации

# Создайте файл ~/.qwen/mcp.json
mkdir -p ~/.qwen
cat > ~/.qwen/mcp.json << EOF
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
    }
  }
}
EOF

Шаг 2: Установка зависимостей

# Установите Node.js (требуется для npx)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

# Проверка установки
node --version
npm --version

Шаг 3: Запуск Qwen Code

# При запуске Qwen Code автоматически обнаружит MCP конфигурацию
qwen

# Теперь можно использовать MCP инструменты:
"Покажи файлы в /home/user/projects через MCP filesystem"

🔐 Безопасность MCP

🛡️

Sandbox

Изолированное выполнение MCP серверов с ограниченным доступом

🔑

Secrets

Токены и секреты хранятся в env переменных, не в коде

🚧

Allowlist

Контроль доступа к путям и ресурсам через конфигурацию

📝

Logging

Полное логирование всех MCP операций для аудита

⚠️ Важно: Никогда не коммитьте токены и секреты в репозиторий. Используйте переменные окружения или менеджеры секретов.

📝 Примеры использования

📁 Работа с файловой системой через MCP

# Конфигурация ~/.qwen/mcp.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"],
      "env": {}
    }
  }
}

# Запросы к Qwen Code:
"Покажи структуру проекта через MCP filesystem"
"Найди все .py файлы в /home/user/projects/src"
"Прочитай файл config.yaml через MCP"
"Создай новый файл README.md в текущей директории"

# Результат:
## Структура проекта:
/home/user/projects/
├── src/
│   ├── main.py
│   └── utils.py
├── tests/
│   └── test_main.py
├── config.yaml
└── README.md

🐙 Интеграция с GitHub

# Конфигурация ~/.qwen/mcp.json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "ghp_xxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

# Запросы к Qwen Code:
"Покажи открытые issues в репозитории owner/repo"
"Создай новый pull request из ветки feature/auth"
"Найди все PR с лейблом 'bug'"
"Покажи последние коммиты в main ветке"

# Пример ответа:
## Открытые issues (owner/repo):

### #142 - Bug in authentication flow
**Status:** Open | **Labels:** bug, high-priority
**Created:** 2 days ago by @user123

### #138 - Feature request: Dark mode
**Status:** Open | **Labels:** enhancement
**Created:** 5 days ago by @designer

🗄️ Работа с PostgreSQL

# Конфигурация ~/.qwen/mcp.json
{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "postgresql://user:password@localhost:5432/mydb"
      }
    }
  }
}

# Запросы к Qwen Code:
"Покажи схему таблицы users"
"Выполни SELECT * FROM users LIMIT 10"
"Найди всех пользователей с ролью 'admin'"
"Покажи статистику по таблицам базы данных"

# Пример ответа:
## Схема таблицы 'users':

| Column    | Type      | Nullable | Default |
|-----------|-----------|----------|---------|
| id        | UUID      | NO       | gen_random_uuid() |
| email     | VARCHAR   | NO       | - |
| name      | VARCHAR   | YES      | NULL |
| role      | VARCHAR   | NO       | 'user' |
| created_at| TIMESTAMP | NO       | NOW() |

## Данные (LIMIT 10):
1. admin@example.com - Admin - 2024-01-15
2. user@example.com - User - 2024-02-20
...

🔧 Создание своего MCP сервера

# Пример простого MCP сервера на Python
# my-mcp-server/main.py

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent

server = Server("my-custom-server")

@server.list_tools()
async def list_tools():
    return [
        Tool(
            name="get_weather",
            description="Get weather for a city",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {"type": "string"}
                },
                "required": ["city"]
            }
        )
    ]

@server.call_tool()
async def call_tool(name: str, args: dict):
    if name == "get_weather":
        city = args["city"]
        # Здесь логика получения погоды
        return [TextContent(text=f"Weather in {city}: 20°C, Sunny")]
    raise ValueError(f"Unknown tool: {name}")

async def main():
    async with stdio_server() as streams:
        await server.run(
            streams[0],
            streams[1],
            server.create_initialization_options()
        )

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())
# Конфигурация для кастомного сервера
{
  "mcpServers": {
    "weather": {
      "command": "python",
      "args": ["/path/to/my-mcp-server/main.py"],
      "env": {
        "WEATHER_API_KEY": "your_api_key"
      }
    }
  }
}

🔍 Отладка MCP

# Включите логирование для отладки
export MCP_DEBUG=1

# Проверка конфигурации
cat ~/.qwen/mcp.json | python -m json.tool

# Тестовый запуск сервера
npx -y @modelcontextprotocol/server-filesystem /home/user/projects

# Просмотр логов MCP
tail -f ~/.qwen/mcp.log

Частые проблемы

⚠️

npx не найден: Установите Node.js 18+

⚠️

Permission denied: Проверьте права доступа к путям

⚠️

Invalid token: Обновите токены в env переменных

⚠️

Server timeout: Увеличьте timeout в конфигурации

💡 Практические примеры

🔍 Поиск всех использований API endpoint

# Запрос: "Найди все места где используется /api/users"

# Qwen Code будет использовать:
1. grep_search:
   pattern: "/api/users"
   glob: "**/*.{js,ts,py,go}"

2. Для каждого файла > 100 совпадений:
   read_file с offset/limit для пагинации

3. Структурированный отчет:
   - Файл: /src/controllers/user.ts:45
   - Контекст: fetch('/api/users')
   - Тип: GET запрос

✏️ Безопасный рефакторинг функции

# Запрос: "Замени console.log на logger.info"

# План Qwen Code:
1. grep_search: "console\\.log" для поиска всех мест

2. Для каждого файла:
   - read_file для получения контекста
   - edit с old_string включая 3 строки контекста
   - replace_all: true если паттерн одинаковый

3. run_shell_command: "npm run lint" для проверки

4. review skill для проверки изменений

🆕 Создание новой функции с тестами

# Запрос: "Создай функцию formatDate с тестами"

# Qwen Code выполнит:
1. glob: "**/*date*" для поиска существующих утилит даты

2. read_file: существующие тесты для понимания паттернов

3. write_file: /src/utils/formatDate.ts
   - Реализация функции
   - JSDoc комментарии
   - TypeScript типы

4. write_file: /tests/formatDate.test.ts
   - Unit тесты
   - Edge cases

5. run_shell_command: "npm test" для проверки

📊 Анализ архитектуры проекта

# Запрос: "Объясни архитектуру этого проекта"

# Qwen Code использует task с subagent:
task:
  description: "Анализ архитектуры"
  subagent_type: "general-purpose"
  prompt: """
    Исследуй структуру проекта:
    
    1. list_directory корневой папки
    2. glob: "**/package.json" для зависимостей
    3. glob: "src/**" для структуры кода
    4. read_file: ключевые файлы конфигурации
    5. grep_search: "export.*class" для основных классов
    
    Верни отчет:
    - Структура проекта
    - Основные модули
    - Зависимости
    - Паттерны архитектуры
  """

🤖 Использование субагента для аудита безопасности

# Запрос: "Найди уязвимости безопасности в проекте"

# Qwen Code запускает субагента:
{
  "tool": "task",
  "params": {
    "description": "Аудит безопасности",
    "subagent_type": "general-purpose",
    "prompt": """
    Проведи аудит безопасности:
    
    1. Найди через grep_search:
       - eval\\(|new Function\\(  → Code Injection
       - \\`SELECT.*\\+  → SQL Injection
       - innerHTML|dangerouslySetInnerHTML → XSS
       - password.*=.*['"] → Hardcoded secrets
    
    2. Для каждой проблемы укажи:
       - Путь и номер строки
       - Тип уязвимости
       - Критичность (Critical/High/Medium/Low)
       - Рекомендацию по исправлению
    """
  }
}

# Результат:
## 🔴 Critical
**Файл:** src/utils/eval.js:15
eval(userCode) → Code Injection
✅ Заменить на sandboxed execution

## 🟠 High  
**Файл:** src/models/user.js:42
`SELECT * FROM users WHERE email = '${email}'`
✅ Использовать параметризованные запросы

📋 Управление задачами через todo_write

# Запрос: "Добавь темную тему в приложение"

# Шаг 1: Создание плана
{
  "tool": "todo_write",
  "params": {
    "todos": [
      {"id": "1", "content": "CSS переменные для темной темы", "status": "pending"},
      {"id": "2", "content": "Переключатель темы в UI", "status": "pending"},
      {"id": "3", "content": "Логика переключения JS", "status": "pending"},
      {"id": "4", "content": "Сохранение в localStorage", "status": "pending"},
      {"id": "5", "content": "Тестирование", "status": "pending"}
    ]
  }
}

# Шаг 2: Обновление прогресса
{
  "tool": "todo_write",
  "params": {
    "todos": [
      {"id": "1", "content": "CSS переменные", "status": "completed"},
      {"id": "2", "content": "Переключатель в UI", "status": "in_progress"},
      {"id": "3", "content": "Логика JS", "status": "pending"},
      {"id": "4", "content": "localStorage", "status": "pending"},
      {"id": "5", "content": "Тестирование", "status": "pending"}
    ]
  }
}

# CSS переменные (выполнено):
:root {
  --bg-primary: #ffffff;
  --text-primary: #1a1a1a;
}

[data-theme="dark"] {
  --bg-primary: #0d1117;
  --text-primary: #e6edf3;
}

✅ Best Practices

🎯

Точные запросы

Формулируйте запросы конкретно. Вместо "найди баги" → "найди обработку ошибок в auth.ts".

📚

Контекст важен

При редактировании включайте 3+ строки контекста до и после изменяемого кода.

Параллелизм

Запускайте независимые задачи параллельно через множественные tool calls.

🔒

Безопасность

Никогда не используйте echo/printf для вывода — пишите напрямую в ответ.

🧪

Тестирование

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

📋

Todo списки

Для сложных задач используйте todo_write для отслеживания прогресса.

🤖

Делегирование

Используйте subagents для задач требующих 3+ шагов поиска/анализа.

🔄

Итеративность

Начинайте с широкого поиска, затем уточняйте на основе результатов.

🚫 Чего избегать

Не используйте find, ls — есть glob и list_directory

Не используйте grep, cat, head — есть grep_search и read_file

Не делайте предположений о содержимом файлов — читайте их

Не запускайте интерактивные команды (git rebase -i)