查看 Markdown

语义 SDK(Semantic)

Semantic 是 AIDC 的数据平台(照 Palantir Foundry:Data Connection + Ontology + Automate + Security)。企业数据的一切都在这里:数据从哪来、存成什么对象、谁能看、谁改了什么、变了之后自动做什么、花了多少钱。ERP / MES / OA 这些数据源永远只读;应用和智能体读对象集、用 Action 改(参数校验、谁能做、留痕)。

ERP / MES / OA ──(发布端,只读)──▶ 数据流 ──(Object Type 定义里的 datasources)──▶ Semantic(对象 · 链接 · Action)──▶ 应用 · 智能体 · 自动化 · SQL
import { semantic } from "/developer/sdk/v1/aidc.js";

Semantic 是数据平台

要做什么 用什么 Palantir 里叫
读对象、沿链接走、聚合 semantic.ontology().objects(t).where(…).fetchPage() / aggregate() / pivotTo() Ontology SDK(OSDK)
实时 objectSet.subscribe({ onChange, onOutOfDate }) Object set subscription
改数据 client.action(a).applyAction(…)(只有这一条写路径) Actions
数据从哪来 semantic.streams / semantic.stream() + Object Type 定义里的 datasources Data Connection · Streams · backing datasource
SQL semantic.sql() / semantic.database() Ontology SQL
谁能看 semantic.filesystem(Private / Group / Public / Open to Internet)· semantic.admin(当前账号、成员) Filesystem ResourceRoles · Admin
变了做什么 semantic.automate(数据变化 / 定时 → Action、模型分析、通知) Automate
留痕与用量 Action Log、editsHistory、semantic.observability、semantic.usage,平台对象类型 aidcModelUsage / aidcAppEvent / aidcAutomationRun Action log · Observability · Resource Management
建本体 分支与提案(智能体作者,人在网页上审核合并) Global Branching · Ontology proposals

原来的连接、数据、权限、工作流、日志、账单六个 SDK 就是上面这些部分,1.20.0 起都在 semantic 里。旧名照样能用、和新家是同一份实现:connect.stream === semantic.stream、auth.me === semantic.admin.getCurrentUser、workflow.run === semantic.automate.run、log.feedback === semantic.observability.feedback、billing.summary === semantic.usage.summary,connect.agent 搬到了 model.agent;应用清单 sdk 里写旧名也照收(归一成 semantic)。

数据从哪来:数据流与数据源

数据在源头一变,源头旁边的发布端(aidc semantic streams pipe + 适配器,只读)就把变化推上来,平台按序落账(数据流)。数据流接到哪个 Object Type、哪一列对哪个属性,写在 Object Type 的定义里(照 Palantir:Ontology Manager 的 Datasources 页选 backing datasource)——改数据源就是改本体:

{ "kind": "objectType", "apiName": "production.order_line", "title": "工单线体进度",
  "schema": {
    "columns": [ { "name": "order_no", "type": "string", "primaryKey": true }, { "name": "line_code", "type": "string", "primaryKey": true }, … ],
    "datasources": [
      { "type": "stream", "stream": "production-progress", "propertyMapping": { "order_no": "aufnr", "line_code": "line", "ok": "gmnga" }, "mode": "mirror" }
    ] } }
aidc semantic streams create production-progress --title "生产进度" --key key --field key --field aufnr --field line --field gmnga:number
aidc semantic streams key production-progress --label "SAP 旁边的发布端"      # aidc-pk-…,只显示一次
aidc semantic datasource set production.order_line --stream production-progress --map order_no=aufnr --map line_code=line --map ok=gmnga
aidc semantic datasource list                                                    # 每个类型的数据源与同步进度
aidc semantic datasource sync                                                    # 平台数据源立即同步(= /semantic 的「立即同步」)
await semantic.streams.create({ name: "orders", title: "订单", key: "order_no", fields: [{ name: "order_no" }, { name: "qty", type: "number" }] });
const pub = semantic.stream("orders").publisher();   // 发布端:只发与上次相比的差
await pub.rows(await readErpOrders());

实时:订阅对象集

