Vayl

io.github.ac12644由 GitHub 账号 ac12644 发布v0.10.0更新于 Oct 30, 2026

Reconciling memory for AI agents: a changed fact retires the old value, with history and approval.

概览

AI 生成的概览

面向 AI 代理的本地持久记忆:事实变更时替换旧值、保留历史,并让高风险变更等待人工批准。

可以做什么
  • 存储、检索与撤回事实:remember、recall、safe_recall、forget、recall_related
  • 查看与修正记忆:list_memories、get_memory、update_memory、history
  • 记录与审计代理决策:record_decision、explain_decision、check_before_act、attest、verify_receipt、verify_audit、export_public_key
  • 审核需确认的变更:pending_changes、confirm_change、reject_change、set_reconcile_policy、get_reconcile_policy
  • 管理主体与数据权利:create_principal、list_principals、revoke_principal、export_memory、delete、delete_all、purge_expired、audit_log
  • 查看健康状态、统计与许可证状态
适用场景
适合需要跟踪随时间变化的事实(项目技术栈、账户状态、偏好、用药)且不能依据过期值作答的助手。也适合需要可审计的决策依据记录、并对敏感变更要求人工确认的代理。
运行要求
以 Python 包形式在本地通过 stdio 运行(pip install vayl-mcp)。需要模型与嵌入服务:OPENAI_API_KEY,未设置时可改用本地 Ollama 模型;README 还提到其他 OpenAI 兼容模型、Anthropic 与 Groq。VAYL_DB 指定 SQLite 数据库路径。仅支持桌面客户端。
安装前请注意
记忆会被写入、替换,也可能被永久删除:delete、delete_all 与 purge_expired 不可逆,purge 的选项还可能超出单个用户范围。主体 API 密钥只显示一次,撤销不可逆。OPENAI_API_KEY 会发送到所配置的模型端点。厂商声明其未获临床使用认证,也未经过第三方审计。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Vayl,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

Vayl

The reconciling memory layer for AI agents.

[PyPI] [Python] [License] [OpenSSF Scorecard] [Docs]

When a fact changes, most agent memory keeps both versions and lets the model guess which is current. Vayl replaces the old value, keeps it in history, and can hold high-stakes changes until a person approves them. It runs locally on SQLite and works with any MCP client: Claude Code, Cursor, Claude Desktop, or your own agent.

[A real run with a fictional patient: warfarin is recorded, then replaced by apixaban. The change waits in pending_changes until a clinician confirms it. Recall then answers apixaban now, warfarin before, and refuses amoxicillin because of the recorded penicillin allergy.]

A real run with gpt-6-luna and the clinical preset. The patient is fictional. Script: assets/demo/clinical_demo.py

Features

  • Reconciles changes. A new value supersedes the old one, and "we stopped X" retracts X. A retired fact is never returned as current.
  • Keeps history. Ask what is true now or what was true before. Every change goes on a signed, tamper-evident audit chain.
  • Human approval where it matters. Mark slots such as medications as confirm-required, and changes wait in a queue. check_before_act blocks an action that depends on a disputed, stale or just-changed fact.
  • Small and local. SQLite by default, Postgres for teams. One model call to store a fact and one to answer. Any OpenAI-compatible model, Anthropic, Groq or a local Ollama model.
  • Built-in presets for clinical, support, finance, sales, coding and assistant memory.

Install

bash
pip install vayl-mcp

Add it to Claude Code:

bash
claude mcp add vayl -e LLM_PROVIDER=openai -e OPENAI_API_KEY=sk-... -e VAYL_DB=$HOME/.vayl/vayl.db -- vayl-mcp

For Cursor, Claude Desktop and other clients, see the quickstart. Run vayl-demo to try reconciliation with no API key.

Use it from code

python
from vayl import Vayl
with Vayl(user_id="cust_5521") as m:    m.remember("Acme's invoice bounced. Account suspended until payment clears.")    print(m.recall("Is Acme's account in good standing?"))    # No. Acme's account is suspended until payment clears.

Integrations

Agent frameworks. Backends plug into the framework's own memory, so facts are stored and recalled on every turn. Tool adapters give the agent memory tools to call.

FrameworkInstallUse
Google ADKpip install 'vayl-mcp[adk]'from vayl.integrations.adk import VaylMemoryService (memory backend)
LlamaIndexpip install 'vayl-mcp[llamaindex]'from vayl.integrations.llamaindex import VaylMemory (memory block)
AutoGenpip install 'vayl-mcp[autogen]'from vayl.integrations.autogen import VaylMemory (memory backend)
LangGraph / LangChainpip install 'vayl-mcp[langgraph]'from vayl.integrations.langgraph import VaylMemory (tools)
OpenAI Agents SDKpip install 'vayl-mcp[openai-agents]'from vayl.integrations.openai_agents import VaylMemory (tools)
CrewAIpip install 'vayl-mcp[crewai]'from vayl.integrations.crewai import VaylMemory (tools)
Pydantic AIpip install vayl-mcp 'pydantic-ai-slim[openai,mcp]'MCPToolset over MCP, no adapter
Agnopip install vayl-mcp agno openaiMCPTools over MCP, no adapter
Vercel AI SDKnpm i @vayl.dev/client ai zodimport { vaylTools } from "@vayl.dev/client/vercel"
Mastranpm i @vayl.dev/client @mastra/core zodimport { vaylTools } from "@vayl.dev/client/mastra"

