Companion code for the YouTube video: Build an AI Coach with Memory — OpenAI Agents SDK
A behavioral interview coach that remembers you across sessions. It tracks your target role, your story bank, your weak spots, and your coaching preferences — without you ever having to repeat yourself.
Built with the OpenAI Agents SDK using the Context Personalization memory pattern from the OpenAI cookbook.
The core pattern this repo teaches is distillation + consolidation:
- Distillation — the agent calls
save_memory_noteandupdate_profilesilently mid-conversation, writing durable insights into a session-scoped staging area as it talks to you - Injection — before every turn, the agent's full memory (profile + notes + practice history) is rendered into the system prompt via SDK lifecycle hooks
- Consolidation — at end of session, a second LLM call merges session notes into long-term global memory, promoting durable insights and dropping session-only context
This pattern is domain-agnostic. Swap the state object and prompts to build a deal coach, a fitness coach, a language tutor — the architecture is identical.
| Layer | Choice |
|---|---|
| Framework | SvelteKit |
| Agent runtime | OpenAI Agents SDK (@openai/agents) |
| Models | gpt-5.4-mini (coaching), gpt-5.4-nano (consolidation) |
| Persistence | Plain JSON file (data/coach-state.json) |
| UI components | shadcn-svelte + Tailwind CSS v4 |
| Package manager | pnpm |
- Node.js 20+
- pnpm —
npm install -g pnpm - An OpenAI API key with access to GPT models — get one here
git clone https://github.com/yourusername/ai-interview-coach.git
cd ai-interview-coach
pnpm installcp .env.example .envOpen .env and replace the placeholder with your key:
OPENAI_API_KEY=sk-...
pnpm devOpen http://localhost:5173. The app creates data/coach-state.json automatically on first run.
The whole memory system lives in the agent layer — everything else is UI plumbing:
src/lib/agent/
├── types.ts ← The state object: profile, globalMemory, sessionMemory
├── state.ts ← Load/write/clone state, memory utilities
├── agent.ts ← Agent definition + two tools (save_memory_note, update_profile)
├── hooks.ts ← Lifecycle hooks: render memory into the system prompt
├── memory.ts ← buildInstructions: assembles profile + memories into prompt
├── consolidation.ts ← End-of-session: LLM merges session notes → global memory
└── prompts.ts ← All prompt text: instructions, tool descriptions, memory policy
Data flow in one line: disk → loadState → cloneState into run context → hooks render → system prompt → agent turn → tools mutate draft → writeState back to disk
The repo ships with pre-seeded state files so you can see the memory system working immediately, without running multiple sessions yourself:
pnpm reset # blank state — completely fresh start
pnpm load:s1 # load after session 1 (profile + global memory notes + 2 practice sessions)
pnpm load:s2 # load after session 2 (more memory accumulated)Recommended first run: pnpm load:s1, then open the app and type "What should we work on today?" — the coach will already know your name, role, and what happened last session.
┌──────────────────────────────────────┐
│ coach-state.json (disk) │
│ ├── profile (structured) │
│ ├── globalMemory (long-term) │
│ └── sessionMemory (staging area) │
└─────────────────┬────────────────────┘
│ loadState() on every API call
▼
cloneState() → run context
│
│ agent_start hook fires
▼
render profile → YAML
render notes → markdown
inject into system prompt
│
▼
agent turn runs
│
tools fire silently mid-turn:
save_memory_note → sessionMemory
update_profile → profile
│
│ agent_tool_end hook re-renders immediately
▼
writeState() back to disk
│
[end of session]
consolidateSessionNotes()
session notes → global memory (via LLM)
ephemeral notes dropped
The key architectural shift vs. a standard chatbot: the system prompt is rebuilt on every single turn with fresh memory injected into it. The agent never relies on scrolling back through chat history to remember who you are.
To build this for a different niche, change three things:
1. src/lib/agent/types.ts — swap InterviewCoachProfile fields for your domain
// PE deal coach example:
interface DealCoachProfile {
dealName: string;
sector: string;
investmentThesis: string;
icTimeline: string;
redFlags: string[];
}2. src/lib/agent/prompts.ts — rewrite BASE_INSTRUCTIONS and the two tool descriptions. The tool descriptions are the most important thing to get right — they are the agent's memory policy and control what gets saved vs. ignored.
3. src/lib/agent/types.ts — update STANDARD_CATEGORIES to your domain's question or topic categories.
The hooks, consolidation logic, and session lifecycle are fully domain-agnostic. Copy them wholesale.
| Resource | Link |
|---|---|
| OpenAI Agents SDK (JS) | https://openai.github.io/openai-agents-js/ |
| Context Personalization cookbook | https://developers.openai.com/cookbook/examples/agents_sdk/context_personalization |
| OpenAI API keys | https://platform.openai.com/api-keys |
| SvelteKit docs | https://kit.svelte.dev/docs |
Each coaching turn uses gpt-5.4-mini. End-of-session consolidation runs one call with gpt-5.4-nano at high reasoning effort — a few cents per session. For a private single-user install, total daily cost is negligible.
MIT