const client = semantic.ontology();
const issues = client.objects("production.order_line").where({ status: "异常" });
const sub = issues.subscribe({
  onChange({ object, state }) { state === "REMOVED" ? drop(object.__primaryKey) : upsert(object); },
  onOutOfDate() { reload(); },            // 整个对象集要重读:刚订阅时来一次、断得太久、依赖的类型变了
  onError({ subscriptionClosed, error }) { if (subscriptionClosed) showOffline(error); },
}, { properties: ["line_code", "gap", "status"] });
// sub.unsubscribe()

写法照 Palantir OSDK 的 objectSet.subscribe:对象进来或变了 → ADDED_OR_UPDATED(带属性),离开对象集(被过滤掉、删了、源头消失)→ REMOVED(只带主键)。同步、Action、别人的修改都会推过来;断线自动带着序号续传,不丢不重;页面隐藏超过 1 分钟断开、切回续上;应用里的连接时长计入应用的计算分钟。CLI:aidc semantic subscribe <类型> [--where '{…}']。官方走 WebSocket,AIDC 在同一路径(/api/v1/ontologySubscriptions/ontologies/{ns}/streamSubscriptions)走 SSE,消息一样。

访问与账号

const me = await semantic.admin.getCurrentUser();      // 我是谁、什么角色、能读哪些类型、能执行哪些 Action
if (!me.signedIn) semantic.admin.signIn();
await semantic.filesystem.setResourceAccess(rid, "public");                        // Private / Group / Public / Open to Internet
await semantic.filesystem.shareResource(rid, { group: "cell-acme:dept:ops", role: "viewer" });
await semantic.filesystem.shareApplication({ audience: "company" });                // 应用的分享

开放程度四档、Owner / Editor / Viewer 三种角色、只有 Owner 改分享;资源是 Ontology、Object Type、数字员工、文件。详见访问与账号。

数据安全:Markings 与安全策略

财务、薪资、采购价、技术配方这类数据也进 Semantic,照 Palantir 用两种控制管住。上面的开放程度和角色决定「能不能打开这个资源」,下面这些再往里管到每一行、每一列:

控制 挂在哪 怎么判
Markings(强制控制) Ontology、Object Type、数据流、TableImport;或者写在行上(marking 类型的属性) 挂着的 Marking 全都满足才看得见(同一个 DISJUNCTIVE 类别里满足任一即可)。不看角色,Owner、开发者也一样;只限制、不授予;沿层级(Object Type ← Ontology)和数据依赖(数据流 → 用它的类型的对象)传播
对象安全策略(行) Object Type 定义里的 objectSecurityPolicy 按对象的属性和读的人(组、账号、用户属性、行上的 Marking)判断每个对象看不看得见
属性安全策略(列) Object Type 定义里的 propertySecurityGroups 一组属性要另外满足的条件或 Marking;不通过的人读到 null,也不能拿它筛选、排序、求和

先建 Marking,再挂到资源上或写进定义:

aidc semantic admin marking-categories create --name 数据分级                  # 类别:本组织开发者建
aidc semantic admin markings create --name 薪资 --category <类别 id> --member cell-demo:dept:hr
aidc semantic admin markings grant <薪资 id> USE <HR 负责人账号 id>             # USE = 可以把它挂到资源上
aidc semantic filesystem mark <配方类型的 rid> <技术配方 id>                    # 整个类型挂 Marking(要 USE、是类型的 Owner)
aidc semantic filesystem markings <rid>                                         # 直接挂的 + 继承来的

Marking 和类别建了不能删。角色:ADMINISTER 管成员与角色,USE 挂上,DECLASSIFY 去掉或停止继承;角色和成员互相独立(管 Marking 的人不一定看得见它保护的数据)。

行和列写在定义里(Demo Company 的员工薪酬;Marking 一律用 id 引用,aidc semantic admin markings list 查):

{
  "kind": "objectType", "apiName": "employeeCompensation", "title": "员工薪酬",
  "schema": {
    "columns": [
      { "name": "employeeId", "type": "string", "primaryKey": true },
      { "name": "accountId", "type": "string" },
      { "name": "baseSalary", "type": "decimal" },
      { "name": "rowMarkings", "type": "array", "arraySubType": "marking", "notNull": true }
    ],
    "objectSecurityPolicy": {
      "name": "compensation-rows",
      "granularPolicy": { "type": "and", "conditions": [
        { "type": "markingProperty", "property": "rowMarkings" },
        { "type": "or", "conditions": [
          { "type": "group", "name": "cell-demo:dept:hr" },
          { "type": "comparison", "comparison": { "operator": "EQUAL",
            "left": { "type": "userProperty", "userProperty": { "type": "userId", "userId": {} } },
            "right": { "type": "property", "property": "accountId" } } }
        ] }
      ] }
    },
    "propertySecurityGroups": [{ "name": "pay", "properties": ["baseSalary"], "appliedMarkings": { "<薪资 id>": "MANDATORY" } }],
    "dataSecurity": { "markingConstraint": { "markingIds": ["<高管薪酬 id>"] } }
  }
}

