API Azure DevOps для ваших искусственных интеллектов
Ваш ИИ-помощник умеет читать код, но не видит, что скрывается в ваших репозиториях Azure DevOps. Этот API наводит мосты: проекты, файлы, коммиты, pull request, всё в простом JSON, с вашими собственными правами доступа.
Давайте сразу проясним: изначально я создавал его для машин. Для ИИ-агента, MCP-сервера, то есть протокола, который позволяет такому помощнику, как Claude, вызывать внешние инструменты, или простого скрипта. Люди тоже могут им пользоваться, но идея в том, чтобы ИИ мог спросить «покажи мне этот файл» или «что изменилось в этом коммите», не пытаясь угадать, как работает API Azure DevOps, мощный, но, откровенно говоря, довольно запутанный.
Вот страница Swagger этого сервиса, где перечислены все вызовы:
Бесплатный или PRO: что вы получаете
Обе формулы дают доступ к одним и тем же вызовам, включая запись. Разница только в количестве запросов в день. Зелёная шкала показывает, сколько вы можете запросить за один день.
Бесплатный API
0 €, достаточно ключа вашей учётной записи
- 10 запросов в день
- Все вызовы, включая чтение и запись
- До 50 файлов, прочитанных за один запрос
- Достаточно, чтобы подключить агента и посмотреть, понимает ли он ваш код
API PRO
12 € в месяц, всё моё программное обеспечение включено
- 1000 запросов в день
- Достаточно для агента, который весь день работает с вашими репозиториями
- Полный телегид на 11 дней и моё программное обеспечение в придачу
- Активируется уже со следующего запроса, с тем же ключом
Счётчик обнуляется в полночь по UTC, то есть в 1 или 2 часа ночи во Франции, в зависимости от сезона. Десять запросов с болтливым агентом улетают быстро. Мой совет, как растянуть их: вызов files:batch возвращает до 50 файлов и считается только за один запрос.
Что умеет API
Около двадцати вызовов, все по адресу https://devops.digital3d.com/api/Devops/. Я сгруппировал их по задачам, а не в алфавитном порядке:
| Потребность | Вызовы | Что возвращает |
|---|---|---|
| Сориентироваться | Projects, Repos, Repos/{repoId} | Проекты организации, Git-репозитории, все или только относящиеся к проекту, и карточку репозитория с его веткой по умолчанию. |
| Просмотреть код | tree, files, search | Дерево каталогов, список всех файлов ветки или поиск по шаблону, например **/*.cs. |
| Читать файлы | file, fileAt, files:batch | Сырое содержимое файла в ветке или на конкретном коммите либо до 50 файлов за раз. |
| Отслеживать историю | branches, tags, commits, pushes | Ветки, теги, журнал коммитов с фильтрацией по пути и ветке, подробности коммита и список изменённых в нём файлов. |
| Сравнивать | diffs/commits | Разницу между двумя коммитами, по умолчанию в компактном виде или в полной версии. |
| Проверять pull requests | pullrequests | Активные, завершённые или закрытые запросы на слияние и подробности одного из них. |
| Записывать | write | Создание или изменение файла, отправляемое как push из одного коммита. |
Есть также два служебных вызова: Health, который отвечает без ключа и никогда не учитывается, и WhoAmI, который подтверждает, что твои заголовки правильно поняты.
Три заголовка, которые нужно отправлять
Каждый запрос содержит три заголовка. Один для меня, два для Azure DevOps.
| Заголовок | Что в него вписать | Для чего он нужен |
|---|---|---|
Authorization | Bearer VotreCleApi | Твой ключ Digital3D. Именно он несёт квоту. |
X-Ado-Org | Название твоей организации | Сообщить API, какую организацию Azure DevOps запрашивать. |
X-Ado-Pat | Твой персональный токен доступа | Вызывать Azure DevOps от твоего имени, с твоими правами и не более того. |
Ключ Digital3D. Создай аккаунт, подтверди свой адрес электронной почты, затем скопируй ключ, отображаемый в твоём аккаунте. Это тот же ключ, что и для моих других сервисов. Если ты пользовался старой версией, учти: заголовок X-Api-Key уступил место Authorization.
Название организации. Войди на https://dev.azure.com и посмотри на адрес. В https://dev.azure.com/ma-societe/ отправляемое значение будет ma-societe. Это название организации, а не проекта.
Персональный токен доступа (PAT, своего рода пароль с ограниченными правами). В Azure DevOps нажми на значок пользовательских настроек в правом верхнем углу, затем «Personal access tokens» и «New Token». Дай ему понятное имя, короткий срок действия (30 или 90 дней) и только нужные права: «Code (Read)» и «Project and Team (Read)» достаточно, чтобы всё читать. Добавь «Code (Read & Write)» только если твоему агенту нужно писать. Скопируй токен сразу, Azure DevOps показывает его только один раз.
Небольшое предупреждение, потому что это твой код: этот токен даёт доступ к твоим репозиториям, и при каждом запросе он проходит через мой сервер. Дай ему минимум прав, установи дату окончания действия и отзови его в тот день, когда он тебе больше не понадобится. На твоём месте я бы поступил именно так.
Первые вызовы
Начни с проверки, что проходят все три заголовка:
curl "https://devops.digital3d.com/api/Devops/WhoAmI" \
-H "Authorization: Bearer VotreCleApi" \
-H "X-Ado-Org: ma-societe" \
-H "X-Ado-Pat: VotreJetonAzure"Затем список репозиториев. У каждого репозитория есть идентификатор (GUID), и именно его все остальные вызовы ожидают вместо {repoId}:
curl "https://devops.digital3d.com/api/Devops/Repos?project=MonProjet" \
-H "Authorization: Bearer VotreCleApi" \
-H "X-Ado-Org: ma-societe" \
-H "X-Ado-Pat: VotreJetonAzure"Чтобы найти все C#-файлы репозитория в его ветке по умолчанию:
curl "https://devops.digital3d.com/api/Devops/Repos/{repoId}/search?glob=**/*.cs" \
-H "Authorization: Bearer VotreCleApi" \
-H "X-Ado-Org: ma-societe" \
-H "X-Ado-Pat: VotreJetonAzure"А чтобы прочитать несколько файлов одним запросом, используется POST со списком путей:
curl -X POST "https://devops.digital3d.com/api/Devops/Repos/{repoId}/files:batch" \
-H "Authorization: Bearer VotreCleApi" \
-H "X-Ado-Org: ma-societe" \
-H "X-Ado-Pat: VotreJetonAzure" \
-H "Content-Type: application/json" \
-d '{ "paths": ["/README.md", "/src/Program.cs"], "refName": "main" }'Везде, где ожидается ветка (refName), можно написать main или полную форму refs/heads/main. Если ничего не указать, берётся ветка репозитория по умолчанию.
Сравнивать и записывать
Вот тут для агента становится по-настоящему интересно. Чтобы узнать, что разделяет два коммита:
curl -X POST "https://devops.digital3d.com/api/Devops/Repos/{repoId}/diffs/commits" \
-H "Authorization: Bearer VotreCleApi" \
-H "X-Ado-Org: ma-societe" \
-H "X-Ado-Pat: VotreJetonAzure" \
-H "Content-Type: application/json" \
-d '{ "baseCommit": "abc123", "targetCommit": "def456", "summaryOnly": true }'При значении true у summaryOnly (это значение по умолчанию), ответ представляет собой компактную сводку: итоги и пути изменённых файлов. Так задумано. ИИ платит за каждое прочитанное слово, так что незачем скармливать ему необработанный ответ Azure DevOps, когда хватает сводки.
А чтобы записать файл:
curl -X POST "https://devops.digital3d.com/api/Devops/Repos/{repoId}/write" \
-H "Authorization: Bearer VotreCleApi" \
-H "X-Ado-Org: ma-societe" \
-H "X-Ado-Pat: VotreJetonAzure" \
-H "Content-Type: application/json" \
-d '{
"path": "/docs/notes.md",
"content": "# Notes\n\nEcrit par mon agent.",
"branch": "feature/notes",
"createBranch": true,
"commitMessage": "Ajout des notes"
}'Ладно, давайте две минуты без шуток: позволять ИИ записывать что-то в репозиторий нужно с предохранителями. Для этого есть три настройки. createBranch создаёт ветку, если её нет, и агент может работать в стороне, а ты потом прочитаешь его работу в pull request. expectHeadCommit сообщает последний коммит, который видел агент: если кто-то тем временем что-то отправил, запись отклоняется, вместо того чтобы затереть его работу. И размер записываемого файла ограничен на стороне сервера. А если ты вообще не хочешь разрешать запись, самым безопасным остаётся токен только для чтения: Azure DevOps сам его отклонит.
Под капотом
Несколько технических решений, которые объясняют поведение API.
Именно ты в каждом запросе указываешь, к какой организации обращаться и с каким токеном. Поэтому один и тот же API работает с любой организацией Azure DevOps, и видит он не больше того, что разрешает твой токен.
Ключ Digital3D проверяется первым. Запрос засчитывается сразу после принятия ключа, что бы потом ни ответил Azure DevOps. Поэтому неправильное имя организации или просроченный токен стоят одного запроса: вот почему стоит один раз проверить конфигурацию с помощью WhoAmI, а не тыкаться наугад.
Две ошибки 401 похожи друг на друга, но причины у них разные. Та, что содержит заголовок WWW-Authenticate: Bearer, возникает у меня: ключ Digital3D отсутствует или отклонён, и ничего не засчитывается. Та, что его не содержит, приходит от Azure DevOps: смотри в сторону X-Ado-Org и X-Ado-Pat.
Размер ответов ограничен, чтобы с ними было проще работать: 50 файлов и примерно 2 МБ за одно групповое чтение, 2000 элементов по умолчанию для списка файлов, 50 коммитов по умолчанию для журнала. Эти ограничения настраиваются параметрами top и maxItems.
Отслеживание своей квоты
Как только ключ принят, каждый ответ содержит три заголовка: X-RateLimit-Limit (ваш дневной лимит), X-RateLimit-Remaining (сколько у вас осталось) и X-RateLimit-Reset (время сброса, в секундах Unix). Хорошо воспитанный агент читает X-RateLimit-Remaining и сбавляет темп, прежде чем врезаться в стену.
429: дневная квота исчерпана. ЗаголовокRetry-Afterсообщает, сколько секунд нужно подождать до сброса.503: сервис не смог проверить ключ. Повтори попытку через 30 секунд.- Остальные ошибки представляют собой JSON-объект с полем
error, которое сообщает, что не так.
Тестировать без написания строки кода
Всё задокументировано в Swagger API. Нажми «Authorize», заполни три поля (ключ, организацию, токен), затем попробуй каждый вызов с помощью кнопки «Try it out». Но учти: эти попытки засчитываются в твою квоту, как и любой другой запрос. Тот же Swagger служит контрактом для ИИ: дай ей адрес файла https://devops.digital3d.com/swagger/v1/swagger.json и она сама обнаружит все вызовы.
Зачем нужна подписка?
Потому что всё это работает на сервере, за который я плачу. Бесплатный вариант остаётся для тестирования и лёгкого использования. Если агент каждый день работает с твоими репозиториями, подписка PRO за 12 € в месяц поднимает лимит до 1000 запросов в день, включает полное руководство по TV и все мои программы, и именно это позволяет сервису жить. Коммерческое использование без подписки не разрешено. А если тебе нужно больше, напиши мне.

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