OpenExp
Memoria de Q-learning para Claude Code. Memoria persistente que aprende qué contexto te ayuda a hacer el trabajo. Los recuerdos que llevan a sesiones productivas (commits, PRs, tests) obtienen automáticamente un rango de recuperación más alto. 16 herramientas MCP, puntuación híbrida BM25 + vector + Q-value,
Documentación
OpenExp
¿Cómo sucedió esto? — un hipocampo para agentes de IA.
Captura trayectorias en bruto. Califica solo cuando la realidad devuelve su veredicto. Construye un corpus etiquetado de decisiones humano-IA vinculadas a resultados concretos.
Inicio Rápido · Cómo Funciona · Pipeline · Publicar · Herramientas MCP · Estado
La Pregunta
Cuando cierras un trato, lanzas una función o pierdes un cliente — ¿cómo sucedió? ¿Qué decisiones, en qué orden, contra qué contexto, sobre qué hipótesis? Los agentes de IA de hoy no pueden responder eso. Siguen habilidades e instrucciones perfectamente, pero no acumulan conocimiento fundamentado sobre cómo llegaron realmente los resultados.
OpenExp captura cada decisión humano-IA como un paso en una trayectoria, vincula esos pasos en recorridos coherentes y califica cada recorrido de forma retroactiva cuando la realidad devuelve su veredicto — un trato se cierra, un sprint se lanza, un pago se acredita. El resultado es un conjunto de datos etiquetado en continuo crecimiento de decisiones vinculadas a resultados, listo para entrenar intuición específica de dominio.
Lo Que No Es
- No es un sistema de memoria Q-learning. Probamos valores Q durante 8 meses. El valor Q medio en 27,000 memorias fue 0.006; el 90% de las memorias nunca recibió señal de recompensa. Eliminado el 2026-04-26.
- No es Mem0 / Zep / Letta. Esas son capas de almacenamiento. El almacenamiento es la parte fácil — la búsqueda semántica por sí sola no te dice qué memoria condujo realmente a un resultado.
- No es un reemplazo para habilidades o CLAUDE.md. Esos dicen cómo hacer algo. OpenExp captura qué sucedió y cómo terminó.
El Núcleo Metodológico: Sin Pre-Etiquetado
No creamos características a mano a nivel de paso (tone: urgent, signal: positive, hypothesis: probable). El pre-etiquetado inyecta los sesgos del etiquetador y corrompe la señal de entrenamiento eventual. Misma higiene que el scoring crediticio: recopila características ricas por solicitante, etiqueta solo el resultado terminal (pagó / no pagó), deja que el modelo aprenda qué predice el reembolso solo a partir de los datos.
Solo los resultados terminales reciben etiquetas:
outcome—closed_won/closed_lost/failed/abandonedgrade—0.0a1.0, estilo escolar
Los pasos se almacenan en bruto. Los autores anotan su propia intención, hipótesis y decisiones ("creía X en este punto", "elegí Y porque Z"). No etiquetan la calidad de la señal de eventos individuales — eso es lo que el modelo eventual aprende.
Analogía casual: los niños en la escuela no reciben anotaciones en cada problema de tarea. Entregan el trabajo, reciben una calificación al final del período y desarrollan intuición a lo largo de cientos de calificaciones.
Inicio Rápido
git clone https://github.com/anthroos/openexp.git
cd openexp
./setup.sh
Eso instala los cuatro hooks en Claude Code, asegura que Qdrant esté activo y registra el servidor MCP.
Si algo ya está sirviendo Qdrant en localhost:6333, el script lo usa y lo deja en paz. De lo contrario, inicia Qdrant en Docker por ti.
Requisitos previos: Python 3.11+, jq y Qdrant — ya sea Docker (el script maneja el contenedor) o un binario nativo de Qdrant que ejecutes tú mismo.
No se requiere clave API para la funcionalidad principal. Los embeddings se ejecutan localmente vía FastEmbed. Una clave API de Anthropic es opcional y solo alimenta el pipeline de dos prompts (anonimizar + extraer experiencia) cuando publicas.
Cómo Funciona
Cuatro hooks se ejecutan automáticamente dentro de Claude Code:
| Hook | Cuándo | Qué |
|---|---|---|
SessionStart | Se abre la sesión | Busca en Qdrant memorias relevantes, inyecta los mejores resultados como contexto |
UserPromptSubmit | Cada mensaje | Recuperación ligera por prompt |
PostToolUse | Después de Write / Edit / Bash | Captura observaciones como JSONL |
SessionEnd | Se cierra la sesión | Ingresa la transcripción en Qdrant; extrae decisiones vía Opus 4.x (async) |
La recuperación clasifica mediante similitud semántica + BM25 + actualidad. Sin números mágicos. Sin componente de scoring Q-value.
El Pipeline
Cuando decides publicar una experiencia — convertir una trayectoria terminal real en un artefacto compartible — dos prompts hacen el trabajo:
-
prompts/anonymize.md— toma los datos de trayectoria en bruto (transcripciones, correos, decisiones) y produce una trayectoria YAML anonimizada. La PII se reemplaza por tokens de categoría (<counterparty_cto>,<regulated_industry>,<value:10k-100k>,<local_currency>,day_+5) mientras se preservan las características estructurales. El prompt impone una regla de identificación inversa: los tokens lo suficientemente específicos para identificar a una contraparte en la jurisdicción deben generalizarse un nivel hacia arriba antes de la publicación. -
prompts/extract_experience.md— lee la trayectoria anonimizada más la etiqueta de resultado terminal y produce unmeta.yamlsolo de hechos (id, etiqueta de resultado, duración, número de pasos, tokens de categoría, licencia). Se niega deliberadamente a escribirapplies_when,searchable_summaryo una razón de calificación — esas son interpretaciones y pertenecen al Claude del lector en el momento de uso, no al publicador en el momento de publicación.
Ejecutas ambos prompts dentro de tu propio Claude Code, contra tu propio Qdrant. Nada se envía a un servidor central.
Publicar una Experiencia
Una experiencia publicada son cuatro archivos en un directorio con nombre UUID (esquema v3, 2026-04-27):
experiences/<uuid>/
├── meta.yaml # facts only: id, outcome label, duration, category tokens, license
├── trajectory.anonymized.yaml # raw ordered timeline of N steps, anonymized
├── README.md # human-readable face for the marketplace
└── SKILL.md # Claude entry point — read first when skill is invoked
Forma de meta.yaml (resumida de la semilla d49e0997):
pack:
id: d49e0997-8455-4d3c-90ca-d6cf54d0f662
author: ivan-pasichnyk
license: MIT
schema_version: 3
outcome:
label: closed_won # fact, not interpretation
closed_at: day_+57
duration_days: 57
step_count: 26
category_tokens: # what appears in the trajectory
- <counterparty_cto>
- <counterparty_pm>
- <regulated_industry>
- <e_signing_platform_local>
# ...
Sin applies_when, sin searchable_summary, sin grade_reason. Los esquemas anteriores (v2) incorporaban la lectura del publicador sobre la línea de tiempo en el artefacto — la interpretación de un Claude, congelada. El esquema v3 invierte eso: el paquete se envía en bruto, y el Claude del lector deriva la coincidencia sobre la marcha contra la situación real del lector. Diferentes lectores, diferentes contextos, diferentes inferencias de la misma trayectoria. Ver CHANGELOG.md para la justificación completa de la transición v2 → v3.
Instalar como habilidad de Claude Code
Una experiencia publicada es una habilidad de Claude Code con espacio de nombres:
openexp:<author-handle>:<experience-slug>
Coloca el paquete en ~/.claude/skills/openexp:<author>:<slug>/ (renombra el directorio a la forma con espacio de nombres de habilidad al copiar). Claude Code lo descubre automáticamente en la próxima sesión.
# Install the seed pack as a skill
cp -r ~/openexp/experiences/d49e0997 \
~/.claude/skills/openexp:ivan-pasichnyk:inbound-acquisition-with-free-pilot
Dos capas de identidad:
- La identidad del autor es pública — firma el paquete, como la autoría en un artículo de investigación.
- La identidad de la contraparte permanece anonimizada — el nombre de la habilidad revela quién creó el paquete, nunca con quién estaban tratando.
SKILL.md dentro del paquete es el punto de entrada — le dice al Claude del usuario cuándo invocar, cómo usar la trayectoria y qué no hacer (sin fabricación, sin desanonimización, atribución requerida).
Ver docs/skill-architecture.md para la convención de nombres completa, el flujo de instalación y la justificación de diseño.
El directorio experiences/ en este repositorio es la semilla de un eventual mercado. Los paquetes publicados se listan en CATALOG.md. El formato de publicación funciona; las semillas se acumularán. Un directorio de experiencias instalables es la superficie eventual, no un producto construido hoy.
Herramientas MCP
Cinco herramientas enfocadas (modelo hipocampo — escribe todo, recupera selectivamente):
| Herramienta | Descripción |
|---|---|
search_memory | Búsqueda híbrida: similitud semántica + BM25 + actualidad |
add_memory | Almacena una memoria. Soporta client_id para etiquetado de entidades |
log_prediction | Registra una predicción basada en paquete. Requerido cuando un paquete de experiencia instalado cita un relative_day específico como base para una recomendación de acción. |
log_outcome | Resuelve una predicción con la señal observada — registro libre de interpretación. |
memory_stats | Estadísticas de colección: conteos de puntos por fuente/tipo, conteo de sesiones |
Instrumentación de predicción / resultado
Las predicciones basadas en paquete son cómo el sistema aprende si un paquete de experiencia publicado realmente mueve resultados del mundo real. Sin pares predicción/resultado, el valor del paquete no puede medirse contra ninguna línea base, y cualquier experimento futuro (votación entre paquetes, recuperación por embeddings, nuevos paquetes de nuevos autores) es infalsificable.
El criterio de activación es preciso. El registro se dispara solo cuando el asistente cita el relative_day específico de un paquete como la razón para una recomendación de acción. Sin cita del día → sin registro. Descripción de una situación sin recomendación → sin registro. Esto mantiene el conjunto de datos honesto y el costo bajo.
log_prediction (nueva ruta, schema_version 2)
| Campo | Requerido | Propósito |
|---|---|---|
pack_id | sí | El slug del paquete |
pack_author | sí | Identificador del autor |
cited_step | sí | El day +N exacto citado |
case_id | sí | Referencia externa (lead_id de CRM, ID de ticket, ID de trato — cadena opaca) |
applied_action | sí | Qué se recomendó HACER |
expected_signal | sí | Resolución observable |
expected_window_days | sí | Plazo en días para log_outcome |
prevented_action | opcional | Predicción de espacio negativo — qué se recomendó NO hacer (a menudo la mitad de mayor valor) |
notes | opcional | Contexto de texto libre |
log_outcome (nueva ruta, schema_version 2)
| Campo | Requerido | Propósito |
|---|---|---|
prediction_id | sí | ID devuelto de log_prediction |
actual_signal | sí | Qué se observó — hecho en bruto, sin interpretación |
days_to_resolve | sí | Cuántos días desde la predicción hasta la resolución |
notes | opcional | Texto libre, p. ej., eventos inesperados |
Lo que deliberadamente NO está en el esquema: confidence (la confianza del lado de Claude no está calibrada hasta ≥30 puntos de datos de resultado), alternative_action_if_no_pack y predicted_outcome_alternative (el mismo Claude que escribe la predicción inventaría el contrafactual, sesgado hacia "el paquete ayudó" — la ablación real necesita una ejecución sin paquete, pista separada).
Compatibilidad hacia atrás. El esquema heredado (prediction, confidence, strategic_value, memory_ids_used) aún es aceptado por ambas herramientas y se registra como datos. A partir del 2026-07-03 nada actualiza valores Q — el motor Q está completamente eliminado. Las entradas de nueva ruta se marcan schema_version: 2 en la fila JSONL.
CLI
openexp search -q "stalled enterprise procurement" -n 5
openexp ingest # ingest pending transcripts into Qdrant
openexp stats # collection + prediction stats
Configuración
Variables de entorno (.env):
| Variable | Predeterminado | Descripción |
|---|---|---|
QDRANT_HOST | localhost | Host del servidor Qdrant |
QDRANT_PORT | 6333 | Puerto del servidor Qdrant |
OPENEXP_COLLECTION | openexp_memories | Nombre de la colección Qdrant |
OPENEXP_DATA_DIR | ~/.openexp/data | Predicciones, registros de recuperación |
OPENEXP_OBSERVATIONS_DIR | ~/.openexp/observations | Salida de hooks |
OPENEXP_SESSIONS_DIR | ~/.openexp/sessions | Resúmenes de sesión |
OPENEXP_EMBEDDING_MODEL | BAAI/bge-small-en-v1.5 | Modelo de embeddings (local, gratuito) |
ANTHROPIC_API_KEY | (opcional) | Requerido solo para el pipeline de publicación |
Estado
Piloto. Congelación de arquitectura aterrizó el 2026-04-26. Primera semilla de experiencia publicada: experiences/d49e0997/ — una adquisición entrante de 57 días que cerró con calificación 1.0 (evaluación del propio autor), anonimizada a tokens de categoría.
Honestos sobre lo que no está hecho:
- La interfaz del mercado es solo un directorio en este repositorio. Sin superficie web aún.
- La anonimización es conservadora pero no infalible para lectores con conocimiento profundo del dominio.
- El esquema puede iterar — los campos de anotación del autor (
author_intent,author_hypothesis,author_decision) son una adición probable a corto plazo. - El modelo de ML eventual entrenado en este corpus no existe todavía. ≥30 trayectorias calificadas primero.
Ver docs/redesign-2026-04-26.md para la congelación completa de arquitectura y docs/claude-design-brief.md para el encuadre del producto v2.
Contribuir
Este proyecto está en etapas tempranas. Consulta CONTRIBUTING.md para la configuración y el flujo de trabajo.
La contribución más útil en este momento es publicar una experiencia real. Toma una de tus propias trayectorias cerradas, pásala por prompts/anonymize.md y prompts/extract_experience.md, y abre un PR agregando un nuevo directorio bajo experiences/.
Licencia
MIT © Ivan Pasichnyk