Building your first agent
A 30-minute walkthrough — write the prompt, spawn it, debug it, ship it.
By the end of this guide you'll have a working agent that summarizes the top story on Hacker News, learns from each run, and is ready to extend toward anything-with-a-feed.
The task
Read the front page of Hacker News. Find the top story. Return a JSON object with the title, link, and a one-sentence "why this matters" summary.
Five minutes to write, 25 minutes to iterate. Let's go.
Step 1 — Write the first version
Open a file, write this:
curl -X POST https://jettson.dev/api/v1/agents \
-H "Authorization: Bearer $JETTSON_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"task": "Use jettson_browser_navigate on https://news.ycombinator.com. Then jettson_browser_extract_text. Find the top story. Return JSON: {top_story: {title, link, why_it_matters}}."
}'Save it as run.sh, make it executable, run.
The Console (at /console/agents) shows the agent spawn, browse, extract, reason, and return — usually 6-8 seconds end to end with a warm-pool hit.
Check final_result. You'll see roughly the right answer. Probably the title is right; the link might be the relative URL item?id=... instead of the full one; "why it matters" might be too generic.
Step 2 — Tighten the prompt
The Mind is good but it's not psychic. Where the output was wrong, the prompt was vague. Iterate:
Use jettson_browser_navigate on https://news.ycombinator.com.
Then jettson_browser_extract_text to grab the page.
Identify the TOP story — the first one listed.
For the link: Hacker News uses relative URLs like "item?id=...".
Convert it to an absolute URL: https://news.ycombinator.com/item?id=...
For "why it matters": be specific. "Talks about X and Y" is bad.
"This matters because Z" is good. One sentence, max 25 words.
Return only this JSON:
{
"top_story": {
"title": "...",
"link": "...",
"why_it_matters": "..."
}
}Run again. Output should be sharper.
Step 3 — Add memory
Here's where it gets fun. Tell the agent to skip stories it's already covered:
[the same prompt as above]
BEFORE returning, call jettson_memory_search with the story title as the query
and namespace="hn_seen".
If a memory with `score >= 0.7` exists, that means we've seen this story
before. Return: { "skipped": true, "reason": "already covered <date>" } instead.
AFTER returning a new story, call jettson_memory_put:
- namespace: "hn_seen"
- key: "story_<id-from-link>"
- value: <title + summary>
- importance: 6
- expires_in_days: 14Run it twice. The second run skips. Run it tomorrow on a different top story; it picks the new one and remembers it.
You've now built an agent that won't repeat itself. That's a real piece of software.
Step 4 — Debug a failure
Eventually the agent will fail. Maybe Hacker News changes its HTML; maybe the timeout fires; maybe the JSON it returns is malformed. Here's how to debug:
- Open the agent in the Console. The Progress timeline shows every
thinking,tool_use,tool_result, and the finalagent_completedoragent_errored. - Look at the last successful tool_result. That's the last known good state. Whatever happened after it is the bug.
- Read the next tool_use input. If the Mind picked a weird selector, the prompt didn't constrain it enough.
Common fixes:
- The Mind picked the wrong element → add a more specific selector hint in the prompt.
- The browser returned
truncated: true→ ask for aselectorargument on the extract call (e.g.tr.athingfor HN's story row). - The JSON had extra prose around it → the prompt is letting the model preface. Add: "Return ONLY the JSON. No prose before or after."
Step 5 — Iterate
The cycle: run → check output → tighten prompt → run again. Five minutes per iteration.
Three patterns that consistently make agents better:
- Constrain the output shape upfront. "Return JSON with these fields." is better than "Tell me about it."
- Reference tools by name. "Use
jettson_browser_extract_text" is better than "look at the page." - Memory in, memory out. Recall before deciding; remember after deciding. That's the whole loop.
What good looks like
When you're done, the prompt is ~50 lines of Markdown. It runs in under 8 seconds. It returns valid JSON every time. It remembers what it's seen. You ship it as a cron job that emails you the top new story every morning.
You wrote it in 30 minutes.
Where to go from here
- Using memory effectively — patterns for the memory layer
- Tool composition patterns — multi-tool recipes
- Handling failures — graceful fallbacks
- Examples — three production-grade templates to fork