Examples for each are in Agent frameworks.

MCP clients. Install vayl-mcp, then add it to your client: Claude Code · Cursor · VS Code · Windsurf · Zed · Cline · Continue · Codex CLI · Gemini CLI. For a shared team memory, run vayl-server and call it over MCP or REST.

Documentation

QuickstartInstall and connect a client
How Vayl worksExtraction, reconciliation and retrieval
Tutorial: a hospital medication assistantClinical preset, critical facts and approval
Tutorial: a customer-support assistantAccount state and safety checks
MCP toolsAll 30+ tools
Deploying vayl-serverTeam server, auth, Docker, Postgres
BenchmarksStale-value and retraction results against Mem0 and Graphiti

Contributing

See CONTRIBUTING.md. The unit tests run offline, with no API key. Good starting points are labeled good first issue.

Security

Data is encrypted at rest by default, and Vayl sends nothing anywhere except to the model endpoints you configure. Vayl is not certified for clinical use and has not been audited by a third party. Report vulnerabilities as described in SECURITY.md.

License

Apache-2.0

来源:README.md,提交 675cc5d

工具

32

remember

Remember (extract & reconcile facts)

Store fact(s) from a statement. Reconciles automatically: a new value SUPERSEDES the old one (not appended), removals are RETRACTED, and multiple facts in one message are all captured. Optional `metadata` tags the facts stored in this call. `source` records WHO/WHAT asserted the fact (an agent id, a person, a connector) — belief provenance, and the basis for source-aware reconciliation in a shared space (see set_reconcile_policy). Examples: 'We switched from Zustand to Redux Toolkit', 'Alice is the new team lead'.

输入参数text必填run_idsourceuser_idagent_idmetadata

recall

Recall from current memory

