Learn to build AI applications with Spring Boot 4 and Spring AI 2, one exercise at a time.
You build one app all the way through: the assistant of Amigos Books, an online bookstore
for developers. Every module adds one capability: prompts, memory, tools, RAG, MCP, agents,
evaluation, production. Each module is a standalone Spring Boot project with a README that
explains the idea, a TASKS.md with what to build, and tests that turn green when you're done.
| # | Module | You learn | Docker |
|---|---|---|---|
| 00 | First Chat | ChatClient, DeepSeek config, tokens |
No |
| 01 | ChatClient in Depth | Message roles, options, streaming, no memory | No |
| 02 | Prompt Templates | .st templates, prompt stuffing, few-shot |
No |
| 03 | Structured Output | .entity(...), lists, retries, validating model output |
No |
| 04 | Chat Memory | MessageChatMemoryAdvisor, windows, memory in Postgres |
Yes |
| 05 | Advisors | Custom advisors, token tracking, guardrails | Yes |
| 06 | Tool Calling | @Tool, the tool loop, ToolContext, authorization |
Yes |
| 07 | Embeddings | Vectors, cosine similarity, local ONNX, pgvector | Yes |
| 08 | RAG | ETL, QuestionAnswerAdvisor, modular RAG, sources |
Yes |
| 09 | MCP | MCP server with tools and resources, MCP client | Yes |
| 10 | Agent Patterns | Chain, routing, parallel, orchestrator, evaluator | Yes |
| 11 | Evaluation | Golden datasets, retrieval metrics, LLM judge | Yes |
| 12 | Production | Spring Security, resilience, rate limits, caching, metrics | Yes |
| 13 | Capstone: Gift Finder | A feature brief and acceptance tests, your design | Yes |
- Java 25, Spring Boot 4.1, Spring AI 2.0
- DeepSeek for chat
- Local ONNX embeddings and Postgres with pgvector (from module 07)
- The MCP Java SDK (module 09), Spring Security and Actuator (module 12)
- Docker Compose for the modules that need a database (from module 04)
Click Fork at the top of the page, then clone your fork:
git clone https://github.com/<your-username>/spring-ai-course.git
cd spring-ai-course
git remote add upstream https://github.com/amigoscode/spring-ai-course.git- Create a key at platform.deepseek.com/api_keys
- Add a few dollars of credit. The whole course costs well under $1 in API calls.
- Copy
.env.exampleto.envin the repo root and paste your key:
cp .env.example .env.env is in .gitignore. Never commit your key. Every module reads the key from this one
file, or from a DEEPSEEK_API_KEY environment variable if you prefer.
- In your fork, go to Settings → General → Features and tick Issues.
- Go to the Actions tab and click I understand my workflows, go ahead and enable them.
- Click Set up my tasks on the left, then Run workflow.
You get one issue per task and a milestone per module with a progress bar. Close the issues
as you go, or write closes #12 in a commit message.
Optional: a kanban board
gh auth refresh -s project
./scripts/create_board.shIt creates a GitHub Projects board with all your task issues. Switch its layout to Board to drag tasks from Todo to Done.
Everything works on Windows. Install Git for Windows
and a Java 25 JDK. You don't need
to install Maven: every module has a Maven wrapper (mvnw for macOS and Linux,
mvnw.cmd for Windows).
| macOS / Linux | Windows PowerShell | Windows cmd |
|---|---|---|
./mvnw test |
.\mvnw test |
mvnw test |
./mvnw test -Dtest=Task3RecommendTest |
.\mvnw test "-Dtest=Task3RecommendTest" |
mvnw test -Dtest=Task3RecommendTest |
cp .env.example .env |
Copy-Item .env.example .env |
copy .env.example .env |
curl "localhost:8080/..." |
curl.exe "localhost:8080/..." |
curl "localhost:8080/..." |
- In PowerShell, put
-D...arguments in quotes, otherwise PowerShell can split them. - In Windows PowerShell 5,
curlis an alias forInvoke-WebRequest. Typecurl.exeinstead. - Modules from 04 onward need Docker Desktop running.
- The optional
scripts/create_board.shruns in Git Bash, which comes with Git for Windows.
The commands in each module's README and TASKS.md use the macOS/Linux form. Swap ./mvnw
for .\mvnw (PowerShell) or mvnw (cmd).
Open 00-first-chat in your IDE (open the module folder, not the repo root) and read its README.
04-chat-memory/
├── README.md the idea, with diagrams. Read it first.
├── TASKS.md what to build, step by step
├── compose.yaml the database, if the module needs one
├── pom.xml a standalone Spring Boot project
└── src/
├── main/ starter code, with // TODO task-N comments
└── test/ one test class per task, failing until you finish it
./mvnw test # all tasks in the module
./mvnw test -Dtest=Task3RecommendTest # one task
./mvnw test -Plive # tests that call the real DeepSeek API
./mvnw spring-boot:run # run the appThe task tests use a fake model: they're instant, free, and work offline. The live
tests call DeepSeek for real and cost a fraction of a cent.
From module 04 on, Docker must be running: the app starts Postgres with Docker Compose, and the tests start their own with Testcontainers. Module 07 also downloads a small embedding model (about 90 MB) the first time.
Each module starts where the previous one ended, so you can jump into any module even if you skipped one.
The finished code is on the solution branch. To see the answer for one module:
git fetch upstream solution
git diff main upstream/solution -- 02-prompt-templatesTry for a while first. Each task also has a hint under it in TASKS.md.
New modules and fixes land on main. To get them:
- Commit your work first:
git add -A && git commit -m "my progress" - Pull the updates:
git fetch upstream
git merge upstream/mainIf you use the Sync fork button on GitHub instead and it shows a conflict, never click "Discard commits". That deletes your work. Use the commands above and resolve the conflict.
See CHANGELOG.md for what changed.