Track
अधिकांश LLM एजेंट हर रन पर शून्य से शुरू होते हैं। वे यूज़र का नाम, पिछली बातचीत, और जिस फ़ाइल पर वे काम कर रहे थे उसे भूल जाते हैं। यूज़र-विशिष्ट हर चीज़ को हर टर्न पर फिर से स्थापित करना पड़ता है।
यह ट्यूटोरियल किसी एजेंट में स्थायी मेमोरी जोड़ता है ताकि अगला रन वहीं से शुरू हो जहाँ पिछला समाप्त हुआ था। मेमोरी परत है Supermemory, एक होस्टेड API जो प्रति-यूज़र तथ्य स्टोर करती है और उन्हें एक ही कॉल में लौटाती है। आप Python में व्यक्तिगत एक्सरसाइज़ ट्रेनर बनाएंगे। एजेंट वर्कआउट लॉग करता है, अगला सत्र सुझाता है, और स्क्रिप्ट के अलग-अलग रन के बीच पसंद और हाल की लिफ्ट्स याद रखता है।
स्टैक छोटा है। Supermemory मेमोरी होल्ड करती है। OpenAI Agents SDK एजेंट लूप चलाता है। ट्रेनर दो Python फ़ाइलों और एक pyproject.toml फ़ाइल से बना है।
आपको Python 3.10 या नया वर्ज़न, एक OpenAI खाता, एक Supermemory खाता, और कमांड लाइन के साथ बुनियादी सुविधा की आवश्यकता होगी।
Supermemory क्या है?
Supermemory को एजेंट्स के लिए AI मेमोरी API के रूप में सबसे अच्छा वर्णित किया जा सकता है। जब आप अपने यूज़र के बारे में स्ट्रिंग्स Supermemory को देते हैं, तो यह बाद में उस यूज़र का संक्षिप्त व्यू लौटाती है—वे कौन हैं और हाल ही में क्या कर रहे हैं। एम्बेडिंग, इंडेक्सिंग और रिट्रीवल सब Supermemory के अंदर चलते हैं, इसलिए आपका एजेंट कोड छोटा रहता है।
LongMemEval बेंचमार्क यह परखता है कि कोई मेमोरी सिस्टम लंबी बातचीत के इतिहास पर प्रश्नों का कितना अच्छा उत्तर देता है। Supermemory सही तथ्यों का 81.6% याद रखती है। Zep, अगला सर्वश्रेष्ठ सिस्टम, 71.2% स्कोर करता है—10 अंकों का अंतर, जो लगभग हर 10 यूज़र प्रश्नों पर 1 अतिरिक्त सही उत्तर में बदलता है। ओपन-सोर्स रिपॉज़िटरी पर 22k+ GitHub स्टार्स हैं, जो वास्तविक उपयोग का एक और संकेत है।
मेमोरी बनाम RAG
अधिकांश पाठक जो किसी एजेंट मेमोरी टूल की ओर बढ़ते हैं, पहले से RAG इस्तेमाल कर चुके होते हैं। It इसे उसके साथ रखना मददगार रहता है। RAG और मेमोरी अलग समस्याएँ हल करते हैं, और अक्सर एक ही एजेंट में साथ रहते हैं।
RAG सिस्टम उस डॉक्यूमेंट कॉर्पस की ओर इशारा करता है जिसे डेवलपर एक बार तैयार करता है। प्रोडक्ट मैनुअल, सपोर्ट आर्टिकल, इंटरनल डॉक्यूमेंट्स। कॉर्पस डिप्लॉय समय पर लोड होता है, रनटाइम पर क्वेरी होता है, और शायद ही बदलता है। एजेंट इसका उपयोग उन प्रश्नों के उत्तर देने के लिए करता है जिनके उत्तर प्रोडक्ट को खुद पता हैं।
एक मेमोरी सिस्टम यूज़र की ओर इशारा करता है। Supermemory यूज़र-विशिष्ट तथ्य लिखती है जब एजेंट उस यूज़र से बात करता है, और हर बातचीत के साथ स्टोर बढ़ता है। एजेंट इसका उपयोग उन प्रश्नों के उत्तर देने के लिए करता है जिनका उत्तर केवल यूज़र ही दे सकता है, जैसे पसंद, इतिहास, और हाल की गतिविधि।

