Первичное наполнение контекста — крайне важная задача, результаты которой влияют на качество решения/сгенерированного кода, возможно, даже больше, чем выбранная модель. В Claude Code за это отвечает Explore sub-agent, который, к слову, справляется неплохо, ровно до тех пор, пока вы не начинаете "по настоящему" использовать Spring: добавляя собственные starters, используя OpenAPI (Spec-first), определяя Bean/Components в стиле Josh Long (описывая их в конфигурациях), а также внедряя множество других инструментов фреймворка. В этом случае качественный анализ можно провести, только зная особенности работы Spring Framework и экосистемы.

В этом выпуске еженедельного дайджеста Skill of the week разберёмся, как, используя Spring Explore Skill, научить агента понимать специфику Spring-приложения и выполнять качественный первичный анализ.

Spring Explore

Spring Explore — Skill, решающий задачу построения первичного контекста для поставленной вами задачи с учётом специфики Spring, Spring Boot, Spring Data JPA/JDBC, Spring MVC и множества других компонентов, применяемых разработчиками при разработке приложений.

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

Как установить

Установить Spring Skills глобально во все обнаруженные агенты:

npx skills add Amplicode/spring-skills -g

Установить только для конкретных агентов (пример — Claude Code + Codex + Gemini CLI):

npx skills add Amplicode/spring-skills -g -a claude-code -a codex -a gemini-cli

С более подробной инструкцией можно ознакомиться тут.

Ручное использование

Для начала разберёмся, как воспользоваться скилом в "ручном" режиме, непосредственно указывая agent на его использование. Нужно это в ситуации, когда вы хотите получить ответ на некоторый вопрос (выяснить, как что-то работает в приложении) или же когда явным образом хотите определить цель исследования.

Попробуем собрать контекст для задачи, приближенной к реальной: issue в spring-petclinic.

Краткое описание:

Управление рабочими расписаниями ветеринаров — функциональность, позволяющая администратору клиники создавать и управлять рабочими графиками ветеринаров: задавать именованные расписания со сменами (дата, время начала и окончания), отмечать одно из расписаний как активное для записи, а также автоматически проверять при создании визита, что выбранный ветеринар работает в указанное время и не занят другим приёмом.

Как видно на видео, skill используется явно /spring-explore ..., а значит, agent активирует его в первую очередь.

Автоматическое использование

Claude Code, Codex и другие agent умеют самостоятельно подбирать и активировать необходимые для задачи skills. Повлиять на это авторы skill могут опосредованно, описав функциональность и возможные паттерны использования в description SKILL.md. Естественно, это не может гарантировать, что skill будет вызван именно для вашей задачи — на этом можно только надеяться.

Использование в собственных skill и агентах

Spring Explore также хорошо использовать в собственных skill — в ситуации, когда skill'у требуется провести некоторый анализ, на основе которого будут приняты решения о том, какой следующий шаг или же в каком виде нужно сгенерировать код.

В качестве примера рассмотрим разработку skill, задача которого — создание новых REST endpoint в нашем приложении. Однако есть одно условие: так как наше приложение полагается на DDD, то и пути в endpoint также должны соответствовать данной логике. Это значит, что на верхнем уровне request path у нас должны присутствовать только aggregate root.

По большому счёту такой skill будет состоять из двух шагов:

  • определение параметров (request path, http method, ...)

  • реализация endpoint в контроллере

Для определения request path нам нужно представление модели в проекции DDD, эту задачу мы как раз и решим с помощью spring-explore.

Назовём наш skill rest-endpoint-ddd

---
name: rest-endpoint-ddd
description: >
  Adds a REST endpoint to a Spring Boot project.
  Use this whenever the user wants to add, create, expose, or design a REST endpoint, API
  route, HTTP handler, or web resource — e.g. "add an endpoint to list an order's line items",
  "expose customers as JSON", "create a GET for articles by tag" — even if they don't say
  the word "REST".
---

# Add a REST Endpoint (DDD-driven)

## Step 1 — Design the request contract

Produce a precise contract to hand to step 2:

```
METHOD  PATH                                params      →  RESPONSE
GET     /orders/{orderId}/items             page, size  →  List<ItemDto>
```

### 1a — Explore the domain and the controllers

Invoke the **spring-explore** skill — `Skill(spring-explore)` — and tell it what you need:

- **DDD aggregate model** for the entities in the task (required) — returns the aggregate tree
  (`[root]` / `[member]` / `→ ref:`) that the path is derived from.
- **Existing controllers** for those entities (its "Get entity controllers" path) — so you know
  whether a controller already owns this resource area.
- Entity descriptions / DTOs / repositories as needed to shape the response and confirm the
  data is reachable.

If this context was already gathered earlier in the conversation, reuse it.

### 1b — Derive the path from the aggregate tree

- **Aggregate root → top-level collection.** `Order [root]` → `/orders`, `/orders/{orderId}`.
- **Member → nested under its root.** A `[member]` is never addressed alone. `Item [member]`
  under `Order` → `/orders/{orderId}/items/{itemId}`; members of members nest further:
  `Note` under `Item` → `/orders/{orderId}/items/{itemId}/notes`.
- **Cross-aggregate reference (`→ ref:`) → query/filter param, never a nesting segment.** The
  referenced root does not own the entity. Orders filtered by customer is `/orders?customerId=…`,
  not `/customers/{id}/orders`.

Method follows intent: read → `GET`, create → `POST`, replace → `PUT`, partial → `PATCH`,
remove → `DELETE`. A trailing `{id}` marks single-item vs. collection.

### 1c — Decide where it lives and what it returns

- **Controller.** Prefer the controller that already owns this resource area (an items endpoint
  joins `OrderController` if it exists). Create a new one only if none fits, matching neighbours'
  package and class style.
- **Response.** Carry member data inline; carry cross-aggregate references as **IDs only**
  (`productId`, not a nested `Product`) — this is what keeps the payload aligned with aggregate
  boundaries instead of leaking unrelated roots.

---

## Step 2 — Implement

Once the contract from step 1 is in hand, **proceed directly to implementation** — do not stop
to present the design and wait for approval. The contract is the input to this step, not a
deliverable to hand back; designing without building leaves the task unfinished. Continue
straight into the work below.

Build the contract in the idiom of this project — the exploration already showed how existing
controllers, DTOs, and repositories are written; match them, and read a neighbour first if a
convention is unclear (annotations, constructor injection, return-body style, naming). Add no
layers, frameworks, or patterns the project doesn't already use.

Build only what the contract requires, in dependency order:

1. **Repository method** — add a derived query (or `@Query`) only if the data isn't already
   reachable; reuse what's there first.
2. **DTO(s)** — add a dedicated shape only if the response/request needs one. Cross-aggregate
   refs are IDs only.
3. **Handler** — add it to the controller chosen in 1c. Map the path, bind params
   (`@PathVariable`, `@RequestParam`, `@RequestBody`), call the repository/service, return the
   response in the project's body convention (e.g. `@ResponseBody` / `@RestController`).
4. **Wiring** — constructor-inject any new dependency the way neighbours do.

Afterwards, confirm the result against the step-1 contract (method, path, params, response) to
catch drift.

Для проверки работоспособности нового skill добавим в проект сущности, связанные с расписанием ветеринара, в качестве aggregate member для сущности Vet.

После чего воспользуемся новым skill для добавления REST endpoint на получение всех расписаний ветеринара.

Если тебе интересно, как настроить свой Agent для разработки на Spring, а также ты не хочешь пропустить новые выпуски Skill of the week и другие полезные материалы по разработке на Spring с AI Agent — подписывайся на канал в ТГК.