Start with the Fundamentals
- Welcome back - let's build something?
- Start with the Fundamentals
I get the same question from every person when I mention how I’m building my Agentic Golf Caddy:
why make it harder than it needs to be?
No Python. No LangChain. No Claude Code. The raw Anthropic SDK in Go, hands on keyboard, built from scratch.
In my experience, you don’t truly understand something until you’ve built close enough to the metal to feel where the sharp edges are.
Learn from the Metal Up.
Frameworks are great — but if you reach for one before you understand what it’s abstracting, you’re not learning the technology you’re learning a framework.
You need to build close to the metal first — understand the trade-offs and find the sharp edges.
The frameworks come later, once you know what they’re actually doing for you.
They exist to accelerate development cycles.
With that principle in mind, I’m building the Agentic Golf Caddy against the raw Anthropic SDK.
Now, the Anthropic GoLang SDK is basically a strongly typed wrapper around the Anthropic API — requests, responses, and action verbs.
Using a more full featured AI framework like a LangChain or similar would obviously provide a lot more higher level abstractions around the conceptts we’ll need to manage - memory, agent loops, tooling, etc.
However, this is exactly why building close to the metal is the right approach - if you want to understand how these solutions really work you need to start with the basics.
Don’t force Agentic when Generative is sufficient.
Starting with the basics, I spent a bunch of time thinking about the labelling of what this solution actually was.
It felt like at this point, I was taking a bit of license by calling this an “Agentic” golf caddy.
I really like this definition of Agentic AI by Google.
Agentic AI is an advanced form of artificial intelligence focused on autonomous decision-making and action. Unlike traditional AI, which primarily responds to commands or analyzes data, agentic AI can set goals, plan, and execute tasks with minimal human intervention. This emerging technology has the potential to revolutionize various industries by automating complex processes and optimizing workflows.
As compared to the Generative AI definition
Generative AI, as its name suggests, is focused on the creation of new content, such as text, images, code, or music, based on input prompts. The LLM is at the heart of generative AI, and the value is generated by what the model can do and simple extensions of the LLM’s capabilities. For example, you can generate or edit content, and even perform simple function calling and chain together various options.
It’s not a matter of which is better - the situation really defines the approach.
- Is it autonomous? No — it’s prompted.
- Is it setting goals? No — goals are defined in the system prompt.
- Is it making decisions on what to do next? Partially — it decides which tools to call and in what order, but only within the boundaries we’ve designed.
- Is it reflecting on its own output? Not yet — there’s no feedback loop that updates its behaviour across sessions.
- Is it taking action in the world? Minimally — it reads data and returns recommendations, but doesn’t act on them.
Just because we’re using tools in a message loop doesn’t make the application “Agentic”.
The “Agentic” label is earned through autonomy, goal-setting and reflection - all things that we will address in later stages of the build.
The First Learning…it’s just text
Twenty-two years in technology and it’s funny how everything eventually comes back to computers sending text over HTTP to other computers and doing something smart with it.
If you’d read the marketing hype without digging in from the ground up, you’d assume AI had fundamentally shifted how these systems are built.
Agentic loops, RAG and tool calls all sound so exotic, but in reality
- Prompt an LLM — call an API with a string
- Define your agent persona and objective — a big string
- Manage your context and memory — strings prepended before the request
- Access a system through a tool — parse a string and go back to step 1
What this means in practice is that the patterns for building reliably on top of these systems have to shift. Anthropic’s own Building Effective Agents is mandatory reading if you want to go deeper.
And the impact of a wordy agent
The first interface was a simple text based interface written in Go using the Huh framework — a quick way to interact with the SQLite database and the agent in real time.

However, as I started requesting shot strategies I ran into a weird problem.
Every now and then — usually on a new hole, but not always — the agent would output a large text-based preamble instead of the strict JSON format I’d explicitly requested.

The system prompt was structured and detailed, but the output format instruction was defined last.
That made sense to me as a human — we tend to prioritise recency.
However from the model’s perspective, content at the end of a prompt is weighted less than content at the start.
So I restructured the prompt, moving the format constraint to the top.
While an interesting learning and good to know for the future, it didn’t fix the issue.
The root cause was more interesting.
The model wasn’t ignoring the instruction randomly.
It was doing it on complex holes — a short par 4 that was potentially driveable, a hole with an unusual strategic tension.
Turns out the model really wants to explain itself. On simple holes it behaves. On interesting ones, the urge to reason out loud overrides the instruction to just return JSON.
The eventual fix was assistant turn prefill — prepopulating the start of the agent’s response before the API call:
// Prefill the assistant response to enforce JSON-only output
messages = append(messages, anthropic.MessageParam{
Role: anthropic.MessageParamRole(anthropic.MessageParamRoleAssistant),
Content: []anthropic.ContentBlockParamUnion{
anthropic.NewTextBlock("{"),
},
})Bear in mind the API returns only the continuation — not the prefill itself — so you need to prepend the { back onto the response before parsing.
It feels like a hack. But it reinforces something important: the model doesn’t actually “know” JSON.
It predicts tokens that look like JSON.
On a routine hole the prediction is clean and the output is the defined JSON, but in an interesting scenario, the urge to reason out loud takes over.
Wrap-Up
A framework would have handled the JSON bug silently, hidden behind an abstraction, and I would probably have never known about it.
When something stranger eventually broke, I’d have had no mental model for why.
Building close to the metal is slower and occasionally frustrating, but it’s the only way to actually understand what you’re building.
However, a working harness is only half the problem. Next up is what you actually feed it — and that turns out to have its own sharp edges.