意思是:HR 部门或本人看得见这一行,行上带的 Marking(比如高管的行带「高管薪酬」)也要满足;金额另外要「薪资」。其他三类数据的常见配法:

数据 配法
财务 Marking「财务」挂在 ERP 财务数据流上,用这条流的类型自动带上
采购价 采购订单行对采购员可见,unitPrice 放进属性安全策略,要「采购价」
技术配方 配方类型整个挂「技术配方」,成员只给研发负责人

规则(照 Palantir):

试策略(照 Ontology Manager 的 Test security policies;只给开发者,结果不带属性值):

aidc semantic security test employeeCompensation --user <账号 id> --pk e1,e2
aidc semantic security test employeeCompensation --user <账号 id> --object '{"employeeId":"x","rowMarkings":[]}' --policy 新策略.json

SDK:semantic.admin.createMarking / addMarkingMembers / addMarkingRoleAssignments…、semantic.filesystem.addMarkings / removeMarkings / resourceMarkings、client.testSecurity(类型, {…});读对象时带 $loadPropertySecurityMetadata: true(照 OSDK),受属性安全策略保护的值会带上它的安全标记。

自动化(Automate)

数据一变(或到了时间)就做事:写在工作流应用的清单 workflow 里,照 Palantir Automate——条件(trigger.change = 对象新建 / 修改,when 过滤;trigger.schedule = 时间;手动)加效果(Action、模型分析、通知)。

const { run } = await semantic.automate.run({ rfq_no: "RFQ-001" }, { slug: "quote-workflow", mode: "preview" });
semantic.automate.watch(run.id, { onRun: draw, onDone: finish }, { slug: "quote-workflow" });

触发读的是 Semantic 的变化账(和对象集订阅同一条),不轮询、不写 cron。详见自动化。

留痕与用量

const byDay = await client.objects("aidcModelUsage").aggregate({ $select: { "costUsd:sum": "desc" }, $groupBy: { day: "exact" } });
const openFeedback = await client.objects("aidcAppEvent").where({ kind: "feedback", status: "open" }).fetchPage();

Ontology(照 Palantir)

语义层的建模语言、名字和 API 形状全部照 Palantir Ontology(设计:docs/semantic-ontology.md)。上面的写法(describe、objects、action().apply)继续可用;新写法是 semantic.ontology(),与 Palantir 的 OSDK 同形。示例取自 Demo Company 的示例本体(打开示例,要先登录 AIDC 账号;命名空间 cell-demo,全部是虚构数据;定义与数据在 developer/apps/ontology-demo-data/,应用在 developer/apps/ontology-demo/)。

语义部分(名词)

Palantir 构件 是什么 Demo 里的例子
Object Type 一类对象:主键、title、属性 customer 客户公司、agent 智能体、application 应用、modelUsage 模型用量、cloudCost 云费用
Property 属性;base type 照官方(string、integer、long、double、decimal、boolean、date、timestamp、array、struct、geopoint、vector、timeseries…) customer.location(geopoint)、customer.contact(struct)、modelUsage.dailyTokens(timeseries)
Derived Property 沿链接读时计算(最多 3 跳;count、sum、avg、min、max、collectList、collectSet) customer.agentCount = 智能体个数;customer.modelCostUsd = 模型费用合计
Link Type 两个 Object Type 的关系,两端各有名字;1:N 用外键,N:M 另存每一条链接 customerAgents:customer.agents ↔ agent.customer;applicationAgents(N:M)
Interface 多个 Object Type 共有的形状,可以继承 Billable(继承 Monthly):modelUsage 和 cloudCost 都实现它,可以一起按月汇总成本
Shared Property 跨类型复用的属性定义 costUsd、month
Value Type 带约束的类型(enum、range、length、regex…),写入时校验 cellId(cell- 开头)、yearMonth、customerStage(试点 / 付费 / 暂停)

