In this section, we're going to create the soul of our AI agent.
If memory is about the user, the soul is about your agent's personality. The soul is just a fancy word for the system prompt, and it defines how we want our agent to act.
So if the user says "my name is Shawn", that goes into Supermemory. But the agent's name, how it likes to talk, the length of its replies — all of that lives in the soul.
Show tutorial/excalidraw/9-soul-identity-flow.excalidraw.
The soul sits in the system prompt.
Memory stores facts about the user. The soul defines the agent's identity — its name, voice, principles, and boundaries.
Open the finished demo, ask the agent:
what's your name?
It should answer with the soul-defined name (e.g. "Ki — your personal AI agent").
We're going to add a new feature: if the soul hasn't been defined yet for the user, the agent runs onboarding as a conversation instead of putting a long form on the screen.
Show tutorial/excalidraw/10b-soul-onboarding-flow.excalidraw.
When a signed-in user has no soul yet, we inject an onboarding prompt into the system prompt. The agent asks a couple of questions, stores user facts with addMemory, and then calls setSoul to commit the agent's identity into the database.
After that, we shouldn't see the onboarding prompt anymore — the saved soul gets prepended to the system prompt on every future message.
Show tutorial/excalidraw/10-soul-prompt-stack.excalidraw.
This is what gets assembled into the system prompt on every message:
- Onboarding prompt — only if
User.soulis null. - Soul — the agent's identity.
- Regular prompt, tool rules, current messages, tools.
The model isn't responding from nothing. It's responding with identity, memory rules, tools, and the current conversation assembled together.
Open README → 🤖 Agent-Ready Prompt 4 — Soul column, onboarding, and /admin/agent.
Copy the prompt into Cursor.
This prompt is a little bigger because it touches the UI, the database, and a new admin page so we can debug everything is working.
- Database: add a nullable
soulcolumn to the user. New users start with an empty soul. - Prompt: if
User.soulis null, inject the onboarding prompt. If it's already defined, use the saved soul as-is. setSoultool: a new tool we add to the model so it can commit the generated identity to the database./admin/agent: a debug page where we can see what the agent wrote and manually edit it if we want.
Paste 🤖 Agent-Ready Prompt 4 from the README into Cursor. Use the project root as context.
After Cursor finishes, walk through it:
- Reset the soul from
/admin/agent(or sign up a fresh user). - Send
hi. - Agent asks for the user's name → user answers →
addMemoryfires. - Agent asks what to call itself and the preferred vibe.
setSoulwrites the agent identity to the database.- Refresh
/admin/agentto see the generated soul. - Start a new chat and ask "what's your name?" → agent answers with its soul-defined name.
Now our agent doesn't just remember the user — it also has a stable identity.
User facts live in Supermemory. The agent's personality lives in User.soul.
That gives us the two pieces we need before we move outside the browser: the agent knows who it is, and it can remember who the user is.