JamJet
El runtime nativo para agentes: duradero, componible y diseñado para producción.
jamjet.dev · Inicio rápido · Conceptos · Referencia de API · Ejemplos · Blog · Discord

JamJet es un runtime nativo para agentes, centrado en el rendimiento, diseñado para agentes de IA. No es otro envoltorio de prompts o un SDK ligero para agentes; es un sustrato de orquestación de grado de producción para agentes que necesitan funcionar, no solo mostrar demos.
El núcleo del runtime es Rust + Tokio para la programación, el estado y la concurrencia. La superficie de creación es Python, Java, Go (planificado) o YAML. Todos se compilan al mismo grafo IR y se ejecutan en el mismo motor.
¿Por qué JamJet?
Problema | Respuesta de JamJet |
Las ejecuciones de agentes pierden el estado al fallar | Ejecución de grafo duradera — basada en eventos, reanudación segura ante fallos |
No hay forma de pausar para aprobación humana | Human-in-the-loop como primitiva de flujo de trabajo de primer nivel |
Agentes aislados en su propio framework | MCP nativo + A2A — interoperabilidad con cualquier agente, cualquier framework |
Orquestación lenta en Python a escala | Núcleo en Rust — sin GIL, paralelismo asíncrono real |
Observabilidad débil, sin repetición | Línea de tiempo completa de eventos, trazas OTel GenAI, repetición desde cualquier punto de control |
Sin identidad de agente estándar | Tarjetas de Agente — cada agente es direccionable y descubrible |
Enrutamiento de agentes codificado | Nodo Coordinador — enrutamiento dinámico con puntuación estructurada + desempate por LLM |
No se pueden usar agentes como herramientas | Agente-como-Herramienta — envuelve cualquier agente como una herramienta invocable (síncrona, streaming, conversacional) |
Sin gobernanza o barreras de seguridad | Motor de políticas — bloqueo de herramientas, aprobaciones, cumplimiento de autonomía, registro de auditoría |
Agentes con acceso sin control | Delegación OAuth — intercambio de tokens RFC 8693, reducción de alcance, alcance por paso |
Fuga de PII en los registros | Gobernanza de datos — redacción de PII (enmascarar/hash/eliminar), políticas de retención, purga automática |
Sin aislamiento de inquilinos | Multi-inquilino — particionamiento a nivel de fila, estado con alcance de inquilino, registros de auditoría aislados |
Bloqueado en un solo lenguaje | SDKs políglotas — Python, Java (JDK 21), Go (planificado), YAML — mismo IR, mismo runtime |
No se puede ejecutar sin un servidor | Ejecución en proceso — |
Inicio rápido
Requisitos: Python 3.11+
El camino más rápido — Python puro, sin servidor
pip install jamjetfrom jamjet import task, tool
@tool
async def web_search(query: str) -> str:
return f"Search results for: {query}"
@task(model="claude-haiku-4-5-20251001", tools=[web_search])
async def research(question: str) -> str:
"""You are a research assistant. Search first, then summarize clearly."""
result = await research("What is JamJet?")
print(result)Sin servidor. Sin configuración. Sin YAML. Solo pip install y ejecuta.
Camino de runtime completo — ejecución duradera
pip install jamjet
jamjet init my-first-agent
cd my-first-agent
jamjet devEn otra terminal:
jamjet run workflow.yaml --input '{"query": "What is JamJet?"}'→ Guía completa de inicio rápido
Hola Mundo
YAML
# workflow.yaml
workflow:
id: hello-agent
version: 0.1.0
state_schema:
query: str
answer: str
start: think
nodes:
think:
type: model
model: claude-haiku-4-5-20251001
prompt: "Answer clearly and concisely: {{ state.query }}"
output_key: answer
next: end
end:
type: endjamjet validate workflow.yaml
jamjet run workflow.yaml --input '{"query": "What is JamJet?"}'Python — @task (el más simple)
from jamjet import task, tool
@tool
async def web_search(query: str) -> str:
return f"Search results for: {query}"
@task(model="claude-haiku-4-5-20251001", tools=[web_search])
async def research(question: str) -> str:
"""You are a research assistant. Search first, then summarize clearly."""
result = await research("What is JamJet?")El docstring se convierte en la instrucción. La firma de la función es el contrato. Eso es todo.
Python — Agent
from jamjet import Agent, tool
@tool
async def web_search(query: str) -> str:
return f"Search results for: {query}"
agent = Agent(
"researcher",
model="claude-haiku-4-5-20251001",
tools=[web_search],
instructions="You are a research assistant. Search first, then summarize.",
)
result = await agent.run("What is JamJet?")
print(result)Python — Workflow (control total)
from jamjet import Workflow, tool
from pydantic import BaseModel
@tool
async def web_search(query: str) -> str:
return f"Search results for: {query}"
workflow = Workflow("research")
@workflow.state
class State(BaseModel):
query: str
answer: str | None = None
@workflow.step
async def search(state: State) -> State:
result = await web_search(query=state.query)
return state.model_copy(update={"answer": result})Los tres niveles se compilan al mismo IR y se ejecutan en el mismo runtime duradero de Rust.
Rendimiento
La compilación IR de JamJet es 88 veces más rápida que la compilación de grafos de LangGraph:
Operación | JamJet | LangGraph |
Compilación / construcción de grafo | ~0.006 ms | ~0.529 ms |
Invocación en proceso | ~0.015 ms | ~1.458 ms |
Medido con Python 3.11, flujos de trabajo de una sola herramienta. JamJet compila un diccionario IR ligero; LangGraph construye un grafo NetworkX.
Llamada a herramienta MCP
nodes:
search:
type: tool
server: brave-search # configured in jamjet.toml
tool: web_search
arguments:
query: "{{ state.query }}"
count: 10
output_key: results
next: summarizeDelegación A2A
nodes:
delegate:
type: a2a_task
agent_url: "https://agents.example.com/research-agent"
input:
query: "{{ state.query }}"
output_key: research
next: endEvaluación con auto-mejora
nodes:
check:
type: eval
scorers:
- type: llm_judge
rubric: "Is the answer accurate and complete?"
min_score: 4
on_fail: retry_with_feedback # injects feedback into next model call
max_retries: 2
next: endCoordinador — enrutamiento dinámico de agentes
from jamjet.coordinator import DefaultCoordinatorStrategy
strategy = DefaultCoordinatorStrategy(registry=my_registry)
# Discover agents by skill, score them, route to the best fit
candidates, _ = await strategy.discover(
task="Analyze quarterly revenue data",
required_skills=["data-analysis", "finance"],
trust_domain="internal",
)
rankings, spread = await strategy.score(task, candidates, weights={})
decision = await strategy.decide(task, rankings, threshold=0.1)
# decision.selected_uri → "jamjet://org/finance-analyst"Agente-como-Herramienta — envuelve agentes como herramientas invocables
from jamjet.agent_tool import agent_tool
# Sync: quick, stateless
classifier = agent_tool(agent="jamjet://org/classifier", mode="sync",
description="Classifies documents by topic")
# Streaming: long-running with early termination on budget
researcher = agent_tool(agent="jamjet://org/researcher", mode="streaming",
description="Deep research with progress", budget={"max_cost_usd": 2.00})
# Conversational: multi-turn iterative refinement
reviewer = agent_tool(agent="jamjet://org/reviewer", mode="conversational",
description="Peer review with feedback", max_turns=5)Auto-enrutamiento — el compilador inserta el Coordinador automáticamente
from jamjet.workflow.graph import WorkflowGraph
graph = WorkflowGraph("pipeline")
graph.add_agent_tool("process", agent="auto", mode="sync", output_key="result")
# ↑ "auto" expands at compile time into: Coordinator → AgentTool
ir = graph.compile()
# IR now has 2 nodes: _coordinator_process → processPatrones de diseño agéntico
JamJet admite los seis patrones principales de orquestación multi-agente. Aquí tienes cuándo usar cada uno:
Patrón | Primitiva de JamJet | Cuándo usar | Ejemplo |
Agente único |
| Prototipos simples, tareas de propósito único | Chatbot, clasificador |
Pipeline secuencial |
| Pasos ordenados donde cada uno depende del anterior | ETL, procesamiento de documentos |
Fan-Out paralelo |
| Tareas independientes que pueden ejecutarse simultáneamente | Investigación multi-fuente, clasificación por lotes |
Bucle y Crítico |
| Tareas críticas de calidad que necesitan refinamiento iterativo | Revisión de código, generación de contenido |
Coordinador (Enrutamiento dinámico) |
| Enrutar al mejor agente en tiempo de ejecución según capacidad, costo, latencia | Enrutamiento de tickets de soporte, delegación de tareas |
Agente-como-Herramienta | Envoltorio | Un agente necesita llamar a otro como una función | Orquestador invocando especialistas |
Elegir el patrón correcto
Is it a single task?
→ Single Agent
Does order matter?
→ Sequential Pipeline
Can tasks run independently?
→ Parallel Fan-Out
Does output need quality checks?
→ Loop & Critic
Do you need to pick the best agent at runtime?
→ Coordinator
Does one agent need to invoke another?
→ Agent-as-ToolCoordinador vs enrutamiento estático
Estático ( | Dinámico ( | |
Candidatos | Declarados en YAML | Descubiertos del registro en tiempo de ejecución |
Selección | Reglas basadas en expresiones | Puntuación estructurada + desempate opcional por LLM |
Cuando los agentes cambian | Reimplementar flujo de trabajo | Automático — nuevos agentes descubiertos |
Observabilidad | Rama tomada registrada | Desglose completo de puntuación + razonamiento en el registro de eventos |
Mejor para | Rutas fijas y conocidas | Entornos dinámicos, multi-inquilino, investigación |
Cómo se compara JamJet
A fecha de marzo de 2026. Todos los frameworks evolucionan — consulta sus documentos para obtener lo último.
Capacidad | JamJet | Google ADK | LangChain | AutoGen | CrewAI |
Configuración simple de agente | ✅ 3 líneas ( | ✅ 5 líneas | 6+ líneas | 10+ líneas | 8+ líneas |
Ejecución en proceso | ✅ | ✅ nativo | ✅ nativo | ✅ nativo | ✅ nativo |
Ejecución duradera | ✅ basada en eventos, segura ante fallos | ❌ efímero | ❌ efímero | ❌ efímero | ❌ efímero |
Enrutamiento dinámico de agentes | ✅ Coordinador con puntuación + LLM | ✅ | ❌ | ❌ | ❌ |
Agente-como-Herramienta | ✅ síncrono, streaming, conversacional | ✅ | ❌ | ❌ | ❌ |
Human-in-the-loop | ✅ primitiva de primer nivel | 🟡 callbacks | 🟡 callbacks | 🟡 conversacional | 🟡 manual |
Soporte MCP | ✅ cliente + servidor | ✅ cliente + servidor | 🟡 solo cliente | 🟡 solo cliente | 🟡 solo cliente |
Protocolo A2A | ✅ cliente + servidor | 🟡 solo cliente | ❌ | ❌ | ❌ |
Evaluación integrada | ✅ juez LLM, aserciones, costo | ✅ 8 criterios integrados | ❌ | ❌ | ❌ |
Observabilidad integrada | ✅ OTel GenAI, repetición de eventos | ✅ Cloud Trace | 🟡 LangSmith (externo) | ❌ | ❌ |
Identidad de agente | ✅ Tarjetas de Agente, descubrimiento A2A | ✅ Tarjetas de Agente | ❌ | ❌ | ❌ |
Política y gobernanza | ✅ motor de políticas, registro de auditoría | 🟡 plugin Model Armor | ❌ | ❌ | ❌ |
Aislamiento multi-inquilino | ✅ particionamiento a nivel de fila | ❌ | ❌ | ❌ | ❌ |
Redacción de PII | ✅ enmascarar/hash/eliminar, retención | 🟡 plugin | ❌ | ❌ | ❌ |
Independencia de modelo | ✅ cualquier proveedor de modelos | 🟡 Gemini-first (escape LiteLLM) | ✅ cualquiera | ✅ cualquiera | ✅ cualquiera |
Complejidad progresiva | ✅ | 🟡 código o YAML | ❌ API única | ❌ | ❌ |
Despliegue gestionado | 📋 Planificado | ✅ Vertex AI Agent Engine | ❌ | ❌ | ❌ |
Lenguaje de runtime | Núcleo Rust + Python/Java/Go | Python/TS/Go/Java | Python | Python | Python |
Mejor para | Sistemas multi-agente de producción | Agentes de IA de Google Cloud | Prototipado rápido | Agentes conversacionales | Equipos basados en roles |
Memoria — Engram
JamJet viene con Engram, una capa de memoria duradera para agentes: grafo de conocimiento temporal, recuperación híbrida, motor de consolidación, todo respaldado por un único archivo SQLite. Engram se ejecuta como una biblioteca Rust integrada o como un servidor MCP/REST independiente, y es consumible desde Python, Java y Spring Boot.
Agnóstico al proveedor. El mismo binario de Engram habla con Ollama (local, gratuito), cualquier endpoint compatible con OpenAI (OpenAI, Azure, Groq, Together, Mistral, DeepSeek, Perplexity, OpenRouter, vLLM, LM Studio, …), Anthropic Claude, Google Gemini, o un shell-out de command para cualquier otra cosa — elige uno con ENGRAM_LLM_PROVIDER=…, sin recompilar.
Forma | Paquete | Cuándo usar |
Biblioteca Rust |
| Integrar memoria directamente en una aplicación Rust |
Binario independiente |
| Clientes MCP (Claude Desktop, Cursor), clientes REST agnósticos al lenguaje, configuraciones sin código |
Cliente Python |
| Agentes de Python hablando con |
Cliente Java |
| Agentes JVM hablando con |
Starter Spring Boot |
|
|
# Try it with Claude Desktop in 30 seconds (uses local Ollama by default)
docker run --rm -i \
-v engram-data:/data \
ghcr.io/jamjet-labs/engram-server:0.3.2
# Or point at Groq instead — same binary, no rebuild
docker run --rm -i \
-e ENGRAM_LLM_PROVIDER=openai-compatible \
-e ENGRAM_OPENAI_BASE_URL=https://api.groq.com/openai/v1 \
-e OPENAI_API_KEY=gsk_... \
-v engram-data:/data \
ghcr.io/jamjet-labs/engram-server:0.3.2Siete herramientas MCP expuestas por el servidor: memory_add, memory_recall, memory_context, memory_search, memory_forget, memory_stats, memory_consolidate. Documentación completa en runtime/engram-server/README.md. Para ver cómo se compara Engram con Mem0, Zep, Spring AI ChatMemory, LangChain4j, Koog, Google ADK Memory Bank y Embabel, consulta java-ai-memory.dev.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jamjet-labs/jamjet'
If you have feedback or need assistance with the MCP directory API, please join our Discord server