<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Start here | Garage Education</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/00-start/</link><atom:link href="https://www.garageeducation.org/docs/agent-harness-spring-ai/00-start/index.xml" rel="self" type="application/rss+xml"/><description>Start here</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-US</language><copyright>©</copyright><lastBuildDate>Sat, 10 Oct 2026 00:00:00 +0000</lastBuildDate><image><url>https://www.garageeducation.org/media/logo.svg</url><title>Start here</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/00-start/</link></image><item><title>Front matter</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/00-start/01-front-matter/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.garageeducation.org/docs/agent-harness-spring-ai/00-start/01-front-matter/</guid><description>&lt;p&gt;Oct 10, 2026 · @Ahmed Hassanien&lt;/p&gt;
&lt;p&gt;This book teaches Java engineers to build an agent harness with Spring AI. The running example is the Log Incident Watcher. Read the chapters in order. Each chapter adds one idea. Run the code in each chapter before you read the next one. All examples use fake data and run offline.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Versions:&lt;/strong&gt; Spring Boot 4.1.1, Spring AI 2.0.1, Spring AI Session 0.6.0, Temporal 1.35.0. Use released versions only.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Local services:&lt;/strong&gt; PostgreSQL 17 with VectorChord, BM25, and AGE. LM Studio with Gemma for chat and BGE-M3 for embeddings. A reranker container for bge-reranker-v2-m3. A Temporal dev server.&lt;/p&gt;
&lt;figure class="arch"&gt;
&lt;script type="application/json"&gt;
{
"title": "The local stack every chapter runs against.",
"nodes": [
{"id": "lm", "type": "boundary", "x": 300, "y": 0, "w": 520, "h": 120, "label": "LM Studio"},
{"id": "app", "x": 0, "y": 175, "w": 200, "label": "Spring Boot app", "detail": "the harness you build", "tone": "platform"},
{"id": "gemma", "x": 320, "y": 40, "w": 230, "label": "Gemma", "detail": "chat model", "tone": "ai"},
{"id": "bge", "x": 570, "y": 40, "w": 230, "label": "BGE-M3", "detail": "embeddings", "tone": "ai"},
{"id": "rerank", "x": 320, "y": 160, "w": 230, "label": "Reranker container", "detail": "bge-reranker-v2-m3", "tone": "ai"},
{"id": "pg", "x": 320, "y": 260, "w": 230, "label": "PostgreSQL 17", "detail": "VectorChord, BM25, AGE", "tone": "data"},
{"id": "temporal", "x": 570, "y": 260, "w": 230, "label": "Temporal dev server", "detail": "durable runs", "tone": "operator"}
],
"edges": [
{"from": "app", "to": "gemma", "label": "chat", "fromSide": "top", "toSide": "left", "animated": true},
{"from": "app", "to": "rerank", "label": "rerank", "fromSide": "right", "toSide": "left"},
{"from": "app", "to": "pg", "label": "read / write", "fromSide": "bottom", "toSide": "left", "both": true}
]
}
&lt;/script&gt;
&lt;figcaption&gt;Figure 0.1. The local stack. Everything runs on one machine with fake data. The figure leaves out the embedding and Temporal connections from the app; later chapters draw each one where it is used.&lt;/figcaption&gt;
&lt;/figure&gt;</description></item><item><title>Glossary</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/00-start/02-glossary/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.garageeducation.org/docs/agent-harness-spring-ai/00-start/02-glossary/</guid><description>&lt;figure class="arch"&gt;
&lt;script type="application/json"&gt;
{
"title": "How the core terms fit together.",
"nodes": [
{"id": "agent", "type": "boundary", "x": 0, "y": 0, "w": 860, "h": 330, "label": "Agent = model + harness + goal"},
{"id": "goal", "x": 30, "y": 50, "w": 170, "label": "Goal", "detail": "what the run must achieve"},
{"id": "harness", "type": "boundary", "x": 230, "y": 40, "w": 400, "h": 270, "label": "Harness"},
{"id": "loop", "x": 250, "y": 80, "w": 170, "label": "Loop", "detail": "model call, tools, result", "tone": "platform"},
{"id": "term", "x": 440, "y": 80, "w": 170, "label": "Termination", "detail": "the rule that ends a run", "tone": "platform"},
{"id": "tools", "x": 250, "y": 170, "w": 170, "label": "Tools", "detail": "Java methods", "tone": "platform"},
{"id": "skills", "x": 440, "y": 170, "w": 170, "label": "Skills", "detail": "loaded only when needed", "tone": "platform"},
{"id": "memory", "x": 250, "y": 245, "w": 360, "label": "Memory", "detail": "short-term conversation, long-term store", "tone": "data"},
{"id": "model", "x": 660, "y": 80, "w": 170, "label": "Model", "detail": "text in, text out", "tone": "ai"},
{"id": "window", "x": 660, "y": 200, "w": 170, "label": "Context window", "detail": "measured in tokens", "tone": "muted"}
],
"edges": [
{"from": "goal", "to": "loop", "label": "drives"},
{"from": "loop", "to": "model", "label": "prompt / reply", "fromSide": "top", "toSide": "top", "both": true, "animated": true},
{"from": "model", "to": "window", "label": "reads one"}
]
}
&lt;/script&gt;
&lt;figcaption&gt;Figure 0.2. How the core terms fit together. Retrieval, evaluation, and durable-execution terms are left out; each has its own part of the course.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Model.&lt;/strong&gt; A large language model. It takes text in and returns text out.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Harness.&lt;/strong&gt; The code around a model. It sends requests, runs tools, keeps state, and decides when to stop.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent.&lt;/strong&gt; A model plus a harness plus a goal.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool.&lt;/strong&gt; A Java method the model can ask the harness to run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool call.&lt;/strong&gt; The model&amp;rsquo;s request to run a tool. It names the tool and gives arguments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loop.&lt;/strong&gt; The cycle of model call, tool execution, and result. It ends when the run stops.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Termination.&lt;/strong&gt; The rule that ends a run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context window.&lt;/strong&gt; The text the model can read in one call. It is measured in tokens.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Token.&lt;/strong&gt; A small piece of text. Providers bill by token.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skill.&lt;/strong&gt; A file of instructions for one task. The harness loads it only when needed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sub-agent.&lt;/strong&gt; An agent that a parent agent calls as a tool.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory.&lt;/strong&gt; Information kept across model calls. Short-term memory is the recent conversation. Long-term memory is stored outside it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embedding.&lt;/strong&gt; A list of numbers that represents the meaning of a text.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vector store.&lt;/strong&gt; A database that finds texts with similar embeddings.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BM25.&lt;/strong&gt; A keyword scoring method. It rewards rare words that appear often in a document.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hybrid search.&lt;/strong&gt; Keyword search and vector search, merged into one result list.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RRF (Reciprocal Rank Fusion).&lt;/strong&gt; A way to merge ranked lists by rank position, not by score.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reranker.&lt;/strong&gt; A model that scores a query and each candidate together, then reorders the candidates.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RAG (retrieval-augmented generation).&lt;/strong&gt; The harness fetches relevant documents before the model answers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HITL (human-in-the-loop).&lt;/strong&gt; A run that pauses until a person approves an action.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Graph.&lt;/strong&gt; A flow of nodes and edges. A knowledge graph stores relationships between things.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Durable execution.&lt;/strong&gt; A run that survives crashes and restarts because its state is stored.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Workflow (Temporal).&lt;/strong&gt; The durable definition of one run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Activity (Temporal).&lt;/strong&gt; A unit of work with side effects, such as a model call. Temporal retries it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Signal (Temporal).&lt;/strong&gt; A message sent to a running workflow, such as an approval.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Eval.&lt;/strong&gt; A fixed set of test inputs with expected properties. Run it before each change.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompt caching.&lt;/strong&gt; The provider reuses work for a stable part of the prompt. It lowers cost.&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>