关于 omnigraph
omnigraph 是用于编写模式、查询和加载数据,以及管理本地或远程 Omnigraph 部署的操作技能。它强调先验证再应用模式变更、使用参数化操作,并谨慎处理远程写入结果。
主要功能
- 01使用前检查模式与查询
- 02应用前规划模式变更
- 03执行类型检查的参数化修改
- 04按明确模式加载 JSONL 数据
- 05管理图分支与别名
- 06处理远程操作及其结果
适用场景
- 01在本地验证模式和查询修改
- 02在分支上审查批量数据加载
- 03部署经过规划的模式变更
- 04重试前核对超时的远程写入
MCP 相关
该技能介绍 Omnigraph 操作,并说明如何通过别名向 Agent 暴露只读操作;未说明 MCP 服务或协议集成。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ modernrelay/ omnigraph --skill omnigraph安装后在 Claude Code 中输入/omnigraph确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/aliases.mdblobs.mdchanges.mdcluster.mdcommands.mddata.mdmigrations.mdqueries.mdremote-ops.mdschema-design.mdschema.mdsearch.mdserver-policy.mdstored-queries.md详细介绍
在本地运行 Omnigraph
本技能记录了操作本地或远程部署的 Omnigraph 的规则。编写架构、编写查询、加载数据、演进架构或自动执行图操作时,请遵循这些规则。
使用这些说明前,请先检查 omnigraph version 和命令的 --help。本技能对应当前 CLI/服务端契约,包括
Omnigraph-Http-Api: 0.14;不支持较旧的 HTTP 契约。引擎报告 internal-schema 16 (serves v14 to v16):前者是写入的存储格式,后者是其支持的格式范围。新图使用 __id/__src/__dst 系统列;已有 id/src/dst 拼写的图会保留其物理列。独立的 v8 或 v9 图(由 0.11.x 写入)或 v13 图会由离线命令 omnigraph upgrade 原位转换;v0.10 图使用 v6,需先用 0.11 二进制升级到 v9,或重新构建。请参阅升级到 v0.11 之后。替换已部署的二进制前,请阅读迁移指南。
包含 skill 命令的 omnigraph 二进制会附带为其编写的这份技能:omnigraph skill export <dir> --force 会将其写入 Agent 加载技能的位置,omnigraph skill show [<path>] 会打印一个文件。当已安装的 CLI 与编写这份副本时使用的 CLI 不同时,优先使用该副本(请参阅版本匹配的技能)。
GQ 2.1 遍历支持
0.12.0 会编译 GQ 2.1,该版本为遍历添加了带类型的边选择。v0.11 二进制无法解析此语法;尚未升级到 0.12 的部署不得使用此语法。$a (knows | likes) $b 选择命名边类型;$a * $b 从捕获的架构中选择兼容类型,并要求声明端点节点类型。
省略边界始终表示 {1,1};递归遍历需要有限边界,例如 {1,3}。$a $e:(knows | likes) $b 会绑定一跳的具体边,并公开 $e.@type 和 $e.@id。所有成员都必须存在类型兼容的公共属性;可空性和枚举域会扩大。
set traversal_work_limit = 1000000; 用于控制使用选择的语句中的共享遍历行工作量。扫描前会计入所选表的完整大小,即使查询的是具有选择性的邻域也不例外。结果限制不能替代此上限。达到上限会导致查询报错终止;已接收的行不会构成部分成功。系统会拒绝历史通配符目标。存储查询验证可能会拒绝导致通配符公共属性引用失效的架构新增项。请参阅遍历和会话设置。
七条规则
- 提交前先执行 lint —
omnigraph lint --schema schema.pg --query queries/foo.gq会验证两侧是否相互匹配。无需运行仓库。 - 先计划,再应用 — 绝不要在未成功执行
schema plan的情况下运行schema apply。应用会造成破坏;计划则不收费。(集群模式遵循同一规则,只是命令不同:先执行cluster plan,再执行cluster apply——计划会包含引擎实际执行的迁移步骤。) - 分支用于数据;apply 用于 Schema — 在功能分支上审查批量数据加载,然后合并。Schema 变更直接进入
main:在集群模式下,编辑.pg并运行cluster apply(目标为服务时会在不停机的情况下部署;目标为直接根节点时则必须停止服务;直接执行schema apply会拒绝操作由集群管理的图);对于托管服务,提交后依次运行cluster push --target managed、cluster plan --target managed --rev <rev>,再运行cluster apply --target managed --plan <run>;schema plan/apply用于非集群存储。 - 选择正确的写入命令 — 编辑使用
mutate(经过类型检查、使用参数化查询);批量 JSONL 使用load,本地或远程均可,但必须指定--mode(merge执行 upsert ·append严格插入 ·overwrite仅替换批次中包含的节点/边类型)。load --from <base>可一次性派生审查分支;单独使用load则要求目标分支已存在。 - 所有内容都使用参数化 — 绝不要在
.gq正文或--params中通过字符串插值传入值。声明$var: Type,并通过--params传值。 - 将 Agent 读取操作公开为别名 — 别名可将读取操作名称与其存储查询实现解耦。别名为只读;使用
omnigraph mutate <name> --target ...调用已提供服务的存储变更操作。 - 将远程响应丢失视为结果未知 — 有副作用的数据变更或加载会返回其确切提交,但代理可能在发布后返回 504。分支语句的结果和回执语义有所不同。超时后,先核对预期效果及相关历史记录,再重放操作。参见
references/remote-ops.md。
要点:查询、变更、加载
以下模式涵盖日常使用的 80%——只需阅读本文件,就足以正确编写 .gq 和 JSONL。更复杂的内容(多跳、否定、聚合、混合搜索、所有装饰器)请参阅 references/queries.md 和 references/schema.md。
.pg 和 .gq 中的注释使用 //,绝不能使用 #(这是最常见的解析错误)。
读取查询(.gq)
query get_signal($slug: String) {
match {
$s: Signal { slug: $slug } // inline property filter goes in the match block
$s formsPattern $p // edge FormsPattern declared PascalCase, traversed lowerCamelCase
}
return { $s.slug, $s.name, $p.slug }
}
- 使用参数化,绝不进行插值。 在签名中声明
$var: Type;通过--params '{"slug":"sig-foo"}'传值。即使签名为空,也需要括号:query foo() { ... }。 - 边遍历使用 lowerCamelCase,即使 Schema 中声明的边为 PascalCase(
FormsPattern→formsPattern)。 - 系统标识使用
@。 读取$s.@id和$e.@src/$e.@dst; 不带@的id、src和dst表示已声明的用户属性。return { $s }会返回一个包含@id及其非 Blob/非 Vector 属性的对象。schema show --json会报告图的物理system_columns;不要 在 GQ 中使用物理__id名称替代。 - 列表/排序:在
return后追加order { $s.stagingTimestamp desc } limit 50。没有order时,limit n可能返回任意n条有效记录(每次发布之间,子集可能变化);如需稳定分页,请使用排序。 nearest和rrf必须以limit N结尾 — 省略会导致编译错误。bm25不要求指定 limit,但应使用 limit 来限制排序结果的数量。排序运算符放在order { }开头,并且仍会限制记录(bm25仅保留文本匹配项;nearest会跳过 null 向量)。先使用match/过滤器限定范围,再排序(order { nearest($d.embedding, $q) } limit 10)。若要投影分数,请重复开头的排序键:return { $d.slug, nearest($d.embedding, $q) as distance }。
Mutation(.gq)
没有顶层的 mutation { }——每个块都是一个命名的 query;动词(insert/update/delete)决定它是写操作。使用 omnigraph mutate 分派(而不是 query)。(源文件也可以只包含一条分支语句——branch create|delete|merge|list;请参阅 references/queries.md。)
query add_signal($slug: String, $name: String, $brief: String, $createdAt: DateTime) {
insert Signal { slug: $slug, name: $name, brief: $brief,
stagingTimestamp: $createdAt, createdAt: $createdAt, updatedAt: $createdAt }
}
query link($from: String, $to: String) { insert FormsPattern { from: $from, to: $to } }
query retitle($slug: String, $t: String) { update Signal set { name: $t } where slug = $slug }
query remove($slug: String) { delete Signal where slug = $slug }
- 必须提供每个非空属性。 如果缺少某个属性,Lint 通常会报告 T12。携带
@embed的非空 Vector 目标是一个已知例外:仅有源文件的插入操作可能通过 Lint,但执行时仍需要该向量。请显式提供;写操作不会自动生成嵌入。 - 单个 mutation 只能包含 insert/update 操作,或仅包含 delete 操作——绝不能同时包含两者(D₂ 规则会在执行前拒绝,不产生任何影响;
lint无法检测);请拆分。 - 边插入时需提供逻辑
from/to端点 ID;无属性的边只需要这些 ID,且 GQ 中没有嵌套的data块。未设置键的边插入采用严格模式(重复插入会创建两条边)。创建边类型时,可以在其主体中声明@key(@src, @dst[, prop…]);此后插入操作会根据派生 ID 执行 upsert,相同的插入操作在两个分支上会在合并时收敛。边不能执行update(T16)。
批量加载(JSONL)
{"type":"Signal","data":{"slug":"sig-foo","name":"Foo","brief":"…","stagingTimestamp":"2026-04-14T00:00:00Z","createdAt":"2026-04-14T00:00:00Z","updatedAt":"2026-04-14T00:00:00Z"}}
{"edge":"FormsPattern","from":"sig-foo","to":"pat-bar","data":{}}
omnigraph load --data seed.jsonl --mode merge --target $GRAPH # --mode is REQUIRED (no default)
omnigraph load --data delta.jsonl --from main --branch review --mode merge --target $GRAPH # fork a review branch in one shot
--mode:merge(按逻辑实体 ID 执行 upsert;有键节点和有键边的 ID 根据其@key元组派生——重新运行 merge 文件会重复创建无键边)·append(ID 冲突时失败)·overwrite(具有破坏性,采用暂存方式)。--from <base>会为不存在的--branch创建分支;单独使用load时需要分支已存在。本地和远程均可使用。- 日期值:
Date使用日历日期字符串(YYYY-MM-DD),DateTime使用精确到毫秒的 ISO 时间戳(.123或.123000;.123456会被拒绝);mutate --params和 JSONL 均适用。load还接受表示Date的整数 epoch 天数。
分派
omnigraph alias signal --params '{"slug":"sig-foo"}' # operator alias → its bound stored read query
omnigraph query get_signal --params '{"slug":"sig-foo"}' # served stored query by name (verb asserts read vs write)
omnigraph query -e 'query q() { match { $s: Signal } return { $s.slug } limit 5 }' # ad-hoc/inline (or: --query f.gq <name>)
omnigraph mutate add_signal --query mutations.gq --params '{"slug":"sig-foo","name":"Foo","brief":"Example","createdAt":"2026-04-14T00:00:00Z"}' # name positional; ad-hoc file source
omnigraph lint --schema schema.pg --query queries/foo.gq # after EVERY .gq/.pg edit (no server needed)
.gq 语法
以下是容易忽略的要点,然后是完整语法:
- 标量参数类型:
String Bool I32 I64 U32 U64 F32 F64 DateTime Date Blob。修饰符:T?(可选)、[T](列表)、Vector(N)。没有Int——请使用I64。 - 读取查询需要同时包含
match和return(order/limit可选);变更查询两者都不包含——仅使用insert/update/delete。 limit接受整数文字,不能使用参数——limit 50,不要写limit $n。- 可变跳数遍历:
$p knows{1,3} $f——范围必须有限({1,}会被拒绝,并提示“unbounded traversal is disabled”)。跳数表示最短路径距离;每个$_都是不同的匿名节点;以__开头的变量名为保留名称。 - 无向遍历:
$p <knows> $f会匹配任一方向的边,并去重(双向连接的一对节点只出现一次)。仅支持两端点类型相同的边(例如Related: Issue -> Issue)——非对称边会被拒绝(T22)。可与范围($p <knows>{1,3} $f)和相关子句块(not { }、exists { }、count { } > 2)组合。 - 边绑定:边名称前可选加
$var:前缀——$src $w:knows $dst,无向形式为$a $w:<related> $b——绑定匹配到的边行,因此边属性可用于筛选($w.confidence = "asserted")、投影(return { $w.role })、聚合和排序。绑定遍历会为每条边返回一行(平行边仍各自独立);绑定{min,max}多跳遍历、重新绑定已使用的名称或投影裸$w都会被拒绝(T23)。 - 字面量和调用:
now()、date("2026-04-29")、datetime("…T00:00:00Z")、列表[…]。starts_with、contains、in、>=、<=、!=、>、<、=、is null、is not null
以上是完整的筛选运算符($m.number in $numbers 用于测试元素是否属于列表参数或字面量);条件可通过 and、or、not、括号以及 is null / is not null 组合。筛选器仅保留表达式结果为 true 的行(比较操作中只要有一个操作数为 null,结果就是 null)。字符串谓词精确匹配且区分大小写。聚合函数包括 count/sum/avg/min/max(count($f) as n);min/max 也接受 String、Bool、Date 和 DateTime。聚合函数可设别名,并按别名排序。
- 结果列名称必须互不相同(
T25):避免别名投影造成名称冲突。 - 存储查询元数据:可在参数列表后添加
@description("…")/@instruction("…")。 - 大小写:类型名称首字母大写(
Signal);标识符/边名称首字母小写(formsPattern);变量以$开头。仅支持//和/* */注释。
编译器语法文件 crates/omnigraph-compiler/src/query/query.pest 是唯一的事实来源。
CLI 参考(精简版)
使用 --target NAME|ADDRESS 或操作员文件中的 defaults.target,选择一个完整的目标位置。每次后端调用都会将解析后的目标打印到 stderr;机器可读结果仍输出到 stdout。遇到未知或不受支持的目标时,会拒绝执行且不会回退。源文件和当前目录都不会选择后端。--config DIR 仅用于指定源输入。
- 直接图:
--target ./graph.omni或已注册的kind: direct, scope: graph条目。 - 直接集群根目录:
--target ./cluster --graph knowledge;已注册的根目标可以设置default_graph。 - 服务:
--target production --graph knowledge;已注册的目标指定端点和一个身份验证提供方。 - 托管模式:账户操作使用
--profile work;托管目标引用该配置文件,并固定集群 ID/实例。图操作需要其端点以及--graph或default_graph。 - 直接目标仅支持本地文件。不支持云端直连、目录和 Unix 套接字目标。远程内联 URL 必须先注册。
裸目标名称从操作文件解析;内联相对路径请使用
./。init --schema schema.pg ./graph.omni是唯一提供位置参数后端地址的便捷用法。--as ACTOR会将受支持的直接操作归属到指定身份,并指定access在直接存储中报告的身份;服务目标根据凭据确定身份,并将--as作为Omnigraph-If-Actor断言发送,若身份不匹配则以actor_mismatch拒绝,并以退出码 4 退出;托管目标不接受此参数。对于破坏性非本地操作,--yes提供明确同意。目标行没有静默开关。旧版--server、--store、--cluster、--managed、--direct、图谱--uri、use和profile命令已移除。
| 类别 | 操作及适用范围 |
|---|---|
| 引擎清单 | catalogue -e '<gq>' 或 catalogue --query file.gq,可选 --json;本地操作,无需操作员配置、凭据或存储 |
| 数据 | query、mutate、load --mode overwrite|append|merge、branch、commit、snapshot、export、blob、diff、changes;适用于直接或服务目标 |
| 托管数据 | graphs list 和常见服务图谱命令,受端点能力和策略限制;没有直接维护回退方式 |
| 直接架构 | schema plan;schema apply 和 schema upgrade-system-columns 要求使用独立图谱目标 |
| 直接维护 | optimize、repair、cleanup、rebuild-full-text-indexes;upgrade --target ADDRESS 要求使用独立目标并处于离线状态 |
| 仅源文件 | lint --schema FILE --query FILE、cluster validate --config DIR;无需后端目标 |
| 根级控制 | queries list/validate、policy validate/test/explain、cluster observe/force-unlock/upgrade-ledger;直接根目标;queries list 还会读取一个服务图谱 |
| 部署 | 在直接根目标或服务端上运行 cluster plan/apply --config DIR;cluster status 仅使用目标 |
| 托管账户 | cluster create/list、organization members/invitations;使用 --profile NAME |
| 托管集群 | cluster members/pull/push/plan/apply/status/history/cancel/token/delete/undo-delete;需要完整集群目标 |
| 本地配置 | config validate/rename-profile/rename-target/recover-rename/recover-operations、target list/inspect/add/refresh/remove、skill export/show、version、embed;alias NAME 自带目标和图谱 |
| 身份验证 | 平台会话可使用 login --create-profile NAME、login --profile NAME,或 logout --profile NAME;credentials set/status/remove/export 需要明确指定配置文件或独立目标 |
| 访问权限 | access [--branch B [--target-branch T]];通过服务端的 access 路由,或对于直接图谱或根目标,通过已安装的策略报告身份及图谱策略授予该身份的操作;清单和托管目标不支持 |
| Agent MCP | mcp --target NAME [--graph G] [--write] 将 Agent 的 stdio MCP 转发到现有服务目标的 /mcp,绑定到单个图谱;除非指定 --write,否则仅提供只读工具;已取消的写入不会得到答复,但仍可能已提交;直接和托管目标不支持 |
query 和 mutate 可通过位置参数名称调用已存储的查询,也可接受
--query FILE / -e SOURCE。请使用 --params 或 --params-file,切勿将值插入查询源代码。
读取操作支持 --format table|json|jsonl|csv|kv;
--json 会保留完整的回执/错误结构。写入状态不确定时,请检查 commit 和
graph_commit_id;不要仅凭超时推断可以安全重试。
托管源代码变更使用 cluster push --config DIR --expected-revision REV,
然后使用 cluster plan --rev REV,再使用 cluster apply --plan PREVIEW_ID,这些命令都必须
指向同一集群目标。托管式 plan/apply 会拒绝本地 --config。创建操作会返回标识;它不会选择新的目标或绑定文件夹。提供方不会相互回退。保留未解决的生命周期证据,并通过显式调用
config recover-operations --source DIR --profile NAME
来协调旧版文件夹证据;没有配置导入器或自动迁移。
对于直接恢复,cluster apply --target ROOT --deployment-id ID --writers-stopped 不接受 --config:它会协调已有尝试。使用调用方 ID 进行全新 apply 时,必须显式指定 --config;重用已有 ID 只会观察该尝试。完整命令形式和边界条件见
命令和集群操作。
模式设计
Omnigraph 模式是本体;当许多 Agent 共用一张图时,模式就是它们的坐标系:它决定事实存放在哪里、已存储的值意味着什么,以及 Agent 会沿着哪些路径推理。设计时应追求收敛:
两个 Agent 获得相同输入时,应写入同一张图,并读回相同的含义。谨慎决定要建模的内容;一旦建模,就应精确约束,因为之后收紧约束需要重建(拒绝添加
@key/@unique/@range/@check、更改基数,以及将 T? → T;只有添加
@index、添加可空字段、扩展枚举、重命名和删除可以原地应用)。
简而言之:遵循 Gruber 的五项标准(清晰 · 连贯 · 可扩展 · 最小编码偏差 · 最小承诺)· 既不能过于宽松(一个含义,多种编码),也不能过于严格(含义无对应编码):在 Agent 必须收敛之处严格,在声明的扩展点保持开放 · 先将问题写成 .gq ·
先设计身份(@key、带键边、先查找再创建)· 种类是类型,角色是边 · 将事实放在决定该事实的对象上 · 将归属、依据、置信度和时间分置于不同维度 · 溯源信息应是结构化的(Claim → 事实、Actor、Source),绝不能是自由文本 source 字段 · 在原始片段之上构建提取和综合所得的知识,并保留回溯至这些片段的脉络;按事实设键(片段 + 提取器 + 陈述摘要)· 存储决策,计算派生事实 · 使用狭窄类型和封闭词汇 · 在模式中定义约束;模式无法表达的规则,应作为 GraphPolicy 节点,由 Agent 对图进行检查,其中包括每个必需链接的孤立节点检查(@card 绝不会将一个未写入任何边的节点计为有效)· 围绕共享身份组合构建(模块添加方面,绝不修改核心),并从可组合的一般原语出发 · 优化检索:用链接提升召回率,用特定边、筛选器和适合回答的单元提升精确率 · 编写名称、@description 和 @instruction,让没有上下文的读者也能理解 · 绝不重新赋予字段其他用途 · 用两个独立编码器衡量收敛情况。完整说明及 Omnigraph 映射见:
references/schema-design.md。
存储与凭据
图谱的字节数据存储在以下三类受支持的 URI 中:
- 本地文件系统 — 路径或
file://URI。目标会明确指定图谱或集群根目录;源目录不会指定存储位置。本地开发无需对象存储。 - 兼容 S3 的对象存储 — AWS、Railway、Tigris 等(
s3://bucket/prefix)。使用标准的AWS_*环境变量约定进行身份验证。 - Azure Blob 存储预览版 —
az://container/prefix。支持读取和 Azurite 资格验证,但 Azure 尚未获得生产环境支持;所有写入或维护流程都必须通过作用域限定为根目录的omnigraph-azure-admission包装器启动。
公共 CLI 仅接受本地直接目标。对于云端图谱,请使用已注册的服务或托管目标;服务或嵌入式宿主负责管理存储凭据。将开发凭据保存在被 git 忽略的 .env.omni 中,并在启动需要这些凭据的进程前加载该文件:
set -a && source .env.omni && set +a
直接执行 init/load 和直接执行 cluster apply,都会在没有 HTTP 服务的情况下写入本地存储。通过服务执行 load 或 cluster apply 时,请求会发送到 omnigraph-server,由它使用自己的存储凭据执行写入。托管的 cluster apply --target NAME --plan PREVIEW_ID 则通过配置文件对应的控制平面提交。服务进程需要具备读写存储权限,才能写入服务的数据平面。使用 curl http://127.0.0.1:8080/readyz 进行验证(HTTP 200,ready: true;/healthz 只能证明进程正在运行),然后执行 omnigraph snapshot --target <name> --graph <id> --json。
项目布局
部署与访问
- 集群部署 — 唯一的服务方式。
cluster.yaml声明整个部署(图谱、架构、存储查询、策略,以及可选的 S3/Azurestorage:根目录);omnigraph cluster apply会使部署收敛至期望状态,而omnigraph-server --cluster .(或--cluster s3://bucket/prefix,无需配置文件)会提供服务。直接执行 apply 时会保留其准入锁:写入完成后,在启动服务前使用cluster force-unlock <LOCK_ID>释放该确切锁;后续变更则使用已注册的服务目标,通过cluster apply --target NAME --config DIR发送。 参见references/cluster.md。 - 直接/嵌入式访问 — 无需服务。 使用本地路径或
--target file:///absolute/path/graph.omni直接访问图谱的存储;init也接受以位置参数传入的创建 URI。 不存在单图谱服务模式——服务仅支持集群模式。 - Agent — 每种场景各有一种方式。 在终端中,Agent 使用
--target运行 CLI 命令,或使用omnigraph mcp --target NAME将其 MCP 客户端连接到现有服务目标(参见references/commands.md中的 Agent MCP);在 Studio 的 Agent 面板中,则使用 Studio 的网关。任何方式都不会启动服务。
两种配置界面
团队负责维护 cluster.yaml 及其引用的架构、查询和策略。
操作员负责维护 ~/.omnigraph/config.yaml 中的 version: 1 文档。
OMNIGRAPH_HOME 用于更改操作员目录;--operator-config FILE
用于指定一个替代文件,不会合并配置。--config DIR 用于指定部署源。
完整的架构、提供方、传输方式、默认值和升级流程,请参阅主要的操作员参考文档。
配置文件用于固定 API/组织,并为一个身份指定一个身份验证提供方。托管目标
引用一个配置文件,并固定集群 ID/实例。独立服务目标
负责管理端点/身份验证。直接图谱/根目标使用绝对本地 file:// URI。
每个独立目标仅使用一个身份验证提供方;同一端点上的不同身份应使用不同目标。--auth 选择器已移除。托管
目标使用其固定的配置文件;默认/全局配置文件无法覆盖该配置。defaults.profile 和 defaults.target 仅适用于各自对应的命令
类别。图谱选择器会覆盖目标的 default_graph;直接图谱不接受此设置。读取输出默认采用 table。整个文档的验证在离线状态下进行。
omnigraph config validate
omnigraph login --create-profile work
omnigraph cluster list --profile work --json
omnigraph target add production --profile work --cluster CLUSTER_ID
omnigraph target inspect production --resolved --json
omnigraph credentials status --profile work --json
切勿在配置中放入机密信息。身份验证提供方包括 omnigraph(托管设备
登录)、token(必须且只能指定一个 store、env 或 file 来源)、exec(绝对路径的 argv,采用有界 JSON 协议),以及仅限独立目标使用的 anonymous。不允许回退。
静态安装使用 credentials set --stdin,而非登录;已有条目需要指定 --replace。托管凭据需要指定 --profile NAME;独立
凭据需要指定 --target NAME。状态检查不会使用网络/辅助程序,也不会显示提示;不读取机密信息时,安全存储是否可用以及身份信息均为未知。导出时只会将原始 bearer 加换行符写入管道,
绝不会输出到终端/文件;导出托管目标凭据会授予数据访问权限;--profile 导出控制访问权限。
两种导出都不会包含刷新令牌。使用凭据命令前,请先阅读参考文档。
使用 config rename-profile FROM TO 或 config rename-target FROM TO 可保留凭据归属并更新
引用/默认值。重命名中断后,必须针对同一个操作员文件运行 config recover-rename;若存在冲突的编辑,命令将拒绝执行。这些命令不支持 --json。
更改配置文件对应的主体时,必须运行 login --profile NAME --replace-principal NEW_PRINCIPAL_ID,以匹配已验证的新身份并使旧的派生凭据失效。请参阅主要的操作员参考文档。
login --create-profile NAME 会显式创建一个新的配置文件,其 API 默认值为
https://platform.omnigraph.dev。不带参数的 login 使用 defaults.profile;如果配置文件不存在,则不会创建。两种形式都不会更改路由默认值。操作员 YAML
可能是只读的;凭据元数据会保存在可写的 OMNIGRAPH_HOME 中。
凭据在发现过程中会保留其过期时间,并在分发前进行检查。
传输方式默认使用经过验证的系统 TLS 和直连路由;除非显式启用代理,否则会忽略代理
变量。自定义 CA 与 HTTPS 代理不兼容。此模型不支持 BYOC 私有路由或工作负载联合身份验证。直接别名
无法执行服务端管理的存储查询注册表。
不提供向后兼容,也不存在 target import。请重新构建旧配置,
保留旧的操作员主目录,并使用兼容的工具处理尚未完成的操作。
凭据和发现机制都不会补全缺失的目标位置。
应提交的内容
提交: schema.pg、queries/*.gq、cluster.yaml、seed.md、seed.jsonl,以及项目的 README.md 和 CLAUDE.md。
忽略: .env.omni(凭据)、.claude/(本地 Agent 状态)、*.omni/(本地图谱产物)、__cluster/ 和 graphs/(集群状态及派生图谱根目录)。
为 Agent 提供 CLAUDE.md
每个项目的 CLAUDE.md 会告诉编码 Agent 文件所在位置以及需要遵循的约定。没有它,Agent 每次会话都会重新探索相同的内容。
常见问题
以下是最容易踩中的陷阱。调试任何解析或运行时错误之前,请先查看此表。
| 陷阱 | 症状 | 修复方法 |
|---|---|---|
.pg 中的 # 注释 | parse error: expected schema_file | 使用 // |
独立的 enum Foo { ... } 块 | parse error: expected EOI or schema_decl | 内联:kind: enum(a, b) |
[Category](枚举列表) | 编译错误 | 使用 [String];列表必须包含标量 |
认为 @embed 必须为其来源加引号 | 不必要的架构变更 | @embed(text) 和 @embed("text") 都有效;带引号的形式是规范形式 |
在新图的边约束中直接使用 src/dst | 离线 lint 通过;init/schema plan 失败,报错 unknown property reference 'Knows.src'; the system field is '@src' | 在边体内使用 @unique(@src);src 表示已声明的用户属性 |
在新图中使用 _ 前缀属性 | property name '_x' is reserved for system columns (names starting with '_') | 重命名;from/to 在边上也属于保留名称(is reserved on edge types) |
以为 @embed 会在加载时填充向量 | 向量缺失或过期 | @embed 是元数据;运行离线 omnigraph embed ... --reembed-all 文件流水线,然后加载其输出 |
有功能分支未关闭时运行 schema apply | schema apply requires a graph with only main | 删除这些分支(使用 merge --delete-branch 或 branch delete);仅合并不会删除分支 |
使用 nearest(...) / rrf(...) 却未指定 limit | 编译错误 | 添加 limit N;仅 BM25 的查询可以省略,但建议限制输出 |
| 添加非空属性但未回填 | 不支持的迁移 | 先设为可选 → 回填;保持可选(不允许将 T? 收紧为 T,OG-MF-106) |
omnigraph init --json | unexpected argument '--json' found | init 不支持 --json;移除该标志 |
对已初始化的 URI 运行 omnigraph init | graph already initialized or initialization metadata exists at '<uri>' | 切勿覆盖。只有在确认不存在图清单后,--force 才会替换孤立的架构文件 |
schema apply 删除属性/类型 | 应用时不会回收任何空间;较早的提交仍能读取已删除的数据 | 若要回收空间,运行 cleanup,并设置不包含删除前提交的保留范围;之后将无法恢复这些数据 |
提交 .env.omni | 凭据泄露 | 将 .env* 添加到 .gitignore |
| 查询值未参数化 | 类型检查结果意外,存在注入风险 | 声明 $param: Type,并通过 --params 传入 |
insert 缺少必需字段 | T12: insert for `X` must provide non-nullable property `Y` | 在变更签名中接收该参数 |
在同一个查询中混用 delete 和 insert/update | lint 通过;mutate 失败,报错 "mixes inserts/updates and deletes" | 拆分为两个变更(D₂ 规则) |
在 v0.10 查询中使用 $p.id、{ id: $v }、where id = | T6/T2/T11:type `Person` has no property `id`; the system identity is `$p.@id` (存储查询注册表检查失败会隔离其图) | 使用 $p.@id、$e.@src/@dst、where @id =;在 v0.11 或更高版本上重启前,对每个 .gq 运行 lint |
| 长期存在的功能分支 | 合并冲突,阻止应用架构 | 尽快合并;完成后删除 |
.gq 中的 mutation { ... } 包装器 | 第 1 行出现 parse error: expected query_file | 使用 query <name>(...) { insert T { ... } };不存在顶层 mutation 关键字 |
在数据/架构命令中使用 --config | unexpected argument '--config' found | 仅在需要指定来源的集群命令中使用;使用 --target 选择目标 |
--as 指定的名称与服务端写入令牌对应的 Actor 不同 | actor_mismatch(退出码 4) | 使用该 Actor 的令牌,或移除 --as;持有者令牌决定 Actor |
| 通过 stdout 输出受限的工具读取大型架构 | 输出被截断、乱码或重复 | 运行 omnigraph schema show --target <name> --graph <id> > /tmp/schema.pg,然后分块读取文件 |
运行 omnigraph load 时未指定 --mode | the following required arguments were not provided: --mode <MODE> | 传入 --mode merge|append|overwrite——没有默认值(overwrite 会造成破坏,因此绝不会隐式启用)。指定直接存储或服务端图 |
| 收到 504 后盲目重试 | 出现重复的未设键节点/边,或重复生效 | 先比较预期的分支/实体状态;只有确认操作未生效后才重试 |
load --from 超时后留下的审查分支 | 加载结果不确定 | 检查其内容和历史;仅与 main 的头部匹配,并不能证明该分支已被放弃或获准删除 |
对集群管理的图运行 omnigraph schema apply / init | 操作被拒绝——绕过集群账本 | 通过 omnigraph cluster apply --target ROOT --config . 演进集群图;schema apply/init 适用于非集群存储 |
| 认为含 Blob 的数据无法压缩 | 不必要地跳过维护 | 支持 Lance 13 Blob 压缩;optimize 会保留空值、空内容和非空值 |
在 Blob 列上使用 @unique/@index | 架构解析/验证被拒绝 | Blob 属性不能作为键、设为唯一或建立索引 |
对使用早于 Lance 11 版本构建的索引进行全文搜索(包括 v0.9 时代的索引),即使已运行 omnigraph upgrade 也是如此 | FullTextIndexRebuildRequired | 停止混合版本访问,并在每个需要文本搜索的活动分支上运行 rebuild-full-text-indexes --branch <b>;upgrade 不会重建这些索引 |
| 使用 v0.12 重新打开 v0.10/v6 图 | __manifest is stamped at internal schema v6, but this omnigraph reads only v14 to v14 | 停止旧版本集群;对独立图先使用 0.11 upgrade 升至 v9,再使用 0.12 upgrade 升至 14,或通过导出、init 和 load --mode overwrite 重建 |
在有分支或包含 _ 属性的图上运行 0.11 二进制的默认 omnigraph upgrade | the route ends at v9, which requires a graph with only main(或 reserves property names starting with '_') | 先删除分支 / 使用 @rename_from,或在检查和执行时都传入 --to-format 8;0.12 upgrade 也会转换 v8,而不仅是 v9 |
| 使用 0.12 打开 v8 或 v9 图 | 操作被拒绝:0.12 仅读取格式 14,并提示 omnigraph upgrade | 停止所有使用该图的进程,备份整个根目录,然后对独立图运行 0.12 upgrade --check 和 upgrade;集群管理的图需使用 0.11.x 导出并重建。参见升级到 v0.11 之后的版本 |
在新图上使用 data.id 作为标识 | unknown input field 'id': move data.id to the top-level 'id' field | 将标识放在 JSONL 顶层的 id 中;data 包含用户属性 |
对包含未设键边的 --mode merge 加载重复运行 | 边重复 | 提供稳定的顶层边 id,或在创建边类型时声明 @key(@src, @dst) |
| 认为每个 JSON 结果单元格都有键 | null 值对应的键缺失 | 查询/导出的 JSON 会省略 null 单元格;变更图像会保留显式 null |
defaults.output: arrow | 配置被拒绝 | 使用 table、json、jsonl、csv 或 kv |
cluster.yaml 相对路径中包含 .. 或符号链接 | config_path_escape / config_path_symlink | 将所引用的文件放在配置目录内,并使用普通相对路径 |
| 旧版运算符格式 | 配置被拒绝 | 将其替换为 version: 1;保留日志,并在弃用旧工具前协调尚未解决的工作 |
同时应用了图和 cluster 包的策略命令 | matches 2 policy bundles | policy validate/test/explain --graph 的当前限制;请直接检查每个包文件 |
深入参考
如果需要了解基础内容以外的信息,请加载相关参考文件。每个文件都是自包含的——只加载所需内容。
| 参考文件 | 何时加载 |
|---|---|
references/schema.md | 编辑 .pg 文件、运行 schema plan/apply、重命名类型、回填必填字段 |
references/schema-design.md | 设计或审查 schema:Gruber 的标准、设计流程、身份、来源、GraphPolicy 规则、组合,以及衡量多个 Agent 间的收敛情况 |
references/queries.md | 编写或 lint .gq 文件、搜索函数、聚合、多跳模式 |
references/data.md | 在 mutate 和 load 之间进行选择(必需的 --mode、用于分叉审查分支的 --from);分支审查工作流;精确覆盖范围 |
references/blobs.md | 写入和读取托管/外部 Blob 值、选择器/范围、安全与生命周期边界 |
references/changes.md | 精确的读写位置、条件变更、提交差异、feed 游标、基线和保留间隙 |
references/remote-ops.md | 通过 --target 操作:精确回执、未知的 504 结果、冲突处理和安全重试决策 |
references/cluster.md | 集群配置、plan/apply、漂移和服务 |
references/search.md | 嵌入、@embed、向量/文本排序、先限定范围再排序的模式 |
references/aliases.md | 为 Agent 定义别名、结构化输出、JSON 参数 |
references/stored-queries.md | 集群存储查询注册表:声明、queries validate/list --target、服务端调用,以及 invoke_query Cedar 门控 |
references/server-policy.md | 启动 HTTP 服务、路由、Bearer 身份验证、Cedar 策略门控、多图模式 |
references/commands.md | 当前命令格式、寻址、输出和维护 |
references/migrations.md | 将 v0.11 图升级到存储格式 14;v0.11 存储/系统列升级和 wire 变更;更早的 v0.9→v0.10 和 pre-0.7 边界 |