← Back to work

AI Personas for Google Chat

A role system for an AI assistant in Google Chat, built during my internship at DevFortress. A command creates a persona from a code, a name, a personality and a source PDF; mention the app in a chat and that persona answers from its document. The main use was onboarding: a new employee is walked through the steps of the company's onboarding guide.

Architecture

Google ChatOrchestrator (Apps Script)Persona subagent (Gemini + PDF)
The orchestrator takes every mention and hands it to the chat's active persona, which answers only from its PDF.

A Google Chat app written in Apps Script receives the messages that mention it. The main model works as an orchestrator: it reads the event, looks up which persona is active in that chat, and hands the message over. Each persona is a subagent with its own instructions, personality and source PDF, and answers with Gemini through retrieval over that PDF. The active persona is stored per chat, so every chat keeps its own.

Key decisions

Personas as subagents, not a rewritten prompt

Turning the assistant itself into each character would make two sets of instructions fight in one prompt. Instead the main model stays the orchestrator, and each persona runs as a subagent with its own context. The persona never competes with the assistant's rules, so it stays in character for the whole conversation.

Answer from the PDF, or hand off

A persona answers through retrieval over its own PDF, not from what the model happens to know. When the answer is not in the document, it does not guess: it sends the new employee to the person responsible. In onboarding a wrong step costs more than a short handoff.

One persona per chat, switched only with permission

The active persona is saved for each chat. Anyone in the chat can talk to it, but only users with permission can switch it, and only one is active at a time. Every answer in a chat comes from one role and one document.

The hard part

Keeping Google Chat waiting without an error

Google Chat expects an app to answer an event quickly, and searching the PDF and then calling Gemini could take longer than that. A slow answer would have shown up as an error in the chat. I made the app acknowledge the message right away and keep the conversation open, so the user saw the typing indicator while the persona prepared its answer, and the reply arrived when it was ready.

Security and performance

  • A persona only wakes up when the app is mentioned, so ordinary messages in a shared chat never trigger or switch a role.
  • Switching the persona of a chat requires permission, and each persona only reads the PDF it was given.

Stack

Apps ScriptGoogle ChatGeminiRAG