किसी वास्तविक प्रोडक्ट में, दोनों साथ-साथ चलते हैं। किसी कंपनी नॉलेज बेस पर RAG उत्तर देता है—"हमारी रिफंड पॉलिसी क्या है?" Supermemory यूज़र के प्रश्न पर—"पिछले सप्ताह मेरा बेंच प्रेस क्या था?"—उत्तर देती है। वही एजेंट, दो डेटा स्टोर, दो काम।
यूज़र प्रोफ़ाइल: स्थिर और गतिशील तथ्य
Supermemory का मुख्य विचार है यूज़र प्रोफ़ाइल। हर लॉग दो बकेट में सॉर्ट होता है: स्थिर तथ्य जो शायद ही बदलते हैं, और वर्तमान गतिविधि के बारे में गतिशील तथ्य। बार-बार आने वाले पैटर्न स्थिर में प्रमोट हो जाते हैं। हाल की गतिविधि गतिशील में रहती है।
जब एजेंट प्रोफ़ाइल पढ़ता है, तो एक कॉल दोनों बकेट्स और मिलते-जुलते मेमोरी चंक्स लौटाती है।
यह विभाजन मायने रखता है क्योंकि स्थिर और गतिशील तथ्य एक ही यूज़र के बारे में अलग प्रश्नों का उत्तर देते हैं:
|
स्थिर तथ्य |
गतिशील तथ्य |
|
डम्बल और पुल-अप बार के साथ घर पर ट्रेन करता/करती है |
वर्तमान फोकस: अपर-बॉडी स्ट्रेंथ |
|
बाएँ घुटने की चोट, डीप स्क्वैट्स नहीं |
आख़िरी बेंच: 185 पाउंड पर 5 रेप्स के 4 सेट |
|
वर्ष के अंत तक बेंच में 20 पाउंड जोड़ना चाहता/चाहती है |
इस सप्ताह ग्रीस-द-ग्रूव पुल-अप्स पर काम कर रहा/रही है |
|
सिर्फ़ शाम को ट्रेन करता/करती है, कभी सुबह नहीं |
कल 28 मिनट में 5k दौड़ा/दौड़ी |
पहली पंक्ति पढ़ें। स्थिर पक्ष बताता है कि यूज़र कैसे ट्रेन करता/करती है: घर पर, अपने उपकरण के साथ। यह हफ्ते-दर-हफ्ते नहीं बदलता। गतिशील पक्ष बताता है कि वे अभी क्या कर रहे हैं: इस साइकल में अपर बॉडी।
वर्कआउट सजेस्टर को दोनों चाहिए। स्थिर पक्ष जिम-ओनली एक्सरसाइज़ को बाहर करता है, गतिशील पक्ष आज का सत्र चुनता है।
उस प्रोफ़ाइल के पीछे, Supermemory चार काम करती है जो अन्यथा आपको खुद बनाने पड़ते: कच्ची मेमोरी स्टोर करना, हर chunk को एम्बेड करना, पढ़ते समय सिमिलैरिटी सर्च चलाना, और लॉग किए हुए कंटेंट से प्रोफ़ाइल तथ्य निकालना। इन चार में से कुछ भी आपके कोड में नहीं आता।

हर मेमोरी को एक स्ट्रिंग टैग के साथ टैग किया जाता है जिसे डेवलपर चुनता है। हर रीड वही स्ट्रिंग वापस पास करती है ताकि आउटपुट सीमित रहे। ट्रेनर एक टैग हार्डकोड करता है क्योंकि प्रोफ़ाइल क्या करती है, यह दिखाने के लिए एक यूज़र काफ़ी है। वास्तविक ऐप्स प्रमाणित यूज़र से, जैसे उनके JWT से, टैग निकालते हैं।
अपना Supermemory एनवायरनमेंट सेट करना
ट्रेनर को दो API कुंजियाँ (Supermemory और OpenAI) और तीन डिपेंडेंसीज़ वाला एक Python प्रोजेक्ट चाहिए। एक त्वरित राउंड-ट्रिप स्क्रिप्ट किसी भी एजेंट कोड के पास जाने से पहले दोनों कुंजियों के काम करने को साबित करती है।
अपनी API कुंजियाँ प्राप्त करना
Supermemory API कुंजी रहती है console.supermemory.ai पर, NOT app.supermemory.ai पर नहीं। app सबडोमेन कंज़्यूमर मेमोरी प्रोडक्ट है (नोट्स सेव करने, अपने स्पेस ब्राउज़ करने के लिए)। इसमें कोई API key पेज नहीं है। इसे छोड़ें और सीधे कंसोल पर जाएँ।
console.supermemory.ai पर:
-
साइन इन करें।
-
साइडबार में API Keys पर क्लिक करें।
-
Create API Key पर क्लिक करें।
-
नाम दें (ट्रेनर डेमो
datacamp-tutorialउपयोग करता है)। -
बनी हुई कुंजी कॉपी करें। यह
sm_से शुरू होती है।