动力部分(动词、函数)

Palantir 构件 是什么 Demo 里的例子
Action Type 受控的写操作:参数 + 规则(createObject、modifyObject、createOrModifyObject、deleteObject、createLink、deleteLink)+ 提交条件(submission criteria) adjust-seats:座位数不能少于成员数;assign-agent:给应用接入一个智能体(建一条 N:M 链接)
Action Log 开了 actionLog 的 Action,每次成功执行都写一个 log.<action> 对象 log.adjust-seats:谁在什么时候把哪家的座位数改成多少
Object Set 对象的集合:过滤、并 / 交 / 差、沿链接走(searchAround)、按接口取、派生属性 付费客户的全部智能体
Function 代码写的逻辑,在隔离运行时里执行 要补(还没有隔离运行时);queryTypes 现在返回空列表

定义

定义还是 JSON,kind 用 Palantir 的名字(objectType、linkType、actionType、interfaceType、sharedPropertyType、valueType;旧的 object、link、action、enum 照旧可用)。

{
  "kind": "linkType",
  "apiName": "customerAgents",
  "title": "公司的智能体",
  "schema": {
    "from": "customer", "to": "agent", "cardinality": "ONE_TO_MANY",
    "apiNameAtoB": "agents", "apiNameBtoA": "customer",
    "foreignKey": { "side": "to", "property": "customerId" }
  }
}
{
  "kind": "actionType",
  "apiName": "adjust-seats",
  "title": "调整座位数",
  "schema": {
    "parameters": [
      { "name": "customer", "type": "object", "objectType": "customer", "required": true },
      { "name": "seats", "type": "integer", "required": true, "min": 1, "max": 10000 }
    ],
    "rules": [{ "type": "modifyObject", "objectType": "customer", "object": "$customer", "values": { "seats": "$seats" } }],
    "submissionCriteria": [{
      "condition": { "type": "comparison", "left": { "param": "seats" }, "operator": "gte", "right": { "param": "customer", "property": "members" } },
      "failureMessage": "座位数不能少于成员数"
    }],
    "actionLog": true
  }
}

名字照官方大小写:Object Type、Property、Link Type 两端、Value Type、Shared Property 用 camelCase,Action Type 用 kebab-case,Interface 用 UpperCamelCase。

从零做一个会执行的 Action(定义、只校验、执行、提交条件、命令行 / SDK / REST、做成应用、交给自动化):Academy 课程《动手:做一个会执行的 Action》,配套样板见样板应用的「座位申请」。新的 Object Type 只能有一个主键属性(旧的复合主键类型照旧可用,定义时给警告)。

定义里写了不认识的字段(多半是拼错了,比如把 submissionCriteria 写成 submissionCriterias)会直接被拒,错误信息给出路径——以前这类字段会被悄悄丢掉,Action 就少了提交条件。

Action 改源系统:writeback webhook

照 Palantir(Action 的 webhook):Action 可以配一个 writeback webhook——校验通过之后、规则之前调用源系统;源系统拒绝(或超时)就整个 Action 不生效,语义层一条都不改,原因原样返回给执行人(webhook_failed)。webhook 的输出在规则里用 $writeback.<输出名>。

{
  "kind": "actionType",
  "apiName": "stop-ec2-instance",
  "title": "关机",
  "schema": {
    "parameters": [{ "name": "instance", "type": "object", "objectType": "ec2Instance", "required": true }, { "name": "reason", "type": "string" }],
    "submissionCriteria": [{ "condition": { "type": "comparison", "left": { "param": "instance", "property": "state" }, "operator": "is", "right": { "literal": "running" } }, "failureMessage": "只有运行中的实例能关机" }],
    "webhooks": { "writeback": { "webhook": "aws/ec2-stop-instances", "inputs": { "region": "$instance.region", "instanceId": "$instance.instanceId", "expectedLaunchTime": "$instance.launchTime" } } },
    "rules": [{ "type": "modifyObject", "objectType": "ec2Instance", "object": "$instance", "values": { "lastAction": "stop", "lastActionAt": "$now", "lastActionResult": "$writeback.currentState" } }],
    "roles": ["developer"],
    "actionLog": true
  }
}

读与写(OSDK 写法)

