Most meeting assistants can summarize what happened. The harder problem starts when you ask them about that meeting again two weeks later.
I wanted MeetingMind to handle that second question.
MeetingMind is an AI meeting intelligence agent that extracts useful information from professional meetings, stores it as persistent memory, and later uses that memory to prepare for future meetings. The key design decision was to make memory part of the agent's workflow rather than treating it as an optional chat-history feature.
The system combines a Spring Boot backend, a Python AI agent, Gemini for structured language processing, MySQL for application data, and Hindsight for persistent agent memory.
The Problem with a Stateless Meeting Assistant
Consider a simple meeting:
Sarah wants the September product launch completed this month.
Rahul is concerned about API performance.
The client requested dark mode.
Rahul agreed to run performance tests before the next meeting.
A stateless LLM can summarize these notes perfectly well.
But later, if I ask:
“Why should I discuss API performance with Rahul?”
the model needs historical context.
The problem isn't generating language. The problem is remembering the right information at the right time.
That is where I introduced Hindsight.
Instead of keeping meeting history only inside the current request, MeetingMind stores extracted knowledge in persistent memory and retrieves it when a future meeting requires that context.
The workflow looks like this:
Meeting Notes
↓
Python AI Agent
↓
Gemini
↓
Structured Meeting Knowledge
↓
Hindsight RETAIN
↓
Persistent Memory
↓
Hindsight RECALL
↓
Gemini
↓
Meeting Brief
The important part is that the same memory can remain useful much later.
I Didn't Want to Store Only Raw Meeting Transcripts
One design decision I made early was to separate different types of information.
Instead of treating every sentence as an undifferentiated piece of history, MeetingMind extracts:
decisions
commitments
unresolved issues
participant preferences and concerns
discussion points
I represented that structure with a Pydantic model:
class MeetingKnowledge(BaseModel):
decisions: List[str] = Field(
default_factory=list
)
commitments: List[str] = Field(
default_factory=list
)
unresolved_issues: List[str] = Field(
default_factory=list
)
participant_preferences: List[str] = Field(
default_factory=list
)
discussion_points: List[str] = Field(
default_factory=list
)
This distinction turned out to matter.
A concern isn't automatically a decision. A client request isn't automatically a commitment. A goal isn't necessarily something that was agreed upon.
Those differences become important when the agent prepares someone for their next meeting.
Using Hindsight as the Agent's Memory Layer
After Gemini extracts the structured knowledge, MeetingMind converts it into a memory representation and sends it to Hindsight.
The memory includes the meeting ID and separates the extracted information into meaningful sections:
memory_content = f"""
MeetingMind historical meeting memory.
Meeting ID: {meeting_id}
DECISIONS:
{...}
COMMITMENTS:
{...}
UNRESOLVED ISSUES:
{...}
PARTICIPANT PREFERENCES AND CONCERNS:
{...}
IMPORTANT DISCUSSION POINTS:
{...}
""".strip()
That information is then retained through Hindsight:
response = requests.post(
f"{HINDSIGHT_BASE_URL}/v1/default/banks/"
f"{HINDSIGHT_BANK_ID.strip()}/memories",
headers=_headers(),
json={
"items": [item]
},
timeout=30
)
The important thing here is that the agent doesn't have to reconstruct the entire conversation history every time.
The historical information lives in the memory layer.
I used Hindsight because persistent memory is central to what MeetingMind is trying to solve.
Recall Is Where the System Becomes Useful
Storing information is only half the problem.
When a user asks MeetingMind to prepare for an upcoming meeting, the agent first searches Hindsight for relevant history.
For example:
query = (
f"Prepare me for the upcoming meeting: "
f"{meeting_title}. "
f"Find relevant previous decisions, unresolved issues, "
f"commitments, participant preferences, client requests, "
f"and important discussion points."
)
memory_response = recall_memory(query)
The recalled memory is then supplied to Gemini along with the current meeting context.
This creates a two-stage process:
Hindsight
↓
Historical Context
↓
Gemini
↓
MeetingBrief
The LLM is no longer expected to remember the past by itself. Hindsight handles persistent memory retrieval, while Gemini uses that retrieved context to construct the meeting preparation brief.
A Concrete Example
After the example meeting, I can ask Hindsight:
“What did Rahul commit to regarding API performance?”
The retrieved memory contains the important relationship:
Rahul is concerned about API performance and committed to running performance tests before the next meeting.
I can also ask:
“Why should I discuss API performance with Rahul?”
The answer is grounded in the stored meeting history rather than being a generic suggestion.
That distinction is the part I care about most.
Without historical memory, “discuss API performance” is just reasonable-sounding advice.
With memory, it is connected to a specific person, a previous concern, and a previous commitment.
Preparing the Next Meeting
MeetingMind ultimately converts the recalled context into a structured meeting brief.
The output contains:
Meeting title
Objective
Previous decisions
Open issues
Commitments
Participant preferences
Client requests
Discussion points
The agent prompt explicitly tells Gemini to preserve names, deadlines, responsibilities, and technical details while avoiding unsupported information.
For example, if Rahul is responsible for performance testing, the preparation should preserve Rahul as the responsible person rather than reducing the information to:
Run performance tests.
The same applies to the client's dark-mode request. The agent should identify it as a client request rather than accidentally turning it into a previous decision.
What I Learned Building It
- Memory needs structure
Simply storing a large block of conversation history isn't enough for a useful meeting assistant.
Decisions, commitments, concerns, and requests have different meanings. Giving those concepts explicit structure makes downstream reasoning more reliable.
- Retrieval is part of the agent
I initially thought about memory as something the application would store in the background.
That wasn't enough.
The agent needs to actively retrieve the historical context that is relevant to the current task. In MeetingMind, recall happens as part of meeting preparation rather than as a separate database lookup.
- Prompts need semantic boundaries
One of the more subtle problems was preventing the model from confusing categories.
For example:
Sarah wants the launch completed this month.
is not necessarily a decision.
Similarly:
The client requested dark mode.
is a request, not automatically a commitment.
Being explicit about these boundaries in the prompt made the resulting structure more useful.
- Persistent memory changes the interaction
The most interesting change wasn't that the agent could produce better summaries.
It was that the questions themselves could become contextual.
Instead of asking:
“What should I discuss in this meeting?”
the user can ask something closer to:
“What should I follow up with Rahul about?”
That question only becomes meaningful when the system remembers what happened previously.
- Keeping the scope narrow matters
Meeting intelligence can easily turn into a huge product involving calendars, video conferencing, transcription, CRM integrations, notifications, and voice assistants.
I deliberately kept MeetingMind focused on one workflow:
Remember previous meetings
↓
Retrieve relevant history
↓
Prepare for the next meeting
That made the role of persistent memory much clearer.
What I Would Build Next
The current architecture gives me a foundation for expanding MeetingMind without changing its central idea.
Future versions could connect meeting preparation to calendars, support automatic ingestion of transcripts, learn recurring participant preferences, and provide stronger follow-up tracking.
But the core principle would remain the same:
An AI agent shouldn't just know what was said. It should be able to use what happened before when deciding what matters next.
That is why I built MeetingMind around persistent memory rather than treating memory as another feature on top of an otherwise stateless assistant.
Resources
Source code:
https://github.com/nazima0410/meetingmind
Hindsight documentation:
https://hindsight.vectorize.io/
Hindsight GitHub:
https://github.com/vectorize-io/hindsight




Top comments (0)