एजेंट के LLM कॉल्स के लिए आपको OpenAI कुंजी भी चाहिए। अगर आपके पास पहले से नहीं है, तो एक लें platform.openai.com/api-keys से।
अपने प्रोजेक्ट रूट में एक .env फ़ाइल बनाएँ और दोनों कुंजियाँ जोड़ें। इसे कमिट न करें।
SUPERMEMORY_API_KEY=sm_your_key_here
OPENAI_API_KEY=sk-your_key_here
Supermemory का फ्री टियर इस ट्यूटोरियल को भुगतान जानकारी दिए बिना कवर करता है। सटीक सीमाएँ प्राइसिंग पेज पर हैं।
डिपेंडेंसीज़ इंस्टॉल करना
ट्यूटोरियल uv का उपयोग p्रोजेक्ट सेटअप और एक्ज़ीक्यूशन के लिए करता है। यदि आपके पास uv नहीं है, तो astral.sh/uv से वन-लाइनर के साथ एक बार इंस्टॉल करें।
प्रोजेक्ट इनिशियलाइज़ करें:
uv init supermemory-trainer
cd supermemory-trainer
uv init जो README.md जोड़ता है, उसे हटा दें। hello.py ऑटो-जनरेटेड फ़ाइल अगले चरण में ओवरराइट हो जाएगी, इसलिए अभी रहने दें।
तीन डिपेंडेंसी जोड़ें:
-
supermemory==3.37.0मेमोरी क्लाइंट है, इस ट्यूटोरियल के लिए सत्यापित वर्ज़न पर पिन्ड। -
openai-agents OpenAI Agents SDK है। पैकेज नाम हाइफ़नेशन के साथ है, इम्पोर्ट पाथ
agentsहै। -
python-dotenvवह.envफ़ाइल पढ़ता है जो आपने अभी बनाई।
uv add supermemory==3.37.0 openai-agents python-dotenv
बनी हुई pyproject.toml:
[project]
name = "supermemory-trainer"
version = "0.1.0"
description = "Personal exercise trainer agent built with Supermemory and the OpenAI Agents SDK."
requires-python = ">=3.10"
dependencies = [
"openai-agents>=0.10.2",
"python-dotenv>=1.2.1",
"supermemory==3.37.0",
]
अपना सेटअप वेरिफ़ाई करना
किसी भी एजेंट कोड को लिखने से पहले, Supermemory को एक वाक्य पर काम करते हुए एक बार देखें। नीचे दी गई स्क्रिप्ट एक तथ्य Supermemory को भेजती है, पाइपलाइन का इंतज़ार करती है, फिर प्रोफ़ाइल को पढ़कर वापस लाती है। यदि यह साफ़-सुथरे ढंग से चलता है, तो कुंजियाँ काम करती हैं और SDK पहुँच में है। आउटपुट आपको यह भी पहली झलक देता है कि Supermemory कच्चे टेक्स्ट के साथ क्या करती है।
hello.py को प्रोजेक्ट रूट में खोलें और ऑटो-जनरेटेड बॉडी को इम्पोर्ट्स और एक write कॉल से बदलें:
import time
from dotenv import load_dotenv
from supermemory import Supermemory
load_dotenv()
client = Supermemory()
USER_ID = "demo_warmup"
response = client.add(
content="The user is learning Supermemory by building a personal trainer agent.",
container_tag=USER_ID,
)
print(f"client.add() -> id={response.id} status={response.status}")
load_dotenv() .env से API कुंजी पढ़कर Supermemory() बनने से पहले एनवायरनमेंट में डालती है। क्लाइंट SUPERMEMORY_API_KEY अपने आप उठा लेता है। container_tag="demo_warmup" मान इस एक तथ्य को एक थ्रोअवे यूज़र तक सीमित करता है।
अब उसी फ़ाइल के नीचे wait और read जोड़ें:
print("Waiting 20 seconds for processing...")
time.sleep(20)
prof = client.profile(container_tag=USER_ID, q="learning")
print(f"profile.static ({len(prof.profile.static)}): {prof.profile.static}")
print(f"profile.dynamic ({len(prof.profile.dynamic)}): {prof.profile.dynamic}")
print(f"search_results.results ({len(prof.search_results.results)}):")
for r in prof.search_results.results[:3]:
print(f" - {r['memory']} (similarity={r['similarity']:.3f})")
20-सेकंड की स्लीप Supermemory की एम्बेड-एंड-एक्सट्रैक्ट पाइपलाइन को नई मेमोरी प्रोसेस करने का समय देती है। इसके बिना, रीड कुछ नहीं लौटाती, और स्क्रिप्ट टूटी हुई लगती है जबकि ऐसा नहीं है।
फ़ाइल चलाएँ:
uv run python hello.py
अपेक्षित आउटपुट:
client.add() -> id=zNLsJBrY1PZupAeZ3Qn6EL status=queued
Waiting 20 seconds for processing...
profile.static (0): []
profile.dynamic (1): ['Building a personal trainer agent to learn Supermemory.']
search_results.results (1):
- Building a personal trainer agent to learn Supermemory. (similarity=0.650)
इस आउटपुट में तीन विवरण मायने रखते हैं। client.add() तुरंत status="queued" के साथ लौटती है, क्योंकि Supermemory डॉक्यूमेंट्स को asynchronously प्रोसेस करती है। 20-सेकंड का इंतज़ार एम्बेड-एंड-एक्सट्रैक्ट पाइपलाइन को कवर करता है। जब तक रीड चलती है, कच्चा वाक्य एक सर्चेबल मेमोरी chunk बन चुका होता है।
दिलचस्प लाइन है profile.dynamic। इनपुट था वाक्य "The user is learning Supermemory by building a personal trainer agent." आउटपुट है गतिशील तथ्य 'Building a personal trainer agent to learn Supermemory.' Supermemory ने तीसरे पुरुष के वाक्य को यूज़र के बारे में पहले पुरुष के तथ्य में बदल दिया। यह प्रोफ़ाइल एक्सट्रैक्टर का काम है।
profile.static एक खाली सूची है। स्थिर तथ्य धीरे-धीरे समेकित होते हैं, कुछ संबंधित लॉग इकट्ठा होने के बाद, इसलिए एक सिंगल वॉर्म-अप write इससे नहीं बनाता। ट्रेनर का सुझाव टूल इसकी योजना बनाता है और static को गारंटी के बजाय बोनस मानता है।
Supermemory एजेंट बनाना: Python में पर्सनल एक्सरसाइज़ ट्रेनर
ट्रेनर client.add() और client.profile() को दो एजेंट टूल्स में रैप करता है, ताकि यूज़र के चैट करते ही रीड्स और राइट्स अपने आप हों। वर्कआउट इतिहास मेमोरी में अच्छी तरह फिट बैठता है। उपकरण, चोटें, और हाल की लिफ्ट्स LLM के ट्रेनिंग डेटा में नहीं रहतीं, और सत्र-दर-सत्र इकट्ठी होती हैं।