const client = semantic.ontology();                        // 应用里自动取应用所在公司;CLI / 智能体用 Key 所属公司

const paying = client.objects("customer").where({ stage: "付费", seats: { $gt: 30 } });
const page = await paying.fetchPage({ $orderBy: { seats: "desc" }, $pageSize: 20 });
// page.data[i]:{ __primaryKey, __apiName, __title, name, seats, location: { type: "Point", coordinates: [...] }, … }

const agents = await paying.pivotTo("agents").fetchPage();  // 沿链接走(searchAround)
const one = await client.objects("customer").fetchOne("cell-demo-a");

// 聚合(结果形状同 OSDK)
const byMonth = await client.interface("Billable").aggregate({ $select: { "costUsd:sum": "desc" }, $groupBy: { month: "exact" } });

// 派生属性
const withCost = client.objects("customer").withProperties({ apps: (b) => b.pivotTo("applications").aggregate("$count") });

// Action:先只校验,再执行
await client.action("adjust-seats").applyAction({ customer: "cell-demo-a", seats: 60 }, { $validateOnly: true });
const r = await client.action("adjust-seats").applyAction({ customer: "cell-demo-a", seats: 60 }, { $returnEdits: true });
// r.validation.result = VALID / INVALID(参数逐项、提交条件逐条);r.edits:新建 / 修改 / 删除了哪些对象和链接

where 写法:$eq $ne $gt $gte $lt $lte $isNull $in $contains $startsWith $containsAnyTerm $containsAllTerms $containsAllTermsInOrder $matchesRegex $within $and $or $not;聚合:$count、属性:sum|avg|min|max|exactDistinct|approximateDistinct,分组 exact、$fixedWidth、$ranges、$duration。

本体由智能体构建(唯一和 Palantir 不同的地方)

智能体不能直接改 main 上的本体。它在分支上改,开提案,由人在网页上审核、合并:

  1. aidc semantic branch create add-department:开分支(基线 = 当前语义版本)。
  2. aidc semantic branch modify add-department ontology/:把定义放到分支上(一整份清单,--dry-run 试跑,--expected-version 防止并发覆盖)。
  3. aidc semantic objects agent --branch add-department:在分支上预览(读接口都收 ?branch=);branch validate 看 merge checks,branch conflicts 看和 main 冲突的地方,branch rebase 跟上 main。
  4. aidc semantic branch propose add-department --title … --trigger "为什么要改":开提案。平台自动附上按资源的改动、校验结果、影响面(30 天的写入与活跃用户、依赖的应用)、破坏性改动。
  5. 人在 /developer/<公司>/ontology/proposals/<id> 逐项批准(破坏性改动要输入资源名确认),全部批准、merge checks 通过后合并:落到 main,发一个语义版本。

作者由凭证决定:Agent Key 一律是智能体;开发者 Key 在环境变量 AIDC_AGENT_ID 存在时,CLI 自动带 x-aidc-author: agent:<id>,作者也记为智能体。智能体作者直接定义 main 会得到 409 branch_required。批准、拒绝、合并只接受人的网页登录,任何 Key 都不行。

和 ERP、OA 的关系

ERP、MES、OA 缺省只读:发布端把数据推进数据流,按 Object Type 定义里的 datasources 同步进来。人和智能体的改动只走 Action,落在语义层(对象的 edits),数据源下一次同步不会冲掉它们。要真的改源系统(关一台服务器、回写一张单据),给 Action 配 writeback webhook(见上一节):源系统先接受,语义层才记一笔。

Semantic 平台(www.ai-dc.ai/semantic)

登录 ai-dc.ai/semantic/app 就进到自己组织的 Semantic;不属于任何组织的账号落到 Public。界面照 Palantir 的应用分工,只调这一页写的同一套 API:

