单机 Agentic 数据与执行基础设施
PyVDisk 是一个包含 VScript 脚本运行时的单机 Agentic 数据与执行基础设施项目:DataDisk 负责统一数据与执行基础设施,VScript 负责安全工作流语言、CLI、REPL 与运行时。
面向单机、单实例 Agentic 项目:一个
.vdisk容器统一承载 workspace、semantic memory、event trace、Checkpoint、WAL、Metadata 和运行状态。
| Agent / 应用 | ||
|---|---|---|
| VScript · Python API · CLI · REPL · HostProxy | ||
| Execution | Capability | Storage |
| ExecutionService DurableQueue worker · lease · retry · DLQ RunState · Audit | ScopedDataDisk FS / Vector / Log / Checkpoint 逐操作权限 | DataDisk 单一 .vdisk WAL · transaction · recovery |
| FS | Vector | Log |
| workspace | HNSW / flat memory generation · checksum | trace sequence · replay · ack |
| VirtualDisk · Volume · lock · fsync · mirror degraded fallback | ||
▶ 打开可交互架构图谱 — 点击模块逐层下钻、悬停查看中英双语介绍、?lang=en 切换英文、#module=<id> 深链直达具体模块。
GitHub 会过滤 README 中的
<script>/<iframe>,自包含的交互页无法内联渲染,因此上传的是一键运行链接:由 htmlpreview 直接执行normify归档分支中的normify-pyvdisk/normify.html(单文件、无外部依赖、无网络请求)。下面的 Mermaid 图则在 GitHub 上原生渲染。
graph TD
R["pyvdisk · 272 模块 / 794 API / 124 依赖箭头"]
R --> pyvdisk_storage["storage · 14"]
R --> pyvdisk_execution["execution · 4"]
R --> pyvdisk_governance["governance · 4"]
R --> pyvdisk_vscript["vscript · 10"]
R --> pyvdisk_cli["cli · 14"]
R --> pyvdisk_contracts["contracts · 7"]
R --> pyvdisk_api["api"]
R --> pyvdisk_compat["compat · 2"]
R --> pyvdisk_tests["tests · 29"]
R --> pyvdisk_docs["docs · 5"]
R --> pyvdisk_delivery["delivery · 3"]
存储与执行平面展开:
graph TD
S["pyvdisk.storage"] --> S_datadisk["datadisk · 7(事务容器)"]
S --> S_fs["fs · 23(inode/目录/块分配)"]
S --> S_vfs["vfs · 16(路径式门面)"]
S --> S_volume["volume · 8(卷与镜像冗余)"]
S --> S_log["log · 6"]
S --> S_driver["driver · 5"]
S --> S_logging["logging · 5"]
S --> S_vector["vector · 4"]
S --> S_identity["identity · 4"]
S --> S_fuse["fuse · 4"]
S --> S_block["block · 3"]
S --> S_checkpoint["checkpoint · 3"]
S --> S_wal["wal · 3"]
S --> S_rwlock["rwlock · 2"]
E["pyvdisk.execution"] --> E_operations["operations · 6"]
E --> E_queue["queue · 5"]
E --> E_service["service · 4"]
E --> E_runstate["runstate · 2"]
G["pyvdisk.governance"] --> G_namespace["namespace(能力门禁)"]
G --> G_files["files"]
G --> G_data["data"]
G --> G_scoped["scoped(ScopedDataDisk)"]
图谱产物已归档到独立的 normify 分支,不占用代码仓库的文件树;下表链接直达该分支:
| 产物 | 说明 |
|---|---|
normify-pyvdisk/normify.html |
单文件可交互图谱(272 模块 / 794 API / 124 依赖箭头) |
normify-pyvdisk/outline.md |
缩进式模块大纲,适合逐层通读 |
normify-pyvdisk/api-index.json |
全量 API 索引 |
normify-pyvdisk/tree.json |
编译产物:模块、每层布局、依赖边、内容指纹 |
normify-pyvdisk/modules/ |
272 个模块 Markdown,frontmatter 为机器可读契约(含源码路径与行号证据) |
图谱由 Normify 从仓库源码生成,每个叶子模块都带仓库内真实文件路径 + 行号区间的 source 证据与 SHA-256 指纹,冻结于 commit 6d203c0;normify_validate 结果为 0 error。
单机、单实例 Agentic 数据与执行基础设施。一个 DataDisk 承载 workspace、semantic memory、event trace、Checkpoint、Metadata、WAL 和运行状态。可以直接用于项目,并按真实负载持续增强。
零依赖:核心只用标准库,pip install pyvdisk 不需要编译任何东西(hnswlib / fusepy 都是可选加速项)。一条命令跑通全栈:
python examples/quickstart.py # 单文件、无外部依赖,Windows / Linux 通用python -m pip install -e .
python -m pip install -e ".[dev]" # 开发依赖
python -m pip install -e ".[vector]" # 可选:hnswlib 近似最近邻(不装则用内置 flat 索引)
python -m pip install -e ".[fuse]" # 可选:FUSE 挂载from pyvdisk import DataDisk
with DataDisk.create("agent.vdisk", 32 * 1024 * 1024) as disk:
disk.fs.write_file("/workspace/hello.txt", b"hello")
disk.vector.create_collection("memory", 3)
disk.vector.upsert("memory", "greeting", [1, 0, 0])
disk.log.create_stream("events")
disk.log.append("events", level="INFO", logger="demo", message="started")AgentSandbox 把 DataDisk 包成一个"给模型用的工作区":路径被限制在镜像内,工具调用全部落进哈希链审计流。
import json
from pyvdisk import AgentSandbox
box = AgentSandbox.create("agent.vdisk") # 或 AgentSandbox.open(...) 续用已有镜像
client = OpenAI().chat.completions # 换成任意框架的客户端
messages = [{"role": "user", "content": "把发现写进 /report.md"}]
while True:
reply = client.create(model="gpt-4o", messages=messages, tools=box.tools())
message = reply.choices[0].message
messages.append(message) # 不追加则模型看不到自己请求过什么
if not message.tool_calls:
break # 模型不再调用工具,结束
for call in message.tool_calls: # 一次可能请求多个工具
result = box.dispatch(call.function.name, json.loads(call.function.arguments))
messages.append({"role": "tool", "tool_call_id": call.id, "content": result})box.tools() 支持 openai / anthropic / mcp 三种 schema;box.dispatch() 永远返回字符串(失败也是字符串),可以直接塞回消息列表,被拒绝的调用也一样——模型看到的是"越权被拒"这条结果,而不是整个 agent loop 崩掉。
三个容易踩的点:json.loads 的是 call.function.arguments(不是 call.arguments);tool_calls 是列表,要逐个 dispatch 并用各自的 call.id 一一对应地回填 tool_call_id;每轮都要把 assistant 消息本身也追加进 messages。
可运行版本见 examples/agent_tools.py(内置脚本化"模型",无需 API key 与网络,因此也能进 CI)。
VScript 与 PyVDisk 共用 DataDisk、namespace、capability、事务、WAL 和审计模型,支持 Lexer、Parser、解释器、变量、表达式、循环、函数、模块、标准库、事务、rollback、task/await/parallel、cron、触发器、REPL 和盘内脚本。详细规范见 docs/VSCRIPT_SPEC.md。
pyvdisk vscript check workflow.vds
pyvdisk vscript run workflow.vds
pyvdisk vscript repl
pyvdisk vscript run-disk tools.vdisk:/.vscript/scripts/job.vds- 零外部依赖:核心仅用标准库,
dependencies = [];Windows / Linux 同一套代码(pyvdisk/compat.py收敛定位读写、文件锁、目录 fsync、uid/gid 等平台差异)。hnswlib(近似最近邻)与 fusepy(FUSE 挂载)是可选加速项,不装也能跑全栈:VectorDisk自动回退到内置 flat 索引,索引文件带写入方标识,两种后端互相可读。 - Storage Plane:FS、Vector、Log、Checkpoint、Metadata、WAL、VirtualDisk、Volume。
- Execution Plane:ExecutionService、DurableQueue、worker、lease、heartbeat、retry、idempotency、dead-letter、RunState、Audit。
- WAL 检查点:日志结算后整段截断(
wal.ckpt.json记录明细),重挂载只重放检查点之后的尾巴;DataDisk 与 VScript 共用同一份 WAL 实现,vscript run --wal是它的真实恢复入口。 - 单 DataDisk ACID:统一 txid、intent、prepare、apply、commit、abort;FS/Vector/Log 副作用走写前补偿日志,未提交事务在 mount 时被幂等补偿,不再出现"元数据回滚、副作用残留"的部分提交。
- VScript 事务撤销:每次可撤销的
fs.*变更都在生效前记账(write/remove/mkdir/rename/symlink/meta/truncate/restore_tree),进程内回滚与崩溃恢复共用同一份 undo 解释器;旧内容 ≥64 KiB 落到挂载内/.system/tx,不再整份留在内存。 - 内部 exactly-once:operation_id、结果持久化、任务去重、Log event_id 去重。
- 安全:ScopedDataDisk、路径/collection/stream scope、Host allowlist、atomic write。
- 可靠性:generation、checksum、fsync、mirror degraded fallback、remount recovery。
不实现分布式调度平台、跨机器 worker 或分布式 broker;不做多租户和旧格式迁移。内部 exactly-once 不覆盖外部邮件、支付、第三方 API 或外部数据库。VScript parallel/task/await 当前为确定性顺序语义。普通 DataDisk 是受信任管理视图,Agent 应使用 ScopedDataDisk。
pyvdisk status agent.vdisk
pyvdisk info image.vdiskstatus 只读显示 DataDisk manifest、namespace 和 RunState 计数。
| 文档 | 内容 |
|---|---|
| ARCHITECTURE.md | 详细设计架构、数据流、恢复和解释器架构 |
| CONTRACTS.md | Storage/Execution/ACID/exactly-once 契约 |
| API_GOVERNANCE.md | API、权限、边界与使用策略 |
| VSCRIPT_SPEC.md | VScript 语言、标准库和安全规则 |
.venv/bin/python -m pytest -qCI 在 3.9 / 3.10 / 3.11 / 3.12 四个版本上跑同一套用例,并额外跑一个不装任何第三方包的
no-dependencies job。两个口径的实测结果(均为 CI 输出,非本地推算):
| 环境 | 结果 |
|---|---|
.[dev,vector](装了 hnswlib) |
447 passed |
.[dev](不装 hnswlib) |
443 passed, 4 skipped |
跳过的是"两种索引后端结果一致"这类对照用例 —— 它们需要 hnswlib 与内置 flat 索引同时在场, 没装加速器时无法对照。核心路径在两种环境下都完整执行。