Learn agent skills from past sessions to improve over time
This guide walks through connecting an agent to a learning space so it automatically learns from task outcomes.Scenario: You have a deploy-assistant agent. You want it to remember what worked and what didn’t across sessions.
1
Create a learning space
Copy
import osfrom acontext import AcontextClientclient = AcontextClient( api_key=os.getenv("ACONTEXT_API_KEY"),)space = client.learning_spaces.create( user="alice@example.com", meta={"domain": "deployments"},)# Two default skills (daily-logs, user-general-facts) are created automatically
2
Create a session and attach it to the space
Create a session, then immediately call .learn() to associate it with the learning space. This must happen before the agent runs — when tasks complete during the session, Acontext automatically picks them up for learning.
Copy
session = client.sessions.create(user="alice@example.com")# Associate with the learning space right awayresult = client.learning_spaces.learn(space.id, session_id=session.id)print(f"Status: {result.status}") # "pending"# Now run your agent with this session...
A session can only belong to one learning space. Attempting to learn the same session in another space returns a 409 Conflict error.
3
Use the session as usual
Insert messages exactly as you normally would — nothing changes in your agent loop. Acontext extracts tasks from the conversation and learns from them in the background.
Copy
from openai import OpenAIllm = OpenAI()messages = [{"role": "user", "content": "Deploy API v2 to staging"}]response = llm.chat.completions.create(model="gpt-4o", messages=messages)# Store both user and assistant messagesclient.sessions.store_message(session.id, blob=messages[0])client.sessions.store_message(session.id, blob=response.choices[0].message)
4
Tasks complete → learning happens
As the agent runs, every task that finishes (success or failure) is automatically sent to the learning pipeline. No extra API call needed.Track progress:
Copy
sessions = client.learning_spaces.list_sessions(space.id)for s in sessions: print(f"Session {s.session_id}: {s.status}") # pending → running → completed
5
Inspect what was learned
Read the skills to see what the agent recorded:
Copy
skills = client.learning_spaces.list_skills(space.id)for skill in skills: print(f"{skill.name}: {skill.description}") # Read a specific file content = client.skills.get_file(skill_id=skill.id, file_path="SKILL.md") print(content.content.raw)
Under the hood: Acontext first distills each task outcome into a structured summary, then an AI agent decides which skill files to update or create. Each learning space is processed sequentially to avoid conflicts.
Every learning space starts with two built-in skills:
Skill
What it captures
daily-logs
Daily activity summaries — one file per day
user-general-facts
User preferences and facts — one file per topic
Example: daily-logs output
Copy
# 2025-06-15## [14:30] Task: Deploy API v2 to staging- **Outcome**: success- **Summary**: Blue-green deploy completed, zero downtime- **Key Decisions**: Ran DB migration before switching traffic- **Learnings**: Set health-check timeout to 30s, not 10s## [16:00] Task: Roll back staging after test failure- **Outcome**: failed- **Summary**: Rollback script timed out on large DB- **Key Decisions**: Attempted manual rollback- **Learnings**: Add rollback timeout flag, pre-test with smaller dataset
Example: user-general-facts output
Copy
# Coding Preferences- Prefers Python 3.11+ with type hints- Uses pytest, not unittest- Wants concise docstrings# Deploy Preferences- Always use blue-green deployments- Run DB migrations before switching traffic- Health-check timeout should be 30s minimum
You can include your own skills alongside the defaults. The learner will update your custom skills too — as long as they have a valid SKILL.md with instructions.
Copy
# Upload a skill ZIP, then include itskill = client.skills.create(file=FileUpload(...))client.learning_spaces.include_skill(space.id, skill_id=skill.id)# List all skills in the spaceskills = client.learning_spaces.list_skills(space.id)for skill in skills: print(f" {skill.name}: {skill.description}")# Remove a skill (idempotent)client.learning_spaces.exclude_skill(space.id, skill_id="skill-uuid")
See Agent Skills for the SKILL.md format and ZIP structure.
# List all spacesspaces = client.learning_spaces.list(limit=10)# Filter by userspaces = client.learning_spaces.list(user="alice@example.com")# Filter by meta tagsspaces = client.learning_spaces.list( filter_by_meta={"domain": "deployments"},)# Paginateif spaces.has_more: next_page = client.learning_spaces.list(cursor=spaces.next_cursor)# Update metaupdated = client.learning_spaces.update( space.id, meta={"version": "2.0"},)# Delete (skills and sessions are NOT deleted)client.learning_spaces.delete(space.id)