Customer-support bot with persistent facts
You’ll build a support bot that remembers what each customer told it,
even across process restarts. Use this pattern for any assistant that
talks to the same people repeatedly and shouldn’t make them repeat
themselves. Facts (user X says they live in Tokyo,
account Y is on the enterprise plan) get extracted automatically
after every conversation and stored per user_id.
import asyncio
from loomflow import Agent
from loomflow.runtime import SqliteRuntime
async def main():
# Postgres URL → resolver builds PostgresMemory + pgvector
# facts table on first agent.run. Schema migrations are
# idempotent; nothing to remember.
agent = Agent(
instructions=(
"You are a customer-support agent for Acme. "
"Use any known facts about the user to personalize replies. "
"Cite the fact's source when you rely on it."
),
model="claude-opus-4-7",
memory="postgres://localhost/support_bot",
runtime=SqliteRuntime("./support_journal.db"),
# auto_extract=True is the default for real models: every run pulls
# structured facts from the conversation into the bi-temporal
# store, partitioned by user_id.
)
while True:
prompt = input("User> ")
if not prompt:
break
# In a real bot, ``user_id`` comes from your auth layer.
result = await agent.run(prompt, user_id="user_42")
print(f"Bot> {result.output}")
await agent.aclose() # wait for background fact extraction before exiting
asyncio.run(main())The first time a user mentions their plan tier, auto-extract stores a
fact like ("user", "subscription_plan", "enterprise"). Extraction
runs in the background after run() returns, which is why the script
ends with agent.aclose(): without it, facts from the last message
can be lost at exit. Later runs see the fact in the Known facts:
section of the system message and tailor responses without asking
again. When the plan changes, the new fact supersedes the old one,
whose validity window is closed automatically, so questions about the
past still get the right answer.