प्रोजेक्ट संरचना और एजेंट
ट्रेनर इतना छोटा है कि पूरा प्रोजेक्ट दो Python फ़ाइलों में फिट हो जाता है, साथ में वह pyproject.toml जो आपके पास पहले से है:
supermemory-trainer/
├── .env # your real keys (gitignored)
├── .env.example # placeholders, committed
├── .gitignore
├── .python-version
├── main.py # agent definition, system prompt, REPL loop
├── pyproject.toml
└── tools.py # log_workout and suggest_next_session
tools.py में वे दो मेमोरी-समर्थित टूल्स हैं जिन्हें आप आगे लिखेंगे। log_workout client.add() के ज़रिए Supermemory में वर्कआउट लिखता है। suggest_next_session client.profile() के ज़रिए यूज़र की प्रोफ़ाइल पढ़ता है। main.py दोनों को इम्पोर्ट करता है और एजेंट को वायर करता है।
main.py का अधिकांश भाग OpenAI Agents SDK बॉयलरप्लेट है। सिस्टम प्रॉम्प्ट में एक वाक्य Supermemory का काम करता है: यूज़र के बारे में हर तथ्य टूल कॉल्स के ज़रिए ही वापस आना चाहिए। एजेंट को बताया जाता है कि उसे अपनी कोई मेमोरी नहीं है। यही एक नियम ट्रेनर को मेमोरी-समर्थित बनाता है।
main.py खोलें और इम्पोर्ट्स और सिस्टम प्रॉम्प्ट से शुरू करें:
import asyncio
from agents import Agent, Runner, SQLiteSession
from tools import log_workout, suggest_next_session
SYSTEM_PROMPT = """You are a personal exercise trainer who logs the user's
workouts and recommends what to do next.
You have no memory of the user's history on your own. Every fact about the
user lives in Supermemory and reaches you only through tool calls.
Two rules, no exceptions:
1. Whenever the user reports completing a workout, call log_workout immediately, before responding. Extract the exercise, sets, reps, weight, and any notes from what they said. If a value is missing, ask one short follow-up question instead of guessing. After logging, confirm in one short sentence and stop. Do NOT recommend the next session unless the user asks for one.
2. When the user explicitly asks what to do next (or asks for a recommendation, suggestion, or plan), call suggest_next_session first. Never recommend from your own training data. The tool returns the user's
recent activity, stable preferences, and matching past sessions. Reference those facts directly in your reply.
Keep replies concise (2-4 sentences). Be specific: name the exercise, sets, reps, and weight. Honor any injuries or equipment constraints the tool surfaces.
"""
सिस्टम प्रॉम्प्ट में दोनों नियम मॉडल को Supermemory के माध्यम से रूट करते हैं।
नियम 1 हर बार यूज़र द्वारा वर्कआउट रिपोर्ट करते ही log_workout कॉल अनिवार्य बनाता है, ताकि हर वर्कआउट मेमोरी स्टोर तक पहुँचे। नियम 2 किसी भी सिफारिश से पहले suggest_next_session रीड अनिवार्य बनाता है, ताकि हर सिफारिश Supermemory की जानकारी पर आधारित हो।
इन नियमों को छोड़ दें, और एजेंट अपने ट्रेनिंग डेटा से उत्तर देगा, जिससे मेमोरी लेयर का उद्देश्य ही विफल हो जाता है।
अब इसी फ़ाइल में एजेंट और चैट लूप परिभाषित करें:
def build_agent() -> Agent:
return Agent(
name="Trainer",
instructions=SYSTEM_PROMPT,
tools=[log_workout, suggest_next_session],
model="gpt-5",
)
async def chat() -> None:
agent = build_agent()
session = SQLiteSession(session_id="trainer-cli")
print("Trainer ready. Type a message, or 'exit' to quit.\n")
while True:
try:
message = input("You: ").strip()
except (EOFError, KeyboardInterrupt):
print()
break
if not message:
continue
if message.lower() in {"exit", "quit"}:
break
result = await Runner.run(agent, message, session=session)
print(f"\nTrainer: {result.final_output}\n")
if __name__ == "__main__":
asyncio.run(chat())
उस ब्लॉक में दो पंक्तियाँ उल्लेखनीय हैं। tools=[log_workout, suggest_next_session] दो मेमोरी-समर्थित टूल्स को रजिस्टर करता है। @function_tool डेकोरेटर (tools.py में) SDK को बताता है कि वे कॉल करने योग्य हैं। डेकोरेटर के बिना, निर्माण कॉल सफल होने के बावजूद रनटाइम पर एजेंट के पास कोई टूल नहीं होगा।
SQLiteSession(session_id="trainer-cli") चल रही Python प्रक्रिया के अंदर अल्पकालिक टर्न हिस्ट्री रखती है। Supermemory प्रक्रियाओं के पार दीर्घकालिक यूज़र तथ्यों को रखती है। Python प्रक्रिया को बंद करने से SQLite सत्र गिर जाता है, लेकिन Supermemory डेटा रहता है।
महत्वपूर्ण: main.py को स्क्रिप्ट की तरह चलाएँ, Jupyter सेल में नहीं, क्योंकि Jupyter का इवेंट लूप asyncio.run() से टकराता है। सिंक्रोनस Supermemory() क्लाइंट async टूल फ़ंक्शंस के अंदर इसलिए काम करता है क्योंकि Agents SDK टूल्स को थ्रेड पूल में चलाता है। SDK के बारे में और जानने के लिए देखें OpenAI Agents SDK ट्यूटोरियल।
वर्कआउट-लॉगिंग टूल लिखना
log_workout एजेंट की मेमोरी का write पक्ष है। फ़ंक्शन एजेंट से स्ट्रक्चर्ड आर्ग्युमेंट लेता है: एक्सरसाइज़ का नाम, सेट्स, रेप्स, वज़न, और वैकल्पिक नोट्स। यह उन्हें एक छोटी अंग्रेज़ी वाक्य में बदलता है और client.add() के माध्यम से Supermemory को सौंप देता है। एम्बेड-एंड-एक्सट्रैक्ट पाइपलाइन उसके बाद Supermemory के अंदर चलती है और ट्रेनर से कुछ नहीं माँगती।
tools.py खोलें और इम्पोर्ट्स और एक साझा क्लाइंट से शुरू करें:
from agents import function_tool
from dotenv import load_dotenv
from supermemory import Supermemory
load_dotenv()
USER_ID = "demo_user"
client = Supermemory()
load_dotenv() इम्पोर्ट समय पर चलती है ताकि SUPERMEMORY_API_KEY Supermemory() बनने से पहले एनवायरनमेंट में हो। एनव लोड होने से पहले क्लाइंट बनाएं, तो आपको अनऑथेंटिकेटेड क्लाइंट मिलेगा। पहली कॉल तब उलझाने वाला 401 लौटाती है। इस फ़ाइल के दोनों टूल फ़ंक्शंस वही क्लाइंट और वही USER_ID कॉन्स्टेंट साझा करते हैं।
क्लाइंट के नीचे लॉगिंग टूल जोड़ें:
@function_tool
def log_workout(
exercise: str,
sets: int,
reps: int,
weight: float,
notes: str = "",
) -> str:
"""Log a completed workout to the user's memory.
Args:
exercise: Name of the exercise.
sets: Number of sets performed.
reps: Number of reps per set.
weight: Weight in pounds. Pass 0 for bodyweight or cardio.
notes: Optional notes about the session.
"""
print(f"[log_workout] {exercise=} {sets=} {reps=} {weight=} {notes=}")
content = f"Performed {exercise}: {sets} sets of {reps} reps at {weight} lbs."
if notes:
content += f" Notes: {notes}"
response = client.add(content=content, container_tag=USER_ID)
print(f"[log_workout] -> id={response.id} status={response.status}")
return f"Logged {exercise} ({sets}x{reps} @ {weight} lb)."
@function_tool डॉकस्ट्रिंग वह है जो LLM टूल कॉल करने का फ़ैसला करते समय देखता है। Args: ब्लॉक प्रति-पैरामीटर विवरणों से मैप होता है। दोनों फ़ंक्शन के साथ एजेंट के कॉन्ट्रैक्ट का हिस्सा हैं।
टूल client.add() को JSON नहीं, एक सादा वाक्य भेजता है। Supermemory का प्रोफ़ाइल एक्सट्रैक्टर प्राकृतिक भाषा पढ़ता है और उससे तथ्य निकालता है। तकनीकी रूप से JSON काम करता है, लेकिन एक्सट्रैक्शन क्वॉलिटी गिरती है क्योंकि मॉडल के पास संक्षेपित करने को कोई नैरेटिव नहीं रहता। "Performed bench press: 4 sets of 5 reps at 185.0 lbs" एक्सट्रैक्टर को काम करने के लिए एक साफ़ वाक्य देता है।
दोनों print() कॉल्स हर टूल इनवोकेशन को टर्मिनल पर लिखती हैं: पहले पार्स किए गए आर्ग्युमेंट्स, फिर रिस्पॉन्स।
[log_workout] exercise='bench press' sets=4 reps=5 weight=185.0 notes=''
[log_workout] -> id=xY7AK3qLzBPx5Vd2HnRf1M status=queued
status="queued" मान वही है जो वॉर्म-अप स्क्रिप्ट ने लौटाया था। कच्चा लॉग स्टोर हो गया है, लेकिन client.profile() पाइपलाइन के पूरा होने तक इसे सर्च रिज़ल्ट के रूप में नहीं लौटाएगा। आप आगे एक वेरिफ़िकेशन स्टेप जोड़ेंगे जो इसके स्थिर होने का इंतज़ार करता है।
वर्कआउट-सुझाव टूल लिखना
suggest_next_session रीड पक्ष है, और यहीं स्थिर-और-गतिशील विभाजन का लाभ मिलता है। एक client.profile(container_tag=USER_ID, q=focus) कॉल एक ही राउंड ट्रिप में यूज़र के तीन व्यू लौटाती है।
स्थिर पसंदें profile.static के रूप में, वर्तमान गतिविधि profile.dynamic के रूप में, और सबसे मिलते-जुलते पिछले मेमोरी search_results.results के रूप में वापस आती हैं। टूल का काम इन तीन व्यूज़ को एक ऐसे कॉन्टेक्स्ट ब्लॉक में समतल करना है जिसे एजेंट उद्धृत कर सके।
कुछ वर्कआउट्स के बाद, टूल ऐसा आउटपुट बनाता है:
Recent activity:
- Trains at home instead of a gym
- Performed deadlift: 3 sets of 5 reps at 225.0 lbs
- Performed 5k run in 26 minutes
- Reports no knee pain during bench press
- Performed bench press: 4 sets of 5 reps at 185.0 lbs
Closest matching past entries:
- Trains at home instead of a gym
- Performed deadlift: 3 sets of 5 reps at 225.0 lbs
- Performed bench press: 4 sets of 5 reps at 185.0 lbs
- Performed 5k run in 26 minutes
- Reports no knee pain during bench press
एजेंट उस ब्लॉक को पढ़ता है और यूज़र के वास्तविक इतिहास पर आधारित सिफारिश लिखता है। Supermemory की प्रोफ़ाइल के बिना, आपको वही कॉन्टेक्स्ट खुद बनाना पड़ता। इसका मतलब अलग से सेमांटिक सर्च, अपनी प्रोफ़ाइल स्टोर, और परिणामों का मर्ज करना होता। एक client.profile() कॉल इन तीनों को बदल देता है।
इसे tools.py में log_workout के नीचे जोड़ें:
@function_tool
def suggest_next_session(focus: str) -> str:
"""Fetch the user's training history and preferences for a given focus.
Returns a context string the agent can use to recommend the next session.
The agent is responsible for the actual recommendation. This tool only
surfaces what Supermemory knows about the user.
Args:
focus: What the user wants to train next (e.g. "upper body", "legs",
"cardio", "today"). Drives semantic search against past logs.
"""
print(f"[suggest_next_session] focus={focus!r}")
profile = client.profile(container_tag=USER_ID, q=focus)
static_facts = profile.profile.static
dynamic_facts = profile.profile.dynamic
matches = profile.search_results.results
print(
f"[suggest_next_session] static={len(static_facts)} "
f"dynamic={len(dynamic_facts)} matches={len(matches)}"
)
sections = []
if static_facts:
sections.append("Stable preferences and constraints:")
sections.extend(f"- {fact}" for fact in static_facts)
if dynamic_facts:
sections.append("Recent activity:")
sections.extend(f"- {fact}" for fact in dynamic_facts)
if matches:
sections.append("Closest matching past entries:")
for r in matches[:5]:
sections.append(f"- {r['memory']}")
if not sections:
return (
"No prior training history found for this user. "
"Ask the user about their goals, equipment, and recent training."
)
return "\n".join(sections)
client.profile(container_tag=USER_ID, q=focus) एक ProfileResponse ऑब्जेक्ट लौटाती है। 5 छोटे लॉग्स के बाद, टूल द्वारा पढ़े जाने वाले तीन फ़ील्ड इस तरह दिखते हैं:
profile.profile.static # [] (list[str])
profile.profile.dynamic # ["Performed bench press: 4 sets of 5 reps at 185.0 lbs", ...]
profile.search_results.results # [{"memory": "...", "similarity": 0.631, ...}, ...] (list[dict])
हर सर्च रिज़ल्ट एक Python dict है, Pydantic ऑब्जेक्ट नहीं। टेक्स्ट के लिए r["memory"] और स्कोर के लिए r["similarity"] का उपयोग करें। पूरा dict निम्नलिखित कुंजियाँ रखता है:
-
id -
memory -
rootMemoryId -
metadata -
updatedAt -
version -
similarity -
filepath -
documents
Supermemory के OpenAI Agents SDK इंटीग्रेशन पेज का r.memory or r.chunk स्निपेट supermemory==3.37.0 पर AttributeError उठाता है। ब्रैकेट एक्सेस का उपयोग करें।
static यहाँ खाली है, इसलिए टूल if static_facts: पर ब्रांच करता है। पहले दर्जन लॉग्स के लिए dynamic और search_results ब्रांच ही असली काम करते हैं।
Supermemory एक डिफॉल्ट सिमिलैरिटी थ्रेशहोल्ड भी लागू करती है। कोई तथ्य जिसे आपने एक बार कहा हो, हर क्वेरी पर वापस न भी आए। ऊपर के 5 लॉग्स q="today" पर सभी लौटे, लेकिन अधिक विशिष्ट क्वेरी स्ट्रिंग कम वापस ला सकती है। if matches: गार्ड इसे बिना फ़ेल हुए संभालता है।
सत्र 1 चलाना: वर्कआउट्स लॉग करना
सत्र 1 शुरू करें और कुछ वर्कआउट लॉग करें ताकि Supermemory में बाद में पढ़ने के लिए सामग्री हो। स्क्रिप्ट चलाएँ:
uv run python main.py
बेंच प्रेस, फिर 5k रन, फिर डेडलिफ्ट लॉग करें, साथ में एक पसंद कथन: "I only train at home, no gym." एजेंट हर वर्कआउट पर एक बार log_workout फायर करता है, और टूल की print() पंक्तियाँ हर कॉल को टर्मिनल में दृश्यमान बनाती हैं।

