Korely

Use cases Sales co-pilot

Your agent shows up to call 3 like it's call 1

Deal stages, objections, contact preferences. Saved once per call. Read back before the next conversation. One agent_id per rep keeps reads separate, audit trail included.

On this page

The notebook

Want to build a sales co-pilot that walks into call three knowing what happened on call one? Here is how

Think about the best account executive you ever worked with. Before every call she pulled out a little notebook. "Last time you said budget gets unlocked after the Q3 board meeting, did that land?" "You mentioned your VP hates long demos, so I cut it short." The prospect feels known.

That notebook is the whole trick. Your agent has perfect grammar and infinite patience, but no notebook, so every call it sounds like a stranger reading a script. The deal stage, the objection from last time, the fact that this buyer prefers email over a phone call, none of it carries forward. The buyer notices, and a relationship that is supposed to compound stalls instead.

Korely is the notebook. The rep writes a line after each call, and the agent reads it back before the next one.

How you build it

Five steps you already half-know, plus the one you skip

  1. Wire your agent to the call

    You already have the easy part. Drop a transcript or live notes from Zoom, Gong, or a phone bridge into Claude Code or Cursor and let the model summarize what was said. This is a weekend of work and you have probably done it already.

  2. Pick what is worth remembering after each call

    Not the whole transcript, just the durable facts: deal stage, who the economic buyer is, the objection that came up, the budget timing, that the contact prefers email over calls and short demos. The model is good at pulling these out of a transcript.

  3. Write those facts to memory, one agent_id per rep, one user_id per account

    After call one your agent calls add() with "stage: discovery done, moving to demo", "objection: pricing vs incumbent", "buyer prefers email, hates long demos". The agent_id keeps Maria reads separate from Tom reads, and the user_id keeps each account apart, so pass both on every read.

  4. Read the memory back before the next call starts

    When the agent opens call three it calls get_context() for this account and gets a block built from the facts open today: where the deal stands now, the objection it still owes an answer to, how this person likes to be sold to. It walks in warm.

  5. Let the agent correct itself when things change

    The prospect said budget was Q3, now it is Q4 after a reorg. The agent just writes the new fact. The old one does not get deleted, it gets marked superseded, so the agent answers from what is true now and you still have the trail of how the deal moved.

  6. The part nobody wants to build, this is where Korely saves you

    The notebook above is not a database row. It is a bi-temporal, typed-fact, graph-RAG memory layer: it has to know what is true now versus what was true in March, resolve the contradiction when the budget date changes, link the objection to the buyer to the account, and surface the right three facts without a generative model on the read path, with no generative model on the read path. That infrastructure is months of work and a research problem in its own right. With Korely you call add() and search(). You skip building the memory, keep building the agent, and it starts at 19 euro a month + VAT.

The shape of the loop

One line written per call, one timeline read back before the next

Call 1, discovery

Agent writes the facts

  • Stage, objection, budget = Q3
  • Buyer prefers email, short demos

Korely memory

Bi-temporal deal timeline

  • Account linked to buyer to objection
  • Q3 superseded by Q4 after the reorg

Call 3, proposal

Agent reads it back

  • Current truth: Q4, open objection
  • Walks in like one conversation
The rep writes one line per call. Korely keeps the timeline straight. The agent reads it back and never sounds like a stranger.

How Korely fits

You build the agent. We are the memory.

What Korely saves you is the entire agentic-memory backend, the part of the sales co-pilot that has nothing to do with sales and everything to do with hard infrastructure. A real sales memory is not just storing notes. It has to be bi-temporal: it must separate when a fact became true in the deal (budget moved to Q4) from when you recorded it, so the agent answers from the current state of the pipeline and not a stale one.

It needs two-stage contradiction handling so when the buyer changes their mind the new fact wins and the old one is kept as history, not silently overwritten. It needs a typed entity graph so the objection, the economic buyer, the competitor, and the account are linked and the agent can pull the whole picture of one deal in a single call. And it needs retrieval (pgvector search plus a lookup of the typed facts, Postgres only) that surfaces the right facts, not just keyword matches, with no generative model on the read path.

The selection is the point. Korely returns the facts and memories that match the question, not the most recent messages, in one block under a token budget you set, 800 tokens by default. For a sales co-pilot that is the difference between the agent recalling the one objection that actually matters and the agent dumping the last thing said.

Reads run no generative model, so memory adds a lookup to the conversation, not another model turn. The store is hosted in the EU; to extract facts, the text of each write, with up to ten earlier memories of the same account (300 characters each) and the earlier facts it is compared with, goes to the model of your project's region, Google's Gemini API by default or Scaleway in Paris if you choose the EU region.

Show me the code

Post-call write, pre-call read

sales_copilot.pypython

# ── After call 1: the agent summarized the transcript ──────────
from korely_memory import Korely

korely = Korely(api_key="kor_live_...")

korely.add(
    "Stage: discovery done, moving to demo. "
    "Objection: pricing vs incumbent. "
    "Buyer prefers email, hates long demos. Budget unlocks Q3.",
    agent_id="rep-maria",
    user_id=f"account-{account_id}",
    metadata={"call_date": call.date_iso, "contact": contact.name},
)