Answer a question from CURRENT memory — the active value ('what state library do we use?') or a multi-hop question over current facts. Returns 'I don't know' rather than guessing, and NEVER answers from a retired/retracted fact. For the timeline of a subject, use `history`. Set `include_history=True` ONLY for questions explicitly about the past — 'what did we use before?', 'when did we switch?' — where retired facts are the answer. It is off by default because with it off, superseded values are never loaded at all, so a stale value cannot be returned as current regardless of how the model behaves. Leaving it off is the guarantee; turning it on trades that for reach into the timeline. `critical_categories` (comma-separated) names fact categories that must ALWAYS reach the answer regardless of ranking — 'allergy,active_medication' in a clinical deployment. Ordinary recall is semantic top-k, so a fact that does not rank is invisible, not merely deprioritised; for some categories that is a safety failure rather than a quality one. Leave empty to use the deployment-wide VAYL_CRITICAL_CATEGORIES; an empty value never means 'none'. Set `explain=True` to also get the PROVENANCE — the exact facts used to answer, each with who asserted it, its confidence, and what it superseded. That's the truthful basis for an audit of why the agent believes what it does (and it's what `record_decision` snapshots).

输入参数run_idexplainuser_idagent_idquestion必填include_historycritical_categories

forget

Forget / retract (kept in history for audit)

Retract a fact — a removal with no replacement. Unlike additive stores, this actually retires it so it stops being returned as current (kept in history for audit). Examples: 'We dropped Sentry', 'Alice left the Platform team', 'we no longer support IE11'.

输入参数text必填run_iduser_idagent_id

get_memory

Get one memory by id

Fetch one memory by its id (the `#id` shown by `list_memories`) — its value, status, scope, confidence, what it supersedes, and any metadata.

输入参数run_iduser_idagent_idmemory_id必填

update_memory

Update a memory (audit-preserving)

Correct a memory by id (the `#id` from `list_memories`). Audit-preserving: the old value is retired to history and the new value becomes active — so the change still shows up in `history`.

输入参数run_iduser_idagent_idmemory_id必填new_value必填

history

Change history for a subject

The change-log for a subject — every value it has held, oldest → newest, with status. The 'what did we use first vs now' view that additive stores can't give you. The `subject` is the key shown by `list_memories`.

输入参数run_idsubject必填user_idagent_id

record_decision

Record a decision + the beliefs behind it

Log a decision an agent is about to take, bound to the EXACT facts it consulted. Atomically recalls `question` with provenance and snapshots those beliefs (value, source, confidence, what they superseded) alongside `action_summary`. The snapshot is immutable and signed, so 'why did the agent do X?' stays answerable even after the facts later change. Returns the decision id and a verifiable receipt hash. Example: action_summary='Issued refund to order #91', question='what is the refund policy and this customer's tier?'.

输入参数run_iduser_idagent_idquestion必填action_summary必填

explain_decision

Explain a past decision (why the agent acted)

Reconstruct why an agent acted: the recorded action and the exact beliefs it held at that moment — even if those facts have since been superseded, retracted, or erased. Also verifies the decision's signed receipt so you know the record itself wasn't altered.

输入参数user_iddecision_id必填

check_before_act

Safety check before acting on a fact

Ask whether it's SAFE to take an autonomous action based on what memory knows about `subject`. Returns SAFE, or BLOCKED with explicit reasons — an unresolved conflict, confidence below the bar, a value that's gone stale, or one that just changed. Call this before any irreversible action (a payment, an email, a config change) so the agent never silently acts on bad memory. Tune the policy via the params (e.g. min_confidence=0.9, max_staleness_days=90 for high-stakes actions).

输入参数run_idsubject必填user_idagent_idmin_confidencerequire_activeblock_on_flaggedmax_staleness_daysblock_on_recent_change_days

safe_recall

Gated recall — answers only if safe to act on

Like `recall`, but for when the agent will ACT on the answer. It answers only if every current fact behind the answer passes the safety policy; otherwise it withholds the answer and returns the reasons (disputed value, low confidence, stale, or nothing current). Use this instead of `recall` on the path to an irreversible action. `critical_categories` behaves as in `recall`, and matters more here: this gate can only judge the facts it was handed, so a critical fact ranked out of context would be invisible to the check as well — it would pass, on an answer it never knew was incomplete.

输入参数run_iduser_idagent_idquestion必填min_confidencerequire_activeblock_on_flaggedmax_staleness_dayscritical_categoriesblock_on_recent_change_days

delete

Erase a subject permanently (GDPR erasure)

PERMANENTLY erase every record of a subject — including history and tombstones — for a user. Unlike `forget` (which retires but retains for audit), this is a hard delete for right-to-be-forgotten / GDPR erasure. The `subject` is the key shown by `list_memories`.

输入参数run_idsubject必填user_idagent_id

delete_all

Erase ALL memory for a user permanently (GDPR erasure)

PERMANENTLY erase memory (history included). With no agent_id/run_id, erases ALL of the user's memory across every space (account deletion / GDPR); pass them to erase just one space. Irreversible — not the same as `forget`, which retains history for audit.

输入参数run_iduser_idagent_id

attest

Attest the current value of a subject (signed proof)

Issue a signed, third-party-verifiable attestation of what memory currently holds for `subject` — 'as of now, the active value is X', anchored to the tamper-evident audit-log head. Use it to prove what was known at a point in time. Verify later with verify_receipt, or independently with export_public_key.

输入参数run_idsubject必填user_idagent_id

verify_receipt

Verify a signed receipt / attestation

Verify a persisted erasure receipt or knowledge attestation: recompute its canonical body and check the Ed25519 signature. Confirms the artifact is authentic and unaltered — the same check a third party can run with only the public key.

输入参数receipt_id必填

verify_audit

Verify the audit log is untampered

Verify the tamper-evident audit chain end-to-end. Recomputes every row's hash and (if signed) signature; reports INTACT, or the exact row where the chain breaks — so you can prove the accountability log wasn't edited, reordered, or truncated.

无需输入参数。

export_public_key

Export the public key for third-party verification

Return Vayl's Ed25519 public key (hex). Anyone can use it to verify erasure receipts, attestations, and the signed audit chain WITHOUT the secret key or access to the database.

无需输入参数。

set_reconcile_policy

Configure how a shared space reconciles conflicting sources

Configure how a SHARED space resolves conflicts between DIFFERENT contributors (sources). A shared space is any space (e.g. user_id='org:acme') that multiple agents/people write to with a `source` on each remember. Modes: • RECENCY — newer assertion wins (default; contributors equally trusted). • AUTHORITY — a higher-ranked source wins; a lower-ranked source contradicting it is FLAGGED, not overwritten. Pass `authority` as {source: rank} (higher = more authoritative). • REVIEW — any cross-source conflict is FLAGGED for a human. A source correcting its OWN earlier fact always supersedes, regardless of mode.

输入参数moderun_iduser_idagent_idauthority

get_reconcile_policy

Show a shared space's reconciliation policy

Show the source-aware reconciliation policy configured for a space (default RECENCY if unset).

输入参数run_iduser_idagent_id

pending_changes

List changes awaiting human approval

List proposed changes to confirm-required slots that have NOT been applied. Slots declared with "confirm" in the slot schema do not auto-apply a replacement or removal — the current value stands until a person approves. This is the queue of what is waiting.

输入参数run_iduser_idagent_id

confirm_change

Approve a pending change

Approve a proposed change to a confirm-required slot, applying it. Needs the `approve` capability (admin and member roles; agents lack it, so an agent can't approve its own proposal). The approver recorded is the authenticated caller; `decided_by` is an optional note.

输入参数run_iduser_idagent_idmemory_id必填decided_by

reject_change

Discard a pending change

Discard a proposed change. The current value stands. The proposal is kept as history — that someone proposed it is itself worth being able to audit. Needs `approve`, like confirm_change: an agent quietly discarding proposals would empty the review queue just as surely as approving them. `decided_by` is an optional note beside the authenticated caller.

输入参数run_iduser_idagent_idmemory_id必填decided_by

create_principal

Create a principal (user/agent) + API key

Admin only. Create a principal (a human user, agent, or service) and issue its API key. Roles: admin, member, agent, viewer, auditor. The key is shown ONCE — store it securely; it can't be recovered (reissue by creating a new principal). `scopes` is a comma-separated list of user_ids this principal may access, e.g. "cust_5521,cust_7788". Leave empty for unrestricted (the default, and correct for a single-tenant deployment). Set it for any multi-tenant deployment: without it, a valid key can read any space by passing that space's user_id. An admin role is unrestricted regardless, since org control implies reaching every space. `tenant` is the org partition this key belongs to (default: the caller's own tenant). It is a HARD boundary: every store query is filtered by it, so a key for one tenant cannot reach another tenant's memory even under the same user_id. Set it per org in a shared multi-tenant deployment. Only the deployment operator (an admin of the "default" tenant) may name a different tenant.

输入参数kindname必填rolescopestenant

list_principals

List principals of this deployment

Admin only. List your tenant's principals — id, name, roles, and whether disabled (the deployment operator sees every tenant's). Never shows API keys (only their hashes are stored).

无需输入参数。

license_status

Show the license / edition status

Show the deployment's edition and entitlements — Community or a licensed edition, seats used vs allowed, expiry, and unlocked features. If a license was rejected (tampered/expired/wrong key), this says so and reports the Community fallback it's running under.

无需输入参数。

revoke_principal

Revoke a principal's access

Admin only. Disable a principal — its API key stops working immediately. Irreversible (create a new principal to restore access). With `erase=True`, the principal row is HARD-deleted (Art. 17 for team members) instead of retained as disabled. A tenant admin can only revoke its own tenant's principals; another tenant's id reads as unknown.

输入参数eraseprincipal_id必填

list_memories

List current memories

List the current active facts (the reconciled current beliefs) for a user, plus a history block of what was superseded / retracted / archived. Active rows show the `#id` for get/update.

输入参数run_iduser_idagent_id

export_memory

Export all memory as JSON (GDPR access/portability)

Export everything held about a user/space as machine-readable JSON — data-subject access & portability (GDPR Art. 15/20). A complete DSAR answer: statements (active + full history), PLUS what the append-only records hold about them — decision snapshots, audit entries, and receipts.

输入参数run_iduser_idagent_id

purge_expired

Purge records older than N days (retention)

Retention / storage-limitation (GDPR Art. 5(1)(e)): permanently delete records written more than `older_than_days` ago. Statements are scoped to the user/space. The optional flags extend the same window to the append-only tables — NOTE these are not per-user: `include_decisions` and `include_receipts` purge those tables for your whole tenant, and `include_audit` purges the audit log from the head of the chain (a signed retention anchor keeps the remaining chain verifiable). There is one chain per deployment, shared by every tenant, so `include_audit` is DEPLOYMENT-WIDE and only the deployment operator may use it.

输入参数run_iduser_idagent_idinclude_auditolder_than_days必填include_receiptsinclude_decisions

audit_log

Audit log (accountability trail)

The accountability trail (GDPR Art. 5(2)) — recent data operations: who / what / when. Optionally filter by user_id. Not affected by memory erasure.

输入参数limituser_id

stats

Usage stats & KPIs

Operational KPIs for this Vayl instance — on-device, nothing leaves the machine: per-tool call counts, average latency and error counts, plus the distribution of reconciliation actions the engine has taken (SUPERSEDE / RETRACT / FLAG / SKIP / ADD / …).

无需输入参数。

health

Health check

Check that Vayl is configured and its dependencies are reachable — database, embedder, LLM, and graph (if enabled). Run this to diagnose setup before relying on memory; it makes one small LLM/embed call, so it costs a few tokens.

无需输入参数。

版本历史

3
  1. v0.10.0最新Oct 22, 2026
  2. v0.9.1Oct 22, 2026
  3. v0.9.0Oct 21, 2026

评分

已满足适用检查项的 90%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分
  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分