Qwen Code Core: Tools API
Ядро Qwen Code (packages/core) предоставляет надежную систему для определения, регистрации и выполнения инструментов. Эти инструменты расширяют возможности модели, позволяя ей взаимодействовать с локальной средой, получать веб-контент и выполнять различные действия, выходящие за рамки простой генерации текста.
Основные концепции
-
Инструмент (
tools.ts) — интерфейс и базовый класс (BaseTool), определяющий контракт для всех инструментов. Каждый инструмент должен иметь:name— уникальное внутреннее имя (используется в API-вызовах к модели).displayName— понятное пользователю имя.description— четкое описание того, что делает инструмент; передается модели.parameterSchema— JSON-схема параметров, принимаемых инструментом. Это важно, чтобы модель могла правильно вызвать инструмент.validateToolParams()— метод для проверки входных параметров.getDescription()— метод, возвращающий человекочитаемое описание действий инструмента с конкретными параметрами до его выполнения.shouldConfirmExecute()— метод, определяющий необходимость подтверждения от пользователя перед запуском (например, при потенциально разрушительных операциях).execute()— основной метод, выполняющий действие инструмента и возвращающийToolResult.
-
ToolResult(tools.ts) — интерфейс, описывающий структуру результата выполнения инструмента:llmContent— фактический контент, который будет отправлен обратно LLM как часть истории взаимодействия. Может быть строкой илиPartListUnion(массив объектов типаPartи строк) для представления сложного контента.returnDisplay— удобный для пользователя формат (часто Markdown) или специальный объект (например,FileDiff) для отображения в CLI.
-
Возврат сложного контента: Инструменты не ограничены простым текстовым выводом. Поле
llmContentможет содержатьPartListUnion, то есть массив, состоящий из объектовPart(изображения, аудио и т. д.) и строк. Это позволяет одному вызову инструмента вернуть сразу несколько элементов сложного контента. -
Реестр инструментов (
tool-registry.ts) — класс (ToolRegistry), отвечающий за следующие задачи:- Регистрация инструментов: хранение коллекции всех доступных встроенных инструментов (например,
ListFiles,ReadFile). - Обнаружение инструментов: также умеет находить инструменты динамически:
- Командное обнаружение: если в настройках указано значение
tools.toolDiscoveryCommand, эта команда будет выполнена. От неё ожидается JSON, описывающий пользовательские инструменты, которые затем регистрируются как экземплярыDiscoveredTool. - Обнаружение через MCP: если задана команда
mcp.mcpServerCommand, реестр может подключиться к серверу по протоколу Model Context Protocol (MCP), получить список инструментов и зарегистрировать их какDiscoveredMCPTool.
- Командное обнаружение: если в настройках указано значение
- Предоставление схем: предоставляет модели схемы
FunctionDeclarationвсех зарегистрированных инструментов, чтобы она знала, какие инструменты доступны и как их использовать. - Получение инструментов: позволяет ядру системы получить конкретный инструмент по имени для его выполнения.
- Регистрация инструментов: хранение коллекции всех доступных встроенных инструментов (например,
Встроенные инструменты
Ядро поставляется с набором предопределённых инструментов, обычно расположенных в packages/core/src/tools/. Среди них:
-
Инструменты для работы с файловой системой:
ListFiles(ls.ts): выводит содержимое директории.ReadFile(read-file.ts): читает содержимое одного файла. Принимает параметрabsolute_path, который должен быть абсолютным путем.WriteFile(write-file.ts): записывает данные в файл.ReadManyFiles(read-many-files.ts): читает и объединяет содержимое нескольких файлов или по glob-паттернам (используется командой@в CLI).Grep(grep.ts): поиск паттернов в файлах.Glob(glob.ts): находит файлы, соответствующие glob-паттернам.Edit(edit.ts): выполняет изменения внутри файлов (часто требует подтверждения).
-
Инструменты выполнения:
Shell(shell.ts): запускает произвольные shell-команды (требует тщательной изоляции и подтверждения от пользователя).
-
Веб-инструменты:
WebFetch(web-fetch.ts): загружает контент по URL.WebSearch(web-search.ts): выполняет веб-поиск.
-
Инструменты памяти:
SaveMemory(memoryTool.ts): взаимодействует с памятью ИИ.
-
Планирование:
Task(task.ts): делегирует задачи специализированным подагентам.TodoWrite(todoWrite.ts): создаёт и управляет структурированным списком задач.ExitPlanMode(exitPlanMode.ts): выходит из режима планирования и возвращается к обычной работе.
Каждый из этих инструментов расширяет класс BaseTool и реализует необходимые методы для своей конкретной функциональности.
Порядок выполнения инструмента
- Запрос модели: Модель, основываясь на запросе пользователя и предоставленных схемах инструментов, решает использовать инструмент и возвращает часть
FunctionCallв своем ответе, указывая имя инструмента и аргументы. - Ядро получает запрос: Ядро парсит этот
FunctionCall. - Получение инструмента: Оно ищет запрашиваемый инструмент в
ToolRegistry. - Валидация параметров: Вызывается метод инструмента
validateToolParams(). - Подтверждение (если необходимо):
- Вызывается метод инструмента
shouldConfirmExecute(). - Если он возвращает данные для подтверждения, ядро передает это обратно в CLI, который запрашивает решение у пользователя.
- Решение пользователя (например, продолжить, отменить) отправляется обратно в ядро.
- Вызывается метод инструмента
- Выполнение: Если проверка пройдена и подтверждено (или если подтверждение не требуется), ядро вызывает метод инструмента
execute()с предоставленными аргументами иAbortSignal(для возможной отмены). - Обработка результата:
ToolResultизexecute()принимается ядром. - Ответ модели:
llmContentизToolResultупаковывается какFunctionResponseи отправляется обратно модели, чтобы она могла продолжить генерацию ответа для пользователя. - Отображение пользователю:
returnDisplayизToolResultотправляется в CLI, чтобы показать пользователю, что сделал инструмент.
Расширение с помощью пользовательских инструментов
Хотя прямая программная регистрация новых инструментов пользователями не описана явно как основной сценарий использования в предоставленных файлах для типичных конечных пользователей, архитектура поддерживает расширение через:
- Обнаружение на основе команд: Продвинутые пользователи или администраторы проекта могут определить
tools.toolDiscoveryCommandвsettings.json. Эта команда при запуске ядром должна выводить JSON-массив объектовFunctionDeclaration. Затем ядро сделает их доступными как экземплярыDiscoveredTool. Соответствующая командаtools.toolCallCommandбудет отвечать за фактическое выполнение этих пользовательских инструментов. - MCP сервер(ы): Для более сложных сценариев можно настроить один или несколько MCP серверов через параметр
mcpServersвsettings.json. Ядро сможет обнаруживать и использовать инструменты, предоставляемые этими серверами. Как упоминалось ранее, если у вас несколько MCP серверов, имена инструментов будут иметь префикс с именем сервера из вашей конфигурации (например,serverAlias__actualToolName).
Эта система инструментов обеспечивает гибкий и мощный способ расширения возможностей модели, делая Qwen Code универсальным помощником для широкого круга задач.