页面 地址 做什么
概览 /semantic/<cell> Object Type 一览(对象数、属性、链接、Public 标记)、最近的变化、待审核的提案、数据库状态
Ontology 图 /semantic/<cell>/graph 画布:Object Type 是节点、Link Type 是边(多对多虚线);拖动、缩放、点开看属性与关系
Object Types /semantic/<cell>/object-types[/<apiName>] Ontology Manager:属性(base type、SQL 列、主键 / 标题 / Value Type / 派生 / 只在语义层)、链接、用到它的 Action、数据源、Share
Object Explorer /semantic/<cell>/objects/<apiName>[/<主键>] 表格:搜索、筛选、排序、按属性看分布;Object View:属性、每条链接上的对象、编辑历史、能执行的 Action
Actions /semantic/<cell>/actions[/<apiName>] 参数表单:先「只校验」(VALIDATE_ONLY)再提交;Action Log
SQL Console /semantic/<cell>/sql Ontology SQL(见下一节);开发者在「连接」里轮换口令拿只读直连串
Proposals /semantic/<cell>/proposals 智能体开的 Ontology proposal:逐项批准(可一次批准全部非破坏性的)、合并
Access /semantic/<cell>/access 开放程度(Private / Group / Public / Open to Internet)、分享给谁、角色,见 访问与账号
Public /semantic/public 所有登录的 AIDC 账号都看得见的 Ontology、Object Type、数字员工、文件,以及「分享给我」