उदाहरण आउटपुट। आपके एजेंट की सटीक शब्दावली अलग होगी क्योंकि मॉडल नॉन-डिटर्मिनिस्टिक है।
तीन status=queued पंक्तियाँ वह क्षण हैं जब Supermemory कार्यभार संभालती है। हर एक Supermemory की ओर एम्बेड-एंड-एक्सट्रैक्ट पाइपलाइन से गुजरते डॉक्यूमेंट से मेल खाती है। ऐसे छोटे टेक्स्ट लॉग्स के लिए, डॉक्यूमेंट ~12 सेकंड में client.profile() के ज़रिए सर्चेबल हो जाता है।
ट्रेनर के कोड में कुछ भी इसका इंतज़ार नहीं करता। एजेंट आगे बढ़ता है, और Supermemory पृष्ठभूमि में काम पूरा करती है।
हर लॉग ठीक एक log_workout कॉल फायर करता है, और एजेंट रुक जाता है। कोई प्रैक्टिव सिफारिश नहीं, कोई अतिरिक्त टूल कॉल नहीं, कोई फॉलो-अप सुझाव नहीं। पहला सिस्टम प्रॉम्प्ट नियम यह काम करता है। नियम के बिना, एजेंट हर लॉग के बाद अगला सत्र सुझाता, जिससे टूल कॉल्स दोगुनी हो जातीं।
सत्र 1 बंद करने के लिए exit टाइप करें। Python प्रक्रिया समाप्त होती है, और SQLiteSession उसके साथ चली जाती है। वर्कआउट लॉग्स और पसंद कथन अब Supermemory में container_tag="demo_user" के तहत रहते हैं, उस स्क्रिप्ट से अलग जिसने उन्हें लिखा था।
रीकॉल वेरिफ़ाई करना और सत्र 2 चलाना
सत्र 2 से पहले, पुष्टि करें कि सत्र 1 के तथ्य क्वेरी किए जा सकते हैं। एक नया Python REPL खोलें या इसे एक छोटी स्क्रिप्ट के रूप में सेव करें:
from dotenv import load_dotenv
from supermemory import Supermemory
load_dotenv()
client = Supermemory()
prof = client.profile(container_tag="demo_user", q="training")
print(f"static ({len(prof.profile.static)}): {prof.profile.static}")
print(f"dynamic ({len(prof.profile.dynamic)}):")
for fact in prof.profile.dynamic:
print(f" - {fact}")
print(f"matches ({len(prof.search_results.results)}):")
for r in prof.search_results.results[:5]:
print(f" - {r['memory']} (similarity={r['similarity']:.3f})")
दो सत्रों के बीच कैप्चर किया गया वास्तविक आउटपुट:
static (0): []
dynamic (5):
- Trains at home instead of a gym
- Performed deadlift: 3 sets of 5 reps at 225.0 lbs
- Performed 5k run in 26 minutes
- Reports no knee pain during bench press
- Performed bench press: 4 sets of 5 reps at 185.0 lbs
matches (5):
- Trains at home instead of a gym (similarity=0.682)
- Performed deadlift: 3 sets of 5 reps at 225.0 lbs (similarity=0.643)
- Performed bench press: 4 sets of 5 reps at 185.0 lbs (similarity=0.631)
- Performed 5k run in 26 minutes (similarity=0.585)
- Reports no knee pain during bench press (similarity=0.585)
देखें कि Supermemory के एक्सट्रैक्टर ने क्या बनाया। यूज़र ने एक बार कहा, "I only train at home, no gym." एक्सट्रैक्टर ने उसे गतिशील तथ्य "Trains at home instead of a gym" में बदला।
बेंच प्रेस लॉग में घुटने में दर्द नहीं होने के बारे में नोट्स फ़ील्ड शामिल थी। एक्सट्रैक्टर ने उस एक लॉग को दो गतिशील तथ्यों में बाँट दिया: एक वर्कआउट के लिए, एक दर्द की अनुपस्थिति के लिए।
चार लॉग पाँच सामान्यीकृत गतिशील तथ्यों में बदले, साथ ही पाँच मिलते-जुलते मेमोरी chunks, जिनके सिमिलैरिटी स्कोर 0.585 और 0.682 के बीच थे। यह स्प्लिटिंग, नॉर्मलाइज़ेशन, या मैचिंग ट्रेनर के कोड में कहीं नहीं चली। यदि dynamic आपके लिए खाली है, 10 सेकंड और प्रतीक्षा करें और स्निपेट दोबारा चलाएँ। प्रोसेसिंग कतार कभी-कभी स्पाइक करती है।
अब एक बिल्कुल नई प्रक्रिया में सत्र 2 शुरू करें:
uv run python main.py
यह एक फ्रेश Python इंटरप्रेटर है। सत्र 1 के साथ कोई साझा मेमोरी नहीं। कोई वॉर्म कैश नहीं। एजेंट जो भी याद रखता है, वह Supermemory से आता है।
एक संदेश भेजें: "आज मेरे वर्कआउट के लिए मुझे क्या करना चाहिए?"

