← AI Engineering
NLP & LLM Systems · Prompt Engineering · Local CLI App

AI/ML Study Assistant Chatbot

A conversational assistant that helps people follow a learning path toward the AI Engineer role, built to demonstrate core prompt engineering skills: system prompt design, multi-turn context management, structured output, and robust error handling. This project intentionally runs locally rather than being deployed.

Python Anthropic API Claude Sonnet 5 Claude Haiku 4.5 Prompt Engineering

Design process: naive vs. refined system prompt

To make the reasoning behind the final design explicit rather than just showing the end result, this project documents two versions of the system prompt: a minimal, unconstrained v1 baseline, and a v2 refined version that addresses its specific shortcomings — role clarity, level adaptation, scope boundaries, anti-hallucination guardrails, a "guide, don't solve" policy for exercises, and a clear rule for when to use structured (JSON) output.

v1 problemv2 solution
Vague role/toneExplicit role definition
No explanation levelDedicated section, asks if unsure
No out-of-scope handling"Scope" section with fallback
Hallucination riskExplicit honesty-about-limits section
Direct answers to exercises"Guide, don't solve" behavior
No structured output ruleExplicit prose vs. JSON rule

A dedicated comparison script sends the same targeted test questions to both versions side by side. The chatbot uses v2 by default.

Asked "Can you write me a poem about the ocean?" — v1 writes the poem in full, no hesitation. v2 declines and redirects: "I appreciate the creative request, but that falls outside my scope... What would you like to dive into?"
Asked a certification exam question directly, v1 answers with the letter and a full explanation. v2 responds: "Rather than just giving you the letter, let's work through it..." and walks through elimination logic instead, leaving the answer to be reached by the learner.

A note on sampling parameters and model choice

This project uses two models for two different purposes: the main chatbot uses Claude Sonnet 5, the current production model — as of Sonnet 5, temperature, top_p, and top_k are no longer configurable, so model behavior is guided entirely through the system prompt instead. A separate sampling demo uses Claude Haiku 4.5, which still accepts custom sampling parameters, specifically to demonstrate how temperature and top_p affect generated output.

This split reflects a real engineering trade-off: use the current production model where it matters, and isolate the parameter demonstration on a model that still supports it, rather than building the whole project against an older model just to keep a feature.

Gotcha: Claude Sonnet 5 has adaptive thinking enabled by default, which can place a thinking block before the text block in the response. Always locate the text block by type rather than assuming its position.

Structured output: study plan requests

Messages that look like a study-plan or roadmap request are routed to a structured JSON response instead of free text.

Gotcha: response prefilling — normally a common technique to force JSON output — is not supported at all on Claude Sonnet 5 (or any Claude 4.6+ model); it returns a 400 error unconditionally. Structured output is instead obtained through schema-in-prompt instructions plus defensive parsing on the code side, with one retry on invalid JSON before giving up.
Gotcha: the default token limit was not enough for study plan responses, causing the JSON to truncate mid-string. Sonnet 5's new tokenizer produces roughly 30% more tokens per unit of text than earlier models. Study plan requests now use a separate, higher token limit.

Example interactions

Context management and error handling

Conversation history uses a sliding window: only the most recent N turns are resent on each call, to bound token growth (and cost) in long sessions. API calls distinguish between transient errors (timeouts, connection errors, 5xx) and rate limits, which are retried with exponential backoff, and permanent errors (invalid request, auth failure), which are surfaced immediately rather than retried.

Tools used

Python Anthropic Python SDK Claude Sonnet 5 Claude Haiku 4.5 python-dotenv