网页会话调 /api/v1/ontologies/** 时,角色由统一的访问判定决定(Private / Group / Public):本组织开发者 = developer(与开发者 Key 同权);本组织成员(Ontology 对组织可见时)= member;别的组织的人按授予——Editor = editor、Viewer = viewer(只读);Ontology 与所有 Object Type 都没有角色 = 403。

Semantic 数据库(Ontology SQL)

每个组织一个 Postgres schema(ont_<组织>),第一次用时按需建好,定义变了下一次查询时自动重建。照 Palantir Ontology SQL:

const r = await semantic.sql(`
  SELECT o.name, count(a.*) AS agents
  FROM organization o LEFT JOIN agent a ON a."organizationId" = o."organizationId"
  GROUP BY 1 ORDER BY 2 DESC`);
const cost = await semantic.sql('SELECT month, sum("costUsd") FROM "modelUsage" WHERE "organizationId" = $1 GROUP BY 1', { parameters: ["cell-aidc"] });
const db = await semantic.database();                       // 表与列、我用哪个角色
const conn = await semantic.rotateDatabaseCredentials();    // 开发者:psql "<conn.uri>"
aidc semantic sql 'SELECT stage, count(*) FROM organization GROUP BY 1' [--csv]
aidc semantic database --rotate
方法 路径 说明
POST /api/v1/sqlQueries/executeOntology 执行(照官方 ExecuteOntologySqlQueryRequest:query、parameters、rowLimit、dryRun、ontologyIdentifier);响应是 JSON(官方是 Arrow)
GET /api/v1/ontologies/{ns}/database 数据库信息;开发者另有直连信息(不含口令)
POST /api/v1/ontologies/{ns}/database/sync 按当前定义重建视图(开发者)
POST /api/v1/ontologies/{ns}/database/credentials 轮换直连口令,新连接串只返回这一次(开发者)

旧写法(1.2.x:describe / objects / action / define / publish)

1.2.x 起的写法照样能用(和上面同一份数据、同一套 Action 引擎),新代码请用上面的 semantic.ontology()。

三个概念

概念 是什么 例子(生产进度看板)
对象类型 一类业务对象:主键 + 属性。属性要么来自数据源(同步进来,只读),要么只在语义层维护(writeback:备注、负责人、异常状态…) production.order_line(工单线体进度):工单、线体、计划、累计合格 ← SAP;异常状态、异常说明、登记人 ← 语义层
链接 对象之间的关系。最常见的是一个属性引用另一个类型的主键(references) 工单线体 → 线体(line_code)
Action 受控的写操作:参数(类型 / 必填 / 长度 / 枚举)+ 改哪些属性 + 谁能做 + 日志里的一句话 production.flag_issue 登记异常:参数「异常说明」「级别」;写 issue、status、owner = 执行人

改数据只有两条路:成员用 Action(校验、权限、留痕);开发者用旧数据层直接改(管理用)。两条路的改动都落在语义层(对象的 edits),数据源下一次同步只更新它自己那一层,不会冲掉人改过的值。

读:说明书与对象

const space = await semantic.describe();
// space.types:看得见的对象类型(属性、单位、同义词、链接、对象数)
// space.actions:Action 与「我能不能执行」(allowed)
// space.markdown:给大模型读的整份说明书——智能体先读它再干活
// space.release:当前语义版本(v3…)

const hit = semantic.search(space, "合格数");        // 按业务说法定位:[{ kind: "property", type: "production.order_line", name: "ok" }]

const issues = await semantic.objects("production.order_line")
  .where({ status: { in: ["关注", "异常"] }, day: "2026-09-26" })
  .sort("-gap")
  .list();                                           // { objects, total, seq }

const order = await semantic.objects("production.order_line").get("100000012345|L01-05");
const line = await semantic.objects("production.order_line").linked(order.pk, "production.order_line.line_code");
const byLine = await semantic.objects("production.order_line").aggregate({ groupBy: ["line_code"], metrics: { ok: ["ok", "sum"] } });

每个对象:props(当前值 = 数据源的值被语义层改动覆盖后)、rev(每改一次 +1)、edited(语义层改过的属性)、overridden(被改动盖住、数据源现在是另一个值的属性 → 数据源的值)、sourceGone(数据源里已经没有这一行)。

条件写法:{ 属性: 值 } 相等;{ 属性: { gt, gte, lt, lte, ne, in, nin, contains, startsWith, null } };多个属性之间是「且」;$or: [{…}, {…}] 任意一组成立。

实时

const view = semantic.objects("production.order_line").where({ day: today }).sort("-ok").live({
  onUpdate(objects, change) { render(objects); },   // 先全量,之后数据一变就回调(同步、Action、别人的修改都算)
  onStatus({ connection }) { badge(connection); },
});
// view.close()

底层是旧数据层的 watch(SSE,断线按序号续传,不丢不重)。

写:执行 Action

const r = await semantic.action("production.flag_issue").apply(
  { issue: "缺料:顶蓬面料未到", severity: "异常" },
  { object: "100000012345|L01-05", ifRev: order.rev },
);
// r.object:改后的对象;r.event.summary:「L01-05 登记异常:缺料…」(进操作记录)

定义与发布(开发者:CLI / 智能体)

定义就是 JSON。四种词条:enum、object、link、action。

{
  "kind": "object",
  "apiName": "production.order_line",
  "title": "工单线体进度",
  "description": "每个工单在每条线体上的当日进度(SAP 生产进度报表)",
  "schema": {
    "titleColumn": "line_code",
    "synonyms": ["工单行", "生产任务"],
    "columns": [
      { "name": "order_no", "type": "text", "primaryKey": true, "title": "工单" },
      { "name": "line_code", "type": "text", "primaryKey": true, "title": "线体", "references": { "entity": "production.line", "column": "line_code" } },
      { "name": "ok", "type": "integer", "title": "累计合格", "unit": "件", "synonyms": ["合格数", "良品数"] },
      { "name": "status", "type": "text", "enumRef": "production.issue_status", "writeback": true, "title": "异常状态" },
      { "name": "issue", "type": "text", "writeback": true, "title": "异常说明" }
    ]
  }
}
{
  "kind": "action",
  "apiName": "production.flag_issue",
  "title": "登记异常",
  "schema": {
    "objectType": "production.order_line",
    "operation": "modify",
    "parameters": [
      { "name": "issue", "type": "text", "title": "异常说明", "required": true, "maxLength": 200 },
      { "name": "severity", "type": "text", "title": "级别", "enumRef": "production.issue_status" }
    ],
    "edits": { "issue": "$issue", "status": "$severity", "owner": "$userName", "flagged_at": "$now" },
    "roles": ["developer", "member", "editor"],
    "summary": "{line_code} 登记异常:{issue}"
  }
}

取值表达式:$参数名、$now(当前时间)、$user(执行人账号)、$userName(执行人名字)、$uuid(新主键,create 用);其他是字面量(以 $ 开头的字面量写成 $$…)。operation:modify 改一个对象、create 新建(edits 要给出主键)、delete 删除(语义层墓碑)。

aidc semantic define ontology/            # 目录里的 *.json 整批提交:一起校验、按 枚举 → 对象 → 链接 → Action 落(有则改)
aidc semantic define ontology/ --dry-run  # 只检查:整批引用是否闭合(批内互相引用算数)、相对上一个语义版本有哪些破坏性变更
aidc semantic publish --notes "加了异常登记"   # 发一个语义版本 vN(只增;定义没变不占号)
aidc semantic describe --markdown         # 给智能体读的说明书
aidc semantic act production.flag_issue --object "100000012345|L01-05" --param issue=缺料 --param severity=异常

权限一览

谁 读 执行 Action 直接写(旧数据层) 定义 / 发布
开发者 Key(CLI / 智能体) 本公司全部 全部 全部 ✓
应用里的 developer 访客 清单 semantic.types 登记的(含部门级) 清单登记 + roles 允许 清单 semantic.write 登记的 —
应用里的 member / editor 清单登记、且对公司全员可见的 清单登记 + roles 允许 — —
viewer(只读分享 / 公开链接) 同上 — — —

应用清单里这样登记:

{
  "sdk": ["semantic", "ui"],
  "semantic": {
    "types": ["production.order_line", "production.line"],
    "actions": ["production.flag_issue", "production.resolve_issue"],
    "write": []
  }
}

"*" 表示看得见的全部(数据浏览器这类通用应用)。

上表之外,数据安全(Markings、对象 / 属性安全策略)对所有人生效,包括开发者 Key:挂了 Marking 的数据,不是成员就读不到。

API

方法 路径 说明
GET /api/v1/developer/semantic/{命名空间} 说明书(按凭证裁剪)
GET / POST /api/v1/developer/semantic/{命名空间}/types 全部定义(开发者)/ 一次定义一批({definitions: […]},整批校验)
GET / PUT / DELETE /api/v1/developer/semantic/{命名空间}/types/{apiName} 读 / 定义 / 归档
POST /api/v1/developer/semantic/{命名空间}/actions/{apiName} 执行 Action
GET / POST /api/v1/developer/semantic/{命名空间}/releases 语义版本列表 / 发布

旧的数据层(/api/v1/developer/data/…:查询、聚合、订阅、直接写)照样能用;新代码用下面的 Ontology API 与对象集订阅。命名空间 = 公司 cellId(cell-…);应用里自动取应用所在公司。

Ontology API 照 Palantir REST API v2,前缀是 /api/v1/ontologies/{命名空间},响应体放在信封的 data 里、字段照官方:

方法 路径 官方操作
GET /ontologies、/ontologies/{ns}、/{ns}/fullMetadata List / Get Ontology、Full Metadata
GET /{ns}/objectTypes[/{type}[/fullMetadata | /outgoingLinkTypes[/{link}]]] Object Type、Outgoing Link Types
GET /{ns}/actionTypes、/interfaceTypes、/sharedPropertyTypes、/valueTypes、/queryTypes(各带 /{apiName}) 各类型的 List / Get
GET /{ns}/objects/{type}、/{type}/{pk}、/{type}/{pk}/links/{link}[/{pk2}] List Objects、Get Object、Linked Objects
POST /{ns}/objects/{type}/search、/aggregate、/count Search、Aggregate、Count
GET / POST /{ns}/objects/{type}/{pk}/timeseries/{property}/firstPoint、lastPoint、streamPoints Time Series
POST /{ns}/objectSets/loadObjects、/aggregate、/createTemporary;GET /{ns}/objectSets[/{rid}] Object Set
POST /{ns}/objectTypes/{type}/editsHistory Edits History
POST /{ns}/actions/{action}/apply、/applyBatch(最多 20 个,一个事务) Apply Action
POST /api/v1/ontologySubscriptions/ontologies/{ns}/streamSubscriptions(SSE) Object set subscription(官方走 WebSocket)
POST /{ns}/datasources/platform/sync 同步 AIDC 平台数据(平台对象类型;开发者)
GET / POST /{ns}/branches[/{name}[/modify | validate | conflicts | discard | rebase | lock | fullMetadata | proposals]] Global Branching
GET / POST /{ns}/proposals[/{id}[/tasks/{apiName}/review | merge | close]] Ontology proposal(review、merge 只收网页登录)
POST /{ns}/objectTypes/{type}/security/test AIDC:Test security policies(Ontology Manager 的同名功能,官方没有公开 API)

Markings 的管理照 Palantir AdminV2 / FilesystemV2:/api/v1/admin/markingCategories[/{id}]、/api/v1/admin/markings[/{id}[/markingMembers[/add \| /remove] \| /roleAssignments[/add \| /remove]]]、/api/v1/admin/markings/getBatch、/api/v1/admin/users/{userId}/getMarkings、/api/v1/filesystem/resources/{rid}/markings \| addMarkings \| removeMarkings。

完整字段见 OpenAPI。

本页由 developer/docs/semantic.md 生成 · Markdown 原文 · llms.txt