# ── Before call 3: the agent preps the brief ───────────────────
context = korely.search(
    f"current stage and open objection for {account_id}",
    agent_id="rep-maria",
    user_id=f"account-{account_id}",
)

# context → the closest notes, best first, each with its score and the first 280
# characters of the memory, scoped to Maria and this account

One write call after each conversation. One search call before the next. Use an agent_id per rep to keep each rep's reads separate and a user_id per account to keep accounts apart. For facts that must never affect each other across reps, give each rep their own user_id for the account (for example account-42-maria) or use separate projects. No bespoke storage to build.

When the deal moves

The agent answers from what is true now, not from what was said most

Three weeks ago the prospect told your rep, "Budget gets approved right after the Q3 board meeting." Your agent saved that. Then last Tuesday there was a reorg and the buyer said, "Actually it is Q4 now, the new VP wants to re-scope." Your agent saved that too.

Today the rep is prepping the renewal-timing pitch and asks the co-pilot, "When can they buy?" A plain memory that just kept the latest few messages might surface the Q3 line because it was repeated more often, or hand back both and let the model guess. Korely answers from what is true now: Q4, because of the reorg, and it can still show you that it used to be Q3 and exactly when that changed.

The rep does not pitch a close date that is already dead. That one correct date, pulled while the call is live, is the whole reason to have memory at all.

timeline.pypython

korely.add(
    "Budget gets approved right after the Q3 board meeting.",
    agent_id="rep-maria",
    user_id=f"account-{account_id}",
    timestamp="2026-04-12",
)

# Three weeks later, a reorg moves the date
korely.add(
    "Budget is Q4 now, the new VP wants to re-scope.",
    agent_id="rep-maria",
    user_id=f"account-{account_id}",
    timestamp="2026-05-04",
)

# Facts are extracted a few seconds after add() returns; read once both memories show status "ready".
ctx = korely.get_context("when can they buy", agent_id="rep-maria", user_id=f"account-{account_id}")
# → a block built from the facts open today (budget Q4); a note whose facts
#   were all superseded stays, marked "(true when said, changed later)".

Frequently asked

Sales co-pilot memory, common questions

Why does my sales agent treat every call like the first one?

Because the agent lives inside one chat session. When the call ends and the session closes, the deal stage, the objection, the buyer preferences, all of it resets to nothing. Call three starts from zero just like call one. Memory means writing those facts to a store the agent re-reads before the next call, so it shows up knowing where the deal stands instead of reading a cold script.

How do I keep one rep's pipeline from leaking into another's?

You scope each rep with an agent_id and each account with a user_id. Maria notes on the Acme deal live under her agent_id and the Acme user_id, Tom notes under his. The agent_id keeps each rep reads separate, but a newer fact about the same account (same user_id) can supersede an older one written by another rep. To keep reps facts from ever affecting each other, give each rep their own user_id for the account (for example account-42-maria) or use separate projects. Each distinct agent_id counts toward your plan agent limit (Hobby 2, Developer 10, Team 100, Scale 500, see pricing). A search scoped with the account user_id returns only that account memory, so the agent does not pull the wrong account into a live call and you can audit exactly what was remembered for each deal.

A prospect changed their mind mid-cycle. Does the agent keep using the old answer?

No, and this is the part most memory layers get wrong. Korely is bi-temporal, so when the budget moves from Q3 to Q4 the agent writes the new fact and it becomes the current truth, while the old one is kept marked as superseded. The agent answers from what is true now, and you still have the full trail of how the deal moved, which is exactly what you want when you are forecasting or doing a deal review.

Will reading the memory slow the agent down during a live call?

No. There is no generative model on the read path: it is a direct vector search and fact lookup over the store. The agent can pull the three facts that matter (the current stage, the open objection, the buyer preference) with a vector search and a fact lookup, and no model turn.

How is this different from just stuffing my CRM notes into the prompt?

CRM notes are a flat pile of text. The agent has to re-read all of it every time and hope the one relevant objection is in there. Korely keeps typed facts in a graph, so the objection is linked to the buyer is linked to the account, and vector search surfaces the right few facts instead of the whole pile. The block the agent reads stays under a token budget you set, 800 tokens by default, however many calls the deal has had. For a sales co-pilot that means recalling the objection that actually matters instead of dumping the last thing said.

Where does the data live, and can I use it for free?

In a managed store in the EU, Postgres with a vector and graph index, nothing for you to host. There is a free Hobby tier to start, and paid plans begin at 19 euro a month + VAT when you need more headroom. The Python and Node SDKs are live, so you sign up, get an API key, and run your first add() and search() in minutes.

You already have the agent. Add the notebook it has been missing.

Sign up free, get an API key, and run your first call-one write in minutes. The korely-memory Python and Node SDKs and the REST API are live today, and paid plans start at 19 euro a month + VAT when you outgrow the free tier.

See pricing and start free

Looking for a different shape? See the other nine use cases →

Back to top ↑