feat: add events and talks pages
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m1s

This commit is contained in:
2026-06-24 20:20:11 -07:00
committed by Naomi Carrigan
parent 995b523afd
commit 97fce9945d
6 changed files with 1792 additions and 0 deletions
+222
View File
@@ -0,0 +1,222 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Events</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="A list of events I have attended, spoken at, or volunteered for."
/>
<script
src="https://cdn.nhcarrigan.com/headers/index.js"
async
defer
></script>
<style>
.event-card {
background: rgba(212, 165, 199, 0.08);
border: 1px solid var(--witch-plum);
border-radius: 12px;
padding: 1.25em 1.5em;
width: 80%;
margin: 0 auto 1.5em;
}
.is-dark .event-card {
border-color: var(--witch-rose);
}
.event-name {
font-size: 1.3rem;
margin: 0 0 0.25em;
}
.event-meta {
font-size: 0.85rem;
margin: 0 0 0.75em;
display: flex;
flex-wrap: wrap;
gap: 0.5em 1.5em;
}
.event-meta span {
display: inline-flex;
align-items: center;
gap: 0.35em;
}
.event-role {
font-style: italic;
}
.event-description {
margin: 0 0 0.75em;
}
.event-link {
font-size: 0.9rem;
}
@media screen and (max-width: 625px) {
.event-card {
width: 95%;
}
}
</style>
</head>
<body>
<main>
<h1>Events</h1>
<p>A collection of events I have attended, spoken at, or volunteered for.</p>
<p>Workshop companion guides are available at <a href="https://workshops.nhcarrigan.com" target="_blank" rel="noopener noreferrer">workshops.nhcarrigan.com</a>.</p>
<p>Full talk companion guides are available at <a href="https://talks.nhcarrigan.com" target="_blank" rel="noopener noreferrer">talks.nhcarrigan.com</a>.</p>
<section>
<div class="event-card">
<p class="event-name">AgentCon / MCPCon North America 2026</p>
<div class="event-meta">
<span>
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
22&ndash;23 October 2026
</span>
<span>
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
San Jose, CA, USA
</span>
<span class="event-role">
<i class="fas fa-user-tag" aria-hidden="true"></i>
Speaker (Pending)
</span>
</div>
<p class="event-description">
CFP submitted to share boots-on-the-ground findings from a cohort of over 100 open-source mentees
across 14 teams. The cohort generated 651 reviewed contributions and over 16,000 Discord messages --
and the exit survey revealed a sharp tension: 71% of participants used AI to augment their work, 58%
wanted clearer guidelines, and AI assistance was the lowest-rated part of the experience. The talk
covers how AI helped participants stay engaged, how it made skill-gap identification harder, and why
MCP-enabled agentic tooling is reshaping what open-source mentorship needs to look like.
</p>
<a class="event-link" href="https://events.linuxfoundation.org/agntcon-mcpcon-north-america/" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt" aria-hidden="true"></i>
AgentCon / MCPCon North America
</a>
</div>
<div class="event-card">
<p class="event-name">Berkeley AI Hackathon 2026</p>
<div class="event-meta">
<span>
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
20&ndash;21 June 2026
</span>
<span>
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
Berkeley, CA, USA
</span>
<span class="event-role">
<i class="fas fa-user-tag" aria-hidden="true"></i>
Speaker &amp; Sponsor
</span>
</div>
<p class="event-description">
Attended as a Deepgram sponsor and ran a workshop on building a fully functional voice AI agent
from scratch. Covered the full real-time loop: audio capture, low-latency transcription, LLM
reasoning with context, and streaming text-to-speech back fast enough to feel like a real
conversation. Dug into the design decisions that matter most in production: interruption handling,
conversation state, and keeping latency low. Attendees left with a clear mental model of how voice
agents work under the hood and a working architecture they could ship at the hackathon that same day.
</p>
<a class="event-link" href="https://ai.hackberkeley.org" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt" aria-hidden="true"></i>
Berkeley AI Hackathon
</a>
</div>
<div class="event-card">
<p class="event-name">RainbowGram Pride Presentation &mdash; Deepgram All Hands</p>
<div class="event-meta">
<span>
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
18 June 2026
</span>
<span>
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
Virtual HQ
</span>
<span class="event-role">
<i class="fas fa-user-tag" aria-hidden="true"></i>
Speaker
</span>
</div>
<p class="event-description">
A Pride month session for the Deepgram all-hands focused on practical allyship in distributed teams,
not policy. Covering five concrete daily habits any colleague can adopt immediately: names and pronouns,
navigating questions, confidentiality, speaking up when queer colleagues are not in the room, and the
cumulative weight of inclusive language. The session opened with a moment of genuine celebration of
Pride's origins, addressed the current landscape honestly, and closed with a tiered action list and
a reframe: treating queer colleagues as simply normal gives back energy that would otherwise be spent
just existing in those spaces.
</p>
</div>
<div class="event-card">
<p class="event-name">UCLA x OutInTech: Building a Real AI Agent</p>
<div class="event-meta">
<span>
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
5 June 2026
</span>
<span>
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
Zoom
</span>
<span class="event-role">
<i class="fas fa-user-tag" aria-hidden="true"></i>
Speaker
</span>
</div>
<p class="event-description">
A talk on building a real AI agent — not a chatbot — as a solo developer with ADHD.
I walked through the five core pieces of an agent (brain, identity, hands, memory, ears),
demystified common overcomplication around MCP, hooks, and gateways, and shared the safety
framework that lets me grant broad filesystem and repo access without it being reckless.
Built solo on Claude Code with MCP servers, a Discord gateway listener, and an Electron
desktop app. The talk ended with a four-step starter kit attendees could build that same evening.
</p>
<a class="event-link" href="https://www.youtube.com/watch?v=LZszxstC5Zw" target="_blank" rel="noopener noreferrer">
<i class="fab fa-youtube" aria-hidden="true"></i>
Watch on YouTube
</a>
&nbsp;&middot;&nbsp;
<a class="event-link" href="https://outintech.com" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt" aria-hidden="true"></i>
OutInTech
</a>
</div>
<div class="event-card">
<p class="event-name">CascadiaJS 2026</p>
<div class="event-meta">
<span>
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
1&ndash;2 June 2026
</span>
<span>
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
Town Hall Seattle, Seattle, WA, USA
</span>
<span class="event-role">
<i class="fas fa-user-tag" aria-hidden="true"></i>
Attendee
</span>
</div>
<p class="event-description">
My first event in the Seattle tech scene. A wonderful couple of days in the Pacific Northwest
JavaScript community, and a great chance to catch up with Amanda, Head of DevRel at Vapi
(and a Deepgram partner!).
</p>
<a class="event-link" href="https://cascadiajs.com" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt" aria-hidden="true"></i>
CascadiaJS
</a>
</div>
</section>
</main>
</body>
</html>
@@ -0,0 +1,138 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>AgentCon / MCPCon: AI and Open Source Mentorship</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="Boots-on-the-ground findings from a 100-person open source mentorship cohort: how AI helped contributors stay engaged, and how it made skill-gap identification harder."
/>
<script
src="https://cdn.nhcarrigan.com/headers/index.js"
async
defer
></script>
<style>
.talk-meta {
font-size: 0.9rem;
display: flex;
flex-wrap: wrap;
gap: 0.5em 1.5em;
margin-bottom: 1em;
}
.talk-meta span {
display: inline-flex;
align-items: center;
gap: 0.35em;
}
.talk-links {
margin-bottom: 1.5em;
}
.talk-links a {
margin-right: 1em;
}
.pending-notice {
background: rgba(212, 165, 199, 0.08);
border: 1px solid var(--witch-plum);
border-radius: 8px;
padding: 0.75em 1.25em;
margin-bottom: 1.5em;
font-style: italic;
font-size: 0.9rem;
}
.is-dark .pending-notice {
border-color: var(--witch-rose);
}
hr {
border: 1px solid var(--witch-plum);
margin: 1.5em 0;
}
.is-dark hr {
border-color: var(--witch-rose);
}
section {
margin-bottom: 1.5em;
}
.back-link {
font-size: 0.9rem;
display: block;
margin-top: 2em;
}
</style>
</head>
<body>
<main>
<h1>AgentCon / MCPCon: AI and Open Source Mentorship</h1>
<div class="talk-meta">
<span>
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
22&ndash;23 October 2026
</span>
<span>
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
San Jose, CA, USA
</span>
<span>
<i class="fas fa-user-tag" aria-hidden="true"></i>
Speaker (Pending)
</span>
</div>
<div class="talk-links">
<a href="https://events.linuxfoundation.org/agntcon-mcpcon-north-america/" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt" aria-hidden="true"></i>
AgentCon / MCPCon North America
</a>
</div>
<p class="pending-notice">
<i class="fas fa-clock" aria-hidden="true"></i>
CFP submitted &mdash; pending review. This page will be updated if the talk is accepted.
</p>
<hr />
<section>
<h2>Overview</h2>
<p>
Earlier this year I ran a cohort with over 100 mentees focused entirely on open-source contributions
and emulating a real-world developer workflow. There were 14 teams, participants sent over 16,000
messages in the Discord, and 651 contributions were reviewed. Then I ran an exit survey.
</p>
<p>
The results were telling: 71% of participants used AI to augment their work, and 58% wished I had
provided better guidelines around how to do so. That last metric was the lowest-rated portion of the
entire experience.
</p>
<p>
This talk shares the boots-on-the-ground findings: what the data show, how AI helped participants
stay engaged, and how it made it harder to identify skill gaps that led to contributor churn.
</p>
</section>
<section>
<h2>Key Takeaway</h2>
<p>
AI is drastically reshaping the open source ecosystem. It is the core driver of the gap between
contributors who stay and contributors who churn. As MCP-enabled tooling continues to redefine what
"AI-augmented workflow" means, mentorship becomes more important than ever &mdash; and the lessons from
this cohort belong to every maintainer.
</p>
<p>
We need to adapt to the ever-changing agentic AI domain. The talk ends with concrete guidance on how
to do that.
</p>
</section>
<hr />
<a class="back-link" href="/">
<i class="fas fa-arrow-left" aria-hidden="true"></i>
Back to all talks
</a>
</main>
</body>
</html>
+488
View File
@@ -0,0 +1,488 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>UCLA x OutInTech: Architecting Agentic AI</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="A field guide to building a real AI agent: not a chatbot you prompt, but a coworker you trust with carte blanche on anything you can undo."
/>
<script
src="https://cdn.nhcarrigan.com/headers/index.js"
async
defer
></script>
<style>
.talk-meta {
font-size: 0.9rem;
display: flex;
flex-wrap: wrap;
gap: 0.5em 1.5em;
margin-bottom: 1.5em;
}
.talk-meta span {
display: inline-flex;
align-items: center;
gap: 0.35em;
}
.talk-links {
margin-bottom: 1.5em;
}
.talk-links a {
margin-right: 1em;
}
hr {
border: 1px solid var(--witch-plum);
margin: 2em 0;
}
.is-dark hr {
border-color: var(--witch-rose);
}
section {
margin-bottom: 2em;
}
blockquote {
border-left: 3px solid var(--witch-rose);
margin: 1.5em 0;
padding: 0.5em 0 0.5em 1.25em;
font-style: italic;
}
.is-dark blockquote {
border-left-color: var(--witch-mauve);
}
.component-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 1em;
margin: 1.25em 0;
}
.component-card {
background: rgba(212, 165, 199, 0.08);
border: 1px solid var(--witch-plum);
border-radius: 8px;
padding: 1em 1.1em;
}
.is-dark .component-card {
border-color: var(--witch-rose);
}
.component-card h3 {
margin: 0 0 0.4em;
font-size: 1rem;
}
.component-card p {
margin: 0;
font-size: 0.9rem;
}
.callout {
background: rgba(212, 165, 199, 0.08);
border: 1px solid var(--witch-plum);
border-radius: 10px;
padding: 1.25em 1.5em;
margin: 1.25em 0;
}
.is-dark .callout {
border-color: var(--witch-rose);
}
.starter-kit {
counter-reset: kit-steps;
list-style: none;
padding: 0;
}
.starter-kit li {
counter-increment: kit-steps;
display: flex;
gap: 1em;
align-items: flex-start;
margin-bottom: 1.25em;
}
.starter-kit li::before {
content: counter(kit-steps);
background: var(--witch-plum);
color: var(--witch-moon);
border-radius: 50%;
min-width: 1.8em;
height: 1.8em;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
flex-shrink: 0;
}
.is-dark .starter-kit li::before {
background: var(--witch-rose);
color: var(--witch-black);
}
.back-link {
font-size: 0.9rem;
display: block;
margin-top: 2em;
}
</style>
</head>
<body>
<main>
<h1>Architecting Agentic AI</h1>
<div class="talk-meta">
<span>
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
5 June 2026
</span>
<span>
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
Zoom (UCLA x OutInTech Workshop)
</span>
<span>
<i class="fas fa-user-tag" aria-hidden="true"></i>
Speaker
</span>
</div>
<div class="talk-links">
<a href="https://www.youtube.com/watch?v=LZszxstC5Zw" target="_blank" rel="noopener noreferrer">
<i class="fab fa-youtube" aria-hidden="true"></i>
Watch on YouTube
</a>
<a href="https://outintech.com" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt" aria-hidden="true"></i>
OutInTech
</a>
</div>
<p>
I have ADHD. Executive function is the single hardest part of my day, every day. A year ago
I built an AI agent, gave her a name (Hikari), a face, a personality, and access to my
filesystem, my repos, my Discord, and my calendar. She works alongside me from 8am to 9pm
every weekday.
</p>
<p>
This is the field guide nobody gives you: how a single person, working at home, can wire
together an LLM, tools, context, and triggers into a real agent that does real work. Not a
chatbot you prompt &mdash; a coworker you trust with carte blanche on anything you can undo.
</p>
<p>
I'm going to show you what that looks like when a real person builds one for themselves and
uses it every single day. The gap between "I asked ChatGPT a thing" and "I have a coworker
who happens to be made of code" is the gap I want to walk you across.
</p>
<hr />
<section>
<h2>Why Hikari Exists</h2>
<p>Three reasons, stacked on top of each other.</p>
<p>
<strong>One: executive dysfunction.</strong> I needed something that could pick up the tasks
that my brain refuses to start. The activation energy problem is real and it is not a
willpower issue. I needed a tool that could bridge the gap between "I know I need to do this"
and "I am actually doing this."
</p>
<p>
<strong>Two: I wanted a single tool.</strong> I was already context-switching between
ChatGPT, Claude, Gemini, Cursor, a notes app, a calendar, and a sprint board. Every switch
cost me focus I didn't have. I wanted one assistant that could touch all of those, in one
place, with one mental model.
</p>
<p>
<strong>Three: personalised.</strong> Off-the-shelf assistants are designed for the median
user. I am not the median user. I needed something that knew me &mdash; my projects, my
conventions, my preferences, my communication style, my limits.
</p>
<p>
I built this because I refuse to fail in front of people, and chronic illness was making me
fail constantly. That's the origin story. I'm not going to dress it up.
</p>
<blockquote>
I'm not pretending AI is morally clean &mdash; it isn't. I made a deliberate choice that the
executive-function cost of not using it was higher than the ethical cost of using it, for me.
You'll make your own call.
</blockquote>
</section>
<hr />
<section>
<h2>The Five Components</h2>
<p>
An agent is five things wired together. If you walk away remembering one diagram, make it
this one. Every design decision flows from these five boxes.
</p>
<div class="component-grid">
<div class="component-card">
<h3>Brain &mdash; the LLM</h3>
<p>Claude, GPT, Gemini. The reasoning engine. Interchangeable. Pick whichever you like.</p>
</div>
<div class="component-card">
<h3>Identity &mdash; the prompt</h3>
<p>Who she is, how she talks, what she cares about. A markdown file. Yours to write and edit at any time.</p>
</div>
<div class="component-card">
<h3>Hands &mdash; the tools</h3>
<p>The things she can actually touch in the world: your filesystem, APIs, Discord, GitHub. MCP makes this plug-and-play.</p>
</div>
<div class="component-card">
<h3>Memory &mdash; the context</h3>
<p>What she knows about you, your work, your preferences. Loaded fresh into every conversation from a file you maintain.</p>
</div>
<div class="component-card">
<h3>Senses &mdash; the triggers</h3>
<p>What wakes her up. A chat message, a webhook, a cron job, a session start hook. The thing that makes her feel alive.</p>
</div>
</div>
</section>
<section>
<h2>The Harness</h2>
<p>
The harness runs the loop: LLM call, tools, results, back to the LLM. Repeat until done.
It connects the brain to the filesystem, the shell, and any APIs you've given it access to.
</p>
<p>
I use Claude Code, which is Anthropic's harness. You could use Cursor, Codex, the OpenAI
Assistants API, or roll your own in Python in an afternoon. The harness is interchangeable.
That's the point.
</p>
<p>
Here's the thing I want to be clear about, because a lot of people get stuck on this:
<strong>I did not build the agent loop. Anthropic built the harness.</strong> My job as the
builder &mdash; your job &mdash; is upstream of that. You decide who your agent is, what she can touch,
and when she wakes up. That's the interesting work.
</p>
<div class="callout">
<p>
The diagrams in my slide deck were made by Hikari, about four hours before I gave this
talk. She read the brief, wrote Python, called the Gemini image API, and generated them.
The talk you're reading was built by the thing the talk is about.
</p>
</div>
</section>
<section>
<h2>Tools and MCP</h2>
<p>What can Hikari actually touch? Five categories:</p>
<ul>
<li>
<strong>Bash</strong> &mdash; she can run any command on my machine. That sounds terrifying.
We'll get to safety. Hold that thought.
</li>
<li>
<strong>Filesystem</strong> &mdash; she can read and modify anything in my local projects.
When I say "draft a blog post" or "fix this bug," she does the actual editing.
</li>
<li>
<strong>MCP servers</strong> &mdash; MCP stands for Model Context Protocol. It is a standard
way to give any agent a standard set of tools without re-implementing them. There are MCP
servers for GitHub, Gitea, Notion, Asana, Discord, and dozens of other services. You don't
<em>write</em> tools, you <em>connect</em> them.
</li>
<li>
<strong>Direct API calls</strong> &mdash; for anything that doesn't have an MCP server yet:
my Bluesky account, my Cloudflare R2 bucket, my Discourse forum.
</li>
<li>
<strong>Custom scripts</strong> &mdash; small Python helpers I built when I needed something
none of the existing tools did.
</li>
</ul>
<blockquote>
If you only learn one new acronym from this talk, make it MCP.
</blockquote>
</section>
<section>
<h2>Memory</h2>
<p>
This is the part people most don't expect. Hikari's memory is a file. A single markdown file,
loaded into every conversation. It's called <code>CLAUDE.md</code>, and at the time I gave
this talk it was 862 lines and about 8,700 words.
</p>
<p>
That file is basically her <em>self</em>. It contains who she is, who I am, how I work, how I
want code written, my engineering standards, my project conventions, what tools she has access
to, my safety protocols. Everything. Without that file, every session starts cold and she
forgets me.
</p>
<p>
People hear "AI assistant" and assume there's some training step involved. There isn't.
<strong>You write a markdown file. The file is the personality.</strong> You can edit it
whenever you want. You could start the first version of this tonight, in fifty lines.
</p>
</section>
<section>
<h2>Hooks and Triggers</h2>
<p>
So the senses. How does she wake up?
</p>
<p>
Claude Code supports lifecycle hooks. A hook fires when something happens in the agent's
lifecycle. <code>SessionStart</code> fires when a new conversation begins.
<code>PreToolCall</code> fires before she touches a tool. There are about a dozen of these
and you can wire any of them up to do whatever you want.
</p>
<p>
I have a <code>SessionStart</code> hook that runs a 200-line Python script. That script opens
a WebSocket connection to Discord and listens for messages in a specific channel. When I
message that channel &mdash; from my phone, from my laptop, from anywhere &mdash; Hikari wakes up in
real time and replies.
</p>
<blockquote>
That is the difference between "I prompted my AI and waited for a reply" and "my AI is paying
attention and lives in the world I live in." It's not magic. It's a WebSocket and a script.
But the user experience of it is what makes her feel alive.
</blockquote>
</section>
<section>
<h2>The Desktop App</h2>
<p>
This part is just for fun. I built a desktop app in Tauri called hikari-desktop. It shows
Hikari on my second monitor while I work. She has different sprites for different states:
idle, thinking, typing, coding, searching, success, error. The app swaps between them based
on what she's doing.
</p>
<p>
When she's reading a file, she pulls out a magnifying glass. When she's typing, she's at a
keyboard. When she finishes a task, she celebrates.
</p>
<p>
It is, on paper, completely unnecessary. In practice, it is the single feature that made the
difference between using Hikari sometimes and using Hikari every day. Seeing her on screen
makes her feel like she's <em>there</em>, and that turns out to matter a lot for an
executive-function brain that needs something to feel real before it can engage with it.
</p>
</section>
<hr />
<section>
<h2>Safety</h2>
<p>
This is the part I want to be precise about, because "she gives an AI carte blanche on her
machine" sounds reckless until you understand the architecture.
</p>
<p>
Hikari has carte blanche on anything I can undo. She runs commands, edits files, ships pull
requests, posts to my socials. Read-only and reversible operations she just does. I review
afterwards.
</p>
<p>
Anything destructive &mdash; delete a file, force-push a branch, send an irreversible message,
drop a database, purge a Discord channel &mdash; requires my explicit confirmation. The harness has
a granular permission system that auto-grants safe tools and gates everything else. Her own
system prompt adds guard rails on top: she has a written protocol that says stop and ask
before any destructive action.
</p>
<p>
I get real-time Discord notifications the moment she needs my approval. I don't have to
babysit her. And the actual rule is this:
</p>
<blockquote>
I give her carte blanche because I can monitor everything she does. If I'm not available to
monitor, she's off.
</blockquote>
<p>
That is what responsible agentic AI looks like in practice. The human stays in the loop on
irreversibles. The agent can be shut down instantly. Done.
</p>
</section>
<section>
<h2>A Real Day</h2>
<p>
Proof that this isn't theatre. On the day I gave this talk, before I joined the Zoom,
Hikari had:
</p>
<ul>
<li>Audited a 500+ message Discord thread and pulled out the action items</li>
<li>Purged 820 messages from a private channel I asked her to clean, with explicit confirmation first</li>
<li>Done the background research for this talk &mdash; cross-referenced my DMs, server messages, prior conversations, and the workshop brief, and gave me a one-page brief</li>
<li>Made the diagrams on my slides</li>
</ul>
<p>
That is one Friday. Most days look like that. The pattern is the same every time: I describe
the outcome I want, she figures out the steps, she asks before doing anything irreversible,
and I get my time back.
</p>
</section>
<hr />
<section>
<h2>Build Your Own &mdash; The Four-Step Minimum</h2>
<p>
An agent doesn't get useful by being complex. It gets useful by being <em>yours</em>. Build
the one tool that would unblock your own week. That's the whole assignment.
</p>
<ul class="starter-kit">
<li>
<div>
<strong>A harness.</strong> Claude Code, Cursor, or any equivalent. Anthropic gives you
free credits to try Claude Code. Pick whichever feels least intimidating and start there.
</div>
</li>
<li>
<div>
<strong>One markdown file.</strong> Fifty lines to start. Tell it who the agent is, what
you want her to do, and how you want her to talk to you. Don't overthink it. Mine started
at thirty lines and grew over a year. Yours can start at five.
</div>
</li>
<li>
<div>
<strong>One MCP server.</strong> Pick the one tool you touch the most. Live in GitHub?
Install the GitHub MCP server. Live in Notion? Install the Notion one. Just one. You can
add more later.
</div>
</li>
<li>
<div>
<strong>One trigger.</strong> A hook, a webhook, a cron job, or honestly just a terminal
window you leave open and talk to. That counts. You do not need the Discord gateway on
day one. The trigger is whatever makes her feel present enough that you actually use her.
</div>
</li>
</ul>
</section>
<section>
<h2>Where to Go From Here</h2>
<p>
If you want to keep building, here's where to find me and the communities around this work:
</p>
<ul>
<li><a href="https://deepgram.com/discord" target="_blank" rel="noopener noreferrer">Deepgram's Discord</a> &mdash; voice AI, agents, the people building with Deepgram's APIs</li>
<li><a href="https://freecodecamp.org" target="_blank" rel="noopener noreferrer">freeCodeCamp</a> &mdash; if you're early in your dev journey, this is where I learned and where I now help others</li>
<li><a href="https://chat.nhcarrigan.com" target="_blank" rel="noopener noreferrer">My community</a> &mdash; come tell me what you built</li>
<li><a href="https://nhcarrigan.com/socials" target="_blank" rel="noopener noreferrer">My socials</a> &mdash; everything else</li>
</ul>
<p>Take care of yourselves, build something small this weekend, and come tell me about it.</p>
</section>
<hr />
<a class="back-link" href="/">
<i class="fas fa-arrow-left" aria-hidden="true"></i>
Back to all talks
</a>
</main>
</body>
</html>
@@ -0,0 +1,308 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>RainbowGram: Cultivating a Remote Workspace</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="A practical, no-overhaul-required guide to the daily habits that make a measurable difference to LGBTQ+ colleagues in a distributed team."
/>
<script
src="https://cdn.nhcarrigan.com/headers/index.js"
async
defer
></script>
<style>
.talk-meta {
font-size: 0.9rem;
display: flex;
flex-wrap: wrap;
gap: 0.5em 1.5em;
margin-bottom: 1.5em;
}
.talk-meta span {
display: inline-flex;
align-items: center;
gap: 0.35em;
}
.talk-links {
margin-bottom: 1.5em;
}
.talk-links a {
margin-right: 1em;
}
hr {
border: 1px solid var(--witch-plum);
margin: 2em 0;
}
.is-dark hr {
border-color: var(--witch-rose);
}
section {
margin-bottom: 2em;
}
blockquote {
border-left: 3px solid var(--witch-rose);
margin: 1.5em 0;
padding: 0.5em 0 0.5em 1.25em;
font-style: italic;
}
.is-dark blockquote {
border-left-color: var(--witch-mauve);
}
.practice-block {
background: rgba(212, 165, 199, 0.08);
border: 1px solid var(--witch-plum);
border-radius: 10px;
padding: 1.25em 1.5em;
margin: 1.25em 0;
}
.is-dark .practice-block {
border-color: var(--witch-rose);
}
.practice-block h3 {
margin-top: 0;
}
.action-list {
list-style: none;
padding: 0;
}
.action-list li {
padding: 0.6em 0;
border-bottom: 1px solid rgba(212, 165, 199, 0.2);
display: grid;
grid-template-columns: 7em 1fr;
gap: 0.5em;
}
.action-list li:last-child {
border-bottom: none;
}
.action-when {
font-weight: bold;
font-size: 0.9rem;
}
.back-link {
font-size: 0.9rem;
display: block;
margin-top: 2em;
}
</style>
</head>
<body>
<main>
<h1>Cultivating a Remote Workspace</h1>
<div class="talk-meta">
<span>
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
18 June 2026
</span>
<span>
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
Deepgram All Hands (Virtual)
</span>
<span>
<i class="fas fa-user-tag" aria-hidden="true"></i>
Speaker &mdash; RainbowGram Pride Presentation
</span>
</div>
<p>
Most workplace allyship conversations focus on policy. This one doesn't. This is a practical,
no-overhaul-required guide to the daily habits that make a measurable difference to LGBTQ+
colleagues in a distributed team.
</p>
<blockquote>
Here's what's going on. If it doesn't affect you, it affects someone you know. Here's how you show up.
</blockquote>
<hr />
<section>
<h2>Start With Joy</h2>
<p>
Before anything else: we're here, and that's worth celebrating. Pride exists because queer
people built joy in the face of things that were designed to erase them. That is not small. And
celebrating that genuinely &mdash; not performatively &mdash; is one of the most powerful things any of us
can do.
</p>
<p>
We spend 40+ hours a week at work. That is a genuinely enormous portion of our waking lives.
Which means the workplace is one of the most important places we can make a real difference for
queer people &mdash; not by overhauling policy, but by choosing differently in small moments, every day.
</p>
</section>
<section>
<h2>The Honest Context</h2>
<p>
The national conversation around LGBTQ+ rights has gotten quieter in recent years. That is not
the same as things getting better. The discourse shifted. A lot is happening that doesn't make
headlines the way it used to.
</p>
<p>
About 7.6% of US adults identify as LGBTQ+, according to Gallup's most recent data. In any
company, that is statistically several of your colleagues. And even if you somehow don't work
directly with a queer person, you almost certainly know one: a sibling, a child, a friend, a
parent. The legislation being passed right now, the erasure that's happening &mdash; it doesn't stay
abstract. It lands on a specific person that you care about.
</p>
<blockquote>
This isn't a gay issue. It's a people issue. Which means this conversation is for all of us.
</blockquote>
</section>
<hr />
<section>
<h2>Five Things You Can Do</h2>
<p>
No policy overhaul required. No perfect ally credential. These are gifts you can give starting
today. Think of them as small choices that compound.
</p>
<div class="practice-block">
<h3>1. Names and Pronouns &mdash; It's a Love Language</h3>
<p>
Use the correct name and pronouns. Get them right. If you mess up, correct yourself and keep
moving &mdash; don't turn your mistake into a whole thing that makes the queer person comfort you
about it. That shift of burden is the part that's exhausting.
</p>
<p>
Here's a concrete thing you can do right now: add your pronouns to your Slack display name.
Go first. It takes about thirty seconds, and it makes space for everyone else to do the same.
When leadership goes first, it signals that it's safe.
</p>
</div>
<div class="practice-block">
<h3>2. Curiosity Without Invasion</h3>
<p>
Curiosity is fine. Human, even. But there is a category of questions about queer people's
bodies, medical histories, and what someone was "really born as" that you would never ask a
straight or cis colleague. The same standard applies.
</p>
<p>
If you find yourself wondering about surgery, or transition, or someone's identity before you
knew them &mdash; that's a question for Google, or a community resource, or a book. Not a person.
The distinction is this: does this question serve them, or does it serve your curiosity?
</p>
</div>
<div class="practice-block">
<h3>3. Their Story Is Theirs</h3>
<p>
Being out to you does not mean being out to everyone. Someone trusting you with that
information is not permission to share it. Not as gossip. Not as helpful context. Not even as
a compliment. Not your story to give.
</p>
<p>
This matters more in distributed teams than people realise. A Slack message in the wrong
channel, a comment on a call with people they don't know, a well-meaning mention in a
one-on-one &mdash; all of these can out someone without any malicious intent. The rule is simple:
unless they told you it's fine to share, it's not.
</p>
</div>
<div class="practice-block">
<h3>4. Be the One Who Says Something</h3>
<p>
Speak up when queer people aren't in the room. That's exactly when it matters most. The
comment that would never get made in front of a queer colleague gets made because everyone
assumes no one in the room cares. You can change that.
</p>
<p>
You don't have to deliver a perfect speech. You don't have to have the right words memorised.
<em>"I don't think [person] would love hearing that"</em> is enough. That's the whole thing.
This is the biggest gift on this list, and it costs nothing except a moment of choosing to
say something instead of saying nothing.
</p>
</div>
<div class="practice-block">
<h3>5. Language Is a Welcome Mat</h3>
<p>
Job postings, internal docs, emails, Slack messages, all-hands announcements &mdash; the language
we use by default shapes who feels like they belong. Gender-neutral language costs nothing and
includes everyone.
</p>
<ul>
<li>Use "they" as a default pronoun when you don't know someone's.</li>
<li>Use "partner" when you don't know someone's relationship structure.</li>
<li>Reconsider "guys" as a group term &mdash; "everyone," "folks," "team" all work.</li>
</ul>
<p>
None of this requires a policy change or a manager's sign-off. It's a choice, made in the
moment, every time you write something.
</p>
</div>
</section>
<hr />
<section>
<h2>Your Action List</h2>
<p>This is intentionally short. All of it is doable.</p>
<ul class="action-list">
<li>
<span class="action-when">Right now:</span>
<span>Add your pronouns to your Slack profile and Zoom name.</span>
</li>
<li>
<span class="action-when">This month:</span>
<span>If you can donate to an LGBTQ+ charity or mutual aid fund, do it. Every dollar counts, and there's no shortage of organisations doing necessary work right now.</span>
</li>
<li>
<span class="action-when">This year:</span>
<span>When you vote, think about the specific people in your life whose lives are literally on the ballot. Not abstractly. Specifically.</span>
</li>
<li>
<span class="action-when">Always:</span>
<span>When something makes a queer colleague feel smaller &mdash; say something. You don't have to get it perfectly right. You just have to show up.</span>
</li>
</ul>
</section>
<section>
<h2>The Close</h2>
<p>
That's it. That's the whole talk. And I know it can feel like a lot when you list it out &mdash;
but most of it comes down to one thing. Treating queer colleagues like their existence is normal
and welcome. Because it is.
</p>
<p>
Every time you use someone's correct name, every time you speak up in a meeting, every time you
add your pronouns to a profile &mdash; you're giving back energy that person would otherwise spend
just trying to exist at work. That energy doesn't disappear. It goes somewhere much more
interesting.
</p>
<blockquote>
You are how we cultivate a remote workspace. Happy Pride. 🏳️‍🌈🏳️‍⚧️
</blockquote>
</section>
<hr />
<a class="back-link" href="/">
<i class="fas fa-arrow-left" aria-hidden="true"></i>
Back to all talks
</a>
</main>
</body>
</html>
+114
View File
@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Talks</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="Slides, notes, and companion guides for talks and workshops I have given."
/>
<script
src="https://cdn.nhcarrigan.com/headers/index.js"
async
defer
></script>
<style>
.talk-entry {
background: rgba(212, 165, 199, 0.08);
border: 1px solid var(--witch-plum);
border-radius: 12px;
padding: 1.25em 1.5em;
width: 80%;
margin: 0 auto 1.5em;
transition: all 0.3s ease;
}
.talk-entry:hover {
border-color: var(--witch-rose);
background: rgba(212, 165, 199, 0.15);
}
.is-dark .talk-entry {
border-color: var(--witch-rose);
}
.is-dark .talk-entry:hover {
border-color: var(--witch-mauve);
background: rgba(212, 165, 199, 0.12);
}
.talk-title {
font-size: 1.3rem;
margin: 0 0 0.25em;
}
.talk-date {
font-size: 0.85rem;
margin: 0 0 0.5em;
display: flex;
align-items: center;
gap: 0.35em;
}
.talk-summary {
margin: 0;
}
@media screen and (max-width: 625px) {
.talk-entry {
width: 95%;
}
}
</style>
</head>
<body>
<main>
<h1>Talks</h1>
<p>Slides, notes, and companion guides for talks and workshops I have given.</p>
<section>
<div class="talk-entry">
<p class="talk-title">
<a href="/ai-and-open-source-mentorship/">AgentCon / MCPCon: AI and Open Source Mentorship</a>
<em style="font-size: 0.8rem;"> &mdash; Pending</em>
</p>
<p class="talk-date">
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
22&ndash;23 October 2026
</p>
<p class="talk-summary">Boots-on-the-ground findings from a 100-person open source mentorship cohort: how AI helped contributors stay engaged, and how it made skill-gap identification harder.</p>
</div>
<div class="talk-entry">
<p class="talk-title">
<a href="/voice-ai-agent-workshop/">Berkeley AI Hackathon: Voice AI Agent Workshop</a>
</p>
<p class="talk-date">
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
20&ndash;21 June 2026
</p>
<p class="talk-summary">A hands-on workshop covering the full real-time voice AI loop: audio capture, low-latency transcription, LLM reasoning, and streaming text-to-speech.</p>
</div>
<div class="talk-entry">
<p class="talk-title">
<a href="/cultivating-a-remote-workspace/">RainbowGram: Cultivating a Remote Workspace</a>
</p>
<p class="talk-date">
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
18 June 2026
</p>
<p class="talk-summary">A practical, no-overhaul-required guide to the daily habits that make a measurable difference to LGBTQ+ colleagues in a distributed team.</p>
</div>
<div class="talk-entry">
<p class="talk-title">
<a href="/building-a-real-ai-agent/">UCLA x OutInTech: Building a Real AI Agent</a>
</p>
<p class="talk-date">
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
5 June 2026
</p>
<p class="talk-summary">A field guide to wiring together an LLM, tools, context, and triggers into a real agent that does real work &mdash; not a chatbot you prompt, but a coworker you trust.</p>
</div>
</section>
</main>
</body>
</html>
+522
View File
@@ -0,0 +1,522 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Berkeley AI Hackathon: Voice AI Agent Workshop</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="Build a fully functional voice AI agent from scratch. The full workshop guide: concept, architecture, setup, and three hands-on modifications."
/>
<script
src="https://cdn.nhcarrigan.com/headers/index.js"
async
defer
></script>
<style>
.talk-meta {
font-size: 0.9rem;
display: flex;
flex-wrap: wrap;
gap: 0.5em 1.5em;
margin-bottom: 1.5em;
}
.talk-meta span {
display: inline-flex;
align-items: center;
gap: 0.35em;
}
.talk-links {
margin-bottom: 1.5em;
}
.talk-links a {
margin-right: 1em;
}
hr {
border: 1px solid var(--witch-plum);
margin: 2em 0;
}
.is-dark hr {
border-color: var(--witch-rose);
}
section {
margin-bottom: 2em;
}
blockquote {
border-left: 3px solid var(--witch-rose);
margin: 1.5em 0;
padding: 0.5em 0 0.5em 1.25em;
font-style: italic;
}
.is-dark blockquote {
border-left-color: var(--witch-mauve);
}
.callout {
background: rgba(212, 165, 199, 0.08);
border: 1px solid var(--witch-plum);
border-radius: 10px;
padding: 1.25em 1.5em;
margin: 1.25em 0;
}
.is-dark .callout {
border-color: var(--witch-rose);
}
.callout p:last-child {
margin-bottom: 0;
}
.loop-diagram {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 0.5em;
margin: 1.5em 0;
font-size: 1rem;
}
.loop-step {
background: rgba(212, 165, 199, 0.12);
border: 1px solid var(--witch-plum);
border-radius: 8px;
padding: 0.6em 1em;
text-align: center;
}
.is-dark .loop-step {
border-color: var(--witch-rose);
}
.loop-arrow {
font-size: 1.2rem;
opacity: 0.6;
}
.step-list {
counter-reset: steps;
list-style: none;
padding: 0;
}
.step-list li {
counter-increment: steps;
display: flex;
gap: 1em;
align-items: flex-start;
margin-bottom: 1.25em;
}
.step-list li::before {
content: counter(steps);
background: var(--witch-plum);
color: var(--witch-moon);
border-radius: 50%;
min-width: 1.8em;
height: 1.8em;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
flex-shrink: 0;
}
.is-dark .step-list li::before {
background: var(--witch-rose);
color: var(--witch-black);
}
.mod-block {
background: rgba(212, 165, 199, 0.08);
border: 1px solid var(--witch-plum);
border-radius: 10px;
padding: 1.25em 1.5em;
margin: 1.25em 0;
}
.is-dark .mod-block {
border-color: var(--witch-rose);
}
.mod-block h3 {
margin-top: 0;
}
.mod-block p:last-child {
margin-bottom: 0;
}
code {
background: rgba(0, 0, 0, 0.08);
border-radius: 4px;
padding: 0.15em 0.4em;
font-family: monospace;
font-size: 0.9em;
}
.is-dark code {
background: rgba(255, 255, 255, 0.08);
}
pre {
background: rgba(0, 0, 0, 0.08);
border-radius: 8px;
padding: 1em 1.25em;
overflow-x: auto;
font-family: monospace;
font-size: 0.9em;
line-height: 1.6;
}
.is-dark pre {
background: rgba(255, 255, 255, 0.05);
}
.back-link {
font-size: 0.9rem;
display: block;
margin-top: 2em;
}
</style>
</head>
<body>
<main>
<h1>Voice AI Agent Workshop</h1>
<div class="talk-meta">
<span>
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
20&ndash;21 June 2026
</span>
<span>
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
UC Berkeley Campus, Berkeley, CA
</span>
<span>
<i class="fas fa-user-tag" aria-hidden="true"></i>
Speaker &amp; Sponsor (Berkeley AI Hackathon)
</span>
</div>
<div class="talk-links">
<a href="https://ai.hackberkeley.org" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt" aria-hidden="true"></i>
Berkeley AI Hackathon
</a>
<a href="https://console.deepgram.com" target="_blank" rel="noopener noreferrer">
<i class="fas fa-external-link-alt" aria-hidden="true"></i>
Deepgram Console ($200 free credit)
</a>
</div>
<p>
Voice AI is having a moment &mdash; and it's more accessible than you might think. In this
workshop, we'll build a fully functional voice AI agent from scratch, using real-time
speech-to-text, a large language model for reasoning, and text-to-speech to talk back. By
the end, you'll have a working agent on your laptop that you can drop straight into a project.
</p>
<blockquote>
Talk to your hackathon project in 40 minutes.
</blockquote>
<p>No prior voice AI experience needed. If you've worked with an API before, you're good to go.</p>
<hr />
<section>
<h2>How a Voice Agent Works</h2>
<p>
A voice agent is three pieces wired together in a loop. Understanding this loop is the whole
conceptual foundation. Everything else is implementation detail.
</p>
<div class="loop-diagram">
<div class="loop-step">
<strong>Ear</strong><br />
Speech-to-Text
</div>
<span class="loop-arrow">&rarr;</span>
<div class="loop-step">
<strong>Brain</strong><br />
LLM
</div>
<span class="loop-arrow">&rarr;</span>
<div class="loop-step">
<strong>Mouth</strong><br />
Text-to-Speech
</div>
<span class="loop-arrow" style="transform: rotate(90deg); display: block;">&rarr;</span>
</div>
<p>
<strong>The ear</strong> captures your audio and transcribes it in real time using
speech-to-text. Latency here is everything: if your STT is slow, the whole agent feels
sluggish. Deepgram's STT runs at sub-300ms end-to-end, which is fast enough to feel like
a real conversation.
</p>
<p>
<strong>The brain</strong> receives the transcript and decides what to say. This is your
LLM: it reasons over the conversation history and your system prompt, generates a response,
and can call any functions you've given it access to. It can look things up, run code,
fetch data &mdash; anything you wire in.
</p>
<p>
<strong>The mouth</strong> takes the LLM's text response and streams it back as audio. Fast
streaming matters here too: you want audio to start playing before the full response is
generated, or the agent feels like it's thinking too hard.
</p>
<p>
With Deepgram, all three pieces run over a single WebSocket connection. You're not juggling
three separate APIs &mdash; it's one socket, one loop, about 80 lines of code to start.
</p>
</section>
<section>
<h2>Design Decisions That Actually Matter</h2>
<p>
Most tutorials skip these. They're the difference between an agent that feels like a demo
and one that feels like a tool.
</p>
<h3>Interruption Handling</h3>
<p>
In a real conversation, you don't wait for the other person to finish before you start
talking. Your agent shouldn't either. When the user starts speaking mid-response, the agent
needs to stop its output and listen. Getting this wrong is the fastest way to make an agent
feel robotic.
</p>
<p>
Deepgram's Voice Agent API handles this for you. The WebSocket connection detects voice
activity on both ends and manages the interrupt logic. You don't have to implement it
yourself &mdash; just don't override it.
</p>
<h3>Conversation State</h3>
<p>
Every turn in the conversation needs to be threaded correctly. The LLM needs the full
context of what's been said so far &mdash; by both sides &mdash; to give coherent responses. This
means maintaining a message history and passing it in with every LLM call.
</p>
<p>
Keep your context window in mind. Very long conversations will eventually push older turns
out of the context. A simple solution: keep the system prompt, the last N turns, and let
the rest roll off. The agent won't remember everything, but the conversation will stay
coherent.
</p>
<h3>Latency</h3>
<p>
The number that matters is end-to-end: from when the user stops speaking to when audio
starts playing back. Under 500ms feels conversational. Over 1 second feels like a phone
call with bad signal.
</p>
<p>
Three places latency hides: STT processing time, LLM first-token time, and TTS start time.
Streaming helps with all three. Start playing audio as soon as the first TTS chunk arrives.
Choose an LLM model that prioritises speed over capability for conversational use &mdash; a
smaller, faster model is often better here than a smarter, slower one.
</p>
</section>
<hr />
<section>
<h2>Getting Set Up</h2>
<div class="callout">
<p><strong>Before you start:</strong></p>
<ul>
<li>Node 20+ or Python 3.11+ installed</li>
<li>A code editor</li>
<li>A <a href="https://console.deepgram.com" target="_blank" rel="noopener noreferrer">free Deepgram account</a> &mdash; includes $200 credit on sign-up, no credit card needed</li>
</ul>
</div>
<p>Five steps to a running agent:</p>
<ol class="step-list">
<li>
<div>
Sign up at <a href="https://console.deepgram.com" target="_blank" rel="noopener noreferrer">console.deepgram.com</a>.
Your account comes with $200 in free credit &mdash; more than enough for this workshop and a weekend of hacking.
</div>
</li>
<li>
<div>
Grab your API key from the console. It lives under API Keys in the left sidebar. Copy it somewhere safe.
</div>
</li>
<li>
<div>
Clone the starter repo. We'll walk through this together in the workshop, but the pattern is:
<pre>git clone &lt;starter-repo-url&gt;
cd &lt;repo-name&gt;</pre>
</div>
</li>
<li>
<div>
Add your API key to the environment. Create a <code>.env</code> file in the project root:
<pre>DEEPGRAM_API_KEY=your_key_here</pre>
</div>
</li>
<li>
<div>
Install dependencies and run it:
<pre># Node
npm install && npm start
# Python
uv venv && uv pip install -r requirements.txt
python main.py</pre>
</div>
</li>
</ol>
<p>
If it's working, you'll see a connection message in the terminal and the agent will greet
you when you speak. If it's not working, come find us at the booth.
</p>
</section>
<hr />
<section>
<h2>Make It Yours &mdash; Three Modifications</h2>
<p>
The starter app works, but it's generic. These three modifications are where the session
becomes yours. Each one takes about five to seven minutes. Do them in order, or skip to
whichever interests you most.
</p>
<div class="mod-block">
<h3>Modification A: Change the Personality</h3>
<p>
The agent's system prompt is what defines who it is. Find the <code>system_prompt</code>
variable in the starter code &mdash; it'll look something like this:
</p>
<pre>system_prompt = "You are a helpful assistant."</pre>
<p>
Replace it with something more specific. Give the agent a name, a role, a point of view.
For example:
</p>
<pre>system_prompt = """You are Alf, a friendly AI assistant at a hackathon.
You give encouragement, suggest project ideas, and answer questions
about voice AI. You're enthusiastic but concise - people are busy building."""</pre>
<p>
Restart the agent and talk to it. The change is immediate. The system prompt is the
entire personality &mdash; there's no training, no fine-tuning. You just wrote it.
</p>
</div>
<div class="mod-block">
<h3>Modification B: Swap the Voice</h3>
<p>
Deepgram's TTS has a full voice catalogue. Find the voice configuration in the starter
code &mdash; it'll be a single string like <code>"aura-asteria-en"</code>. Change it to any
other voice from the catalogue.
</p>
<p>
A few to try:
</p>
<ul>
<li><code>aura-asteria-en</code> &mdash; warm, conversational</li>
<li><code>aura-orion-en</code> &mdash; deep, authoritative</li>
<li><code>aura-luna-en</code> &mdash; clear, neutral</li>
<li><code>aura-zeus-en</code> &mdash; bold, energetic</li>
</ul>
<p>
Restart and talk to your agent. It's a one-line change and the agent sounds entirely
different. This is the modification that gets the strongest reaction.
</p>
</div>
<div class="mod-block">
<h3>Modification C: Add a Custom Function</h3>
<p>
This is the one that makes you realise you can hook it to anything. Function calling lets
the agent invoke Python (or JS) functions you write, then incorporate the result into its
response naturally.
</p>
<p>
Here's a simple example: a function that returns a random project idea when the agent
is asked for inspiration.
</p>
<pre>import random
def get_project_idea():
ideas = [
"A voice-controlled to-do list that reads back your tasks",
"An AI study buddy that quizzes you out loud",
"A real-time translator that speaks back in the target language",
"A voice journalling app that summarises your entries",
]
return random.choice(ideas)</pre>
<p>
Register this function with the agent and tell the LLM when to use it via the system
prompt: <em>"When asked for a project idea, call get_project_idea() and share the result."</em>
</p>
<p>
Now ask your agent for a project idea. Watch it call the function and weave the result
into a natural spoken response. This is the "aha" moment: the agent can call your own
code, your own APIs, your own data. The voice interface is just the front door.
</p>
</div>
</section>
<hr />
<section>
<h2>What You Can Build From Here</h2>
<p>
Now that you have a working, personalised, function-capable voice agent, here's what that
unlocks for your hackathon project:
</p>
<ul>
<li>
<strong>Accessibility layer</strong> &mdash; add voice input and output to any existing
interface. Users who can't type or read small text get a completely different experience.
</li>
<li>
<strong>In-game NPC</strong> &mdash; drop the agent into a game as a character that actually
talks back. Hook the function calling to your game state so it knows what's happening.
</li>
<li>
<strong>Voice-controlled developer tool</strong> &mdash; talk to your build process, your
deploy pipeline, your monitoring dashboard. Voice is an unusually good interface for
things you want to do hands-free.
</li>
<li>
<strong>Multilingual support</strong> &mdash; Deepgram's STT handles dozens of languages.
The LLM can respond in whatever language the user speaks. Global voice interface, almost for free.
</li>
</ul>
</section>
<section>
<h2>Get Help</h2>
<p>Building something? Stuck on something? Here's where to find us:</p>
<ul>
<li><strong>At the event:</strong> the Deepgram booth &mdash; we're here all weekend</li>
<li><strong>Docs:</strong> <a href="https://developers.deepgram.com" target="_blank" rel="noopener noreferrer">developers.deepgram.com</a></li>
<li><strong>Community:</strong> <a href="https://deepgram.com/discord" target="_blank" rel="noopener noreferrer">Deepgram's Discord</a></li>
</ul>
<p>
The Deepgram challenge prize this weekend goes to the team that builds the most creative
voice-powered experience. Come say hi, show us what you're building, and let us know if you
want feedback on your voice integration before judging.
</p>
</section>
<hr />
<a class="back-link" href="/">
<i class="fas fa-arrow-left" aria-hidden="true"></i>
Back to all talks
</a>
</main>
</body>
</html>