eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

1. Overview

Large Language Models (LLMs) have advanced to agentic systems capable of executing tasks more complex than simply generating text. One of the emerging areas is agent skills as introduced by Antropic.

Agent skills enable LLM to produce document files without an additional API, such as Apache POI. They invoke the built-in capabilities that generate documents on the provider server and return them via file identifiers. Spring AI supports skills with the Anthropic models, making it easy to integrate with Java applications.

In this tutorial, we’ll explore what Anthropic provides in terms of agent skills and how we integrate them with Spring AI.

2. Anthropic Pre-built Skills

Anthropic provides a set of pre-built agent skills that can generate a document and populate it with content. Thus, the model can return a document file rather than plain text.

Of course, there are a few document formats that Anthropic currently supports:

  • DOCX: Word documents with formatting
  • PDF: Formatted PDF reports
  • PPTX: PowerPoint slides
  • XLSX: Excel spreadsheets

In Spring AI, we can use these Anthropic pre-built skills by applying them via chat options.

3. Configuration

To get started with the Anthropic skills, let’s add the required dependency to pom.xml:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-anthropic</artifactId>
</dependency>

Next, we configure the Anthropic API key in application.yml to use Anthropic models:

spring:
  ai:
    anthropic:
      api-key: "${ANTHROPIC_API_KEY}"

This way, we don’t need to supply the key separately.

4. Sample Implementation

To demonstrate the features, let’s build a simple web application that generates a sales report. Moreover, the implementation enables us to output a specific document format supported by the pre-built skills via the request prompt.

4.1. Data Service

To begin with, we need to provide a model to represent the data sent to the chat model:

public record MonthlySale(String product, int year, Month month, BigDecimal amount) {
}

For demonstration purposes, we create a simple data service layer to return hardcoded data. In this case, the service returns a List of MonthlySale containing 12 months of sales for product A and product B:

@Service
public class MonthlySalesService {
    public List<MonthlySale> getMonthlySalesForYear(int year) {
        return List.of(
            // Product A monthly sales
            new MonthlySale("Product A", year, Month.JANUARY, new BigDecimal("1200")),
            new MonthlySale("Product A", year, Month.FEBRUARY, new BigDecimal("1325")),
            ...
            // Product B monthly sales
            ...
            new MonthlySale("Product B", year, Month.NOVEMBER, new BigDecimal("1330")),
            new MonthlySale("Product B", year, Month.DECEMBER, new BigDecimal("1395"))
        );
    }
}

In reality, we could replace it with an MCP tool to retrieve the sales data from the database and integrate it with the chat model.

4.2. Controller

Next, we expose an HTTP endpoint to accept a request prompt that shapes the document content and format.

Since the document format isn’t known in advance, we return the mime type, which is determined from the chat model, to the client:

@RestController
@RequestMapping("/agent-skills")
@Validated
public class AgentSkillsController {
    private final AgentSkillsService agentSkillsService;

    public AgentSkillsController(AgentSkillsService agentSkillsService) {
        this.agentSkillsService = agentSkillsService;
    }

    @GetMapping("/report")
    public ResponseEntity<byte[]> genReport(@RequestBody @Valid ReportRequest reportRequest) {
        AnthropicDocument document = agentSkillsService.genReport(reportRequest);
        return ResponseEntity.ok()
          .contentType(MediaType.parseMediaType(document.mimeType()))
          .header(HttpHeaders.CONTENT_DISPOSITION,
            ContentDisposition.attachment()
              .filename(document.fileName())
              .build()
              .toString())
          .body(document.content());
    }
}

Let’s introduce a simple placeholder record:

public record ReportRequest(@NotNull String prompt) {
}

This holds the prompt message input by the user, which gets passed to the AgentSkillService.

4.3. Agent Skill Service

Now, we create a service to generate a document using the Anthropic chat model with the pre-built skills. The Anthropic chat options can support multiple skills. 

In this example, we put all the available pre-built skills into the chat model, and employ the user prompt to control what document format we would like to produce. This aims to demonstrate that the chat model can select the appropriate skill based on the prompt.

