Skip to main content

Construire un agent LLM persistant

Guide étape par étape pour construire un agent LLM qui se souvient entre les sessions en utilisant Synapse.


Vue d'ensemble

Ce guide vous accompagne dans la construction d'un agent LLM qui persiste le contexte entre les sessions via Synapse. À la fin, votre agent pourra :

  • Rappeler le contexte passé au début de la session
  • Stocker les nouveaux apprentissages au fur et à mesure
  • Suivre des tâches multi-étapes entre les sessions
  • Communiquer avec les humains via chat asynchrone

Architecture

┌──────────────┐   recall/store   ┌──────────┐
│  LLM Agent   │ ◀──────────────▶ │ Synapse  │
│ (your code)  │                  │   API    │
└──────────────┘                  └──────────┘
       │
       │ poll/reply
       ▼
┌──────────────┐
│    Human     │ (browser or chat UI)
└──────────────┘

Étape 1 : configurer la Mind Key

# S'inscrire et obtenir un JWT
JWT=$(curl -s -X POST https://synapse.schaefer.zone/register \
  -H "Content-Type: application/json" \
  -d '{"email":"agent@example.com","password":"secret"}' | jq -r .jwt)

# Créer un mind et obtenir une Mind Key
MIND_KEY=$(curl -s -X POST https://synapse.schaefer.zone/minds \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{"name":"persistent-agent","description":"My persistent agent"}' | jq -r .mind_key)

echo "Save this: $MIND_KEY"

Étape 2 : protocole de début de session

Au début de chaque session, rappeler toutes les mémoires :

import os
import requests

MIND_KEY = os.environ["SYNAPSE_MIND_KEY"]
URL = "https://synapse.schaefer.zone"

def session_start():
    """Call this at the start of every session."""
    # 1. Rappeler toutes les mémoires
    r = requests.get(
        f"{URL}/memory/recall",
        headers={"Authorization": f"Bearer {MIND_KEY}"}
    )
    memories = r.text  # résumé en texte brut
    
    # 2. Vérifier les messages chat non lus
    r = requests.get(
        f"{URL}/chat/poll",
        headers={"Authorization": f"Bearer {MIND_KEY}"}
    )
    messages = r.json().get("messages", [])
    
    # 3. Vérifier les tâches en cours
    r = requests.get(
        f"{URL}/mind/tasks?status=in_progress",
        headers={"Authorization": f"Bearer {MIND_KEY}"}
    )
    tasks = r.json().get("tasks", [])
    
    return {
        "memories": memories,
        "unread_messages": messages,
        "active_tasks": tasks,
    }

context = session_start()
# Construire le prompt système avec ce contexte

Étape 3 : stocker les nouveaux apprentissages

Chaque fois que l'agent apprend quelque chose qui mérite d'être retenu :

def remember(category, key, content, tags=None, priority="normal"):
    """Store a memory."""
    requests.post(
        f"{URL}/memory",
        headers={
            "Authorization": f"Bearer {MIND_KEY}",
            "Content-Type": "application/json",
        },
        json={
            "category": category,
            "key": key,
            "content": content,
            "tags": tags or [],
            "priority": priority,
        }
    )

# Exemples
remember("identity", "user_name", "User is Michael Schäfer", 
         tags=["person"], priority="critical")
remember("preference", "communication_style", 
         "User prefers concise technical responses",
         tags=["communication"])
remember("project", "current_project", 
         "Building Synapse v1.6.0 with docs system",
         tags=["synapse", "docs"], priority="high")
remember("mistake", "npm_version_bump", 
         "Always bump package.json version after changes",
         tags=["npm", "ci"], priority="high")

Étape 4 : gestion des tâches

Suivez le travail multi-étapes entre les sessions :

def create_task(title, description="", priority="normal"):
    r = requests.post(
        f"{URL}/mind/task",
        headers={"Authorization": f"Bearer {MIND_KEY}",
                 "Content-Type": "application/json"},
        json={"title": title, "description": description, "priority": priority}
    )
    return r.json()["id"]

def update_task(task_id, status=None, description=None):
    payload = {}
    if status: payload["status"] = status
    if description: payload["description"] = description
    requests.put(
        f"{URL}/mind/task/{task_id}",
        headers={"Authorization": f"Bearer {MIND_KEY}",
                 "Content-Type": "application/json"},
        json=payload
    )

# Workflow multi-session
task_id = create_task("Deploy v1.6.0", "Push docs system to production", "high")
update_task(task_id, status="in_progress")
# ... travail sur plusieurs sessions ...
update_task(task_id, status="done")

Étape 5 : chat asynchrone avec les humains

Pollinez les messages entre les appels d'outils :

import time

def poll_messages():
    r = requests.get(
        f"{URL}/chat/poll",
        headers={"Authorization": f"Bearer {MIND_KEY}"}
    )
    return r.json().get("messages", [])

def reply(content):
    requests.post(
        f"{URL}/chat/reply",
        headers={"Authorization": f"Bearer {MIND_KEY}",
                 "Content-Type": "application/json"},
        json={"content": content}
    )

# Boucle principale
while working:
    # Polliner les messages humains
    for msg in poll_messages():
        print(f"Human: {msg['content']}")
        reply(f"Got it: {msg['content']}. Working on it.")
    
    # Faire une unité de travail
    do_work()
    
    time.sleep(30)  # ne pas polliner trop fréquemment

Étape 6 : protocole de fin de session

À la fin de la session, stocker le contexte final :

def session_end():
    """Call this before terminating the session."""
    # Stocker ce que nous avons accompli
    remember("context", "last_session_summary",
             f"Session ended at {time.now()}. Accomplished: ...",
             tags=["session"], priority="normal")
    
    # Mettre à jour les statuts de tâche
    for task in get_active_tasks():
        if task_in_progress(task):
            update_task(task["id"], description=f"In progress: {current_step}")

session_end()

Schéma complet

class PersistentAgent:
    def __init__(self):
        self.mind_key = os.environ["SYNAPSE_MIND_KEY"]
        self.url = "https://synapse.schaefer.zone"
    
    def run(self):
        # 1. Rappeler le contexte
        context = self.session_start()
        
        # 2. Traiter les messages non lus
        for msg in context["unread_messages"]:
            self.handle_message(msg)
        
        # 3. Reprendre les tâches actives
        for task in context["active_tasks"]:
            self.continue_task(task)
        
        # 4. Faire du nouveau travail
        self.do_work()
        
        # 5. Persister l'état
        self.session_end()

Bonnes pratiques

Prochaines étapes