उदाहरण आउटपुट। वही मेमोरी स्टोर, फ्रेश Python प्रक्रिया।
एजेंट suggest_next_session("today") कॉल करता है। टूल static=0 dynamic=5 matches=5 प्रिंट करता है। कैप्चर किए गए रन ने घर पर लोअर-बॉडी सत्र (स्क्वैट्स, लंजेस, स्टेप-अप्स) से उत्तर दिया।
सिफारिश पिछले लॉग्स के अनुरूप थी क्योंकि Supermemory की प्रोफ़ाइल ने एजेंट को बताया कि वे क्या थे। बेंच, डेडलिफ्ट, और 5k अपर-बॉडी या कार्डियो थे, और यूज़र केवल घर पर ट्रेन करता/करती था/थी। दोनों तथ्य उसी client.profile() कॉल से लौटे। आपका रन शब्दों को अलग तरह से रखेगा क्योंकि मॉडल नॉन-डिटर्मिनिस्टिक है, लेकिन रीकॉल पाथ वही रहेगा।
अपने Supermemory एजेंट के लिए अगले कदम
डेमो एक यूज़र, दो टूल्स, और एक CLI है। ट्रेनर का वास्तविक वर्ज़न एजेंट लूप को छुए बिना तीन Supermemory-आकार दिशाओं में फैलता है।
वास्तविक यूज़र के अनुसार मेमोरी स्कोप करें। USER_ID = "demo_user" कॉन्स्टेंट एक व्यक्ति के लिए काम करता है। प्रोडक्शन ऐप्स प्रमाणित यूज़र की ID से टैग निकालते हैं, जैसे container_tag="user_sarah" या container_tag=customer_id। यूज़र्स के बीच मेमोरी अलग रहती है क्योंकि हर रीड टैग वापस पास करती है। tools.py में एक बदलाव, और कोई कोड नहीं हिलता।
और मेमोरी-समर्थित टूल्स जोड़ें। डीलोड वीक, PR ट्रैकिंग, और साप्ताहिक मोबिलिटी प्रॉम्प्ट्स। हर एक और @function_tool फ़ंक्शन है जो writes के लिए client.add() और reads के लिए client.profile() को उसी container_tag के विरुद्ध कॉल करता है। टूल का आकार वही रहता है। केवल एजेंट क्या रिकॉर्ड करता है और क्या पूछता है, वह बदलता है।
Supermemory विफलताओं को संभालें। client.add() और client.profile() को try/except supermemory.APIError में रैप करें ताकि Supermemory की अस्थायी विफलताएँ एजेंट को क्रैश न करें। यदि आपका एजेंट नियंत्रित वातावरण में चलता है, तो प्रति-रिक्वेस्ट टाइमआउट सेट करें।
एजेंट-लूप पक्ष का काम Supermemory से स्वतंत्र है और बाद में बदला जा सकता है। CLI के सामने Telegram, Discord, या Slack रखें, ताकि यूज़र वर्कआउट टेक्स्ट करे और बॉट Runner.run() कॉल करे। या फ्रेमवर्क बदलें। यदि आपका स्टैक पहले से LangChain इंटीग्रेशन पर है तो Supermemory का LangChain एजेंट्स के लिए इंटीग्रेशन है, और मेमोरी कोड नहीं बदलता।
स्थिर-और-गतिशील विभाजन अन्य डोमेन्स में भी फिट बैठता है।
- कस्टमर सपोर्ट एजेंट: स्थिर = ज्ञात समस्याएँ और अकाउंट पसंद, गतिशील = खुले टिकट और हाल के संपर्क।
- कोडिंग एजेंट: स्थिर = पसंदीदा भाषाएँ और फ़्रेमवर्क्स, गतिशील = वर्तमान कार्य और हाल में छुई गई फ़ाइलें।
जब भी यूज़र स्रोत-ए-ट्रुथ हो, यह विभाजन काम करता है।
निष्कर्ष
आपने अभी Python में दो टूल्स और प्रक्रियाओं के पार स्थायी मेमोरी के साथ एक ट्रेनर बनाया। client.add() वर्कआउट्स लिखता है। client.profile() यूज़र को एक कॉल में स्थिर तथ्य, गतिशील तथ्य, और सेमांटिक मैच के रूप में पढ़ता है—सब container_tag द्वारा स्कोप किया हुआ। Supermemory वह chunking, embedding, search, और प्रोफ़ाइल एक्सट्रैक्शन करती है जिसे डेमो को लिखने की ज़रूरत नहीं पड़ी।
इसे RAG के साथ जोड़ें, और वही एजेंट यूज़र और प्रोडक्ट—दोनों के बारे में प्रश्नों का उत्तर देता है। LLM एजेंट्स एक्सप्लेंड व्यापक एजेंट पैटर्न कवर करता है, और Associate AI Engineer for Developers ट्रैक मेमोरी-समर्थित एजेंट्स में और आगे जाता है।
Supermemory FAQs
Supermemory क्या है?
Supermemory एक होस्टेड मेमोरी API है जो AI एजेंट्स के लिए लंबी अवधि का संदर्भ स्टोर, इंडेक्स और रिट्रीव करती है ताकि वे सत्रों के पार यूज़र्स को याद रख सकें।
Supermemory साधारण वेक्टर डेटाबेस से कैसे अलग है?
Supermemory स्टोरेज के ऊपर एम्बेडिंग्स, इंडेक्सिंग, सेमांटिक सर्च, और प्रोफ़ाइल-स्टाइल फ़ैक्ट एक्सट्रैक्शन जोड़ती है, ताकि आपको एक ही API कॉल में उपयोगी मेमोरीज़ मिलें।
क्या Supermemory RAG और यूज़र मेमोरी—दोनों संभाल सकती है?
हाँ, यह फ़ाइलों और URLs पर डॉक्यूमेंट-स्टाइल RAG के साथ-साथ यूज़र-सेंट्रिक मेमोरीज़ को भी सपोर्ट करती है, जिससे वही API प्रोडक्ट नॉलेज और पर्सनल हिस्ट्री—दोनों को पावर कर सके।
क्या मुझे Supermemory के साथ अपनी एम्बेडिंग मॉडल्स मैनेज करने की ज़रूरत है?
नहीं, Supermemory आपके लिए एम्बेडिंग और रिट्रीवल पाइपलाइन चलाती है; आप कच्चा टेक्स्ट या कंटेंट भेजते हैं और बाद में बिना मॉडल या इंडेक्स संभाले उसे क्वेरी करते हैं।
क्या Supermemory को आज़माने के लिए कोई फ्री टियर है?
हाँ, परीक्षण और छोटे प्रोजेक्ट्स के लिए एक फ्री प्लान है, जिसमें मासिक टोकन और क्वेरी लिमिट्स हैं ताकि आप अपग्रेड से पहले इंटीग्रेट और एक्सपेरिमेंट कर सकें।