Runnable, minimal LLM examples for Java - Spring AI & LangChain4j. RAG, agents, MCP servers, tool calling, structured output, evals.
One folder = one command. Every example is isolated, has its own build, and runs in under a minute.
Most "AI in Java" examples are either a single hello-world or a full demo app with 40 dependencies. This repo sits in between: each recipe shows one pattern, in one file where possible, with no framework magic hidden.
- Same pattern implemented in both Spring AI and LangChain4j, so you can compare them honestly
- Works with OpenAI, Anthropic, and local models via Ollama - switch with an env var
- Every recipe has a test, so the examples don't silently rot
git clone https://github.com/alxkm/java-ai-cookbook.git
cd java-ai-cookbook/spring-ai/01-chat-basic
export OPENAI_API_KEY=sk-... # or: export OLLAMA_BASE_URL=http://localhost:11434
./mvnw spring-boot:runThat's it. Open the folder of any recipe and run the command in its README.
| # | Pattern | Spring AI | LangChain4j | What you learn |
|---|---|---|---|---|
| 01 | Chat basics | → | → | ChatClient / ChatModel, system prompt, model switching |
| 02 | Streaming | → | → | Token streaming to console and SSE endpoint |
| 03 | Structured output | → | → | JSON → Java record, schema enforcement, retries |
| 04 | Tool calling | → | → | Expose Java methods as tools, multi-step calls |
| 05 | Conversation memory | → | → | In-memory vs persisted history, token windows |
| 06 | Embeddings | → | → | Embedding models, similarity, batching |
| 07 | RAG - minimal | → | → | Load → split → embed → retrieve → answer |
| 08 | RAG - pgvector | → | → | Production vector store with Testcontainers |
| 09 | RAG - advanced | → | → | Query rewriting, re-ranking, metadata filters |
| 10 | Agent - ReAct loop | → | → | Planning, tool selection, stopping conditions |
| 11 | Multi-agent | → | → | Orchestrator + workers, hand-offs |
| 12 | MCP client | → | → | Consume tools from an MCP server |
| 13 | MCP server | → | → | Expose your Java service as an MCP server |
| 14 | Multimodal | → | → | Images in, text out |
| 15 | Guardrails | → | → | Input/output validation, PII, prompt injection |
| 16 | Observability | → | → | Tracing, token/cost metrics, Micrometer |
| 17 | Evals | → | → | LLM-as-judge, regression tests for prompts |
| 18 | Local models | → | → | Ollama, no API key, offline |
| 19 | Retry & rate limits | → | → | 429s, backoff with jitter, a wall-clock budget |
| 20 | Progressive tool disclosure | → | → | Hundreds of tools without hundreds of tool definitions |
More recipes are added regularly - see open issues for what's next, or propose one.
- Spring AI vs LangChain4j - a side-by-side comparison written after implementing all 20 patterns twice, with links into the code for every claim.
- Choosing a model - which model for which recipe, what it costs, and what breaks when you go smaller.
- CONTRIBUTING.md - the recipe template and the conventions.
java-ai-cookbook/
├── spring-ai/
│ ├── 01-chat-basic/ # independent Maven project
│ │ ├── README.md # what it shows, how to run, what to look at
│ │ ├── pom.xml
│ │ └── src/
│ └── ...
├── langchain4j/
│ └── ... # same numbering, same patterns
├── docs/
│ ├── spring-ai-vs-langchain4j.md # honest side-by-side comparison
│ └── choosing-a-model.md
├── .github/workflows/build.yml # one CI job per recipe, no API keys
├── tools/ # run-all-tests, link and config-key checks
├── CONTRIBUTING.md
└── .env.example
Each recipe README follows the same shape: What / Run / Where to look / Gotchas.
All recipes read the same environment variables:
| Variable | Purpose |
|---|---|
OPENAI_API_KEY |
Use OpenAI models (default provider) |
ANTHROPIC_API_KEY |
Use Anthropic models |
OLLAMA_BASE_URL |
Use a local Ollama instance |
AI_PROVIDER |
openai | anthropic | ollama - overrides auto-detection |
EMBEDDING_PROVIDER |
openai | ollama - used by the embedding and RAG recipes, because Anthropic has no embedding endpoint |
Copy .env.example to .env and fill in what you have. Nothing else is required.
- Java 21+
- Docker (only for recipes marked with pgvector / Testcontainers)
- One of: an OpenAI key, an Anthropic key, or Ollama running locally
Recipes are welcome. Keep them small, keep them runnable, keep them tested. See CONTRIBUTING.md for the recipe template.