JamJet
Die Agent-native Laufzeitumgebung — robust, kompositionell, für die Produktion gebaut.
jamjet.dev · Quickstart · Konzepte · API-Referenz · Beispiele · Blog · Discord

JamJet ist eine auf Performance ausgelegte, Agent-native Laufzeitumgebung für KI-Agenten. Es ist kein weiterer Prompt-Wrapper oder ein schlankes Agent-SDK — es ist ein Produktions-Substrat für die Orchestrierung von Agenten, die funktionieren müssen, nicht nur als Demo.
Der Kern der Laufzeitumgebung besteht aus Rust + Tokio für Scheduling, Status und Nebenläufigkeit. Die Erstellung erfolgt über Python, Java, Go (geplant) oder YAML. Alles wird in denselben IR-Graphen kompiliert und auf derselben Engine ausgeführt.
Warum JamJet?
Problem | JamJets Antwort |
Agenten verlieren bei Absturz den Status | Dauerhafte Graphenausführung — Event-Sourcing, absturzsichere Wiederaufnahme |
Keine Möglichkeit für menschliche Freigabe | Human-in-the-loop als Workflow-Primitiv erster Klasse |
Agenten in eigenen Frameworks isoliert | Natives MCP + A2A — Interoperabilität mit jedem Agenten, jedem Framework |
Langsame Python-Orchestrierung bei Skalierung | Rust-Kern — kein GIL, echte asynchrone Parallelität |
Schwache Beobachtbarkeit, kein Replay | Vollständige Event-Timeline, OTel GenAI-Traces, Replay ab jedem Checkpoint |
Keine Standard-Agentenidentität | Agent Cards — jeder Agent ist adressierbar und auffindbar |
Hartkodiertes Agenten-Routing | Coordinator Node — dynamisches Routing mit strukturiertem Scoring + LLM-Tiebreaker |
Agenten können nicht als Tools genutzt werden | Agent-as-Tool — jeden Agenten als aufrufbares Tool verpacken (sync, streaming, konversationell) |
Keine Governance oder Leitplanken | Policy Engine — Tool-Blockierung, Freigaben, Autonomie-Durchsetzung, Audit-Log |
Agenten mit ungeprüftem Zugriff | OAuth-Delegierung — RFC 8693 Token-Austausch, Scope-Einschränkung, schrittweise Scoping |
PII-Lecks in Logs | Data Governance — PII-Schwärzung (maskieren/hashen/entfernen), Aufbewahrungsrichtlinien, Auto-Purge |
Keine Mandantenisolierung | Multi-Tenant — zeilenbasierte Partitionierung, mandantenspezifischer Status, isolierte Audit-Logs |
An eine Sprache gebunden | Polyglot SDKs — Python, Java (JDK 21), Go (geplant), YAML — gleiche IR, gleiche Laufzeit |
Kann nicht ohne Server ausgeführt werden | In-Process-Ausführung — |
Quickstart
Voraussetzungen: Python 3.11+
Schnellster Weg — reines Python, kein Server
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)Kein Server. Keine Konfiguration. Kein YAML. Einfach pip install und ausführen.
Vollständiger Laufzeit-Pfad — dauerhafte Ausführung
pip install jamjet
jamjet init my-first-agent
cd my-first-agent
jamjet devIn einem anderen Terminal:
jamjet run workflow.yaml --input '{"query": "What is JamJet?"}'→ Vollständige Quickstart-Anleitung
Hello World
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 (am einfachsten)
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?")Der Docstring wird zur Anweisung. Die Funktionssignatur ist der Vertrag. Das ist alles.
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 (volle Kontrolle)
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})Alle drei Ebenen kompilieren zur gleichen IR und laufen auf der gleichen dauerhaften Rust-Laufzeitumgebung.
Performance
JamJets IR-Kompilierung ist 88× schneller als die Graphen-Kompilierung von LangGraph:
Operation | JamJet | LangGraph |
Kompilierung / Graphenbau | ~0.006 ms | ~0.529 ms |
In-Process-Aufruf | ~0.015 ms | ~1.458 ms |
Gemessen mit Python 3.11, Single-Tool-Workflows. JamJet kompiliert ein leichtgewichtiges IR-Dict; LangGraph baut einen NetworkX-Graphen.
MCP-Tool-Aufruf
nodes:
search:
type: tool
server: brave-search # configured in jamjet.toml
tool: web_search
arguments:
query: "{{ state.query }}"
count: 10
output_key: results
next: summarizeA2A-Delegierung
nodes:
delegate:
type: a2a_task
agent_url: "https://agents.example.com/research-agent"
input:
query: "{{ state.query }}"
output_key: research
next: endEval mit Selbstverbesserung
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: endCoordinator — dynamisches Agenten-Routing
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"Agent-as-Tool — Agenten als aufrufbare Tools verpacken
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-Routing — Compiler fügt Coordinator automatisch ein
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 → processAgentische Design-Muster
JamJet unterstützt die sechs wichtigsten Multi-Agenten-Orchestrierungsmuster. Hier ist, wann man welches verwendet:
Muster | JamJet-Primitiv | Wann zu verwenden | Beispiel |
Single Agent |
| Einfache Prototypen, zweckgebundene Aufgaben | Chatbot, Klassifikator |
Sequential Pipeline |
| Geordnete Schritte, bei denen jeder vom vorherigen abhängt | ETL, Dokumentenverarbeitung |
Parallel Fan-Out |
| Unabhängige Aufgaben, die gleichzeitig laufen können | Multi-Quellen-Recherche, Batch-Klassifizierung |
Loop & Critic |
| Qualitätskritische Aufgaben, die iterative Verfeinerung benötigen | Code-Review, Content-Erstellung |
Coordinator (Dynamisches Routing) |
| Routing zum besten Agenten zur Laufzeit basierend auf Fähigkeit, Kosten, Latenz | Support-Ticket-Routing, Aufgaben-Delegierung |
Agent-as-Tool |
| Ein Agent muss einen anderen als Funktion aufrufen | Orchestrator ruft Spezialisten auf |
Das richtige Muster wählen
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-ToolCoordinator vs. statisches Routing
Statisch ( | Dynamisch ( | |
Kandidaten | In YAML deklariert | Zur Laufzeit aus Registry entdeckt |
Auswahl | Ausdrucksbasierte Regeln | Strukturiertes Scoring + optionaler LLM-Tiebreaker |
Wenn sich Agenten ändern | Workflow neu bereitstellen | Automatisch — neue Agenten werden entdeckt |
Beobachtbarkeit | Genommener Zweig protokolliert | Vollständige Scoring-Aufschlüsselung + Begründung im Event-Log |
Am besten für | Feste, bekannte Routen | Dynamische Umgebungen, Multi-Tenant, Forschung |
Wie JamJet im Vergleich abschneidet
Stand März 2026. Alle Frameworks entwickeln sich weiter — prüfen Sie deren Dokumentation für den neuesten Stand.
Fähigkeit | JamJet | Google ADK | LangChain | AutoGen | CrewAI |
Einfaches Agenten-Setup | ✅ 3 Zeilen ( | ✅ 5 Zeilen | 6+ Zeilen | 10+ Zeilen | 8+ Zeilen |
In-Process-Ausführung | ✅ | ✅ nativ | ✅ nativ | ✅ nativ | ✅ nativ |
Dauerhafte Ausführung | ✅ event-sourced, absturzsicher | ❌ ephemer | ❌ ephemer | ❌ ephemer | ❌ ephemer |
Dynamisches Agenten-Routing | ✅ Coordinator mit Scoring + LLM | ✅ | ❌ | ❌ | ❌ |
Agent-as-Tool | ✅ sync, streaming, konversationell | ✅ | ❌ | ❌ | ❌ |
Human-in-the-loop | ✅ Primitiv erster Klasse | 🟡 Callbacks | 🟡 Callbacks | 🟡 konversationell | 🟡 manuell |
MCP-Unterstützung | ✅ Client + Server | ✅ Client + Server | 🟡 nur Client | 🟡 nur Client | 🟡 nur Client |
A2A-Protokoll | ✅ Client + Server | 🟡 nur Client | ❌ | ❌ | ❌ |
Eingebaute Eval | ✅ LLM-Judge, Assertions, Kosten | ✅ 8 eingebaute Kriterien | ❌ | ❌ | ❌ |
Eingebaute Beobachtbarkeit | ✅ OTel GenAI, Event-Replay | ✅ Cloud Trace | 🟡 LangSmith (extern) | ❌ | ❌ |
Agentenidentität | ✅ Agent Cards, A2A-Discovery | ✅ Agent Cards | ❌ | ❌ | ❌ |
Policy & Governance | ✅ Policy Engine, Audit-Log | 🟡 Model Armor Plugin | ❌ | ❌ | ❌ |
Multi-Tenant-Isolierung | ✅ zeilenbasierte Partitionierung | ❌ | ❌ | ❌ | ❌ |
PII-Schwärzung | ✅ maskieren/hashen/entfernen | 🟡 Plugin | ❌ | ❌ | ❌ |
Modellunabhängigkeit | ✅ jeder Modellanbieter | 🟡 Gemini-first (LiteLLM) | ✅ jeder | ✅ jeder | ✅ jeder |
Progressive Komplexität | ✅ | 🟡 Code oder YAML | ❌ einzelne API | ❌ | ❌ |
Managed Deployment | 📋 Geplant | ✅ Vertex AI Agent Engine | ❌ | ❌ | ❌ |
Laufzeitsprache | Rust-Kern + Python/Java/Go | Python/TS/Go/Java | Python | Python | Python |
Am besten für | Multi-Agenten-Systeme in Produktion | Google Cloud AI-Agenten | Schnelles Prototyping | Konversationelle Agenten | Rollenbasierte Teams |
Speicher — Engram
JamJet wird mit Engram ausgeliefert, einer dauerhaften Speicherschicht für Agenten — temporaler Wissensgraph, hybrides Retrieval, Konsolidierungs-Engine, alles gesichert durch eine einzelne SQLite-Datei. Engram läuft als eingebettete Rust-Bibliothek oder als eigenständiger MCP/REST-Server und ist von Python, Java und Spring Boot aus nutzbar.
Provider-agnostisch. Das gleiche Engram-Binary spricht mit Ollama (lokal, kostenlos), jedem OpenAI-kompatiblen Endpunkt (OpenAI, Azure, Groq, Together, Mistral, DeepSeek, Perplexity, OpenRouter, vLLM, LM Studio, …), Anthropic Claude, Google Gemini oder einem command Shell-Out für alles andere — wählen Sie eines mit ENGRAM_LLM_PROVIDER=…, kein Neukompilieren.
Form | Paket | Wann zu verwenden |
Rust-Bibliothek |
| Speicher direkt in eine Rust-Anwendung einbetten |
Eigenständiges Binary |
| MCP-Clients (Claude Desktop, Cursor), sprachunabhängige REST-Clients, Zero-Code-Setups |
Python-Client |
| Python-Agenten, die über REST mit |
Java-Client |
| JVM-Agenten, die über REST mit |
Spring Boot Starter |
| Drop-in |
# 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.2Sieben MCP-Tools, die vom Server bereitgestellt werden: memory_add, memory_recall, memory_context, memory_search, memory_forget, memory_stats, memory_consolidate. Vollständige Dokumentation unter [runtime/engram-server/README.md](runtime/eng
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