However, it’s usually better to enable the required skills only to reduce the chance of outputting an unpredictable format:

@Service
public class AgentSkillsService {
    private final AnthropicChatModel chatModel;
    private final AnthropicApi anthropicApi;
    private final MonthlySalesService monthlySalesService;

    public AgentSkillsService(
      AnthropicChatModel chatModel,
      AnthropicApi anthropicApi, 
      MonthlySalesService monthlySalesService) {
        this.chatModel = chatModel;
        this.anthropicApi = anthropicApi;
        this.monthlySalesService = monthlySalesService;
    }

    public AnthropicDocument genReport(ReportRequest reportRequest) {
        ChatResponse response = ChatClient.create(chatModel)
          .prompt()
          .system( "Given the dataset of monthly sales for our product: " 
            + monthlySalesService.getMonthlySalesForYear(2025))
          .user(reportRequest.prompt())
          .options(AnthropicChatOptions.builder()
            .model("claude-sonnet-4-5")
            .skill(AnthropicApi.AnthropicSkill.DOCX)
            .skill(AnthropicApi.AnthropicSkill.PDF)
            .skill(AnthropicApi.AnthropicSkill.PPTX)
            .skill(AnthropicApi.AnthropicSkill.XLSX)
            maxTokens(4096)
            .build())
          .call()
          .chatResponse();

        List fileIds = AnthropicSkillsResponseHelper.extractFileIds(response);
        if (fileIds.isEmpty()) {
            throw new IllegalStateException("No document was generated by the skill");
        }

        return downloadReport(fileIds.get(0));
    }

    public AnthropicDocument downloadReport(String fileId) {
        AnthropicApi.FileMetadata metadata = anthropicApi.getFileMetadata(fileId);
        byte[] content = anthropicApi.downloadFile(fileId);
        return new AnthropicDocument(metadata.filename(), metadata.mimeType(), content);
    }
}

Notably, we set the maxTokens to 4096 to control the maximum amount of content that could be generated in a response. As a rule of thumb, one (1) token is roughly equal to four (4) characters. In this case, 4096 should be more than sufficient. However, we could extend it to a larger size if we expect a lengthy report.

Once we receive the response from the chat model, we can use the AnthropicSkillsResponseHelper to extract the file ID from that response. This file ID uniquely identifies the generated file stored on the Anthropic server.

Let’s check the files in the Claude console:

claude console files

Thus, we use the AnthropicAPI provided by Spring AI to obtain the file information based on the file ID. Of course, the AnthropicApi.FileMetadata contains details about the file:

  • file name
  • file size
  • creation date
  • MIME type

While AnthropicDocument is a simple Java record to store the file name, the mime type and the file content, it returns them to the client via the controller:

public record AnthropicDocument(String fileName, String, mimeType, byte[] content) {
}

Thus, we have the basic application ready for testing.

5. Test Run

Everything is set, and we can start testing. To that end, let’s call the endpoint using Postman to trigger the request.

5.1. PDF Report

To begin with, we create an example request for generating a sales report with a summary and a table in PDF format:

agent skills postman call-01

At this point, we see the content, including the monthly sales table and a summary in the generated file:

anthropic skills docx sample

So, all information is there and in a structured format.

5.2. Excel Spreadsheet

Let’s change the prompt to generate an Excel spreadsheet instead, with a bar chart instead of a summary:

{
    "prompt": "Create a Excel spreadsheet for our product monthly sales. Include a monthly sales table, and a monthly bar chart next to the table."
}

Now, the report reflects the format change:

agent skills xlsx

So, we see the spreadsheet with the correct data and formatting.

6. Conclusion

In this article, we explored how to integrate the pre-built agent skills of Anthropic with a chat model to generate various documents using Spring AI.

Furthermore, we demonstrated how to use a prompt to control the actual output document format. In particular, this provides flexibility to generate different document formats without changing the application logic.

As usual, the complete code examples are available over on GitHub.

Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)