
Haki
io.github.GetHaki由 GitHub 账号 GetHaki 发布v0.1.0更新于 Oct 24, 2026
Long-term memory for AI agents: bitemporal fact ledger, contradiction detection, explainability.
概览
Haki 是为 AI 智能体提供长期记忆的服务器,保存带日期和来源的事实,并按需返回相关上下文及决策追踪。
- 可以做什么
- 在编码前按 token 预算召回项目相关上下文,并附带来源与有效期(haki_context)。把决策、约定和已解决的缺陷保存为持久事实(haki_capture)。查看某条记忆为何被保留、排除或拦截的追踪记录(haki_inspect)。遗忘某条信息,删除会级联传播并生成回执(haki_forget)。
- 适用场景
- 适合需要让智能体跨会话保留决策、约定和偏好的场景,也适合必须拦截过期或矛盾信息而不是照常返回的场合。适用于 Cursor 等能主动调用工具的 MCP 客户端。
- 运行要求
- 需要一个运行中的 Haki API 端点(托管 Cloud 服务,或用 Docker 与 uv 自建、依赖 PostgreSQL 加 pgvector 和 Redis 的实例)。需要按项目发放的 API 密钥,以 Bearer 令牌方式发送;README 说明首个密钥免费,之后每个密钥管理自己的项目。
安装
在 SourceWeft 中
- 打开 控制台中的 Haki,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。
交给智能体安装
把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。
阅读 https://sourceweft.com/mcp/io.github.GetHaki%2Fhaki/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。其他 MCP 客户端
把它添加到你客户端的 mcpServers 配置中。
{
"mcpServers": {
"haki": {
"type": "http",
"url": "https://api.gethaki.space/mcp/"
}
}
}README
Haki
Reliable memory for AI agents
Context with proof: every fact carries a date, a source, and a status.
[Tests] [Python] [PostgreSQL] [p95 context] [License]
Haki gives any AI agent a memory that lasts for months — that tells current from stale — and that can prove every recollection.
Quickstart · Coded agent · Cursor · n8n · Gateway · API · gethaki.space
What Haki does
Today, an AI agent remembers nothing beyond a single conversation: every new session starts from scratch, re-explains context, and can apply a preference that went stale months ago with no way to tell.
Haki is an open-source (Apache-2.0), persistent memory layer, independent of
whatever model or framework you use: it extracts structured facts from an
agent's exchanges, keeps them current over time, and hands every new request
a relevant, dated, sourced context packet. It stays entirely under your
control — one docker compose up installs it, and your existing agent,
model, and infrastructure don't change.
The problem
Teams building AI agents in production run into the same limits, every time:
Existing approaches (generic vector stores, conversation summaries) work in a demo but degrade after a few weeks of real usage: stale information served as current, undetected contradictions, zero explainability.
The approach
A fact ledger, not a conversation history. Haki doesn't archive raw messages to replay later: it extracts structured facts from them — preferences, constraints, decisions — each one linked back to the source event that grounds it.
Bitemporality and supersession. Every fact carries an explicit validity date and status. When information changes, the old fact is marked superseded — never silently deleted, never served again as current. On an unresolved contradiction, both versions are held back and flagged rather than served at random.
Systematic traceability. Every context packet injected comes with its sources, its validity dates, and a trace explaining which memories were kept, excluded, or blocked, and why. "Why did the agent use this piece of information?" has a verifiable answer in under a minute.
Quickstart
Prerequisites: Docker and uv. The defaults in
.env.exampleare enough to get started — no key required. For custom configuration (a real LLM key, etc.), copy that file to.env.
If anything goes wrong,
bash scripts/doctor.shdiagnoses Docker, the containers, Postgres,.env, migrations, and the API in one command — read only, no side effects, safe to re-run as often as needed.
In a second terminal, verify everything works:
haki verify runs a complete scenario in a few seconds: a preference, then a
change of mind in the same conversation, then a new conversation that
queries memory. It must serve the current value, keep the old one at status
superseded instead of erasing it, and tie the whole thing to a trace.
The command exits 1 if the stale value is still served, or if the old value isn't found marked as superseded: serving the right value by accident, with no link between the two facts, isn't a memory that actually updates.
Multilingual by default: local embeddings are multilingual (French, English, Spanish, and about fifty other languages) — the demo scenario above is captured in French on purpose, and a query in a different language still finds it. Verified end-to-end (
scripts/check_multilingual.py).
Four ways to use Haki
1. Coded agent — SDK and CLI
Python or TypeScript developers. A few lines around your existing LLM call.
SDK details (methods, async, errors)
capture(events, idempotency_key)— idempotent ingestion: a network retry never creates a duplicate;context(subject_id, query, project_id, budget_tokens=2000)— the ContextPacket, withtrace_id;inspect(trace_id)— why these memories were chosen;timeline(subject_id, project_id),consolidate_subject(...),facts(...),consolidate(),forget(...),health();- Async variant:
AsyncHakiClient; - Typed errors:
HakiApiError(error_type,field,status_code),HakiConnectionError.
CLI: haki login (device-code sign-in, see below), haki connect
(configure and test with a key in hand), haki verify (timed memory test),
haki status (API health), haki mcp (Cursor packaging).
haki login — for a Cloud account, the hk_ key is only ever shown
once, at provisioning: the terminal has no way to retrieve it again. The
device-code flow (RFC 8628) closes that gap without a new secret. The CLI
shows an XXXX-XXXX code and opens
<HAKI_CONSOLE_BASE_URL>/cli-auth with the code already filled in
(verification_uri_complete); the code stays on screen too, so it can be
typed by hand from a phone. You approve it in the console, already signed
in — the terminal then receives a fresh, dedicated key, not the
console's own — revoking that terminal from Keys disconnects nothing else.
The key is served exactly once, by the poll that consumes it.
Server-side, HAKI_CONSOLE_SERVICE_KEY must be configured (it's what
authenticates the console against /v1/cli/device/approve). Wrong codes are
rate-limited per person, not per IP: every approval arrives from the same
address (the console's own backend), so a per-IP counter would be a shared
bucket any single user could exhaust for everyone else.
TypeScript SDK (parity with the Python SDK)
Same methods, same typed errors, same <haki_memory> block — zero runtime
dependency (native fetch, Node 18+).
CLI haki-ts (node dist/cli.js …): connect, verify, status — same
~/.haki/config.json file as the Python CLI, the two are interchangeable.
Runnable example:
sdk/typescript/examples/basic-agent.mjs.
2. Cursor — MCP server
Cursor users. One-click install, no key to copy by hand.
- The "Add Haki to Cursor" deeplink installs the MCP server;
- The Project Rule (
.cursor/rules/haki.mdc) tells the agent when to remember and when to recall; - Cursor then keeps decisions, conventions, and resolved bugs across sessions.
Four tools show up in Cursor:
Known, documented limit: MCP can't intercept every Cursor conversation — the server only sees the tool calls Cursor decides to trigger. The Project Rule tells the agent when to call them; real coverage is measured, never presented as total.
3. n8n — template and nodes
No-code builders. One template to import, three things to configure.
Chain: Webhook → Haki Context → AI Agent → Haki Capture → Respond
Two options in integrations/n8n/:
- Native template
haki-persistent-support-agent.json— importable into any n8n instance, no extra install (standard HTTP nodes); - Node package
n8n-nodes-haki— visualHaki ContextandHaki Capturenodes, with built-in validation.
Three settings are all it takes: the Haki credential, the LLM credential, and
the counterpart's identity (subject). A call with no identity is refused —
a memory with no stable identity isn't reliable.
Verified against a real n8n instance (Docker): a preference stated in the first message is recalled in the second, with its source.
4. OpenAI-compatible gateway
Apps already speaking the OpenAI API. Only base_url changes — memory
becomes automatic.
On every POST /gateway/v1/chat/completions call: the subject's memory is
injected at the top of the system message (a <haki_memory>…</haki_memory>
block), the call is forwarded to the configured provider (HAKI_LLM_* — the
Haki key itself is never sent upstream), the exchange is then captured
(conversation.turn, idempotent), and consolidation resumes in the
background. The response returned is the provider's own, unchanged, plus
three headers: X-Haki-Memory, X-Haki-Trace-Id, X-Haki-Context-Ms.
- Identity travels via headers, never the request body (the model never
chooses what gets remembered):
X-Haki-Subject-Id(required for memory),X-Haki-Thread-Id,X-Haki-Run-Id,X-Haki-Purpose,X-Haki-Idempotency-Key(default: a hash of the body — a retry never creates a duplicate). - Controlled degradation: with no identity, the request passes through
unmodified (
X-Haki-Memory: disabled); if context can't be built, the request still goes out, flaggeddegraded. The agent is never blocked by Haki. - Streaming:
stream: truepasses straight through (X-Haki-Memory: disabled, no injection, no capture) — a deliberate choice: injecting without being able to capture the final response would break the memory loop, and buffering the whole stream would defeat the point of streaming in the first place. - Documented limit (see
research/Haki_Memory_Runtime.mdin the private repo): the gateway observes calls to the model, not tools the agent runs locally between two calls — those are captured via the SDK or the API directly.
An httpx variant lives in the SDK too: haki.gateway.gateway_client(base_url, api_key, subject_id, ...) (and async_gateway_client). Memory overhead is
dominated by build_context (about 15 ms locally, /v1/context p95 under
250 ms) — reproducible benchmark:
uv run python scripts/benchmark_gateway.py --api-key hk_....
Hosted Cloud
Prefer not to run your own infrastructure? gethaki.space hosts the same API, plus a web console for browsing memory, inspecting traces, and resolving conflicts by hand. Self-hosting stays fully supported and free — the API in this repository is the same one Cloud runs.
How it works
- CAPTURE — Your application sends an event (a message, an action, a tool result). Haki records it as immutable evidence and replies in a few milliseconds. A network retry never creates a duplicate (idempotence).
- CONSOLIDATION — In the background, Haki reads events and decides what should become a durable fact. It deduplicates, detects changes (the old fact becomes superseded) and contradictions (status conflict, held back until resolved). A fact is identified by (subject, predicate, qualifiers): "weekday wake-up time" and "weekend wake-up time" are two distinct, coexisting facts, not a contradiction — and a different qualifier is never conflated with another one, no matter how close the wording.
- CONTEXT — Before every response, the agent asks for relevant memory.
Haki only returns active, valid, in-scope facts, ranked by relevance,
within a strict token budget — p95 measured at 249 ms across 10,000 facts
(see
scripts/benchmark_context.py). - INSPECT — At any time, the trace explains why a piece of information was kept, excluded, or blocked.
- FORGET — A correction or an erasure propagates to everything derived from it, with a timestamped receipt.
Concepts
Positioning
Measured performance
Reproducible benchmark: uv run python scripts/benchmark_context.py (100
requests per size, local embeddings, Windows development machine).
Embeddings are computed locally (ONNX on CPU, multilingual 384-dimension model) — no network call in the critical path. Retrieval combines a vector index (hnsw) with a full-text index (GIN), then scores only the best candidates. LLM cost (extraction) is fully asynchronous and never slows down a response.
Public benchmarks
Haki publishes a reproducible benchmark harness, not a cherry-picked number: a frozen, versioned configuration (dataset and checksum, models, prompts, budgets, prices), a full-context baseline re-run under the exact same protocol (same model, same prompt, same judge), and metrics the field rarely publishes — contradiction leakage, abstention rate, tokens per packet, latency, cost.
- Harness:
eval/(LoCoMo and LongMemEval_S loaders, pipeline, judge, reports). - Results are never committed to this repository on purpose — run the
harness yourself against the pinned dataset and frozen config, and the
numbers you get (written to
eval/results/, gitignored) are yours to trust or challenge, not a number we chose to show you. - Reproduction: exact commands in
eval/README.md.
API at a glance
The curl examples below assume an existing key: create one with
curl -X POST http://localhost:8100/v1/keys -d '{"org_id":"org_acme","project_id":"prj_support","label":"dev"}'(the first key is free, after that every key manages its own project), then add-H "Authorization: Bearer hk_..."to every call.
Errors are typed and actionable:
{"error": {"type": "missing_scope", "message": "...", "field": "..."}}
— never a generic message.
Full example: capture then context
Response: the fact invoice_language: {"language": "fr"}, its validity
date, the source event id, and a trace_id.
Security, scopes, and forgetting
- Per-project API keys: every
/v1/*call requiresAuthorization: Bearer hk_...by default. A key is bound to a single project: asking for another one returns403 forbidden_scope, without ever revealing that other projects exist. Managed viaPOST/GET/DELETE /v1/keys(details indocs/SECURITY.md). - PostgreSQL Row-Level Security: isolation is guaranteed by the database itself (RLS on events, facts, traces, conflicts) — even if an application filter is forgotten, a query can't cross projects (proven by a non-disclosure test).
- Deterministic policy engine: every read and write goes through explicit rules (scope present, key/project match, audit) — never through the language model.
- The model never chooses scopes:
project_idandsubject_idcome from the calling backend or its configuration, never from the LLM. - Feedback and correction:
POST /v1/feedback(useful/irrelevant/incorrect— a fact flagged incorrect becomesdisputedand is never served again);POST /v1/conflicts/{id}/resolvesettles a contradiction with full history. - Secrets: the LLM key lives in
.env(git-ignored, template provided in.env.example), never in code, the terminal, or the frontend. - Real forgetting:
POST /v1/forgetpropagates erasure to facts, embeddings, events, and traces, with a timestamped receipt inforget_receipts. - An open dev mode exists (
HAKI_AUTH_REQUIRED=false) for local use only, with an explicit warning at startup.
Architecture
Stack and modules (for the technically curious)
Stack: FastAPI · SQLAlchemy 2.0 async · PostgreSQL 16 + pgvector (hnsw) · Alembic · Redis 7 · fastembed (ONNX CPU) · official MCP SDK.
Modules:
- Memory Ledger (
app/ledger/) — bitemporal, append-only events (occurred_at= business time,recorded_at= system time), versioned facts, explicit status transitions:candidate → active → superseded/disputed/disabled → deleted(terminal). - Memory Consolidator (
app/consolidator/) — LLM extraction validated by Pydantic (no batch can ever crash), content-based deduplication (idempotent replay), supersession, conflict sets. A provider failure marks the jobfailedwithout touching events, which stay replayable. - Context Assembler (
app/context/) — strict filters (active, scope, validity) then a hybrid score:0.6 × cosine similarity + 0.25 × full-text + 0.15 × recency, plus cross-encoder reranking, multi-hop entity expansion, and a temporal grounding pass (seeresearch/Haki_Livre_Construction_2026-08-15.mdin the private repo for how these interact). Two-phase retrieval (index selection, then scoring) for a cost that stays stable regardless of memory size. - Interchangeable providers (
app/providers/) — extractor (HAKI_LLM_PROVIDER=fake|openai) and embedder (HAKI_EMBED_PROVIDER=local|fake, local by default) configured independently. No vendor SDK hardcoded in. - MCP server (
app/mcp_server/) — mounted inside the API, Streamable HTTP transport. - Gateway (
app/gateway/) — OpenAI-compatible proxy: injects the<haki_memory>block (rendered by the SDK'sbuild_prompt_context, a single shared implementation), forwards upstream viaHAKI_LLM_*(never the Haki key itself), captures idempotently after the response, documented pass-through for streaming.
Database (Alembic migrations): events, facts (vector(384)
embedding, search_vector tsvector + GIN), jobs, conflict_sets,
context_traces, forget_receipts, organizations, subject_aliases,
predicate_aliases.
Quality and tests
376 Python tests and 14 Node tests against a real PostgreSQL database (no
database mocking): uv run pytest and cd sdk/typescript && npm test.
Tests verify behavioral guarantees, not implementation details:
- a superseded fact is never returned as active;
- one subject never sees another subject's memory;
- a network retry never creates a duplicate;
- an open conflict holds back both facts involved;
- after forgetting, nothing is ever served again;
- illegal status transitions are rejected;
- the gateway injects memory, degrades without ever blocking, forwards upstream errors, and captures exactly once per idempotency key.
End-to-end checks already run against real conditions: LLM extraction (OpenRouter), MCP server (official client), n8n workflow (Docker), latency benchmark.
The current guarantees, each one citing the mechanism and the test that
proves it, are documented in
docs-site/en/production-guarantees.mdx.
Roadmap
Repository structure
This is the self-hosted OSS core: the API, both SDKs, the MCP server, the n8n integration, and the public eval harness. The hosted web console (browsing memory, resolving conflicts by click, billing) is part of the Cloud offering and lives in a separate, private repository — self-hosting Haki never requires it.
Documentation
Product documentation (guides, full API reference, the production-guarantees
contract) lives in docs-site/en/ — a Mintlify site, run
locally with mint dev from that folder (Node 18/20/22 LTS required). A
French translation is maintained in parallel under
docs-site/fr/.
Haki — your agent remembers what matters, and can prove it.
来源:README.md,提交 1e5da85
工具
0版本历史
1- v0.1.0最新Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通必需25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式必需10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分