# Palantir Foundry 本体教学系列 · 完整语料
> 本文件包含 187 篇中文教学页面的完整正文,整理自 Palantir Foundry 官方文档。技术术语保留英文原文以便对照原文。
> 更新时间:2026-09-24|索引:https://www.hanzhongpin.xyz/ontology/llms.txt
---
## 动作日志(Action log)
- 页面:https://www.hanzhongpin.xyz/ontology/action-log.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/action-log/
- 主题分组:动作类型详解
动作类型详解
# 动作日志(Action log)
谁在什么时候、因为什么改了数据?动作日志把"成功的动作提交"建模成本体里的对象,让决策与审计可追溯。这一篇讲清它记什么、在哪配、有何限制。
## 一句话速览
动作日志(Action log):谁在什么时候、因为什么改了数据?动作日志把"成功的动作提交"建模成本体里的对象,让决策与审计可追溯。这一篇讲清它记什么、在哪配、有何限制。
1 动作日志(action log) 动作日志(action log)把成功的动作提交建模为对象类型(object type),以便在本体感知(object-aware)…
2 一次提交 = 一个日志对象 提交一个动作,会生成一个对应的动作日志对象,并自动链接到该动作编辑过的所有对象
## 什么是动作日志(action log)
它把"成功的动作提交"变成本体里可以分析、展示的对象。
动作日志(action log)把成功的动作提交建模为对象类型(object type),以便在本体感知(object-aware)的 Foundry 工具中分析与展示。你可以把它作为决策流程的输入,也能用它监控本体的变更。
"The action log models successful action submissions as object types to be analyzed and displayed in object-aware Foundry tooling."动作日志把成功的动作提交建模为对象类型,以便在本体感知的 Foundry 工具中分析与展示。
生成的动作日志对象类型,显示名自动取为 [Log] <动作类型名>,复数显示名取为 [Logs] <动作类型名>。它的设计目标,是简化"代表决策与数据编辑"的对象类型的生成与维护。
## 什么时候用它:五个能力别搞混
Foundry 提供多个回答"变更"问题的能力,它们不可互换。
你想回答的问题 该用的能力
什么决策、谁、何时、在何种语境下做出的? Action log(动作日志)
这个对象每一次编辑的完整历史(不论怎么改的)? Edit history(编辑历史)
动作多久成功/失败一次、花了多长时间? Action metrics(动作指标)
怎么撤销一个动作应用的编辑? Undo / revert(回滚)
动作开始失败时怎么告警? Monitoring(监控)
两条直接结论:① 动作日志只记录成功的提交,不记录失败——失败由动作指标跟踪。② 它只记录通过动作类型做出的编辑;直接写底层数据源或旧的 Foundry Forms 回写不会产生日志对象。
## 在哪配置动作日志
有两个不同的配置入口,分别针对"单个动作"和"整类对象"。
入口一为单个动作类型生成日志对象
在动作类型的 Capabilities 标签里开启。
打开动作类型 → 选 Capabilities 标签 → 找到 Create action log objects 区块(界面描述为"每次成功触发此动作就生成一个对象")→ 打开开关 → 选 Generate object type 创建底层日志对象类型。
入口二要求编辑某类对象的所有动作都带日志
在对象类型的 Datasources 标签里强制。
打开对象类型 → 选 Datasources 标签 → 在 Edits 区开启 Only allow Action types with action logs(界面描述:编辑该类型对象的所有动作都需要动作日志才能运作)。注意:该开关只有在对象类型已开启编辑后才会出现。
## 日志本体:一次提交 = 一个日志对象
动作日志对象类型与动作类型一一对应,并自动链接到被编辑的所有对象。
提交一个动作,会生成一个对应的动作日志对象,并自动链接到该动作编辑过的所有对象。例如一个 Close Alerts 动作类型,一次性把 10 个 Alert 对象的"Status"改为"Closed"——配置日志后,会产出单个日志对象,通过外键链接到全部 10 个 Alert 对象。
互动实验:一次动作 = 一个日志对象
提交 Close Alerts(一次性关闭 10 个告警)
> 点击按钮,观察动作日志如何建模这次提交。
> 提示:应用一个动作日志支持的动作类型,需要对该日志对象类型拥有相应权限,就像对动作通过规则/函数创建或修改的其他对象一样。
## 日志里记什么:必填值与可选值
把下列字段分到"必填(Required)"还是"可选(Optional)"(点击每行右侧)。
必填值里还包含"副作用与回滚的溯源"信息,点击揭晓有哪些:
点击这里揭晓 →
## 限制与函数后端动作
设计流程前,先知道这些硬约束;并用函数后端动作时还有额外要求。
- 属性类型一旦创建即固定:日志属性类型创建后不可改;若源属性类型变了,动作类型会校验失败,需新建属性并改映射。
- 摘要长度:摘要最多 20 个部分,每个纯文本部分最多 50 字符(参数部分不受此限)。
- 摘要内容:摘要不能引用对象类型参数。
- 无回填(No backfill):开启日志不会为已经提交的旧动作补建日志对象,从保存配置那一刻才开始记。
- 编辑上限:日志对象同样受对象编辑的规模与属性上限约束。
> 函数后端动作:要为函数后端动作配置动作日志,其底层的 Ontology 编辑函数必须配置 Edits provenance(编辑溯源);否则日志无法记录。
## 一页带走
① 记成功提交 把成功的动作提交建模为 [Log] 对象;不记失败、不记非动作编辑。
② 两个入口 动作 Capabilities 开日志;对象 Datasources 强制"编辑必带日志"。
③ 一对一映射 一次提交 = 1 个日志对象,自动链接所有被编辑对象。
④ 限制须知 无回填、属性类型固定、摘要有限长;函数后端需 Edits provenance。
### 常见问题速答 · FAQ
关于「动作日志(Action log)」,读者最常问的几个问题。
什么是动作日志(action log)? 动作日志(action log)把成功的动作提交建模为对象类型(object type),以便在本体感知(object-aware)的 Foundry 工具中分析与展示。你可以把它作为决策流程的输入,也能用它监控本体的变更。
日志本体:一次提交 = 一个日志对象是什么? 提交一个动作,会生成一个对应的动作日志对象,并自动链接到该动作编辑过的所有对象。例如一个 Close Alerts 动作类型,一次性把 10 个 Alert 对象的"Status"改为"Closed"——配置日志后,会产出单个日志对象,通过外键链接到全部 10…
---
## 动作指标(Action metrics)
- 页面:https://www.hanzhongpin.xyz/ontology/action-metrics.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/action-metrics/
- 主题分组:动作类型详解
动作类型详解
# 动作指标(Action metrics)
动作上线后到底成不成功、慢不慢?动作指标给你近 30 天的实时概览,并细分失败原因。这一篇带你读懂这些数字。
## 一句话速览
动作指标(Action metrics):动作上线后到底成不成功、慢不慢?动作指标给你近 30 天的实时概览,并细分失败原因。这一篇带你读懂这些数字。
1 指标(metrics) 动作指标(action metrics)展示一个动作类型在最近 30 天的近乎实时的使用情况
2 数据来源与如何嵌入应用 所有指标都通过 Foundry Telemetry Service(FTS)的最新数据,以近乎实时的方式更新——让你随时掌握动作的健…
3 权限与要点 要查看动作指标,你必须是该动作的 viewer(查看者)
## 什么是指标(metrics)
指标是"量",告诉你动作用得怎么样;它和"日志""监控"互补但不同。
动作指标(action metrics)展示一个动作类型在最近 30 天的近乎实时的使用情况。你可以在两处查看:
- Ontology Manager 中该动作类型的概览页(overview page);
- Workflow Lineage 中选中某次执行的动作节点(action node)。
"Action metrics display the near real-time usage of an action type over the last 30 days."动作指标展示一个动作类型在最近 30 天的近乎实时的使用情况。
> 提示:指标不需要动作日志(action log)就能展示;与日志相反,指标会跟踪失败,而日志只记录成功的提交。
## 两类核心指标
指标面板里最值得盯的就是这两个。
成功 / 失败计数 用成功数与失败数监控动作当前状态,快速发现异常、主动排查,让失败一发生就被处理。
P95 时长(duration) 跟踪每个动作类型的第 95 百分位执行时长,凸显执行时间的上沿,帮你发现性能瓶颈、优化工作流。
## 失败类型分类(Failure types)
指标把失败分成多种类别,便于你定位"为什么挂了"。
失败类别 含义
Invalid parameter(参数无效) 提交的参数在该动作语境下不合法。
Scale limit(规模超限) 影响的对象类型超过允许上限(默认通常约 10,000)。
Authentication(鉴权失败) 用户未通过动作的安全提交标准。
Side effect(副作用失败) 因 webhook 或配置错误的副作用而失败。
Function(函数失败) 底层函数失败;仅函数后端动作可能出现。
User-facing function(面向用户的函数失败) 函数抛出拟展示给用户的错误;仅函数后端动作。
Conflict(冲突失败) 因冲突(如并发修改)而失败。
Unclassified(未分类) 不属于以上任何类别的失败。
> 提示:其中 Function 与 User-facing function 两类,只有函数后端(function-backed)动作才可能出现。
## 数据来源与如何嵌入应用
指标为什么"近实时"?它从哪里来,又能放到哪里看。
所有指标都通过 Foundry Telemetry Service(FTS)的最新数据,以近乎实时的方式更新——让你随时掌握动作的健康状况,用于监控、调试与维护。
- 你还能查看运行历史(run history):给出某动作过去 7 天执行的完整视图。
- 可以把指标直接嵌进运营应用:在 Workshop 里用 Observability Chart widget 展示,把资源健康度与工作流其余部分放在一起看。
## 权限与要点
想看指标,先确认你有没有权限;再动手看看指标长什么样。
要查看动作指标,你必须是该动作的 viewer(查看者)。这是查看指标的唯一权限门槛。
互动实验:近 30 天动作指标速览
成功 / 失败计数
P95 时长
运行历史(7 天)
> 点击上方按钮,查看对应指标说明(以下为示意数据,非真实数值)。
## 一页带走
① 指标 = 量 近 30 天近乎实时;核心看成功/失败计数与 P95 时长。
② 会跟踪失败 与日志相反,指标跟踪失败并细分 8 类失败原因。
③ 数据来自 FTS 由 Foundry Telemetry Service 近实时更新;另有 7 天运行历史。
④ 权限门槛 查看指标只需是动作的 viewer;可嵌入 Workshop 图表。
### 常见问题速答 · FAQ
关于「动作指标(Action metrics)」,读者最常问的几个问题。
什么是指标(metrics)? 动作指标(action metrics)展示一个动作类型在最近 30 天的近乎实时的使用情况。你可以在两处查看。
数据来源与如何嵌入应用? 所有指标都通过 Foundry Telemetry Service(FTS)的最新数据,以近乎实时的方式更新——让你随时掌握动作的健康状况,用于监控、调试与维护。
权限与要点是什么? 要查看动作指标,你必须是该动作的 viewer(查看者)。这是查看指标的唯一权限门槛。
---
## 动作回滚(Action reverts)
- 页面:https://www.hanzhongpin.xyz/ontology/action-reverts.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/action-reverts/
- 主题分组:动作类型详解
动作类型详解
# 动作回滚(Action reverts)
点错了、删错了怎么办?Foundry 允许你在动作刚提交后立刻"撤销"。这一篇讲清回滚是什么、能回滚谁、以及那些容易踩的坑。
## 一句话速览
动作回滚(Action reverts):点错了、删错了怎么办?Foundry 允许你在动作刚提交后立刻"撤销"。这一篇讲清回滚是什么、能回滚谁、以及那些容易踩的坑。
1 回滚(revert) 在 Ontology Manager 里,动作回滚(action revert)允许一个动作在应用之后立即被撤销(undone)
2 只限 Object Storage v2 动作回滚仅适用于 Object Storage v2(OSv2):也就是说,只有修改或创建 OSv2 对象类型的动作才能被回滚
3 配置一个可回滚的动作 在动作的 Form 标签页里,打开 Allow revert after action submission(提交后允许回滚)开关…
4 删除动作的特别处理 执行了删除(delete)动作、且想撤销删除,但那条回滚提示已经不在了——此时可选的"补救"只有两条路
## 什么是回滚(revert)
回滚就是"撤销"——在动作刚被应用后,立刻把它做的编辑还原回去。
在 Ontology Manager 里,动作回滚(action revert)允许一个动作在应用之后立即被撤销(undone)。做法很简单:任意一次成功的动作应用后,在成功提示(success message)里选择 Undo 即可。
"Action reverts in Ontology Manager allow an action to be reverted (that is, undone) immediately after the action has been applied."本体管理器中的动作回滚,允许一个动作在应用之后立即被撤销(即撤销)。
新建的动作默认就是可回滚的(revertible)。但要记住下面这条铁律——
关键:那一条成功提示(toast)是你唯一能撤销动作的时机。尤其在执行删除(delete)动作时,更要抓紧这条提示。
## 谁能回滚:只限 Object Storage v2
回滚不是对所有动作都开放,它依赖底层的对象存储版本。
动作回滚仅适用于 Object Storage v2(OSv2):也就是说,只有修改或创建 OSv2 对象类型的动作才能被回滚。如果你的对象类型还停留在 OSv1,需要先迁移到 OSv2。
可以回滚
动作只修改 / 创建 OSv2 对象类型
→ 默认可回滚(新建动作)。
OSv1 可参考官方迁移指南升级到 v2。
≠
不能回滚
动作只修改 OSv1 对象类型
→ 无法回滚。
提示里不会出现可用的 Undo。
## 如何配置一个可回滚的动作
默认行为已经很友好,但了解开关在哪里仍然重要。
在动作的 Form 标签页里,打开 Allow revert after action submission(提交后允许回滚)开关,保存回本体后该动作即可回滚。
默认规则:2024 年 5 月之后创建、且只修改 OSv2 对象类型的动作,这个开关默认就是开启的。而 2024 年 5 月之前存在、但修改 OSv2 对象的动作,默认不会开启,需要手动打开。
点击揭晓:目前回滚动作还有什么身份限制?
点击这里揭晓 →
## 限制与注意事项(Caveats)
回滚会失败,也有"管不到"的地方。先来动手感受一下"唯一时机"。
互动实验:回滚的机会只有一次
> 你刚刚成功执行了一个动作。下方是成功后弹出的提示(toast)。
撤销(Undo)
先对该对象再做一次编辑
重置场景
>
### 回滚会失败的两种情况
- 对象已有后续编辑:只要该对象被做过任何后续编辑(哪怕是不同的属性),这个动作就无法回滚——它必须仍然是该对象"最近一次"编辑。
- 开关被关过:如果提交后回滚开关被关掉过(哪怕后来又打开),该动作也无法回滚。
点击揭晓:回滚会不会把"副作用"也一起撤销?
点击这里揭晓 →
## 删除动作的特别处理
如果删除的 toast 已经消失,撤销就不是点一下那么简单了。
执行了删除(delete)动作、且想撤销删除,但那条回滚提示已经不在了——此时可选的"补救"只有两条路:
- 迁移到一个新的对象类型,并用函数(functions)把想要的编辑复制过去;
- 直接丢弃(drop)该对象类型上的所有编辑。
记住:删除动作一旦错过 toast,就没有"一键撤销"。所以删除前务必确认,或提前用动作日志(action log)留痕。
## 一页带走
① 回滚 = 撤销 成功提示里的 Undo 是唯一时机,删除动作尤其要抓紧。
② 只限 OSv2 仅修改/创建 OSv2 对象类型的动作可回滚,OSv1 不行。
③ 配置与限制 Form 标签开关;对象有后续编辑或开关被关过则无法回滚。
④ 副作用不回滚 回滚只还原对象编辑,不撤销通知/webhook 等副作用。
### 常见问题速答 · FAQ
关于「动作回滚(Action reverts)」,读者最常问的几个问题。
什么是回滚(revert)? 在 Ontology Manager 里,动作回滚(action revert)允许一个动作在应用之后立即被撤销(undone)。做法很简单:任意一次成功的动作应用后,在成功提示(success message)里选择 Undo 即可。
只限 Object Storage v2是什么? 动作回滚仅适用于 Object Storage v2(OSv2):也就是说,只有修改或创建 OSv2 对象类型的动作才能被回滚。如果你的对象类型还停留在 OSv1,需要先迁移到 OSv2。
如何配置一个可回滚的动作? 在动作的 Form 标签页里,打开 Allow revert after action submission(提交后允许回滚)开关,保存回本体后该动作即可回滚。
限制与注意事项(Caveats)是什么? 点击揭晓:回滚会不会把"副作用"也一起撤销?
---
## 动作类型(Action Type):让本体"动手"
- 页面:https://www.hanzhongpin.xyz/ontology/action-types.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/overview/
- 主题分组:本体零件(十)
循序渐进 · 教学 · 本体零件(十)
# 动作类型(Action Type):让本体"动手"
本体不能只"看"不"动"。动作类型就是让人(或系统)在合规前提下
改变对象、属性和链接的那套定义。这一篇讲清它是什么、由什么组成、什么时候该用。
## 一句话速览
动作类型(Action Type):让本体"动手":本体不能只"看"不"动"。动作类型就是让人(或系统)在合规前提下 改变对象、属性和链接的那套定义。这一篇讲清它是什么、由什么组成、什么时候该用。
1 动作类型 = 一次受治理的变更 在本体里,用户通过动作(action)去改动对象、属性与链接
2 Assign Employee 原文给的例子是 Assign Employee(分配员工)动作类型
3 为什么要用动作类型 原文强调一个核心事实:Foundry 本体不是抽象数据模型,而是把每个本体概念 映射到了组织真实的业务数据
4 它适合什么场景?权限怎么管 动作类型擅长的是捕获人的决策:审批订单、改状态、指派人员、建立关系……
## 一句话:动作类型 = 一次受治理的变更
An action type defines a set of changes a user can take at once.
在本体里,用户通过动作(action)去改动对象、属性与链接。
一次 action 是一笔事务(transaction):基于用户定义的逻辑,改变一个或多个对象的属性。
An action type is the definition of a set of changes or edits to objects, property values, and links that a user can take at once. It also includes the side effect behaviors that occur with action submission.
动作类型,是"用户可一次性执行的一组对对象、属性值、链接的改动"的定义;它还包括随提交一起发生的副作用行为。
重点在"一次性"和"受治理":一个动作类型把要改什么、怎么改、谁有权改、改完顺带做什么
全部打包成一份可复用的定义。业务人员点一下就能完成一整套合规变更。
>
和函数(function)先分清:动作类型捕获的是人的一次决策与改动;
函数是一段计算逻辑,常为决策提供依据。两者常配合,但本质不同(functions 那篇细讲)。
## 一个例子:Assign Employee
改属性、自动建链接、发通知、做权限校验,一次完成。
原文给的例子是 Assign Employee(分配员工)动作类型。设想 HR 要把 "Melissa Chang" 的岗位改成 "Product Manager":
改属性
定义如何改变某个 Employee 对象的 role 属性值。
要参数
需要"参数定义(parameter)",让员工以标准化表单输入新岗位,而不是随手敲。
自动建链接
可包含规则:自动在 Employee 与新 Manager 之间建立链接。
副作用 + 校验
可附带"通知新旧经理"的副作用;并校验只有 HR 等授权员工才能执行。
于是,HR 只需执行一次动作,就能把 Melissa Chang 切到 Product Manager——
属性改了、链接建了、相关人通知了、权限也拦住了不该操作的人。
## 一个动作类型由什么组成?
参数、编辑、副作用、校验,四件套。
组成部分 作用
Parameters 参数 采集用户输入(如"新岗位"),以标准化表单呈现,避免随手填错。
Edits / Operations 编辑与操作 对对象、属性值、链接的增改删;可自动按规则建立链接。
Side effects 副作用 提交时顺带发生的行为,如发送通知(notify)给相关人。
Validation / Submission criteria 校验与提交条件 规定谁能执行、在什么条件下才允许提交(如仅 HR 角色)。
>
记忆口诀:动作类型 = 要改什么(edits) + 靠什么输入(parameters) +
改完顺带做啥(side effects) + 谁能改(validation)。
## 为什么要用动作类型?
本体映射到真实数据,提交即写回,跨应用一致。
原文强调一个核心事实:Foundry 本体不是抽象数据模型,而是把每个本体概念
映射到了组织真实的业务数据。动作带来的改动,正是"把人的决策与洞察"沉淀进数据资产的方式——数据资产因此越用越值钱。
× 手动改底层数据
问题
· 改动散落在 CSV / 数据库,难以治理
· 各应用看到的不是同一份真相
· 谁改的、为什么改,无从追溯
→
✓ 用动作类型
收益
· 提交即写入本体,所有应用即时反映
· 同一套逻辑与校验在所有前端应用一致
· 改动被记录、受权限与治理约束
>
写回(writeback):用户编辑后,融入了用户改动的、最新版本的对象数据,会被捕获进该对象类型的
写回数据集(writeback dataset)。这正是"决策沉淀为数据"的落点。
## 它适合什么场景?权限怎么管?
凡是"人要做一次受治理的改动",优先考虑动作类型。
动作类型擅长的是捕获人的决策:审批订单、改状态、指派人员、建立关系……
- 改动会改变本体中的对象,而不是只做只读计算。
- 改动需要在提交时做权限校验与副作用(通知、联动)。
- 同一套逻辑与校验要在所有用户应用里保持一致。
权限方面,动作类型在其定义里就内嵌了校验与提交条件:
比如"仅人力资源(HR)等授权员工可执行"。这使得"能动手但要合规"成为默认保障。
别混淆:把外部系统的数据每天同步进数据集,那是本体之下的数据集成(pipeline),
不是动作类型——动作类型改的是已经在本体里的对象,而不是把原料搬进来。
## 动手:该不该用动作类型 / 用哪种?
逐个场景判断。点选项看解析。
## 一次提交,背后发生了什么?
点开看推荐顺序。
点我看推荐顺序 →
>
上手路径(原文推荐):从
create an action type(创建动作类型)与
explore other action types(浏览现有动作类型)入手;
再深入了解 rules(规则)、parameters(参数)与
submission criteria(提交条件)。
提示:动作类型与函数、接口常协同——接口定义形状,函数提供计算,动作类型执行受治理的改动。
## 本模块的 37 篇详解
上面是动作类型的"总览"。下面 37 篇从快速开始一路讲到监控与日志,按主题分组,按需查阅或顺着读。
① 入门与基础
快速开始
动作能做什么
在页面触发
上线前试跑
规则全解
② 参数
参数总览
默认值
过滤
下拉安全
覆盖
性能
③ 接口 · 结构体 · 函数动作
提交条件
接口上的动作
结构体上的动作
函数动作·总览
函数动作·上手
函数动作·批量
④ 副作用 · 通知 · Webhook
副作用·总览
通知
配置通知
Webhook
配置 Webhook
定时触发
⑤ 配置 · 上传 · 权限
配置分组
上传媒体
上传附件
规模与限制
内联编辑
动作权限
读写授权
⑥ 运维 · 监控 · 市场
一致性保证
监控
动作回滚
分支动作
动作指标
动作日志
市场动作
## 一页带走
① 动作类型 = 受治理的改动 一次性事务:改对象/属性/链接,并带提交时的副作用。
② 四件套 参数 + 编辑 + 副作用 + 校验/提交条件。
③ 映射到真实数据 提交即写入本体、跨应用一致、写回数据集,决策沉淀为数据。
④ 该用才用 要"改动+权限+副作用"用动作类型;只读计算用函数;数据同步用 pipeline。
### 常见问题速答 · FAQ
关于「动作类型(Action Type):让本体"动手"」,读者最常问的几个问题。
一句话:动作类型 = 一次受治理的变更是什么? 在本体里,用户通过动作(action)去改动对象、属性与链接。一次 action 是一笔事务(transaction):基于用户定义的逻辑,改变一个或多个对象的属性。
一个例子:Assign Employee是什么? 原文给的例子是 Assign Employee(分配员工)动作类型。设想 HR 要把 "Melissa Chang" 的岗位改成 "Product Manager"。
为什么要用动作类型? 原文强调一个核心事实:Foundry 本体不是抽象数据模型,而是把每个本体概念 映射到了组织真实的业务数据。动作带来的改动,正是"把人的决策与洞察"沉淀进数据资产的方式——数据资产因此越用越值钱。
它适合什么场景?权限怎么管? 动作类型擅长的是捕获人的决策:审批订单、改状态、指派人员、建立关系……
---
## 动作·接口(Actions on Interfaces)
- 页面:https://www.hanzhongpin.xyz/ontology/actions-on-interfaces.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/actions-on-interfaces/
- 主题分组:动作类型详解
动作类型详解
# 动作·接口(Actions on Interfaces)
接口(interface)让"一次定义、作用于所有实现它的对象"成为可能。这一篇讲如何在动作里使用接口:
接口动作规则与接口引用参数,以及它们的能力边界。
## 一句话速览
动作·接口(Actions on Interfaces):接口(interface)让"一次定义、作用于所有实现它的对象"成为可能。这一篇讲如何在动作里使用接口:接口动作规则与接口引用参数,以及它们的能力边界。
1 一次定义,作用于所有实现该接口的对象 你可以创建通用动作(generic actions),作用于你选定的某个接口(interface)下的所有对象
2 先想清楚再建 提交前务必想清楚:哪些用户有权在所有实现类型上创建 / 修改 / 删除对象
## 一句话:一次定义,作用于所有实现该接口的对象
创建适用于某个接口下全部对象的"通用动作"。
你可以创建通用动作(generic actions),作用于你选定的某个接口(interface)下的所有对象。
换句话说:只要一个对象类型实现了该接口,这个动作就能用在它身上。
You can create generic actions that apply to all objects of a chosen interface.
你可以创建适用于某个选定接口下所有对象的通用动作。
接口层面还有两个相关概念:接口动作类型约束(interface action type constraints)描述"实现该接口的对象类型应当用具体动作类型满足的能力"——
它是一个接口级的"动作契约";而动作规则(action rules)描述动作类型被提交时真正执行的编辑。目前前者是本体管理器里的建模/映射功能,并非终端用户应用或 SDK 的调用面。
## 两种用法:接口动作规则 + 接口引用参数
从动作内部使用接口,主要有两种方式。
接口动作规则 Interface action rules
对配置了接口的对象进行创建、修改、删除、链接。规则作用于"实现接口的对象"。
接口引用参数 Interface reference parameters
引用"实现该接口的"对象。这是 Modify / Delete 接口动作规则的必填项,也可用于任何其他动作规则。
>
类比:接口引用参数(interface reference)很像对象引用参数(object reference),区别在于——
前者列出任何实现了该接口类型的对象,后者只锁定单一对象类型。
## 怎么创建一个接口动作类型
本体管理器里,从 New 菜单选 Action type。
步骤 1选择接口与规则类型
在 Ontology Manager 的 New 菜单选 Action type,于 Interfaces 下挑选目标接口和规则类型。
例如选 "Ticket" 接口 + "Create" 规则,就会得到一个能创建该接口下各类对象的动作。
步骤 2加入共享属性
按需加入要包含在动作里的接口共享属性(shared properties)。
注意:只能包含接口共享属性,不能包含某个具体对象类型特有的属性。
步骤 3填元数据 + 提交条件
写描述动作类型的元数据(对所有实现类型通用);在 Submission criteria 里选能执行该动作的用户。
这些权限会对所有实现该接口的对象类型生效(前提是该用户也有编辑它们的权限)。
步骤 4Create 完成
点 Create 完成动作类型的创建。
之后可在 Workshop / Object Explorer 等应用里,对实现该接口的对象看到并使用它。
提示:点击每条可展开更多细节。
## 各类规则能干啥、注意啥
Create / Modify / Delete / 创建链接 / 删除链接。
规则类型 能力 / 注意点
Create 会自动生成"Object type"参数让用户选要创建的类型。没有主键就无法创建——接口与 Create 规则都要包含可用作主键的接口属性。
Modify 可改任意实现接口的对象;生成"interface reference"参数。但主键不可被修改,否则提交失败(如把 Bug 的 Title 当主键又被改)。
Delete 可用 interface reference 参数指定要删除的对象。
Create link 基于接口链接约束创建链接;若约束在"两接口之间",源/目标都自动生成为接口引用参数。一个对象类型上若有多个具体链接实现会失败。
Delete link 基于接口链接约束删除链接;若对象类型上有多个具体链接实现,会尝试删除全部。
>
口诀:接口动作规则只能改接口共享属性或删除对象。例如 Feature request 与 Bug 都是 Ticket 接口的对象类型,
你可以用"Create a ticket"动作去创建二者,但不能去创建"只属于 Bug 或只属于 Feature request"的特有属性。
## 权限与局限:先想清楚再建
提交条件对实现接口的所有类型"一视同仁"。
最大的坑:提交条件对实现该接口的所有对象类型统一生效。你无法在单个接口动作里"按对象类型"分别配置权限。
要收紧,需到 Ontology Manager 的 Interfaces 选项卡,在 Interface action control 里为特定对象类型禁用继承来的接口动作。
更细粒度的权限控制仍在开发中。
- 接口动作规则遵循与对象动作类型相同的权限模型。
- 动作日志(action logs)暂不支持接口动作。
- 接口上的动作不能与函数(functions)一起使用。
提交前务必想清楚:哪些用户有权在所有实现类型上创建 / 修改 / 删除对象。
## 动手:接口形状判定
点击左侧卡片,判断它是否适合用"接口动作规则"实现。
候选操作(点击判定)
修改某实现 Ticket 接口的对象的共享属性 Title
对所有实现 Ticket 的对象通用
删除一个实现了接口的对象
用 interface reference 指定目标
用接口链接约束在两类接口对象间创建链接
源/目标自动生成为接口引用参数
创建仅属于 Bug 对象类型特有的属性
这是具体实现类型私有的属性
用函数(function)实现这个接口动作
想靠代码逻辑完成编辑
给不同的对象类型设置不同的提交权限
希望 A 类型宽松、B 类型严格
判定结果
绿色 = 适合用接口动作规则;红色 = 不适合(原因见卡片下方)。
## 一页带走
① 通用动作 一次定义,作用于所有实现该接口的对象类型。
② 两种用法 接口动作规则(做编辑)+ 接口引用参数(引用对象)。
③ 只能改共享属性 不能创建某实现类型特有的属性;主键不可改;无主键无法创建。
④ 局限 提交条件统一生效、暂不支持动作日志、不能与函数共用。
### 常见问题速答 · FAQ
关于「动作·接口(Actions on Interfaces)」,读者最常问的几个问题。
一次定义,作用于所有实现该接口的对象是什么? 你可以创建通用动作(generic actions),作用于你选定的某个接口(interface)下的所有对象。换句话说:只要一个对象类型实现了该接口,这个动作就能用在它身上。
权限与局限:先想清楚再建是什么? 提交前务必想清楚:哪些用户有权在所有实现类型上创建 / 修改 / 删除对象。
---
## 动作·结构体(Actions on Structs)
- 页面:https://www.hanzhongpin.xyz/ontology/actions-on-structs.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/actions-on-structs/
- 主题分组:动作类型详解
动作类型详解
# 动作·结构体(Actions on Structs)
结构体(struct)属性把多个字段打包成一个值。这一篇讲怎么用结构体参数(struct parameter)
来创建和修改带 struct 属性的对象,以及它的映射、默认值与约束规则。
## 一句话速览
动作·结构体(Actions on Structs):结构体(struct)属性把多个字段打包成一个值。这一篇讲怎么用结构体参数(struct parameter)来创建和修改带 struct 属性的对象,以及它的映射、默认值与约束规…
1 用 struct 参数喂给 struct 属性 结构体属性(struct property)的值,可以通过动作来创建和修改——值由动作里的一个 结构体参数(struct param…
2 定义作用于 struct 属性的动作 用带 struct 参数的动作,你可以创建和修改带 struct 属性的对象类型
3 表单呈现与默认值 在动作表单(action form)里,struct 参数和别的参数一样能填,只是它的字段会成组渲染,而不是散开成独立字段
4 字段级约束 约束(constraints)可以像普通参数一样,逐字段配置在 struct 参数字段上
## 一句话:用 struct 参数喂给 struct 属性
结构体属性的值,只能通过结构体参数来提供。
结构体属性(struct property)的值,可以通过动作来创建和修改——值由动作里的一个
结构体参数(struct parameter)提供。
A struct parameter is a parameter of base type STRUCT, where the type contains nested parameter fields that have their own individual names and base types.
结构体参数是一种基础类型为 STRUCT 的参数;其类型包含嵌套的参数字段,每个字段各有自己的名称和基础类型。
也就是说:一个 STRUCT 类型的参数,内部可以嵌套多个字段(如 summary、resolutionTime、owner),
分别有自己的基础类型。它专门用来给一个 struct 属性"整体供货"。
>
支持的基础类型:struct 参数字段支持 BOOLEAN、DATE、DOUBLE、GEOPOINT、
INTEGER、LONG、STRING、TIMESTAMP。
## 定义作用于 struct 属性的动作
要把 struct 参数的每个字段,映射(map)到 struct 属性的对应字段。
用带 struct 参数的动作,你可以创建和修改带 struct 属性的对象类型。struct 属性的值在一个映射到该属性的 struct 参数里提交;
struct 属性的每个字段都要映射到 struct 参数的某个具体字段。
>
映射要"完整且类型匹配":① struct 属性与 struct 参数之间的映射必须完整——属性每个字段都要映射到参数的字段;
② 参数字段的基础类型必须与所映射的属性字段基础类型一致。
如果 struct 属性类型发生破坏性变更(新增字段、删除字段、改字段基础类型),相关的动作类型也必须跟着改,否则会出问题。
## 表单呈现与默认值
字段在表单里成组出现;默认值可取自某对象的同类属性。
在动作表单(action form)里,struct 参数和别的参数一样能填,只是它的字段会成组渲染,而不是散开成独立字段。
默认值(default values)是逐字段定义的:每个参数字段映射到某个指定对象类型 struct 属性的字段。
必须给参数字段的所有字段都定义默认值,且都映射到同一对象类型 struct 属性的字段。
充当默认值的对象由动作里一个 ObjectReference 参数指定——提交时提供的那个对象,其 struct 属性字段值会自动填进对应的参数字段。
>
默认值的来源限制:只有单一对象类型的 struct 属性字段能充当默认值;
静态值等其它方式不被支持。
## 字段级约束
每个字段可单独设约束;整组必须全过才有效。
约束(constraints)可以像普通参数一样,逐字段配置在 struct 参数字段上。
例如给字符串字段加一个"长度在 10 到 500 之间"的约束,那么 summary 字段就至少要 10 个字符、最多 500 个字符。
整组才有效:一个 struct 参数值,只有当所有字段都满足约束时才算有效。
只要有一个字段(比如不足 10 字符的 summary)不达标,用户就无法提交整个 struct 参数值。
点我看 struct 参数"何时算有效"的判定 →
## 局限:记住这四条
struct 属性的进出通道相当受限。
- struct 属性值只能通过 struct 参数创建或修改;静态值、引用对象属性等方式都不支持。
- 一个 struct 属性只能通过单个 struct 参数创建或修改,动作里不能有多个参数映射到同一 struct 属性。
- struct 参数只能用来创建/修改 struct 属性;其字段不能单独拿去创建/修改非 struct 属性。
- 只有单一对象类型的 struct 属性字段能作默认值,静态值等不被支持。
## 动手:关于 struct 参数,哪句对?
逐个判断。点选项看解析。
## 一页带走
① struct 参数 基础类型 STRUCT,内含嵌套字段,专给 struct 属性整体供货。
② 映射要完整 属性每字段都映射到参数字段,且基础类型一致。
③ 默认值 + 约束 默认值逐字段、取自单一对象类型;约束逐字段,整组全过才有效。
④ 局限 只经 struct 参数、单一参数映射、只能改 struct 属性、默认值限单一类型。
### 常见问题速答 · FAQ
关于「动作·结构体(Actions on Structs)」,读者最常问的几个问题。
定义作用于 struct 属性的动作是什么? 用带 struct 参数的动作,你可以创建和修改带 struct 属性的对象类型。struct 属性的值在一个映射到该属性的 struct 参数里提交;struct 属性的每个字段都要映射到 struct 参数的某个具体字段。
表单呈现与默认值是什么? 在动作表单(action form)里,struct 参数和别的参数一样能填,只是它的字段会成组渲染,而不是散开成独立字段。
字段级约束是什么? 约束(constraints)可以像普通参数一样,逐字段配置在 struct 参数字段上。例如给字符串字段加一个"长度在 10 到 500 之间"的约束,那么 summary 字段就至少要 10 个字符、最多 500 个字符。
---
## AI FDE 最佳实践
- 页面:https://www.hanzhongpin.xyz/ontology/aip-ai-fde-best-practices.html
- 官方原文:https://www.palantir.com/docs/foundry/ai-fde/best-practices/
- 主题分组:AI FDE(五)
循序渐进 · AIP 教学 · AI FDE(五)
# AI FDE 最佳实践
让智能体替你操作平台,如何既高效又不失控?这一篇给出实操建议。
## 先记住这几条
① 给清晰的任务与边界 任务越明确,结果越可靠。
② 保持在可审核的节奏上 关键步骤要留人看的余地。
③ 善用计划能力 让它在动手前先出方案给你审。
④ 关注系统完整性 效率不能以破坏一致性为代价。
## 写在前面
请审阅以下最佳实践,以帮助你在保持系统完整性并优化结果的同时,有效地利用 AI FDE。
## 核实资源与流程
> 要点:让它确认自己理解对了再动手。
在生产环境中实施生成的资源之前,务必先验证它们。此验证过程应包括审查所有生成的代码是否正确,以及是否符合组织标准。
使用有代表性的样本数据测试变换逻辑,以确保其在各种条件下都能如期运行。AI FDE 默认会在分支上进行更改,并在 Global Branch 提案或 Code Repository 的 pull request 中提出更改以供审查。
取决于所使用的工具和工具配置,AI FDE 可能会在执行动作前请求工具批准。请确保你理解模型试图执行的动作,并在批准前检查正在使用的工具。
## 限制工具与上下文
> 要点:给得越少,跑偏概率越低。
我们建议只向模型提供给定任务所必需的上下文和工具。提供不必要的上下文或工具可能导致次优或错误的动作。通过将可用工具限制为特定任务所需的那些,并只包含最相关的上下文,你可以降低混淆或出错的可能性。限制工具和上下文可以提升 AI FDE 的效率和准确性,同时通过最小化对敏感操作或信息的访问来增强安全性。
## 拆解问题、迭代推进
> 要点:别一次给一个大任务。
复杂操作应分解为更小、更易管理的步骤。我们建议从基本结构开始,随着每个组件得到验证再逐步增加复杂度。
AI FDE 在快速原型设计方面尤其有效,允许快速探索不同方法。对于生产级实现,请将 AI 生成的基础与手动开发相结合,以进行微调和优化。
## 用 AIP Evals 跟踪表现
> 要点:效果要有数据衡量。
使用 AIP Evals 来评估并跟踪由 AI FDE 创建或修改的 functions 的表现。为你的 LLM 支撑的 functions 创建评估套件,让你能够衡量更改随时间推移的影响,并比较不同方法。这在使用 AI FDE 进行迭代式 function 开发时尤其有价值,因为它能就更改是提升还是降低了表现提供定量反馈。
## 考虑基础设施约束
> 要点:算力与配额的现实限制。
使用 AI FDE 时,重要的是要认识到其运作模式与人类开发者之间的差异。人类开发者通常一次执行一个操作,常常在动作之间停下来思考并休息;而 AI FDE 可以快速连续地执行操作,每个动作之间只间隔几秒。这可能在几分钟内触发数十个操作,并持续运行直到任务完成。多个 AI FDE 会话可能并行运行,从而使对基础设施的整体影响叠加。这可能暴露出那些对人类较慢、较顺序的活动而言尚可应对的基础设施瓶颈。
请仔细考虑以下方面:
- 存储读写
- 计算资源,尤其是 GPU
- 存储容量
AI FDE 的使用可能需要能够容纳高频并行操作、持续计算负载、增加的网络活动和扩展的存储需求的基础设施。
### 常见问题速答 · FAQ
关于「AI FDE 最佳实践」,读者最常问的几个问题。
核实资源与流程是什么? 让它确认自己理解对了再动手。在生产环境中实施生成的资源之前,务必先验证它们。此验证过程应包括审查所有生成的代码是否正确,以及是否符合组织标准。
限制工具与上下文是什么? 给得越少,跑偏概率越低。我们建议只向模型提供给定任务所必需的上下文和工具。提供不必要的上下文或工具可能导致次优或错误的动作。通过将可用工具限制为特定任务所需的那些,并只包含最相关的上下文,你可以降低混淆或出错的可能性。
拆解问题、迭代推进是什么? 别一次给一个大任务。复杂操作应分解为更小、更易管理的步骤。我们建议从基本结构开始,随着每个组件得到验证再逐步增加复杂度。
用 AIP Evals 跟踪表现是什么? 效果要有数据衡量。使用 AIP Evals 来评估并跟踪由 AI FDE 创建或修改的 functions 的表现。为你的 LLM 支撑的 functions 创建评估套件,让你能够衡量更改随时间推移的影响,并比较不同方法。
---
## AI FDE 的模式与能力
- 页面:https://www.hanzhongpin.xyz/ontology/aip-ai-fde-modes-and-capabilities.html
- 官方原文:https://www.palantir.com/docs/foundry/ai-fde/modes-and-capabilities/
- 主题分组:AI FDE(三)
循序渐进 · AIP 教学 · AI FDE(三)
# AI FDE 的模式与能力
AI FDE 用模式(mode)界定当前在做什么大类任务,用能力(capability)表示跨模式的细粒度技能。理解这两层,才用得准。
## 先记住这几条
① 模式 = 大类任务 数据集成、Ontology 编辑、函数编写等。
② 能力 = 细粒度技能 跨模式复用,各自映射到具体工具。
③ 模式决定加载什么 只给相关文档与工具,避免跑偏。
④ 模式可手动也可自动 你可以指定,也可以让智能体自己判断(甚至中途切换)。
## 写在前面
AI FDE 使用模式(modes)和能力(capabilities)来完成任务,并提供一种简便的方式来管理智能体的上下文。模式是当前要处理的大类任务,例如数据集成或 ontology 编辑;而能力是可在不同模式间使用的细粒度能力。
## 模式
> 要点:大类任务:数据集成、本体编辑、函数编写等。
模式告诉智能体你正在处理哪类任务。你可以手动选择模式,也可以直接在输入字段中输入任务,让智能体为你选择模式。智能体还可以随着任务演进在任务中途切换模式。模式通过加载正确的文档、让智能体访问相关工具,以及调整其处理问题的方式来聚焦智能体。为智能体提供正确的上下文有助于确保它们不会分心或使用错误的工具;一个编写 Python transforms 的智能体不需要治理工具或 React 应用工具,因此只会提供相关的文档和工具。
AI FDE 模式包括以下这些:
- Data integration: 构建或修改数据管道(Python transforms 或 Pipeline Builder)。
- Data connection: 创建、管理和调试 Data Connection 源、出口策略及其他能力。
- Ontology editing: 创建或更新构成你 ontology 的对象、链接和 actions。
- Functions editing: 用 Logic、TypeScript 或 Python 编写 Foundry functions。
- Exploration: 只读调查;在做出更改之前了解你平台中已存在什么。
- Governance: 审计权限、访问控制、标记和数据保护。
- Machine learning: 训练、评估、部署和调优机器学习模型。涵盖分类、回归、时间序列预测和自定义预测建模。
- OSDK React: 构建连接到 Foundry 数据的 React 应用或自定义 widget。
- Platform Q\&A: 提出关于 Foundry 如何工作的一般性问题。
某些模式允许你细化其配置。智能体会使用这些选择来确定要阅读哪些文档以及要调用哪些工具。
Mode Configuration options Data integration Python transforms or Pipeline Builder Function editing Language selection Machine learning Model Studio (no-code) or pro-code development, and preferred code editing environment

> 图:输入字段上方的 AI FDE Mode 选择器,带有额外的配置选项。
## 能力
> 要点:跨模式复用的细粒度技能,各自映射到具体工具。
能力是智能体可以在任何模式中使用的单项能力。模式决定大类的任务上下文,而能力则更为细粒度。每一项能力都映射到智能体可以调用的一个或多个具体工具。能力分为智能体能力(agent capabilities)和领域能力(domain capabilities)。
智能体能力是智能体管理自身和进行沟通的方式。包括以下这些:
- Change mode: 当工作需要时,智能体可以在任务中途切换到不同模式,无需你手动切换。
- Request clarification: 当智能体在继续之前需要更多信息时,它可以向你提问(选择题或自由文本)。
- Generate plan: 在采取行动之前,智能体起草一份计划供你审阅。这对于模糊或多步骤的任务很有用。
- Load documentation: 智能体可以按需查找 Foundry 文档。
- Manage context/Manage capabilities: 随着任务演进,智能体可以整理自己的工作记忆并调整哪些能力处于激活状态。
领域能力是智能体可以在 Foundry 中执行的真实动作,包括但不限于以下这些:
- Filesystem: 创建文件夹、浏览资源并移动内容。
- Notepad: 读取、创建和更新 Notepad 文档。
- Solution design: 创建和编辑解决方案设计图。
- Execute actions: 对 ontology 对象运行 actions。
能力可以被启用或禁用。如果需要,智能体也可以在任务中途打开或关闭能力,这是通过 Manage capabilities 实现的。
### 常见问题速答 · FAQ
关于「AI FDE 的模式与能力」,读者最常问的几个问题。
模式是什么? 大类任务:数据集成、本体编辑、函数编写等。模式告诉智能体你正在处理哪类任务。你可以手动选择模式,也可以直接在输入字段中输入任务,让智能体为你选择模式。智能体还可以随着任务演进在任务中途切换模式。
能力是什么? 跨模式复用的细粒度技能,各自映射到具体工具。能力是智能体可以在任何模式中使用的单项能力。模式决定大类的任务上下文,而能力则更为细粒度。每一项能力都映射到智能体可以调用的一个或多个具体工具。
---
## AI FDE 界面与导航
- 页面:https://www.hanzhongpin.xyz/ontology/aip-ai-fde-navigation.html
- 官方原文:https://www.palantir.com/docs/foundry/ai-fde/navigation/
- 主题分组:AI FDE(二)
循序渐进 · AIP 教学 · AI FDE(二)
# AI FDE 界面与导航
这一篇概览 AI FDE 的界面、导航与可用控件,动手前先认清每个部分在哪、干什么。
## 先记住这几条
① 界面是对话式 输入框是主要操作入口。
② 控件聚焦上下文管理 让你控制智能体"知道什么"。
③ 导航结构简单 上手成本低。
## 写在前面
本页概述 AI FDE 的界面、导航和可用控件。
## 启动会话
> 要点:怎么开始对话。
导航到 AI FDE 应用,并从页面底部的输入字段开始提问或提出请求。

> 图:AI FDE 输入字段。
会话可以在顶部工具栏中管理,你可以在那里创建新会话并管理现有会话。

> 图:AI FDE 会话管理菜单。
## 管理上下文
> 要点:控制智能体知道什么。
AI FDE 只能访问已添加到聊天中的上下文。
上下文可以通过多种方式添加:
- 描述你想要完成的任务,智能体会为你选择一个模式(mode),并基于你的提示词确定可用的上下文和工具。
- 从输入字段上方的 Modes 菜单中选择一个模式。取决于模式的不同,会有额外的配置可用,例如你想用于 functions 的语言,或者你是否想使用 transforms 而不是 Pipeline Builder。

- 从提示词输入字段上方的功能区手动添加上下文。你可以添加与你想让 AI FDE 执行的任务相关的文档包(documentation bundle),或上传媒体。你还可以选择以下 Foundry 资源:
- Datasets
- Functions
- Branches
- Interfaces
- Action types
- Object types

- 将 Foundry 中其他应用的链接拖放到 AI FDE 中。
- 启用搜索工具,使 AI FDE 能够找到相关资源。
### Chat outline
聊天大纲位于右侧一个可折叠面板中,包含会话中提示词、响应和所用工具的历史记录。消息可以在主聊天区或大纲中被摘要或完全移除,以防止在长时间运行的会话中触及模型的上下文窗口。大纲还会显示每条消息所用的 token 数量。

> 图:AI FDE 会话中的大纲面板。
## 工具配置
> 要点:它能调用哪些工具。
AI FDE 提供对工具的可定制访问。当只启用完成任务所需的那部分工具时,模型的表现会更好。你可以使用输入字段下方的工具菜单选择要启用哪些工具。

> 图:提示词输入字段下方的工具菜单。
在使用 AI FDE 执行各种任务时,你可能会被要求批准工具使用。默认情况下,在以下情形执行工具需要批准:
- 该工具正在默认分支上进行更改。
- 该工具正在执行非分支更改,例如创建代码仓库。
- 该工具可能会有副作用,例如数据集构建。

> 图:AI FDE 会话中拒绝或允许工具使用的选项。
所有工具的工具批准都可以在工具选择面板中定制。例如,可以将相关工具设置为在允许列表(allowlist)中的分支和项目上自动执行。
### 常见问题速答 · FAQ
关于「AI FDE 界面与导航」,读者最常问的几个问题。
启动会话是什么? 怎么开始对话。导航到 AI FDE 应用,并从页面底部的输入字段开始提问或提出请求。
管理上下文是什么? 控制智能体知道什么。AI FDE 只能访问已添加到聊天中的上下文。
如何工具配置? 它能调用哪些工具。AI FDE 提供对工具的可定制访问。当只启用完成任务所需的那部分工具时,模型的表现会更好。你可以使用输入字段下方的工具菜单选择要启用哪些工具。
---
## AI FDE 总览:会动手的智能体
- 页面:https://www.hanzhongpin.xyz/ontology/aip-ai-fde-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/ai-fde/overview/
- 主题分组:AI FDE(一)
循序渐进 · AIP 教学 · AI FDE(一)
# AI FDE 总览:会动手的智能体
AI FDE(AI-powered forward deployed engineer)是一个交互式智能体:你用自然语言下指令,它直接在 Foundry 里替你操作。这一篇是它的定位与能力边界。
## 先记住这几条
① 它是"会动手"的智能体 不只是回答问题,而是操作平台。
② 以你的身份运行 不是独立机器人账号。
③ 用对话替代点击 把繁琐操作变成一句话。
④ 全程受权限约束 与手动操作同一套检查。
## 写在前面

> 图:AI FDE overview 头图。
AI FDE,即 AI 驱动的前向部署工程师(AI-powered forward deployed engineer),是一个交互式智能体,通过对话式命令为你操作 Foundry。AI FDE 将自然语言请求转化为 Foundry 操作,让你能够执行数据变换、管理代码仓库、构建并维护你的 ontology(本体)等等。你还可以向 AI FDE 提供来自 Foundry 的上下文,以促进和指导这些操作。
## 要求
> 要点:使用前提。
AI FDE 要求在你的注册上启用 AIP。还建议启用 Global Branching 以支持来自 AI FDE 的 Ontology 编辑。请联系你的 Palantir 管理员为你的注册启用 AIP 和 Global Branching。
## AI FDE 如何工作
> 要点:运行机制。
当你以自然语言提供请求时,AI FDE 会采取以下步骤:
- 分析你的意图和所提供的上下文。
- 确定要执行的适当 Foundry 操作。
- 借助原生工具支持执行所请求的动作。
- 返回带上下文的解释和文档。
所有操作都会遵守用户现有的权限,包括应用和数据访问权限。你可以选择要使用的具体模型,以及模型可用的工具和数据,从而使 AI FDE 只能访问所请求操作所需的能力。
### Customizable tools
AI FDE 可以使用与用户在平台中可执行操作相匹配的工具,包括创建对象类型、编写 transforms 和运行构建。对于需要在真实环境中可靠地与开发工具、API 和基础设施交互的生产系统而言,使用工具的能力至关重要。AI FDE 会显示用于执行动作的工具,并在聊天大纲中保留活动会话期间使用的所有提示词和工具记录。
### Context management
AI FDE 赋予用户对模型可访问信息的完全控制权和可见性。在初始状态下,AI FDE 只加载最少的上下文,为模型提供 Foundry 概念的一般知识,但不访问用户数据。这一基线配置确保系统在每次交互时都从干净状态开始。这种受控的上下文方式可防止「上下文污染」(context pollution)——即不相关信息稀释模型推理有效性时可能发生的情况;通过从受控基线开始,AI FDE 能够对模型的能力和知识边界保持精确治理。
用户可以通过多种方式扩展此上下文,包括拖放文件夹、数据集或文档以提供相关信息。进一步了解上下文管理。
### Closed-loop operation
AI FDE 采用闭环(closed-loop)运行模型:模型执行一个动作、观察结果,并利用该反馈来决定其下一个动作。这形成了一个持续反馈循环,其中一次操作的输出会成为后续决策的输入,从而支持复杂的多步骤工作流。
AI FDE 可以执行各种动作来验证自身的更改,包括但不限于:
- 运行 transform 预览以验证 transform 代码。
- 运行 function 预览以验证 function 行为。
- 查看 CI 检查以验证在 Code Repositories 中编写的代码。
## 能力
> 要点:能做什么、不能做什么。
AI FDE 可以访问若干模式和能力,使其能够执行广泛的操作。你可以在请求输入字段下方的 Tools 菜单中定制 AI FDE 可用的工具。
AI FDE 能够基于自然语言描述执行各种任务,包括:
- Data integration: 构建或修改数据管道(Python transforms 或 Pipeline Builder)。
- Data connection: 创建、管理和调试 Data Connection 源、出口策略(egress policy)及其他能力。
- Ontology editing: 创建或更新构成你 ontology 的对象、链接和 actions。
- Functions editing: 用 Logic、TypeScript 或 Python 编写 Foundry functions,并使用 AIP Evals 测试它们。
- Exploration: 只读调查;在做出更改之前了解你平台中已存在什么。
- Governance: 审计权限、访问控制、标记(marking)和数据保护。
- OSDK React: 构建连接到 Foundry 数据的 React 应用或自定义 widget。
- Platform Q\&A: 提出关于 Foundry 如何工作的一般性问题。
默认情况下,AI FDE 在所有工作流中都使用分支(branching)。AI FDE 会在 Global Branch 提案或 Code Repository 的 pull request 中提出更改以供审查。
## 模型支持
> 要点:用哪些模型驱动。
要让某个模型可被 AI FDE 使用,必须为你的注册启用该模型。AI FDE 对 Anthropic、OpenAI、Google 和 xAI 模型提供一等支持,并支持原生工具 API。
Note: AIP feature availability is subject to change and may differ between customers.
### 常见问题速答 · FAQ
关于「AI FDE 总览:会动手的智能体」,读者最常问的几个问题。
要求是什么? 使用前提。AI FDE 要求在你的注册上启用 AIP。还建议启用 Global Branching 以支持来自 AI FDE 的 Ontology 编辑。请联系你的 Palantir 管理员为你的注册启用 AIP 和 Global Branching。
AI FDE 如何工作? 运行机制。当你以自然语言提供请求时,AI FDE 会采取以下步骤。
能力是什么? 能做什么、不能做什么。AI FDE 可以访问若干模式和能力,使其能够执行广泛的操作。你可以在请求输入字段下方的 Tools 菜单中定制 AI FDE 可用的工具。
模型支持是什么? 用哪些模型驱动。要让某个模型可被 AI FDE 使用,必须为你的注册启用该模型。AI FDE 对 Anthropic、OpenAI、Google 和 xAI 模型提供一等支持,并支持原生工具 API。
---
## AI FDE 的安全与治理
- 页面:https://www.hanzhongpin.xyz/ontology/aip-ai-fde-security-and-governance.html
- 官方原文:https://www.palantir.com/docs/foundry/ai-fde/security-and-governance/
- 主题分组:AI FDE(四)
循序渐进 · AIP 教学 · AI FDE(四)
# AI FDE 的安全与治理
安全与治理是内建在 AI FDE 里的,因为它完全以你的身份和权限运行 —— 它不是独立服务账号,只是"换了个交互方式的你"。
## 先记住这几条
① 以你的身份运行 不是独立的服务账号或机器人。
② 沿用你的会话 代表你行事,权限范围就是你。
③ 每个动作都过检查 与手动操作完全相同的权限校验。
④ 因此可审计 谁让它做了什么,都有迹可循。
## 写在前面
安全与治理内建于 AI FDE 之中,因为它完全以你的身份和权限运行。AI FDE 不是一个单独的服务账号或机器人;它使用你现有的 Foundry 会话代表你行事。它采取的每一个动作都受到与你手动执行操作相同的权限检查、治理控制和审计日志记录约束。
## 以你的权限为界
> 要点:它做不了你做不到的事。
当你使用 AI FDE 时,所有操作都使用你已认证的 Foundry 会话执行。不涉及单独的凭据、服务账号或提权。
AI FDE 在你的用户账号相同的权限约束下运行:
- 如果你没有创建仓库的权限,AI FDE 也没有。
- 如果你无法编辑某个对象类型或执行某个 action,AI FDE 也不能。
- 权限错误与你手动执行相同操作时会看到的一致。
这适用于所有能力,包括 OSDK 应用创建、ontology 编辑、数据集构建和代码仓库操作。
## 敏感操作需用户批准
> 要点:危险动作前会先问你。
除了服务器端的权限强制执行之外,AI FDE 还实现了工具批准系统,在执行变更操作之前需要用户明确确认。默认设置最大限度地保守;任何可能影响生产工作流的操作都不会被自动批准。你也可以在会话期间批准特定工具,并在相关时限定于某个分支或项目。
Category Examples Requires approval every time Executing ontology actions, creating applications or widgets, publishing, or creating tags. Branch-aware approval File edits and dataset builds auto-approve on feature branches, but require approval on protected branches. Auto-approved Read-only operations such as searching and reading definitions.
你对智能体的行为始终保持控制。未经你的同意,AI FDE 无法执行写操作,无论同意是按动作授予的还是会话级预先授予的。
## 会话访问与安全
> 要点:会话本身怎么保护。
每个 AI FDE 会话仅创建该会话的用户可以访问。会话无法与其他用户共享或被其他用户访问。
创建新会话时,你有权访问的标记(marking)会被应用到该会话。如果你失去了对某个已应用于会话的标记的访问权限,将会失去对该会话的访问权。重新获得该标记的访问权将恢复对该会话的访问。
## 审计日志与归因
> 要点:谁让它做了什么,都能查。
所有活动都可以通过标准的 Foundry 审计日志完全审计。由于每次 API 调用都携带你的身份,Foundry 的平台级审计日志记录会捕获所有归因于你的操作,与手动操作的处理方式完全一致。这包括仓库操作、ontology 更改、数据集构建以及所有其他平台交互。
LLM 用量也归因到你个人的用户身份,确保用量跟踪和速率限制按用户生效。
## 要点回顾
> 要点:这一节的核心结论。
Control Description Identity All actions are performed on your behalf using your credentials. There is no service account or separate identity. Permissions Standard Foundry permissions are enforced server-side on every operation. User approval Mutating actions require user consent, either confirmed per-action or through session-level pre-approval scoped to a branch or project. Session access Sessions are only accessible to the user who created it and secured by the user's markings. Audit trail Logging through both AI FDE session logs and standard Foundry audit logs is fully in effect. LLM attribution Model usage is tracked to your individual account. Governance Existing Foundry governance including permissions, branching controls, and audits apply without exception.
AI FDE 是你现有 Foundry 会话中的一个生产力工具,不能超越你的权限。所有动作都以你的身份记录,标准治理模型完整生效。
### 常见问题速答 · FAQ
关于「AI FDE 的安全与治理」,读者最常问的几个问题。
以你的权限为界是什么? 它做不了你做不到的事。当你使用 AI FDE 时,所有操作都使用你已认证的 Foundry 会话执行。不涉及单独的凭据、服务账号或提权。
敏感操作需用户批准是什么? 危险动作前会先问你。除了服务器端的权限强制执行之外,AI FDE 还实现了工具批准系统,在执行变更操作之前需要用户明确确认。默认设置最大限度地保守;任何可能影响生产工作流的操作都不会被自动批准。你也可以在会话期间批准特定工具,并在相关时限定于某个分支或项目。
会话访问与安全是什么? 会话本身怎么保护。每个 AI FDE 会话仅创建该会话的用户可以访问。会话无法与其他用户共享或被其他用户访问。
审计日志与归因是什么? 谁让它做了什么,都能查。所有活动都可以通过标准的 Foundry 审计日志完全审计。由于每次 API 调用都携带你的身份,Foundry 的平台级审计日志记录会捕获所有归因于你的操作,与手动操作的处理方式完全一致。
---
## AIP 的计算用量与计费
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-aip-compute-usage.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/aip-compute-usage/
- 主题分组:核心平台(九)
循序渐进 · AIP 教学 · 核心平台(九)
# AIP 的计算用量与计费
LLM 按 token 计费:输入文本和输出文本都要算钱。这一篇讲清用量从哪来、怎么算、怎么控。
## 先记住这几条
① 计费单位是 token 输入与输出都计量,不同模型单价不同。
② 用量来源很多 提示词、上下文、检索结果、模型输出都算。
③ 可预测、可优化 理解构成才能控成本。
## 写在前面
AIP 计算用量(compute usage)涉及大语言模型(LLM)。从根本上说,LLM 以文本作为输入,并以文本作为输出进行响应。输入和输出的文本量以 token 来计量。LLM 的计算用量以「每若干 token 的计算秒数(compute-seconds)」来计量。不同模型可能有不同的计算用量费率,详见下文。
## AIP 中的 token
> 要点:token 是什么、怎么计量。
Token 是 LLM 用来处理和理解输入的基本文本单位。一个 token 可以短至单个字符,也可以长至一整个单词,具体取决于语言和特定模型。
重要的是,token 与单词并非一一对应。例如,常见单词可能是一个 token,但较长或不太常见的单词可能被拆分成多个 token。甚至标点符号和空格也可以算作 token。
不同的模型提供商对什么构成一个 token 有各自不同的定义;例如,OpenAI ↗ 和 Anthropic ↗。平均而言,一个 token 大约 4 个字符长,其中一个字符是指单个字母或标点符号。
在 AIP 中,token 由那些向 LLM 发送提示词(prompt)并从中接收响应的应用所消耗。每个这样的提示词和响应都由可计量的 token 数构成。这些 token 可以发送给多个 LLM 提供商;由于提供商之间的差异,这些 token 会被转换为计算秒数,以匹配底层模型提供商的价格。
所有提供由 LLM 支持的能力的应用在使用时都会消耗 token。以下列表列出了在你使用其由 LLM 支持的能力时可能会消耗 token 的应用集合。
- AIP Assist
- AIP Logic
- AIP Error Enhancer
- AIP Code Assist
- AIP Analyst
- AI FDE
- Workshop 中由 LLM 支持的工具
- Quiver 中由 LLM 支持的工具
- Pipeline Builder 中由 LLM 支持的工具
- 对 Language Model Service 的直接调用(包括 Python 和 TypeScript 库)
AIP 将文本直接路由到后端 LLM,由它们自行执行分词(tokenization)。文本的大小将决定后端模型为提供响应所使用的计算量。
以下面这句发送给 GPT-4o 模型的句子为例。
AIP incorporates all of Palantir's advanced security measures for the protection of sensitive data in compliance with industry regulations.
这句话包含 140 个字符,将按以下方式分词,用 | 字符分隔每个 token。一个 token 并不总是等同于一个单词;有些单词会被拆分成多个 token,如下例中的 AIP 和 Palantir。
A|IP| incorporates| all| of| Pal|ant|ir|'s| advanced| security| measures| for| the| protection| of| sensitive| data| in| compliance| with| industry| regulations|.
这句话包含 24 个 token,将使用以下数量的计算秒数:
Code compute-seconds = 24 tokens * 43 compute-seconds / 10,000 tokens
compute-seconds = 24 * 43 / 10,000
compute-seconds = 0.1032
上述句子中的 token 数和字符数已通过 OpenAI 的 Tokenizer 功能 ↗核实。
## 理解 AIP 计算用量的来源
> 要点:用量由哪些环节产生。
由 LLM token 产生的计算秒数用量会直接挂载到请求该用量的那个应用资源上。例如,如果你使用 AIP 在 Pipeline Builder 中自动解释一条流水线,那么 LLM 为生成该解释所使用的计算秒数将归属到那条具体的流水线。这一点在整个平台范围内都成立;记住这一点将有助于你追踪自己在何处使用了 token。
在某些情况下,计算用量无法归属于平台中的单个资源;例子包括 AIP Assist 和 Error Explainer 等。当用量无法归属于单个资源时,token 将归属到发起 token 使用的用户文件夹。
我们建议你持续留意那些代表你发送给 LLM 的 token。一般而言,你在使用 LLM 时包含的信息越多,使用的计算秒数就越多。例如,以下场景描述了使用计算秒数的不同方式。
- 在 Pipeline Builder 中,你可以要求 AIP 解释你的转换节点;所选节点的数量会影响 LLM 为生成响应所使用的 token 数,进而影响计算秒数用量。这是因为随着节点数量增加,LLM 必须处理的关于这些节点配置的文本量也会增加。
- 在 AIP Assist 中,要求 LLM 生成大段代码需要更多的输出 token。较短的响应使用更少的 token,因而消耗更少的计算量。
- 在 AIP Logic 中,随提示词一起发送大量文本需要更多 token,因而需要更多计算秒数。
### Exporting AIP token usage data
要详细分析你注册的 LLM 用量,你可以从 Control Panel 的 Internal dataset export 部分导出 AIP Token Usage 数据集。该数据集提供按模型和资源划分的每日 token 消耗明细,以及相应的计算秒数和货币用量。如需了解更多信息,请参阅内部数据集导出。
## AIP 的按用量计费换算
> 要点:token 如何折算成费用。
> 以下费率适用于在特定默认合同条款下托管于 AWS 的 Foundry 注册。这些费率并不适用于所有客户。如果你与 Palantir 已有合同,请联系你的 Palantir 代表以确认适用于你的费率。
Model Foundry region Compute seconds per 10k input tokens Compute seconds per 10k output tokens Grok-2 ↗ 北美 36 182 欧盟 / 英国 31 154 南美 / 亚太 / 中东 25 125 Grok-2-Vision ↗ 北美 36 182 欧盟 / 英国 31 154 南美 / 亚太 / 中东 25 125 Grok-3 ↗ 北美 55 273 欧盟 / 英国 46 231 南美 / 亚太 / 中东 38 188 Grok-3-Mini-Reasoning ↗ 北美 5.5 9.1 欧盟 / 英国 4.6 7.7 南美 / 亚太 / 中东 3.8 6.3 Grok-4 <= 128k tokens ↗ 北美 54.5 272.7 欧盟 / 英国 46.2 230.8 南美 / 亚太 / 中东 37.5 187.5 Grok-4 > 128k tokens ↗ 北美 109.1 545.5 欧盟 / 英国 92.3 461.5 南美 / 亚太 / 中东 75.0 375.0 Grok-4 Fast Reasoning <= 128k tokens ↗ 北美 3.6 9.1 欧盟 / 英国 3.1 7.7 南美 / 亚太 / 中东 2.5 6.3 Grok-4 Fast Reasoning > 128k tokens ↗ 北美 7.3 18.2 欧盟 / 英国 6.2 15.4 南美 / 亚太 / 中东 5.0 12.5 Grok-4 Fast Non-Reasoning <= 128k tokens ↗ 北美 3.6 9.1 欧盟 / 英国 3.1 7.7 南美 / 亚太 / 中东 2.5 6.3 Grok-4 Fast Non-Reasoning > 128k tokens ↗ 北美 7.3 18.2 欧盟 / 英国 6.2 15.4 南美 / 亚太 / 中东 5.0 12.5 Grok Code Fast 1 ↗ 北美 3.6 27.3 欧盟 / 英国 3.1 23.1 南美 / 亚太 / 中东 2.5 18.8 Grok-4.1 Fast Non-Reasoning ↗ 北美 3.6 9.1 欧盟 / 英国 3.1 7.7 南美 / 亚太 / 中东 2.5 6.3 Grok-4.1 Fast Reasoning ↗ 北美 3.6 9.1 欧盟 / 英国 3.1 7.7 南美 / 亚太 / 中东 2.5 6.3 Grok-4.20 Reasoning <= 200k tokens ↗ 北美 36.4 109.1 欧盟 / 英国 30.8 92.3 南美 / 亚太 / 中东 25.0 75.0 Grok-4.20 Reasoning > 200k tokens ↗ 北美 72.7 218.2 欧盟 / 英国 61.5 184.6 南美 / 亚太 / 中东 50.0 150.0 Grok-4.20 Non-Reasoning <= 200k tokens ↗ 北美 36.4 109.1 欧盟 / 英国 30.8 92.3 南美 / 亚太 / 中东 25.0 75.0 Grok-4.20 Non-Reasoning > 200k tokens ↗ 北美 72.7 218.2 欧盟 / 英国 61.5 184.6 南美 / 亚太 / 中东 50.0 150.0 Grok-4.3 <= 200k tokens ↗ 北美 22.7 45.5 欧盟 / 英国 19.2 38.5 南美 / 亚太 / 中东 15.6 31.3 Grok-4.3 > 200k tokens ↗ 北美 45.5 90.9 欧盟 / 英国 38.5 76.9 南美 / 亚太 / 中东 31.3 62.5 Grok-4.5 <= 200k tokens ↗ 北美 36.4 109.1 欧盟 / 英国 30.8 92.3 南美 / 亚太 / 中东 25.0 75.0 Grok-4.5 > 200k tokens ↗ 北美 72.7 218.2 欧盟 / 英国 61.5 184.6 南美 / 亚太 / 中东 50.0 150.0 Grok-4.6 <= 200k tokens ↗ 北美 36.4 109.1 欧盟 / 英国 30.8 92.3 南美 / 亚太 / 中东 25.0 75.0 Grok-4.6 > 200k tokens ↗ 北美 72.7 218.2 欧盟 / 英国 61.5 184.6 南美 / 亚太 / 中东 50.0 150.0 Grok Build 0.1 <= 200k tokens ↗ 北美 18.2 36.4 欧盟 / 英国 15.4 30.8 南美 / 亚太 / 中东 12.5 25.0 Grok Build 0.1 > 200k tokens ↗ 北美 36.4 72.7 欧盟 / 英国 30.8 61.5 南美 / 亚太 / 中东 25.0 50.0 GPT-4.5 ↗ 北美 1159.1 2318.2 欧盟 / 英国 980.8 1961.5 南美 / 亚太 / 中东 796.9 1593.8 GPT-4o ↗ 北美 43 172 欧盟 / 英国 36 145 南美 / 亚太 / 中东 30 118 GPT-4o mini ↗ 北美 2.6 10.3 欧盟 / 英国 2.2 8.7 南美 / 亚太 / 中东 1.8 7.1 GPT-4.1 ↗ 北美 31 124 欧盟 / 英国 26 105 南美 / 亚太 / 中东 21 85 GPT-4.1-mini ↗ 北美 6.2 24.7 欧盟 / 英国 5.2 20.9 南美 / 亚太 / 中东 4.3 17 GPT-4.1-nano ↗ 北美 1.5 6.2 欧盟 / 英国 1.3 5.2 南美 / 亚太 / 中东 1.1 4.3 GPT-5 ↗ 北美 20.5 163.6 欧盟 / 英国 17.3 138.5 南美 / 亚太 / 中东 14.1 112.5 GPT-5-mini ↗ 北美 4.1 32.7 欧盟 / 英国 3.5 27.7 南美 / 亚太 / 中东 2.8 22.5 GPT-5-nano ↗ 北美 0.82 6.5 欧盟 / 英国 0.69 5.5 南美 / 亚太 / 中东 0.56 4.5 GPT-5-pro ↗ 北美 231.8 1854.5 欧盟 / 英国 196.2 1569.2 南美 / 亚太 / 中东 159.4 1275.0 GPT-OSS-20B ↗ 北美 1.1 4.9 欧盟 / 英国 1.0 4.2 南美 / 亚太 / 中东 0.79 3.4 GPT-OSS-120B ↗ 北美 2.5 9.8 欧盟 / 英国 2.1 8.3 南美 / 亚太 / 中东 1.7 6.8 GPT-5 Codex ↗ 北美 20.5 163.6 欧盟 / 英国 17.3 138.5 南美 / 亚太 / 中东 14.1 112.5 GPT-5.1 Codex Mini ↗ 北美 5.5 36.4 欧盟 / 英国 4.6 30.8 南美 / 亚太 / 中东 3.8 25 GPT-5.1 Codex ↗ 北美 23.6 181.8 欧盟 / 英国 20 153.8 南美 / 亚太 / 中东 16.3 125 GPT-5.1 ↗ 北美 23.6 181.8 欧盟 / 英国 20 153.8 南美 / 亚太 / 中东 16.3 125 GPT-5.1 Codex Max ↗ 北美 22.7 181.8 欧盟 / 英国 19.2 153.8 南美 / 亚太 / 中东 15.6 125.0 GPT-5.2 ↗ 北美 31.8 254.5 欧盟 / 英国 26.9 215.4 南美 / 亚太 / 中东 21.9 175.0 GPT-5.2 Codex ↗ 北美 32.7 254.5 欧盟 / 英国 27.7 215.4 南美 / 亚太 / 中东 22.5 175 GPT-5.2 Pro ↗ 北美 381.8 3054.5 欧盟 / 英国 323.1 2584.6 南美 / 亚太 / 中东 262.5 2100.0 GPT-5.3 Codex ↗ 北美 31.8 254.5 欧盟 / 英国 26.9 215.4 南美 / 亚太 / 中东 21.9 175.0 GPT-5.4 <= 272k tokens ↗ 北美 45.5 272.7 欧盟 / 英国 38.5 230.8 南美 / 亚太 / 中东 31.3 187.5 GPT-5.4 > 272k tokens ↗ 北美 90.9 409.1 欧盟 / 英国 76.9 346.2 南美 / 亚太 / 中东 62.5 281.3 GPT-5.4 Pro <= 272k tokens ↗ 北美 545.5 3272.7 欧盟 / 英国 461.5 2769.2 南美 / 亚太 / 中东 375.0 2250.0 GPT-5.4 Pro > 272k tokens ↗ 北美 1090.9 4909.1 欧盟 / 英国 923.1 4153.8 南美 / 亚太 / 中东 750.0 3375.0 GPT-5.4-mini ↗ 北美 13.6 81.8 欧盟 / 英国 11.5 69.2 南美 / 亚太 / 中东 9.4 56.3 GPT-5.4-nano ↗ 北美 3.6 22.7 欧盟 / 英国 3.1 19.2 南美 / 亚太 / 中东 2.5 15.6 GPT-5.5 <= 272k tokens ↗ 北美 81.8 490.9 欧盟 / 英国 69.2 415.4 南美 / 亚太 / 中东 56.3 337.5 GPT-5.5 > 272k tokens ↗ 北美 163.6 736.4 欧盟 / 英国 138.5 623.1 南美 / 亚太 / 中东 112.5 506.3 GPT-5.6 Sol <= 272k tokens ↗ 北美 81.8 490.9 欧盟 / 英国 69.2 415.4 南美 / 亚太 / 中东 56.3 337.5 GPT-5.6 Sol > 272k tokens ↗ 北美 163.6 736.4 欧盟 / 英国 138.5 623.1 南美 / 亚太 / 中东 112.5 506.3 GPT-5.6 Terra <= 272k tokens ↗ 北美 32.7 196.4 欧盟 / 英国 27.7 166.2 南美 / 亚太 / 中东 22.5 135.0 GPT-5.6 Terra > 272k tokens ↗ 北美 65.5 294.5 欧盟 / 英国 55.4 249.2 南美 / 亚太 / 中东 45.0 202.5 GPT-5.6 Luna <= 272k tokens ↗ 北美 3.3 19.6 欧盟 / 英国 2.8 16.6 南美 / 亚太 / 中东 2.3 13.5 GPT-5.6 Luna > 272k tokens ↗ 北美 6.5 29.5 欧盟 / 英国 5.5 24.9 南美 / 亚太 / 中东 4.5 20.3 GPT-6 Astra <= 272k tokens ↗ 北美 163.6 818.2 欧盟 / 英国 138.5 692.3 南美 / 亚太 / 中东 112.5 562.5 GPT-6 Astra > 272k tokens ↗ 北美 327.3 1227.3 欧盟 / 英国 276.9 1038.5 南美 / 亚太 / 中东 225.0 843.75 GPT Realtime ↗ 北美 72.7 290.9 欧盟 / 英国 61.5 246.2 南美 / 亚太 / 中东 50 200 GPT Realtime 1.5 ↗ 北美 72.7 290.9 欧盟 / 英国 61.5 246.2 南美 / 亚太 / 中东 50.0 200.0 o1 ↗ 北美 232 927 欧盟 / 英国 196 785 南美 / 亚太 / 中东 159 638 o1-mini ↗ 北美 17 68 欧盟 / 英国 14 58 南美 / 亚太 / 中东 12 47 o3 ↗ 北美 31 124 欧盟 / 英国 26 105 南美 / 亚太 / 中东 21 85 o3-mini ↗ 北美 17 68 欧盟 / 英国 14 58 南美 / 亚太 / 中东 12 47 o3-pro ↗ 北美 345.5 1381.8 欧盟 / 英国 292.3 1169.2 南美 / 亚太 / 中东 237.5 950.0 o4-mini ↗ 北美 17 68 欧盟 / 英国 14 58 南美 / 亚太 / 中东 12 47 ada embedding ↗ 北美 1.68 N/A 欧盟 / 英国 1.42 N/A 南美 / 亚太 / 中东 1.16 N/A text-embedding-3-large ↗ 北美 2.24 N/A 欧盟 / 英国 1.89 N/A 南美 / 亚太 / 中东 1.54 N/A text-embedding-3-small ↗ 北美 0.34 N/A 欧盟 / 英国 0.29 N/A 南美 / 亚太 / 中东 0.24 N/A OpenAI Text Embedding 3 Large ↗ 北美 2.2 N/A 欧盟 / 英国 1.9 N/A 南美 / 亚太 / 中东 1.5 N/A OpenAI Text Embedding 3 Small ↗ 北美 0.3 N/A 欧盟 / 英国 0.3 N/A 南美 / 亚太 / 中东 0.2 N/A OpenAI Text Embedding Ada 002 ↗ 北美 1.7 N/A 欧盟 / 英国 1.4 N/A 南美 / 亚太 / 中东 1.2 N/A Anthropic Claude 3 ↗ 北美 52 258 欧盟 / 英国 44 218 南美 / 亚太 / 中东 35 177 Anthropic Claude 3 Haiku ↗ 北美 4.3 21.5 欧盟 / 英国 3.6 18.2 南美 / 亚太 / 中东 3.0 14.8 Anthropic Claude 3.5 Haiku ↗ 北美 12 62 欧盟 / 英国 10 52 南美 / 亚太 / 中东 9 43 Anthropic Claude 4.5 Haiku ↗ 北美 17.3 86.4 欧盟 / 英国 14.6 73.1 南美 / 亚太 / 中东 11.9 59.4 Anthropic Claude 3.5 Sonnet ↗ 北美 52 258 欧盟 / 英国 44 218 南美 / 亚太 / 中东 35 177 Anthropic Claude 3.5 Sonnet v2 ↗ 北美 46 232 欧盟 / 英国 39 196 南美 / 亚太 / 中东 32 159 Anthropic Claude 4 Sonnet ↗ 北美 46.4 231.8 欧盟 / 英国 39.2 196.2 南美 / 亚太 / 中东 31.9 159.4 Anthropic Claude 4.5 Sonnet ↗ 北美 51.8 259.1 欧盟 / 英国 43.8 219.2 南美 / 亚太 / 中东 35.6 178.1 Anthropic Claude 4.6 Sonnet ↗ 北美 54.5 272.7 欧盟 / 英国 46.2 230.8 南美 / 亚太 / 中东 37.5 187.5 Anthropic Claude 5 Sonnet ↗ 北美 36.4 181.8 欧盟 / 英国 30.8 153.8 南美 / 亚太 / 中东 25.0 125.0 Anthropic Claude 4 Opus ↗ 北美 232 1159 欧盟 / 英国 196 981 南美 / 亚太 / 中东 159 797 Anthropic Claude 4.1 Opus ↗ 北美 259 1295 欧盟 / 英国 219 1096 南美 / 亚太 / 中东 178 891 Anthropic Claude 4.5 Opus ↗ 北美 90.9 454.5 欧盟 / 英国 76.9 384.6 南美 / 亚太 / 中东 62.5 312.5 Anthropic Claude 4.6 Opus ↗ 北美 90.9 454.5 欧盟 / 英国 76.9 384.6 南美 / 亚太 / 中东 62.5 312.5 Anthropic Claude 4.7 Opus ↗ 北美 90.9 454.5 欧盟 / 英国 76.9 384.6 南美 / 亚太 / 中东 62.5 312.5 Anthropic Claude 4.8 Opus ↗ 北美 90.9 454.5 欧盟 / 英国 76.9 384.6 南美 / 亚太 / 中东 62.5 312.5 Anthropic Claude 5 Opus ↗ 北美 90.9 454.5 欧盟 / 英国 76.9 384.6 南美 / 亚太 / 中东 62.5 312.5 Mistral Small 24B ↗ 北美 158 525 欧盟 / 英国 133 444 南美 / 亚太 / 中东 108 361 Mistral Small 24B Instruct ↗ 北美 157.5 525 欧盟 / 英国 133.3 444.2 南美 / 亚太 / 中东 108.3 360.9 Llama 3.1_8B ↗ 北美 158 525 欧盟 / 英国 133 444 南美 / 亚太 / 中东 108 361 Llama 3.3_70B ↗ 北美 158 525 欧盟 / 英国 133 444 南美 / 亚太 / 中东 108 361 Llama 3.3 70B Instruct ↗ 北美 157.5 525 欧盟 / 英国 133.3 444.2 南美 / 亚太 / 中东 108.3 360.9 Llama 4 Scout_17B 16E Instruct ↗ 北美 1.5 5.7 欧盟 / 英国 1.2 4.8 南美 / 亚太 / 中东 1.0 3.9 Llama 4 Maverick_17B 128E Instruct ↗ 北美 2.1 8.4 欧盟 / 英国 1.8 7.1 南美 / 亚太 / 中东 1.4 5.8 Nemotron 3 Nano 30B ↗ 北美 1.1 4.4 欧盟 / 英国 0.9 3.7 南美 / 亚太 / 中东 0.8 3.0 Nemotron 3 Super 120B ↗ 北美 2.7 11.8 欧盟 / 英国 2.3 10.0 南美 / 亚太 / 中东 1.9 8.1 Nemotron 3 Ultra 550B A55B NVFP4 ↗ 北美 10.9 43.6 欧盟 / 英国 9.2 36.9 南美 / 亚太 / 中东 7.5 30.0 DeepSeek V3.2 ↗ 北美 9.3 27.9 欧盟 / 英国 7.9 23.6 南美 / 亚太 / 中东 6.4 19.1 Kimi K2.5 ↗ 北美 9.0 17.1 欧盟 / 英国 7.6 14.4 南美 / 亚太 / 中东 6.2 11.7 Kimi K3 ↗ 北美 54.5 272.7 欧盟 / 英国 46.2 230.8 南美 / 亚太 / 中东 37.5 187.5 GLM-5 ↗ 北美 45.2 62.2 欧盟 / 英国 38.2 52.7 南美 / 亚太 / 中东 31.1 42.8 GLM 5.3 ↗ 北美 25.5 80.0 欧盟 / 英国 21.5 67.7 南美 / 亚太 / 中东 17.5 55.0 GLM 5.3 Flash ↗ 北美 2.7 9.1 欧盟 / 英国 2.3 7.7 南美 / 亚太 / 中东 1.9 6.25 Qwen3 32B ↗ 北美 2.3 9.2 欧盟 / 英国 1.9 7.7 南美 / 亚太 / 中东 1.6 6.3 Qwen3 235B A22B 2507 ↗ 北美 3.4 13.3 欧盟 / 英国 2.9 11.3 南美 / 亚太 / 中东 2.3 9.1 MiniMax M2 ↗ 北美 5.9 23.3 欧盟 / 英国 5.0 19.7 南美 / 亚太 / 中东 4.1 16.0 MiniMax M2.5 ↗ 北美 5.9 23.3 欧盟 / 英国 5.0 19.7 南美 / 亚太 / 中东 4.1 16.0 Snowflake Arctic Embed ↗ 北美 38 38 欧盟 / 英国 32 32 南美 / 亚太 / 中东 26 26 Snowflake Arctic Embed M ↗ 北美 38.2 38.2 欧盟 / 英国 32.3 32.3 南美 / 亚太 / 中东 26.2 26.2 Gemma 4 31B ↗ 北美 2.1 4.8 欧盟 / 英国 1.8 4.0 南美 / 亚太 / 中东 1.5 3.3 Gemini 1.5 Flash ↗ 北美 1.3 5.2 欧盟 / 英国 1.1 4.4 南美 / 亚太 / 中东 0.9 3.5 Gemini 1.5 Pro ↗ 北美 21 86 欧盟 / 英国 18 73 南美 / 亚太 / 中东 15 59 Gemini 2.0 Flash ↗ 北美 1.5 6.2 欧盟 / 英国 1.3 5.2 南美 / 亚太 / 中东 1.1 4.3 Gemini 2.5 Flash Lite ↗ 北美 1.7 6.9 欧盟 / 英国 1.5 5.8 南美 / 亚太 / 中东 1.2 4.8 Gemini 2.5 Flash ↗ 北美 5.2 43.2 欧盟 / 英国 4.4 36.5 南美 / 亚太 / 中东 3.6 29.7 Gemini 2.5 Pro <= 200k tokens ↗ 北美 21.6 172.7 欧盟 / 英国 18.3 146.2 南美 / 亚太 / 中东 14.8 118.8 Gemini 2.5 Pro > 200k tokens ↗ 北美 43.2 259.1 欧盟 / 英国 36.5 219.1 南美 / 亚太 / 中东 29.7 178.1 Gemini 3 Flash ↗ 北美 9.1 54.5 欧盟 / 英国 7.7 46.2 南美 / 亚太 / 中东 6.3 37.5 Gemini 3 Pro <= 200k tokens ↗ 北美 34.5 207.3 欧盟 / 英国 29.2 175.4 南美 / 亚太 / 中东 23.8 142.5 Gemini 3 Pro > 200k tokens ↗ 北美 69.1 310.9 欧盟 / 英国 58.5 263.1 南美 / 亚太 / 中东 47.5 213.8 Gemini 3.1 Pro <= 200k tokens ↗ 北美 34.5 207.3 欧盟 / 英国 29.2 175.4 南美 / 亚太 / 中东 23.8 142.5 Gemini 3.1 Pro > 200k tokens ↗ 北美 69.1 310.9 欧盟 / 英国 58.5 263.1 南美 / 亚太 / 中东 47.5 213.8 Gemini 3.1 Flash Lite ↗ 北美 4.5 27.3 欧盟 / 英国 3.8 23.1 南美 / 亚太 / 中东 3.1 18.8 Gemini 3.5 Flash ↗ 北美 25.9 155.5 欧盟 / 英国 21.9 131.5 南美 / 亚太 / 中东 17.8 106.9 Gemini 3.5 Flash Lite ↗ 北美 5.2 43.2 欧盟 / 英国 4.4 36.5 南美 / 亚太 / 中东 3.6 29.7 Gemini 3.6 Flash ↗ 北美 13.0 64.8 欧盟 / 英国 11.0 54.8 南美 / 亚太 / 中东 8.9 44.5 Gemini 3.7 Flash ↗ 北美 13.0 64.8 欧盟 / 英国 11.0 54.8 南美 / 亚太 / 中东 8.9 44.5 Gemini 3.8 Flash ↗ 北美 13.0 64.8 欧盟 / 英国 11.0 54.8 南美 / 亚太 / 中东 8.9 44.5 Gemini Live 2.5 Flash Native Audio ↗ 北美 8.6 51.8 欧盟 / 英国 7.3 43.8 南美 / 亚太 / 中东 5.9 35.6 Gemini Embedding 2 Text ↗ 北美 3.6 N/A 欧盟 / 英国 3.1 N/A 南美 / 亚太 / 中东 2.5 N/A Document Information Extraction 北美 182 N/A 欧盟 / 英国 154 N/A 南美 / 亚太 / 中东 125 N/A
### 常见问题速答 · FAQ
关于「AIP 的计算用量与计费」,读者最常问的几个问题。
AIP 中的 token是什么? token 是什么、怎么计量。Token 是 LLM 用来处理和理解输入的基本文本单位。一个 token 可以短至单个字符,也可以长至一整个单词,具体取决于语言和特定模型。
理解 AIP 计算用量的来源是什么? 用量由哪些环节产生。由 LLM token 产生的计算秒数用量会直接挂载到请求该用量的那个应用资源上。例如,如果你使用 AIP 在 Pipeline Builder 中自动解释一条流水线,那么 LLM 为生成该解释所使用的计算秒数将归属到那条具体的流水线。
AIP 的按用量计费换算是什么? token 如何折算成费用。以下费率适用于在特定默认合同条款下托管于 AWS 的 Foundry 注册。这些费率并不适用于所有客户。如果你与 Palantir 已有合同,请联系你的 Palantir 代表以确认适用于你的费率。
---
## AIP 能力清单:平台各处的 AI 特性
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-aip-features.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/aip-features/
- 主题分组:核心平台(二)
循序渐进 · AIP 教学 · 核心平台(二)
# AIP 能力清单:平台各处的 AI 特性
平台里几乎每个应用都配备了 AIP 驱动能力。这一篇把它们按应用分类列全,作为你的能力索引表。
## 先记住这几条
① 能力是分散在各应用里的 AIP 不是单一应用,而是一组渗透到平台各处的能力。
② 由你选定的 LLM 驱动 用哪个模型由你决定,模型清单见 Supported LLMs。
③ 可以按需开关 哪些能力开启由管理员控制。
## 写在前面
如本页所述,Palantir 平台中的各类应用都配备了由 AIP 驱动的能力。这些能力由你所选择的、受平台支持的 LLM 提供支持(LLMs supported by the platform)。
## AIP 应用与构建者能力
> 要点:面向应用使用者和面向构建者的能力各有哪些。
AIP 使开发者和构建者能够使用 LLM 原生工具(例如 AIP Chatbot Studio(原名 AIP Agent Studio)和 AIP Logic)或由 AIP 加速的平台应用(例如 Pipeline Builder 和 Workshop),在 Palantir 平台上创建由 LLM 支持的工作流、智能体和应用。
Palantir 提供的 LLM 也可在核心 Foundry 功能中使用,例如 Functions、Transforms 以及通过 Code Workspaces 使用的 Jupyter® notebook。
此外,Palantir 现有的模型集成能力允许用户连接自定义大语言模型,并独立地从零构建用例。
更多信息请参见下文的应用参考。
### AIP application reference
下表介绍了 AIP 应用,并说明了你可能在何种情况下使用它们。 你也可以查阅 Foundry 套件应用的参考页面。
Application Description AIP Assist AIP Assist 是一款由 LLM 驱动的支持工具,通过提供实时、安全的自然语言协助,帮助用户熟悉 Palantir 平台。用户可以向 AIP Assist 提问,并以自己偏好的语言获得上下文感知的回答,从而加速工作流并提高生产力。 AIP Logic AIP Logic 是一个无代码开发环境,用于创建、测试和部署 AI 驱动的函数——让你可以通过点击式操作,利用由 Ontology 中数据支撑的 LLM 能力。AIP Logic 提供直观的界面,用于设计提示词(prompt)、设置自动化,以及集成结构化或非结构化的 Ontology 数据。你可以使用 AIP Logic 轻松简化和自动化复杂流程(例如排程或优化问题),同时保持强大的安全控制。 AIP Chatbot Studio AIP Chatbot Studio 使你能够创建交互式聊天机器人,它们可以利用 Ontology 中的企业专属数据以及一系列工具来完成任务、达成目标。你可以部署由 LLM 驱动的 AIP 聊天机器人,以自动化手动操作、编辑 Ontology 数据、简化工作流并增强应用交互。 AIP Evals AIP Evals 是生产环境中稳定、可靠的 AIP 工作流的基础;通过使用 AIP Evals 测试和评估基于 LLM 的函数与提示词,你可以对由 LLM 支持的工作流建立信心。通过在 AIP Evals 中设置测试用例和评估标准,你可以系统地进行调试、迭代和改进实现,比较不同模型,并检查多次运行之间的差异。 AIP Threads AIP Threads 为你提供了一种使用 LLM 执行任务和临时分析的简便方式,无需任何技术配置即可与文档和 AIP 聊天机器人交互——只需将文档拖放到 AIP Threads 中,或从一系列现有资源和聊天机器人中挑选,然后用你的请求提示 LLM。 Palantir MCP Palantir MCP 使外部 AI IDE 和智能体能够连接到 Palantir 平台,并获取关于你的 Ontology 和 Foundry 工具的上下文。使用 Palantir MCP 可让外部 AI 系统查询数据、访问文档,并更高效地构建应用。
## AIP 与开发者工具链
> 要点:写代码的人能用上哪些 AI 能力。
Palantir 的开发者工具链为你提供了构建可直接使用 Ontology 数据、逻辑和操作的 AI 应用的积木。Ontology SDK 让你可以用 Python、Java 或 TypeScript 编写由 AIP 驱动的应用,并内置对 AIP Logic 函数的访问能力。Palantir MCP 将外部 AI IDE 和智能体连接到 Palantir 平台,为它们提供关于你的 Ontology 和 Foundry 应用的上下文,使其能够更高效地查询数据、访问文档并构建应用。这些工具共同让你能够轻松构建接入组织数据的 AI 解决方案,而不必把各种孤立的系统拼凑在一起。
## 各平台应用中的 AIP 能力
> 要点:查"某个应用有没有 AI 能力"就看这一节。
AIP 功能也已嵌入核心 Foundry 应用中,以帮助用户加速工作流并释放平台的更多价值。以下只是 AIP 功能的部分示例,并非完整清单。最新的 AIP 更新可在文档的公告板块中找到。平台管理员可以通过 Control Panel 中的 AIP settings 来治理这些能力的使用。
### AIP Assist sidebar
在任意平台应用中,你都可以打开 AIP Assist 侧边栏来获取支持;AIP Assist 具备上下文感知能力,因此对查询的回答会随当前激活的平台应用而变化。你可以从工作区导航栏打开 AIP Assist,也可以使用键盘快捷键(macOS 为 Cmd + Shift + U,Windows 为 Ctrl + Shift + U)访问它。
进一步了解 AIP Assist。
### Pipeline Builder
在 Pipeline Builder 中使用 AIP,可帮助你更好地理解、构建和管理你的 pipeline。Pipeline Builder 拥有一组核心的 Assist 功能,以及用于自定义工作流的额外 AIP 能力。
在具备相应权限的情况下,你可以在 Pipeline Builder 中使用用于自定义工作流的 AIP 能力,例如:
- Use LLM 节点提供了一种便捷方式,可在你的数据上大规模执行大语言模型(LLM)。
- 你也可以对输入数据集中的少量行运行试验,在将模型运行于整个数据集之前先迭代你的提示词。
- Pipeline Builder 中提供的文本转嵌入表达式允许你使用文本嵌入 ada-002 模型将文本字符串转换为语义向量表示,从而实现基于词句含义的高级文本分析和操作。
Pipeline Builder 的用户还可受益于核心 Assist 功能,其中一些包括:
- Explain: 进一步了解你 pipeline 开发中的各个步骤,并建议相关的名称和描述。

- Regex Helper: 生成为你量身定制的正则表达式,适用于所有技能水平。

- Transform Assist: 创建和编辑正则表达式,并轻松地将字符串转换为特定的时间戳格式。
### Automate
Automate 应用使用户能够构建自动化流程,持续监控已定义的条件,并在满足这些条件时自动执行相应效果。
Automate 已与 AIP Logic 集成,使你能够直接从 AIP Logic 文件创建自动化流程。该能力通过自动化地应用 Ontology 编辑或将其暂存以供人工审核,改善你的 Ontology 管理体验。该工作流的用户可以检查每个拟议操作背后的逻辑,并在批准后让更改自动应用。
### Notepad
AIP 为 Notepad 带来了由 LLM 驱动的功能,你可以使用 AIP 自动进行拼写检查、缩短、修改或翻译文本,而不影响文档现有格式。

> 图:Notepad 中显示可用功能的 AIP 下拉菜单。
### Scheduler
你可以在创建具有特定时间触发器的数据集构建排程时,在 Scheduler 应用中使用 AIP 来生成排程配置。在 New schedule view 侧边面板中输入排程触发提示词,即可为复杂的触发器生成正确的 cron 格式。
Jupyter®、JupyterLab® 以及 Jupyter® 徽标是 NumFOCUS 的商标或注册商标。
### 常见问题速答 · FAQ
关于「AIP 能力清单:平台各处的 AI 特性」,读者最常问的几个问题。
AIP 应用与构建者能力是什么? 面向应用使用者和面向构建者的能力各有哪些。AIP 使开发者和构建者能够使用 LLM 原生工具(例如 AIP Chatbot Studio(原名 AIP Agent Studio)和 AIP Logic)或由 AIP 加速的平台应用(例如 Pipeline Bu…
AIP 与开发者工具链是什么? 写代码的人能用上哪些 AI 能力。Palantir 的开发者工具链为你提供了构建可直接使用 Ontology 数据、逻辑和操作的 AI 应用的积木。
各平台应用中的 AIP 能力是什么? 查"某个应用有没有 AI 能力"就看这一节。AIP 功能也已嵌入核心 Foundry 应用中,以帮助用户加速工作流并释放平台的更多价值。以下只是 AIP 功能的部分示例,并非完整清单。最新的 AIP 更新可在文档的公告板块中找到。
---
## Ontology 与 AIP 的可观测性
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-aip-observability.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/aip-observability/
- 主题分组:核心平台(十)
循序渐进 · AIP 教学 · 核心平台(十)
# Ontology 与 AIP 的可观测性
AI 跑出问题了,怎么查?这一篇讲 Workflow Lineage 里的一组能力,让你看清每条 AI 流程的来龙去脉。
## 先记住这几条
① 可观测性 = 能看清 不只知道失败,还能知道为什么。
② 依托 Workflow Lineage 在血缘图里追踪资源与执行。
③ 本体与 AIP 都覆盖 不只是底层基础设施。
## 写在前面
Ontology 与 AIP 可观测性(observability)是指 Workflow Lineage 中的一组能力,它们让你能够洞察 AIP 与 Ontology 工作流的执行情况,包括指标、执行历史、分布式追踪、日志与日志搜索。这些能力是 Palantir 平台级可观测性策略的一部分。
要进一步了解可用的工具以及如何开始,请参阅 Ontology 与 AIP 可观测性章节。
---
## AIP 的安全与隐私
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-aip-security.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/aip-security/
- 主题分组:核心平台(八)
循序渐进 · AIP 教学 · 核心平台(八)
# AIP 的安全与隐私
把 AI 接进企业数据,安全是第一道门槛。这一篇讲 AIP 如何保护客户数据的隐私与安全。
## 先记住这几条
① 数据保护是首要原则 从产品设计阶段就内建,而非附加。
② 权限体系沿用平台 不新建一套,直接用既有治理机制。
③ 数据流向可审计 谁在什么时候让 AI 看了什么,都能查。
## 写在前面
Palantir 致力于保护客户数据的隐私与安全。对客户信息的保护与负责任处理是我们运营的核心,并作为首要原则融入到我们的产品(包括 AIP)之中。
尽管生成式 AI 模型(包括 LLM)为改进和加速业务流程与决策提供了机会,但这些技术也可能在隐私与安全、偏见与歧视,以及人类判断所扮演的角色等方面引发问题。Palantir 严肃对待这些关切;本页包含了一系列关于 AIP 安全与隐私的常见问题。如需了解更多信息,请参阅 Palantir 信任门户 ↗ 中的《常见问题:Palantir AIP 利用第三方托管的 LLM 的安全与隐私》↗。
## AIP 是否受与 Foundry 数据相同的安全措施保护?
> 要点:最常见的第一个疑问。
是的。 AIP 纳入了 Palantir 所有先进的安全措施,以在符合行业法规的前提下保护敏感数据。AIP 提供强大的访问控制、加密与审计能力,以维护数据的完整性与透明度。此外,内置的治理工具帮助组织在 AI 运营中保持问责制与历史血缘。
## AIP 的第三方托管模型来自哪里?
> 要点:模型服务的部署位置。
在集成第三方托管的模型时,AIP 的设计目标是在可用且可行的前提下尽可能利用区域端点。这样做有助于降低延迟,目前针对部分模型在美国、英国和欧盟等地区提供。具体的地理区域取决于通过 AIP 可用的第三方托管 AI 模型服务所存在的技术限制与约定,这些限制可能随时间发生变化。进一步了解 AIP 的地理限制。
## 第三方模型服务商是否会存储客户数据?
> 要点:数据留存问题。
不会。 当 Palantir AIP 使用第三方托管的模型服务时,提示词(prompt)或补全(completion)中包含的任何客户数据都不会被相关第三方保留。
在 AIP 中提供新模型之前,Palantir 会从第三方托管的模型服务提供商处获得技术与合同层面的保证,以确保该政策得到一致执行。
## 客户数据会被用于再训练模型吗?
> 要点:这是企业最关心的红线之一。
不会。 当 AIP 访问第三方托管的模型服务时,不会使用任何客户数据来重新训练此类模型。Palantir 从第三方托管的模型服务提供商处获得严格的技术与合同保证,以确保提示词中提交的或补全中包含的客户数据都不会被用于模型训练。
与第三方托管的模型服务完全独立的是:如果客户确实希望重新训练自己私有的 AI 模型部署,可以使用 AIP 来支持这种私有的、受治理的重新训练,并提供全方位的治理工具,供团队审计、审查和监控模型性能。
## 第三方模型服务商能否访问 AIP 提示词中的数据?
> 要点:数据可见性边界。
没有。 鉴于 Palantir 在为任何给定的第三方托管模型服务建立访问权限时所确保的严格技术保证,第三方托管模型服务提供商的任何人员都无法访问提示词或补全内容。第三方托管模型服务提供商同样不会存储或保留客户的提示词或补全内容。所有传输到底层服务的数据在提示词完成处理后都会被立即丢弃。
关于各服务提供商相关的隐私考量,请查阅 Azure ↗、AWS ↗ 和 Google Cloud ↗ 的相关文档以了解更多信息。
## AIP 调用第三方模型服务有多安全?
> 要点:整体链路的安全保障。
Palantir AIP 服务构建在来自云服务提供商(包括 AWS、Azure、Google Cloud)的安全基础设施之上。通过 AIP 提供的第三方托管模型服务提供商,除非在你与 Palantir 就 AIP 签订的协议中另有明确说明,否则均已获得 ISO 27017、SOC(1、2、3)、CSA STAR 和/或其他认证。要进一步了解 Palantir 的安全态势,请访问 Palantir 的信任门户 ↗。
## Palantir 就客户数据的 AI 处理作了哪些合同承诺?
> 要点:法律层面的保障。
在开始代表客户处理任何个人数据之前,Palantir 会签署数据保护协议以及实质相似的协议(例如业务伙伴协议)。这些合同承诺通常适用于 Palantir 提供的所有服务,包括 AIP。
## Palantir 如何支持负责任的 AI 使用?
> 要点:机制与能力。
Palantir 的隐私与公民自由团队提供了关于开发、构建和部署 AI 使能技术的大量指导 ↗。Palantir 致力于遵循以下 AI 伦理原则:
- 关注完整集成的系统,而不只是其组成部分工具。
- 承认技术的局限性。
- 不去解决本就不应解决的问题。
- 遵循稳健数据科学的方法论最佳实践。
- 保持 AI 负责任、可问责,并以人为本。
- 促进多方利益相关者的参与。
- 确保在数据与技术应用中具备技术、治理与文化层面的意识。
Palantir 在安全、隐私与负责任使用方面的原则,是我们产品开发与部署的基石。
### 常见问题速答 · FAQ
关于「AIP 的安全与隐私」,读者最常问的几个问题。
AIP 的第三方托管模型来自哪里?是什么? 模型服务的部署位置。在集成第三方托管的模型时,AIP 的设计目标是在可用且可行的前提下尽可能利用区域端点。这样做有助于降低延迟,目前针对部分模型在美国、英国和欧盟等地区提供。
第三方模型服务商是否会存储客户数据? 数据留存问题。不会。当 Palantir AIP 使用第三方托管的模型服务时,提示词(prompt)或补全(completion)中包含的任何客户数据都不会被相关第三方保留。
客户数据会被用于再训练模型吗? 这是企业最关心的红线之一。不会。当 AIP 访问第三方托管的模型服务时,不会使用任何客户数据来重新训练此类模型。Palantir 从第三方托管的模型服务提供商处获得严格的技术与合同保证,以确保提示词中提交的或补全中包含的客户数据都不会被用于模型训练。
AIP 调用第三方模型服务有多安全?是什么? 整体链路的安全保障。Palantir AIP 服务构建在来自云服务提供商(包括 AWS、Azure、Google Cloud)的安全基础设施之上。
---
## 分析资源(Analysis resources)
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-analyst-analysis-resources.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-analyst/analysis-resources/
- 主题分组:AIP Analyst(四)
循序渐进 · AIP 教学 · AIP Analyst(四)
# 分析资源(Analysis resources)
一次有价值的分析不该用完就丢。把分析保存为 Compass 资源,就能回头再看、共享给协作者、并纳入项目管理。
## 先记住这几条
① 分析可以保存 存成平台里的正式资源。
② 保存后可协作 别人能打开、能继续。
③ 纳入项目体系 和其他 Foundry 资源一起管理。
## 写在前面
AIP Analyst 让你将一次分析保存为 Compass 资源,这样你就可以回到你的工作、与协作者共享,并将其与你的其他 Foundry 项目一起组织管理。
分析是动态的,这意味着它们会与你的数据保持同步。当你重新打开一次分析时,AIP Analyst 会针对你 Ontology 的最新状态重新运行智能体的工具,因此结果始终反映当前的真实情况,并遵守每位查看者的权限。
为支持这种行为,一次分析会存储重建该分析所需的对话状态:你的消息、所调用的工具,以及所引用的资源。它不存储工具结果或智能体的响应。
## 查看已保存内容
> 要点:回到历史分析。
在保存之前,保存对话框包含一个 Review 面板,让你预览将要被存储的内容。它将分析拆分为两个视图:
- Messages and tools: 用户在会话期间发送的消息以及智能体生成的工具调用。
- References: 智能体在分析期间可访问的 Foundry 资源,例如对象集、数据集和 functions。

> 图:保存对话框的 Review 面板。
## 单次分析设置
> 要点:每次分析的独立配置。
设置会随每个已保存的分析一同保存。保存时,AIP Analyst 会记录你的分析设置、模型选择和已启用的工具,因此重新打开该分析时会恢复相同的配置。
## 权限
> 要点:谁能看、谁能改。
已保存的分析遵循标准的 Compass 权限模型。
打开一个分析资源并不会授予对该分析所引用的每一个资源的访问权限。当分析加载时,AIP Analyst 会检查查看者对每个被引用资源的权限。查看者无法访问的引用可能会显示错误或被跳过。
如果你的注册使用了基于分类的访问控制,保存对话框会在保存前提示你为分析应用分类标记(classification marking)。
## 管理员配置
> 要点:组织级的管理设置。
可以在 Control Panel 中于注册级别禁用分析保存。AIP Analyst 会检查每位用户的主要组织(primary organization)的注册,以确定保存是否可用。当分析保存被禁用时,AIP Analyst 会隐藏分析侧边栏和资源标题栏,用户也无法从 AIP Analyst 创建或打开分析资源。

> 图:AIP Analyst 分析保存的 Control Panel 设置。
### 常见问题速答 · FAQ
关于「分析资源(Analysis resources)」,读者最常问的几个问题。
查看已保存内容是什么? 回到历史分析。在保存之前,保存对话框包含一个 Review 面板,让你预览将要被存储的内容。它将分析拆分为两个视图。
单次分析设置是什么? 每次分析的独立配置。设置会随每个已保存的分析一同保存。保存时,AIP Analyst 会记录你的分析设置、模型选择和已启用的工具,因此重新打开该分析时会恢复相同的配置。
权限是什么? 谁能看、谁能改。已保存的分析遵循标准的 Compass 权限模型。
如何管理员配置? 组织级的管理设置。可以在 Control Panel 中于注册级别禁用分析保存。AIP Analyst 会检查每位用户的主要组织(primary organization)的注册,以确定保存是否可用。
---
## AIP Analyst 的能力(工具)
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-analyst-capabilities.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-analyst/capabilities/
- 主题分组:AIP Analyst(二)
循序渐进 · AIP 教学 · AIP Analyst(二)
# AIP Analyst 的能力(工具)
AIP Analyst 靠工具(tool)来搜索、分析并呈现答案。工具在 Tools 菜单里按类别分组,可整体或单独启用/禁用。
## 先记住这几条
① 能力由工具提供 每个工具对应一类操作。
② 工具按类别分组 便于管理。
③ 可精细开关 按需启用,控制能力与风险。
④ 也支持 Manage tools 可按场景调整可用工具集。
## 写在前面
AIP Analyst 使用工具来搜索、分析并呈现对你的问题的回答。工具在 Tools 菜单中按类别分组,你可以在其中启用或禁用整个类别或单个工具。AIP Analyst 也可以通过 Manage tools 工具自行调整已启用的类别。
大多数工具本身不执行计算;它们调用现有的 Foundry 系统,并适用该系统的计算模型。关于每个类别消耗的资源,请参阅 Federated Foundry compute。

> 图:AIP Analyst 工具菜单。
## Ontology
> 要点:查对象、看关系。
这些工具搜索、加载并分析来自你 Ontology 的数据。搜索范围(search scope)设置适用于 Object type search 和 Object search 工具。
- Object type lookup: 获取特定对象类型的完整元数据,包括其属性和指向相关对象类型的链接。
- Interface type lookup: 获取特定接口类型的元数据,包括其属性以及实现它的对象类型。
- Object type search: 基于对象类型元数据(例如显示名称、ID、描述、别名或状态)识别相关对象类型。匹配的接口类型会与对象类型一并返回。
- Object lookup: 通过其主键获取特定对象,返回该对象的所有属性值。
- Object search: 在整个 Ontology 或指定的对象类型中搜索,返回按对象类型分组的匹配对象。
- Object set: 创建一个对象集,可选择性地通过应用过滤、search-around 或语义搜索等操作进行筛选或变换。
- Import object set: 将现有的已保存对象集导入当前分析上下文。
- Ontology SQL: 对对象集执行 SQL 查询,返回可用于复杂分析的表格数据。
- Ontology aggregation: 对对象集执行聚合操作,并可选地带分组属性。支持的操作包括 count、sum、average、min、max、percentile、cardinality、standard deviation 和 variance。
- Map visualization: 在交互式地图上可视化对象集的地理空间属性。
## 可视化
> 要点:生成图表。
- Create visualization: 渲染由 Vega-Lite 规范定义的图表,该图表基于表格数据构建,例如 Ontology 聚合、SQL 结果或数据集查询。
## 规划
> 要点:先出分析计划再执行。
这些工具帮助 AIP Analyst 组织其工作、管理自身上下文并复用先前的分析。
- Analysis lookup: 通过资源标识符(RID)加载特定已保存分析的模板,使其所用资源和所发起工具调用的结构可供使用。
- Clarifying questions: 当查询存在歧义时,AIP Analyst 可能会提出澄清性问题,以便在继续之前细化其分析方法。
- Context cleanup: 隐藏对话中较早的过时或不必要的工具响应,让智能体专注于与你当前问题相关的数据。
- Manage tools: 在分析过程中按类别启用或禁用工具,使 AIP Analyst 能够专注于与当前问题相关的能力。你仍然可以从 Tools 菜单手动配置工具。
- Write skill: 从当前分析创建或更新一个可复用的 AIP Skill,记录下某种方法以便日后再次应用。
- Skill lookup: 当智能体判定某个 AIP Skill 相关时,加载该技能的完整指令。
## 数据集
> 要点:直接读数据集。
- Backing dataset lookup: 获取给定对象类型的后备数据集(backing dataset),从而能够对 Ontology 数据进行直接的数据集级分析。
- Dataset SQL: 对数据集执行 SQL 查询以检索并分析数据,返回可用于进一步分析或串联到后续查询的表格数据。支持引用多个数据集分支。
- Dataset lookup: 查找并预览特定数据集,包括 schema 信息和样本数据。
## 函数
> 要点:调用平台函数。
- Function lookup: 获取 function 的签名及其源码预览。
- Execute function: 使用给定的输入参数集执行 function。你可以直接在分析会话中查看输入和输出。
## 动作
> 要点:触发写操作。
- Action lookup: 获取特定 action type 的元数据,包括其参数。
- Execute action: 执行 action 以创建或修改对象。除非该 action 被配置为自动提交,否则 action 在执行前需要你的批准。
## 媒体
> 要点:处理图片等媒体内容。
- Media item lookup: 从媒体集中获取特定项(例如图像或 PDF)以进行处理和分析。
- Read PDF pages: 读取媒体集中某个 PDF 的特定页面范围,使 AIP Analyst 能够处理过大而无法一次加载的文档。
- PDF semantic search: 在媒体集中的某个 PDF 上运行语义搜索,以找出与查询最相关的段落。
## 时间序列
> 要点:时序数据分析。
- Time series transform: 变换并可视化来自时间序列属性或时间序列同步(time series sync)的时间序列数据。
- Time series lookup: 从时间序列同步或对象的 time series 属性创建单个时间序列。
- Time series sync lookup: 通过其 RID 获取特定的时间序列同步。
## Notepad
> 要点:文档化分析过程。
- Notepad documents: 根据分析结果创建和编辑 Notepad 文档。
- Notepad lookup: 获取现有 Notepad 文档的内容。
## Quiver
> 要点:分析结果呈现。
- Quiver analyses and dashboards: 创建和编辑 Quiver 分析,并将其发布为可共享的仪表板。
- Import Quiver analysis: 将现有 Quiver 分析导入当前分析上下文。
## Contour
> 要点:数据集分析。
- Contour analyses: 创建和修改 Contour 分析以进行进一步的数据探索。
- Import Contour analysis: 将现有 Contour 分析导入当前分析上下文。
## Workshop
> 要点:应用集成。
- Workshop lookup: 获取某个 Workshop 模块所引用的对象类型、链接、functions 和 action types。
## Machinery
> 要点:流程编排。
- Machinery lookup: 获取一个 Machinery 流程图画(process graph)。
## 文件与媒体支持
> 要点:能处理哪些格式。
你可以将文件上传到分析中供 AIP Analyst 处理:
- Spreadsheets: Excel(.xlsx 和 .xls)以及 CSV 文件。
- Documents: Word(.docx)文件。内嵌图像会与文本一并被抽取,因此智能体可以解读文档中的图表、示意图和截图,而不只是正文文字。
- Images: JPEG、PNG、GIF 和 WebP。
- PDFs: 文本和视觉内容都会被处理,因此智能体可以解读页面上渲染的图表、示意图和表格。
你还可以将媒体集中的媒体项作为分析上下文附加进来。
### 常见问题速答 · FAQ
关于「AIP Analyst 的能力(工具)」,读者最常问的几个问题。
Ontology是什么? 查对象、看关系。这些工具搜索、加载并分析来自你 Ontology 的数据。搜索范围(search scope)设置适用于 Object type search 和 Object search 工具。
规划是什么? 先出分析计划再执行。这些工具帮助 AIP Analyst 组织其工作、管理自身上下文并复用先前的分析。
文件与媒体支持是什么? 能处理哪些格式。你可以将文件上传到分析中供 AIP Analyst 处理。
---
## AIP Analyst 的计算用量
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-analyst-compute-usage.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-analyst/compute-usage/
- 主题分组:AIP Analyst(五)
循序渐进 · AIP 教学 · AIP Analyst(五)
# AIP Analyst 的计算用量
AIP Analyst 是智能体式应用:一个问题可能引发大量模型调用与 Ontology 查询。理解用量来源,才能预测成本、选对模型、设计高效分析。
## 先记住这几条
① 单次提问可能很贵 智能体会多轮调用模型与工具。
② 用量来自两块 模型调用 + Ontology 查询。
③ 可以主动优化 提问方式与模型选择都影响成本。
## 写在前面
AIP Analyst 是一个智能体式应用:单个问题可能会引发大量模型调用和对 Foundry 的大量查询。理解这些用量来自哪里,有助于你预测成本、选择模型并设计高效的分析。
来自 AIP Analyst 的用量分为两类:
- LLM tokens: 每次模型调用都会消耗输入和输出 token,它们会按取决于模型的速率转换为 compute-seconds(计算秒)。请参阅 LLM token usage。
- Federated Foundry compute: 每次工具调用都会针对底层 Foundry 系统运行,例如 Ontology、数据集或 function,并消耗该系统的计算,此外还会消耗用于请求和读取结果所花费的 token。请参阅 Federated Foundry compute。
> 如果你与 Palantir 签有企业合同,在进行计算用量估算之前,请联系你的 Palantir 代表。
## LLM token 用量
> 要点:主要成本来源。
AIP Analyst 的工作方式是反复将对话发送给模型,并根据响应采取行动。每个请求都包含系统指令、你的消息、已启用工具的定义,以及仍在上下文中的先前工具调用结果。模型的回复(包括任何扩展思考)都计为输出 token。
这种设计带来三个后果:
- token 用量会随着对话的继续而增长, 因为先前的消息和工具结果会在每一新轮次中重新发送。一次很长的分析在末尾时每个问题的成本比开头更高。
- 庞大的工具结果是主要驱动因素。 加载数千个对象、返回很宽的 SQL 结果集,或读取很长的 PDF,都会把大量文本放入上下文,而它会在之后的每一轮次中重新发送,直到被移除。
- 已启用工具的集合本身也有成本, 因为工具定义会包含在每个请求中。在 Tools 菜单中禁用你不需要的类别,可以减小分析中每个请求的大小。
不同模型之间 token 到 compute-second 的速率差异很大。关于当前速率,请参阅 Usage-based pricing compute translation for AIP。关于 token 如何计数的一般背景,请参阅 Tokens in AIP。
一次分析所用的模型会与该分析一同记录,因此已保存的分析重新打开时会使用相同的模型。请参阅 Per-analysis settings。
## 联邦 Foundry 计算
> 要点:跨环境查询的消耗。
大多数 AIP Analyst 工具本身不执行计算。相反,它们代表你调用现有的 Foundry 系统,并适用该系统通常的计算模型。下表将每个工具类别映射到执行该工作的系统。
Tool category Work performed by Usage documentation Ontology Ontology query layer Compute usage with Ontology queries Actions Ontology writeback Ontology Query Compute Datasets SQL against datasets Compute usage with SQL in Foundry Functions Function execution Understand function compute costs Time series Time series query layer Time series query compute usage Media Media set transformations and downloads Media set compute usage Contour Contour analyses Compute usage with Contour Quiver and Notepad The applications embedded in the resource, such as Ontology queries List of Foundry applications and associated usage Workshop Workshop module configuration metadata Compute usage with AIP Machinery Machinery process graph metadata Compute usage with AIP Visualization and Planning The model only Compute usage with AIP
Visualization 和 Planning 类别中的工具,例如 Create visualization 和 Context cleanup,不会查询单独的后端。它们的成本是用于生成和读取结果所花费的 token。Workshop lookup 和 Machinery lookup 工具的行为方式相同。它们各自读取某个资源的配置,而不是运行查询,因此其成本是用于读取所返回定义所花费的 token。之后对其呈现出的对象类型、functions 或 action types 进行的任何工作,都计入相应的类别。
> AIP Analyst 的 Ontology 工具查询的是与 Object Explorer、Workshop 以及 Ontology SDK (OSDK) 相同的 Ontology 层,并按相同的模型计量。AIP Analyst 发起的一次 Ontology aggregation 的计费方式与来自 OSDK 应用的等效请求一样,都作为一次聚合查询。区别在于查询的数量。一个在陌生 Ontology 中探索的智能体会比一个围绕一组已知固定查询构建的应用发起更多搜索和更多被丢弃的中间查询。
AIP Analyst 创建的资源在分析结束后仍会继续消耗计算。一个已发布的 Quiver 仪表板或一个已保存的 Contour 分析,每次有人打开时都会消耗计算,并归因到该资源,而不是 AIP Analyst。
## 成本归属
> 要点:费用算在谁头上。
Foundry 中的 compute-seconds 通常归因到资源而不是用户。对于 AIP Analyst,token 用量按如下方式归因:
- Saved analyses: 用量归因到分析资源。
- Embedded analyses: 用量归因到所属资源,例如包含 AIP Analyst widget 的 Workshop 模块。
- Unsaved analyses: 默认情况下,用量归因到运行该分析的用户。如果配置了 Unsaved analysis cost attribution 设置,用量则改为归因到该设置中所选的项目。请参阅 General settings。
AIP Analyst 联合(federate)到其他应用的计算遵循这些应用自己的归因规则。特别是对于 Ontology 查询,计算会附加到查询发起所在的资源(如果存在),否则附加到被查询的对象类型。请参阅 Investigating Foundry compute usage from Ontology queries。
## 监控用量
> 要点:在哪里看。
你可以在几个粒度级别上查看用量:
- During an analysis: 会话中的 token 估算器显示当前上下文大小。大纲会报告每次单个工具调用的 token 用量,这使得找出加载了过多数据的步骤变得很直接。
- Across your enrollment: 从 Control Panel 导出 AIP Token Usage 数据集,以获得按模型和资源细分的每日 token 消耗。请参阅 Exporting AIP token usage data。
- Alongside other usage: 在 Resource Management 中查看按项目和资源细分的 compute-seconds,并使用 AIP usage metrics 跟踪随时间变化的模型请求。
## 管理用量
> 要点:怎么降下来。
下面的手段可以减少用量,而不会改变你可以提出的问题。
### Keep context small
- 移除你不再需要的数据。 使用上下文清理工具,或从大纲中隐藏单个工具结果,使庞大的结果不再在每一轮次中重新发送。
- 用分支代替继续。 当你转向一个不相关的问题时,创建一个新标签页,而不是延长一个很长的对话。请参阅 Tabs and branching。
- 用聚合代替加载。 优先使用 Ontology aggregation 或 Ontology SQL,而不是加载一个庞大的对象集并要求模型对其进行摘要。一行聚合输出的成本只是其背后对象的一小部分。
### Narrow the search space
- 限制搜索范围。 限制 Ontology、对象类型组、项目、状态和可见性,既能减少智能体发起的搜索查询数量,也能减小其结果大小。请参阅 Limit search scope。
- 提前加载正确的上下文。 事先添加相关的对象类型或数据集可以完全省去探索性搜索。在 Workshop widget 中,预加载上下文并固定已启用的工具,会让引导式工作流的用量可预测得多。
- 禁用未使用的工具类别。 已启用工具越少,意味着请求越小,智能体走入无成效路径的机会也越少。
### Choose an appropriate model
最大与最小模型之间的速率差异超过一个数量级。将能力最强的模型保留给真正困难的推理,而日常的查找和摘要则优先使用较小的模型。对于问题事先已知的嵌入式工作流,明确设定模型并隐藏模型选择器,使用量保持可预测。请参阅 View options 和 Chat controls。
## 集成工具与函数、智能体的对比
> 要点:不同实现方式的成本差异。
当某个工作流已被充分理解时,你可以将工作从智能体的工具循环中移出,放入 AIP Analyst 所调用的资源,或放入完全独立运行的资源。这样做会同时改变成本结构和结果的可靠性。
Approach How AIP Analyst uses it Token cost Best suited to Integrated tools The agent selects and calls tools directly, one step at a time Highest: every intermediate result enters context, and each step needs a model call Ad-hoc and exploratory questions, where the steps are not known in advance Skills The agent loads a set of reusable instructions, then uses integrated tools to follow them Similar to integrated tools, with fewer wasted steps Recurring analyses that follow a known approach but still need judgment Functions The agent calls the function once with Execute function and reads the returned value Low: only the inputs and the returned value enter context Deterministic, repeated computation, such as a business calculation or a fixed multi-step query Pro-code agents Triggered outside the session; results are read back from the Ontology Separate from the analysis: the agent runs its own model loop Long-running or autonomous work that does not need to complete inside an interactive session
使用以下指导在它们之间进行选择:
- 当问题仍在成型时,优先使用集成工具。 它们的优势在于不需要预先建模,且 graph 视图让每个步骤都可审计。它们的代价是中间数据会经过模型的上下文。
- 一旦逻辑稳定下来,就将其移入 function。 一个 function 会将原本需要多次工具调用的工作压缩为一次。它的中间数据永远不会进入分析上下文,其结果由确定性逻辑产生而非推理得出,其计算也归因到该 function。对于你预期会重复进行的计算,这通常是正确的选择,而且通常既比要求智能体每次都重新推导逻辑更便宜,也更可靠。
- 使用 skill 来记录方法,而不是记录计算。 一个 skill 记录如何应对某一类问题。由于智能体仍使用集成工具来执行它,skill 能提升一致性,但本身不会减少联合计算。
- 对于不应阻塞交互式会话的工作,使用 pro-code agent。 Pro-code agents 异步运行,且不受同步 function 执行限制的约束,这使它们适合长时间运行的任务。
> Pro-code agents 并非 AIP Analyst 工具的即插即用替代品。已发布的 agent function 返回 Void,因此它不能作为查询 function 被调用,也无法将值返回给分析。让该 agent 将其结果写入 Ontology 对象,然后从 AIP Analyst 读取这些对象。请参阅 Publish and call a pro-code agent。
一个实用的模式是结合使用这些方式。用集成工具进行探索,直到你理解该分析,然后将稳定、昂贵的部分移入 function,并将 AIP Analyst 保留用于围绕它的解释和呈现。
## 相关资源
> 要点:延伸阅读。
- Compute usage with AIP
- Compute usage with Ontology queries
- Usage types
- Supported LLMs
### 常见问题速答 · FAQ
关于「AIP Analyst 的计算用量」,读者最常问的几个问题。
LLM token 用量是什么? 主要成本来源。AIP Analyst 的工作方式是反复将对话发送给模型,并根据响应采取行动。每个请求都包含系统指令、你的消息、已启用工具的定义,以及仍在上下文中的先前工具调用结果。模型的回复(包括任何扩展思考)都计为输出 token。
联邦 Foundry 计算是什么? 跨环境查询的消耗。大多数 AIP Analyst 工具本身不执行计算。相反,它们代表你调用现有的 Foundry 系统,并适用该系统通常的计算模型。下表将每个工具类别映射到执行该工作的系统。
成本归属是什么? 费用算在谁头上。Foundry 中的 compute-seconds 通常归因到资源而不是用户。对于 AIP Analyst,token 用量按如下方式归因。
监控用量是什么? 在哪里看。你可以在几个粒度级别上查看用量。
---
## 嵌入 AIP Analyst
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-analyst-embed.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-analyst/embed/
- 主题分组:AIP Analyst(七)
循序渐进 · AIP 教学 · AIP Analyst(七)
# 嵌入 AIP Analyst
通过 iframe 把 AIP Analyst 嵌到 Workshop 或 OSDK 应用里,并用 URL 参数做定制化。这篇列出可用参数。
## 先记住这几条
① iframe 嵌入方式 比微件更通用的集成路径。
② 支持 URL 参数定制 控制显示内容与行为。
③ 多值参数用逗号分隔 例如指定多个对象类型组。
## 写在前面
AIP Analyst 可以通过 iframe 嵌入到 Workshop 或 OSDK 应用中。它支持若干 URL 参数以实现定制化。接受多个值的参数使用逗号分隔的列表(例如 objectTypeGroupRids=group1,group2)。
关于 Workshop 模块内更深入的集成,请参阅 AIP Analyst Workshop widget。
## 控制 AIP Analyst 能访问哪些数据
> 要点:边界配置。
- ontologyRid: 设置 AIP Analyst 可以探索的 Ontology,例如 ri.ontology.main...。
- objectTypeGroupRids: 将 AIP Analyst 限制为在特定对象类型组中搜索。
- compassProjectRids: 将 AIP Analyst 限制为在特定 Compass 项目或文件夹内的资源中搜索。
- hideManualContextMenu: 设为 true 时,阻止用户手动添加其他数据源。
plaintext /workspace/aip-analyst?ontologyRid=ri.ontology.main.abc123&objectTypeGroupRids=group1,group2&hideManualContextMenu=true
## 预加载会话
> 要点:让用户一进来就有上下文。
预填用户的第一条消息,或预加载上下文,让用户一开始就能使用相关资源:
- workshopRids: 从你的 Workshop 模块加载对象类型、链接和 functions,例如 ri.workshop.main.module...。
- objectSetRids: 加载已保存的对象集,例如 ri.object-set.main...。
- datasetRids: 加载特定数据集。
- objectTypeIds: 加载单个对象类型。
- objectRids: 加载单个对象。
- functionRids: 加载单个 functions。
- actionTypeRids: 加载单个 action types。
- autoSubmitActionTypeRids: 加载单个 action types,并允许 AIP Analyst 在无需用户批准的情况下执行它们。
- notepadRids: 加载 Notepad 文档。
- initialMessage: 在 AIP Analyst 加载时预填第一条用户消息。
- autoStart: 当设为 true 且设置了 initialMessage 时,AIP Analyst 会在页面加载后立即发送初始消息并开始分析。用它来嵌入「提问并回答」式的体验,以响应宿主应用的上下文。
plaintext /workspace/aip-analyst?workshopRids=ri.workshop.main.module.xyz789&initialMessage=Summarize+sales+by+region&autoStart=true
## 视图选项
> 要点:界面元素的显示控制。
- embedded: 设为 true 时隐藏工作区侧边栏,以获得更简洁的外观。
- hideSettingsMenu: 设为 true 时隐藏设置菜单。
- theme: 设置颜色主题(light 或 dark)。
- modelRid: 设置用于分析的特定模型。
> URL 参数只覆盖可用设置的一个子集。对于任何无法用参数配置的内容,请创建一个包含单个全页面 AIP Analyst widget 的 Workshop 模块,在那里进行配置,然后改为嵌入该模块。该 widget 暴露的控制要细粒度得多,包括哪些界面元素可见、默认启用哪些工具,以及分析如何保存和加载。
### 常见问题速答 · FAQ
关于「嵌入 AIP Analyst」,读者最常问的几个问题。
预加载会话是什么? 让用户一进来就有上下文。预填用户的第一条消息,或预加载上下文,让用户一开始就能使用相关资源。
视图选项是什么? 界面元素的显示控制。URL 参数只覆盖可用设置的一个子集。对于任何无法用参数配置的内容,请创建一个包含单个全页面 AIP Analyst widget 的 Workshop 模块,在那里进行配置,然后改为嵌入该模块。
---
## AIP Analyst 总览:对话式分析
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-analyst-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-analyst/overview/
- 主题分组:AIP Analyst(一)
循序渐进 · AIP 教学 · AIP Analyst(一)
# AIP Analyst 总览:对话式分析
AIP Analyst 是面向智能体工作流的界面:用自然语言在 Ontology 上做即席分析,不用写查询、不用搭看板。
## 先记住这几条
① 面向智能体工作流 不是一个死板的报表工具。
② 自然语言即席分析 想分析什么,直接问。
③ 站在 Ontology 上 分析直接基于业务对象。
④ 分析可沉淀 结果能保存成资源供复用。
## 写在前面
AIP Analyst 是一个面向智能体工作流(agentic workflow)的界面,让你能够使用自然语言在 Ontology 上执行即席分析(ad-hoc analysis)。你可以向 AIP Analyst 提出一个问题,智能体会通过自主搜索你的 Ontology、创建对象集并变换数据来回答,然后生成摘要和可视化。
## 示例工作流
> 要点:一次完整分析是怎么进行的。
举个例子,假设有一位经营连锁咖啡店的用户,想要进行竞品分析。他们想研究在英格兰北安普顿开设新门店是否可行。为了开始分析,该用户可以问:「Which coffee shops are within 10km of Northampton? Are any chains particularly prominent?」
AIP Analyst 会使用多个搜索词在你的 Ontology 中搜索相关数据,以提高找到相关对象类型的可能性。

> 图:一次 AIP Analyst 对象类型搜索。
找到一些咖啡店之后,AIP Analyst 会检查数据并应用一个以北安普顿为中心的地理空间过滤器。

> 图:AIP Analyst 地理空间过滤器。
最后,在对连锁品牌执行一些额外的聚合之后,它会生成指定区域内店铺以及竞争连锁品牌的摘要。

> 图:一个 AIP Analyst 摘要示例。
## 更多使用方式
> 要点:嵌入、保存、复用。
除了运行即席分析外,AIP Analyst 还可以:
- Save analyses as Compass resources: 使用分析资源(analysis resources)稍后回到你的工作,或与协作者共享。
- Embed in other applications: 添加 Workshop widget 以便更紧密地集成到 Workshop 模块中,或使用 URL 参数 在 OSDK 或其他 Foundry 应用中通过 iframe 嵌入。
## 资源消耗
> 要点:钱花在哪里。
由于 AIP Analyst 是智能体式的,单个问题可能会引发大量模型调用和对 Foundry 的大量查询。用量来自两个来源:智能体自身推理所消耗的 LLM token,以及每次工具调用背后 Foundry 系统的计算。该系统可能是 Ontology、某个数据集,或某个 function。
Compute usage with AIP Analyst 涵盖每个能力(capability)消耗什么、用量如何归因到项目和资源,以及如何监控它。它还包括关于何时将工作移出智能体的工具循环、改放入 function 或 pro-code agent 的指导。
Note: AIP feature availability is subject to change and may differ between customers.
### 常见问题速答 · FAQ
关于「AIP Analyst 总览:对话式分析」,读者最常问的几个问题。
示例工作流是什么? 一次完整分析是怎么进行的。举个例子,假设有一位经营连锁咖啡店的用户,想要进行竞品分析。他们想研究在英格兰北安普顿开设新门店是否可行。为了开始分析,该用户可以问:「Which coffee shops are within 10km of Northampton…
资源消耗是什么? 钱花在哪里。由于 AIP Analyst 是智能体式的,单个问题可能会引发大量模型调用和对 Foundry 的大量查询。用量来自两个来源:智能体自身推理所消耗的 LLM token,以及每次工具调用背后 Foundry 系统的计算。
---
## 使用 AIP Analyst
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-analyst-using-aip-analyst.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-analyst/using-aip-analyst/
- 主题分组:AIP Analyst(三)
循序渐进 · AIP 教学 · AIP Analyst(三)
# 使用 AIP Analyst
这一篇逐个介绍构成一次分析会话的功能与概念,让你知道界面上每个部分在做什么。
## 先记住这几条
① 会话是分析的单位 一次分析围绕一个问题展开。
② 界面元素各有职责 提问、观察推理、看结果。
③ 过程可追溯 能看到它怎么得出答案。
## 写在前面
本页介绍构成一次 AIP Analyst 会话的功能和概念。
## 上下文
> 要点:喂给分析的信息。
上下文(context)是 AIP Analyst 在一次分析过程中可访问的信息,例如你之前的消息、智能体的工具结果,以及你添加的任何 Foundry 资源。
你可以使用输入字段中的 + 按钮手动向上下文添加资源。你也可以将 Foundry 资源直接拖放到聊天输入区域,将它们添加为上下文。从其他浏览器标签页或从 Foundry 内部拖动资源 URL,会自动解析该资源并将其加载到你的分析中。支持的资源包括数据集、对象集、Notepad 文档、Workshop 模块、functions 等。你还可以将 Foundry 资源标识符(RID)直接粘贴到输入框中以导入它们。
你可以使用大纲(outline)手动管理上下文,或让 AIP Analyst 使用上下文清理(context cleanup)工具来处理。

> 图:手动向 AIP Analyst 添加上下文。
## 设置
> 要点:可调整的行为选项。
Settings 对话框分为三个标签页:Analysis、Skills 和 General。

> 图:AIP Analyst 的 Settings 菜单。
### Analysis settings
分析设置控制搜索范围、初始上下文以及高级智能体行为。这些设置存储在哪里取决于该分析是否已被保存:
- Unsaved analyses: 更改会应用到当前分析,并成为你所有新分析的默认值。
- Saved analyses: 该标签页会带有 Current analysis 标记,更改只会应用到那个分析资源。要将当前值提升为新分析的默认值,请选择 Save as user defaults 并确认。
Limit search scope
使用这些设置来限制 AIP Analyst 搜索哪些 Ontology 实体。设置限制后,Object type search 和 Object search 工具只会返回匹配的结果。对于拥有数百或数千个对象类型的 Ontology,应用这些过滤器可以提升性能。
- Ontology: 将搜索限制在单个 Ontology 内。
- Object type groups: 将搜索限制在所选 Ontology 内的特定对象类型组中。
- Object type statuses: 按状态过滤可发现的对象类型:Endorsed、Active、Experimental、Deprecated 或 Example。
- Object type visibility: 按可见性过滤可发现的对象类型:Prominent、Normal 或 Hidden。
- Projects: 将搜索限制在特定项目内包含的 Ontology 实体中。此设置不适用于手动添加的上下文,且任何不是项目的所选文件夹都会被忽略。
Initial context
这些设置控制在 AIP Analyst 启动时自动添加到其中的资源:
- Include recent resources: 在对话中包含关于你最近查看过的资源的上下文。
- Include favorite resources: 在对话中包含关于你收藏的资源的上下文。
Advanced
- Object set tool similarity threshold: 设置 object set 工具中语义搜索的阈值,介于 0(最宽泛)与 1(精确)之间。数值越高,返回结果越少但越相关。
### Skills
Skills 标签页列出你的分析中可用的 AIP skills。一个 skill 打包了可复用的指令,当 AIP Analyst 判定该 skill 与你的问题相关时便可以加载它。
在此标签页中,你可以:
- 选择 Add skills 将某个 skill 添加到你的库中,或在你可访问的所有 skills 中搜索。
- 按名称搜索你的库。
- 打开或关闭每个 skill。当某个 skill 启用时,智能体可以自行发现并调用它。
- 选择某个 skill 以打开其详情面板,你可以在其中查看其名称、描述和最后更新时间,或将其从你的库中移除。
你也可以使用导出菜单从一次对话创建 skill。
### General
常规设置是应用程序级别的偏好设置,适用于你的所有分析:
- Appearance: 将颜色主题设为浅色或深色。
- Notifications: 如果启用,AIP Analyst 在后台运行时可以发送通知,让你能够提问并在分析需要你关注时得到通知。你的浏览器和系统设置也必须允许通知。
- Unsaved analysis cost attribution: 选择未保存分析的成本归因到哪个项目。已保存和嵌入式分析则根据其所属资源进行归因。关于用量如何归因的详细信息,请参阅 Compute usage with AIP Analyst。
## 标签页与分支
> 要点:多条分析线并行。
分析路径可以在任意位置分叉,创建一个新标签页,其中只包含先前的上下文,使用户能够从相同的起始状态探索多条分析路径。可以使用标签页标题栏中的 + 按钮创建空的分析路径。标签页即使不在焦点中也会继续运行。

> 图:从给定消息创建新分支的选项。
## 大纲
> 要点:分析的步骤脉络。
分析大纲提供会话的结构化摘要,显示你的问题、手动添加的上下文以及智能体的工具使用情况。你的消息以圆形图标显示,而工具调用则以其功能对应的图标标记。
你可以使用大纲来:
- 快速导航到之前的分析步骤。
- 查看每次工具调用的 token 用量。其他跟踪消耗的方式请参阅 Monitor your usage。
- 通过选择悬停在大纲项上时出现的眼睛图标,隐藏特定的工具结果。被隐藏的结果在之后的轮次中不再重新发送给模型,从而减少 token 用量。

> 图:一个 AIP Analyst 大纲。
## 图谱
> 要点:关系可视化。
为了提高对 AIP Analyst 输出的信心,你可以通过查看 graph 视图来追溯分析过程,这是一个有向图,展示分析中每个步骤的来源和逻辑路径。graph 视图让你能够:
- 追溯智能体是如何得出结论的,并检查每个步骤的逻辑。
- 审计分析过程中应用的数据变换,并确保结果的可复现性。
- 验证结果是基于真实数据而非幻觉。借助 AIP Analyst,你可以查看每个步骤所使用的 Ontology 数据,并确保所有结论都准确。

> 图:一个 AIP Analyst graph 示例。
## 音频输入
> 要点:用说的而不是打字。
你可以直接从聊天界面录制音频输入,从而实现语音驱动的分析。
## 导出
> 要点:把结果带走。
选择会话标题栏中的 Export 按钮,将当前对话转化为一件持久化的产物。
- Print to PDF: 将你的对话导出为可打印的 PDF 文档。导出对话框让你选择要包含哪些上下文项、展开或折叠工具结果,并在打印前预览文档。这会使用你浏览器的打印对话框,让你能够将输出保存为 PDF 文件。
- Export to Notepad: 从你的对话生成一个 Notepad 文档。
- Export to Skill: 将你的对话转化为可复用的 AIP Skill,AIP Analyst 随后可以将其应用到未来分析中的类似问题。更多信息请参阅 skills。
- Export to Quiver: 将结果转换为 Quiver 分析或仪表板。
- Export to Contour: 将结果转换为 Contour 分析。

> 图:AIP Analyst 导出菜单。
在 Workshop widget 中,PDF、Notepad、Quiver 和 Contour 目标可以各自单独隐藏。
### 常见问题速答 · FAQ
关于「使用 AIP Analyst」,读者最常问的几个问题。
上下文是什么? 喂给分析的信息。上下文(context)是 AIP Analyst 在一次分析过程中可访问的信息,例如你之前的消息、智能体的工具结果,以及你添加的任何 Foundry 资源。
如何设置? 可调整的行为选项。Settings 对话框分为三个标签页:Analysis、Skills 和 General。
标签页与分支是什么? 多条分析线并行。分析路径可以在任意位置分叉,创建一个新标签页,其中只包含先前的上下文,使用户能够从相同的起始状态探索多条分析路径。可以使用标签页标题栏中的 + 按钮创建空的分析路径。标签页即使不在焦点中也会继续运行。
大纲是什么? 分析的步骤脉络。分析大纲提供会话的结构化摘要,显示你的问题、手动添加的上下文以及智能体的工具使用情况。你的消息以圆形图标显示,而工具调用则以其功能对应的图标标记。
---
## AIP Analyst 的 Workshop 微件
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-analyst-workshop-widget.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-analyst/workshop-widget/
- 主题分组:AIP Analyst(六)
循序渐进 · AIP 教学 · AIP Analyst(六)
# AIP Analyst 的 Workshop 微件
把 AIP Analyst 作为 Workshop widget 嵌进业务应用,用户在自己的工作界面里就能用上 AI 分析,还能精细控制数据访问与工具范围。
## 先记住这几条
① 可作为微件嵌入 AI 能力直接进入业务应用。
② 配置项很丰富 数据访问、工具可用性、界面都能定制。
③ 便于控制边界 限定能看什么、能用什么。
## 写在前面
AIP Analyst 可以作为 Workshop widget 嵌入,直接在 Workshop 模块中提供 AI 驱动的分析能力。该 widget 支持大量配置选项,用于控制数据访问、工具可用性和用户界面定制。

> 图:AIP Analyst Workshop widget 配置。
## 微件配置
> 要点:数据访问、工具范围、界面定制。
AIP Analyst widget 可以进行配置,以便为你的用户定制分析体验。配置按若干区域组织,用于控制该 widget 的行为方式以及可用的能力。
### Base configuration
基础配置控制 AIP Analyst widget 的基本行为:
- Custom system prompt: 提供具体指令,引导该特定 widget 实例中智能体的行为。可用它来设定分析重点、定义回答风格,或建立领域特定准则。该提示词会追加到默认 AIP Analyst 系统提示词的末尾。这可以是一个静态值,也可以连接到 Workshop 变量以实现动态提示词。
- Select default model: 用特定的 AI 模型覆盖该 widget 的应用默认模型。这确保了你的 Workshop 模块所有用户的行为一致。如果所选模型无法归因到该项目,则会改用回退模型。
- Suggested prompts: 定义一组预置提示词,在聊天为空时显示。这些有助于引导用户提出与你的用例相关的常见问题或分析工作流。提供静态列表,或连接一个 Workshop 变量以根据应用状态改变提示词。
### Input configuration
输入配置让你可以预加载上下文并自动触发分析。预加载上下文让用户无需手动搜索即可立即访问相关数据。
- User message: 连接一个 Workshop 变量以自动启动分析。当该变量变化时,会发送一条包含该变量值的用户消息,智能体无需用户干预即开始处理。这使你的 Workshop 应用内能够实现动态、事件驱动的分析。
- Object sets: 向上下文添加一个对象集列表。默认会添加每个对象集的对象类型。在聊天中,这些对象集会按指定顺序命名为 Input 1、Input 2 等。一旦聊天开始,它就会停止监听对象集更新,直到被重置或创建新聊天。
- Notepad documents: 向上下文添加一个 Notepad 文档列表。
- Skills: 添加一个提供给智能体的 AIP skills 列表。skill 名称及其触发条件会被添加到系统提示词中,智能体仅在相关时才加载某个 skill 的完整指令。
- Enable user skills: 让每位用户自己的 skill 库可供智能体使用,并在聊天输入区显示一个 skills 按钮以便他们管理。
- Object types: 向上下文添加一个对象类型列表。
- Functions: 向上下文添加一个 functions 列表。
- Actions: 向上下文添加一个 actions 列表。对于每个 action,你可以设置 Should auto-submit action。启用时,智能体自主提交该 action;禁用时,会显示一个表单供用户提交。
- Workshop modules: 向上下文添加一个 Workshop 模块列表。
- Datasets: 向上下文添加一个数据集列表。
- Media items: 向上下文添加一个媒体集列表。每个媒体集中的单个项必须通过 RID 指定。仅支持 image 或 PDF 类型的媒体集。
- Recent resources context: 在 widget 加载时将用户最近的资源纳入上下文。
- Favorite resources context: 在 widget 加载时将用户收藏的资源纳入上下文。
每个预加载资源都接受一个可选的 Title and description 说明。用它来告诉智能体为什么提供该资源,以及应如何使用它。
### Output configuration
输出配置让你能够将分析结果抽取到 Workshop 变量中,以便在应用的其他部分使用:
- Last object set: 捕获分析过程中产生的最新对象集。你可以选择性地指定一个对象类型,此时该变量会捕获该类型的最后一个对象集。
- Last user message: 抽取用户最近的问题。
- All user messages: 检索会话中用户问题的完整列表。
- Last assistant message: 捕获 AIP Analyst 最近的响应。
- All assistant messages: 抽取智能体生成的所有响应。
- All Vega chart specs: 将所有已解析的 Vega-Lite 图表规范以字符串形式抽取出来,让你能够在 Workshop 模块的其他位置渲染图表。数据内嵌在这些规范中,因此它们是快照而非实时视图。
- All messages: 检索会话中的所有消息(包括工具调用),并可选择包含所配置的输入上下文项。工具使用和工具结果消息的 JSON 结构可能会变化,不提供向后兼容性保证。
- Selected cited object: 捕获最近选中的行内引用所引用的对象。设置此变量会覆盖默认的行内引用行为。
- Selected cited media reference: 捕获最近选中的行内引用的媒体引用。该变量必须是包含 mediaItemRid、mediaSetRid 和 mediaItemReadToken 字段的 struct。设置此变量会覆盖默认的行内引用行为。
- Active tab agent running: 一个布尔值,表示智能体当前是否正在活动标签页中运行。用它来显示加载状态,或在分析进行时禁用输入。
这些输出可以驱动你的 Workshop 模块中的可视化、过滤器或其他逻辑。
Apply actions
你可以配置在响应分析事件时触发的 actions。每个 action 都必须配置好所有必需参数,因为它会严格按照配置执行。两个选项都可以选择性地显示一个 toast 通知,指明该 action 是否成功,该通知还可能允许撤销该 action。
- On user message send: 每次用户发送消息时执行一个 action。Text input value 和 Chat session ID 参数由 widget 提供。该 action 在消息提交之前执行,因此 All user messages 输出此时还不会包含刚提交的消息。
- On agent stopped: 当活动标签页中的智能体停止运行时执行一个 action。Chat session ID 参数由 widget 提供。这对于日志记录、审计或触发后续工作流很有用。该 action 运行期间无法发送新的用户消息。
### Tool configuration
工具配置让你可以控制 AIP Analyst 的能力和范围。下面的过滤器适用于所有 Object type search 和 Object search 工具调用。
- Customize default enabled tools: 选择 widget 加载时默认启用哪些工具。将此与 Hide configure tools button 结合使用,可保证 AIP Analyst 只使用你选择的工具。
- Filter to Ontology: 将搜索结果限制在单个 Ontology 内。
- Filter to object type groups: 将搜索结果限制在特定对象类型组内。提供静态列表,或连接一个包含对象类型组 RID 的 Workshop 变量。
- Filter to projects: 将搜索结果限制在特定项目内的实体中。所选文件夹中不是项目的会被忽略。
- Filter to object type statuses: 将搜索结果限制在具有所选状态的对象类型。
- Filter to object type visibilities: 将搜索结果限制在具有所选可见性的对象类型。
- Default semantic search threshold: 设置 object set 工具的语义搜索相似度阈值,为介于 0 和 1 之间的数字。
关于每个范围过滤器的具体行为,请参阅 Analysis settings。
### View configuration
视图配置控制用户可见的界面元素,让你能够为特定用例打造精简的体验。
Empty state and input
- Customize empty state: 定制空聊天状态的标题、描述和图片。图片可以是带有自定义颜色的图标,也可以是上传的图像。
- Customize input placeholder: 设置聊天输入框空状态时的占位文本。
- Hide input area: 移除聊天输入字段,防止用户直接在 widget 中发送消息。消息仍然可以通过 User message 输入变量来触发。
- Hide input resources section: 隐藏 widget 空状态中的预加载资源区域。
Header and export
- Hide tab header: 移除聊天标签页标题栏并禁用创建新标签页。这也会禁用聊天分支。
- Hide PDF export button: 移除将聊天导出为 PDF 的选项。如果标签页标题栏被隐藏,导出按钮会转而显示在最底行。
- Hide Quiver export button: 移除将聊天导出到 Quiver 的选项。
- Hide Contour export button: 移除将聊天导出到 Contour 的选项。
- Hide Notepad export button: 移除将聊天导出到 Notepad 的选项。
Chat controls
- Hide outline sidebar: 移除分析大纲和 graph 侧边栏。
- Hide configure tools button: 移除工具配置按钮,使 AIP Analyst 只能使用默认启用的工具。
- Hide record audio button: 从输入区域移除音频录制按钮。
- Add context options: 控制 Add context 菜单中可用的选项,例如对象类型、对象集、数据集、媒体集、Notepad 文档或文件上传。通过粘贴 URL、拖放或消息文本加载的上下文不受影响,此设置也不改变 AIP Analyst 可以使用的工具。
- Hide token estimator: 移除 token 用量估算器。
- Hide model selector: 移除 AI 模型选择器,使 AIP Analyst 只能使用默认模型。
- Hide thinking details: 对用户隐藏模型的扩展思考输出。
- Default collapse tools: 默认折叠工具使用消息,只显示工具名称而不显示完整结果。
- Hide upgrade to media set panel: 隐藏提议将上传文件升级为媒体集的提示。
Session lifecycle
- Clear chat on navigation: 当用户离开该页面时清除聊天会话,使每次返回时都开始一个新会话。
- Reset key: 连接一个 Workshop 变量,每当其值变化时就将 widget 重置为一个全新会话。用它来从模块的其他位置触发重置。

> 图:AIP Analyst Workshop 视图配置。
### Save configuration
启用 Analysis saving 以控制 widget 如何保存和加载分析。如果你的注册禁用了分析保存,配置这些选项时 widget 会显示错误。
- Save location: 定义新创建的分析所存储的文件夹。启用 Require save location 可防止用户更改它;对该文件夹没有权限的用户将无法保存分析。
- Loaded analysis source: 在 widget 中打开某个特定的已保存分析。硬编码一个 Compass 资源,或连接一个 Workshop 变量以根据应用状态加载不同的分析。
- Unsaved analysis header: 设置尚未保存的分析所显示的标题文本。
- Only show analyses created in this module: 将可发现的分析过滤为此 Workshop 模块内创建的那些。如果该 widget 是通过嵌入模块消费的,则改用顶层模块。
> 当加载一个已保存的分析时,在此 widget 上配置的工具选项会优先于该分析上存储的设置。已保存分析中现有的聊天不会使用此 widget 配置的输入;新建聊天或重置聊天则会使用。
### Session persistence
默认情况下,只要用户的浏览器标签页保持打开,AIP Analyst widget 就会将草稿聊天状态保存在内存中。这使 widget 在同一个 Workshop 模块内被隐藏后又显示时(例如 widget 被放在标签页或可折叠区域中时),能够保留对话历史、上下文项和工具结果。刷新或关闭浏览器标签页会清除这些未保存的草稿状态。
要在每次隐藏 widget 时重置聊天,请启用视图配置中的 Clear chat on navigation 选项。启用后,当 widget 从页面中移除时,草稿状态会被丢弃,再次显示时会开始一个全新会话。
你也可以通过 Reset key 视图选项以编程方式强制重置——连接一个 Workshop 变量,每当该变量的值变化时,widget 就会重置为一个全新会话。
## 最佳实践
> 要点:嵌入时的注意事项。
在为你的 Workshop 模块配置 AIP Analyst widget 时,请考虑以下做法:
- 预加载上下文以获得更快的结果: 在输入配置中添加相关的对象类型、数据集或对象集,可以省去初始搜索时间,并引导用户找到正确的数据。
- 使用自定义系统提示词实现专门分析: 通过在系统提示词中提供领域特定的指令或分析框架,来定制智能体的行为。
- 连接变量以实现自动化工作流: 将 Workshop 变量链接到 user message 输入,以创建动态、事件驱动的分析,从而响应模块其他位置的用户交互。
- 抽取输出以驱动额外逻辑: 使用输出变量将 AIP Analyst 结果纳入其他可视化、过滤器或分析组件。
- 限制范围以实现聚焦分析: 在构建特定用途的应用时应用 Ontology、对象类型组和项目限制,以提高性能并防止访问不相关的数据。
- 精简界面: 在为非技术用户构建引导式体验时,隐藏高级功能和控制项。
- 使用已应用的 actions 实现集成: 配置 On user message send 和 On agent stopped actions 以触发后续工作流,例如记录分析活动或保存结果。
- 提供建议提示词: 定义建议提示词,引导用户提出常见问题并降低开始分析的门槛。
### 常见问题速答 · FAQ
关于「AIP Analyst 的 Workshop 微件」,读者最常问的几个问题。
如何微件配置? 数据访问、工具范围、界面定制。AIP Analyst widget 可以进行配置,以便为你的用户定制分析体验。配置按若干区域组织,用于控制该 widget 的行为方式以及可用的能力。
最佳实践是什么? 嵌入时的注意事项。在为你的 Workshop 模块配置 AIP Analyst widget 时,请考虑以下做法。
---
## 提示词工程最佳实践
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-best-practices-prompt-engineering.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/best-practices-prompt-engineering/
- 主题分组:核心平台(四)
循序渐进 · AIP 教学 · 核心平台(四)
# 提示词工程最佳实践
写提示词(prompt)这件事,直接决定 LLM 输出的质量。这一篇讲怎么写出稳定可靠的提示词,是所有 AI 应用的基本功。
## 先记住这几条
① 提示词的目标是引导 设计输入,让模型产出你想要的输出。
② 最重要的信息放前面 任务概述优先,数据与规则随后。
③ 模型只知道你给它的 没写进去的上下文,模型无从得知。
④ 好提示词可以复用 沉淀成模板,而不是每次重写。
## 写在前面
编写有效的提示词——这一过程被称为提示词工程(prompt engineering)——对于充分释放大语言模型的潜力至关重要。提示词工程的目标是设计出能够引导 LLM 生成期望输出的输入。提示词的质量直接影响模型回答的相关性、准确性和连贯性。本指南提供了一些提示词工程的最佳实践以及示例说明。虽然每种策略的有效性可能因所使用的 LLM 而异,但以下最佳实践考量可帮助你开始设计出有用且准确的提示词。
如果你专门在使用 AIP Assist,请查阅我们的 AIP Assist 最佳实践。
## 有效提示词的关键策略
> 要点:可直接照做的一套写法。
有效的提示词工程是一个动态且迭代的过程,它结合了清晰性、具体性和上下文相关性。通过遵循这些最佳实践并加入示例,用户可以最大化大语言模型的效果。随着 AI 技术的演进,持续了解新策略将进一步提升提示词质量和输出的准确性。
- 保持清晰和具体
- 要清晰: 使用直白易懂的语言来定义任务或问题。
- 示例: 不要问「你对编程了解什么?」,而应具体说明「总结我用于开发 Web 应用的框架选项。」
- 指定上下文: 提供上下文以锚定模型的回答。
- 示例:「作为一名软件工程师,解释抽象的好处。」
- 精炼并迭代
- 测试并调整: 尝试不同的提示词结构,并根据输出质量对其进行精炼。
- 示例: 先以「列出 Web 应用的优点。」开始。如果回答过于宽泛,则精炼为「与原生应用相比,列出 Web 应用在维护方面的优势。」
- 反馈循环: 利用模型反馈持续改进提示词设计。
- 示例: 如果模型误解了某个提示词,调整措辞并重新测试。
- 使用示例
- 演示期望的输出: 提供示例以设定对格式和内容的预期。
- 示例:「将下面这句话翻译成法语:'Hello, how are you?' 示例:'Hello' 译为 'Bonjour'。」
- 突出模式: 使用示例建立一致的回答模式。
- 示例:「对每种水果,列出其颜色和味道。示例:Apple - Red, Sweet。」
- 管理长度和复杂度
- 保持简洁: 提供必要的细节,但不要让模型负担过重。
- 示例: 不要用「你能讲讲机器人的历史、现状和未来吗?」,而应用「简要描述机器人的历史。」
- 避免过载: 将复杂任务拆分为更简单的部分。
- 示例:「首先,列出半导体制造流程的各个步骤。然后,详细解释每一步。」
- 加入约束条件
- 设定边界: 定义清晰的约束来引导回答的范围。
- 示例:「用不超过三句话总结这篇文章。」
- 限制不想要的输出: 使用反例或明确的指令。
- 示例:「生成一份远程办公的利弊清单,但排除个人观点。」
- 提供相关上下文
- 与模型能力相匹配: 使提示词契合模型的强项和局限。
- 示例: 对于在医疗数据上训练的模型,应问「解释糖尿病的症状」,而不是无关的话题。
- 保持相关性: 确保提示词与模型的训练数据相关。
- 示例:「讨论 AI 近期的进展」,与模型的知识库保持一致。
- 优化交互方式
- 角色扮演: 分配角色以引导模型的语气和深度。
- 示例:「作为一名机械工程师,描述在重型制造流程中最重要的传感器。」
- 顺序提示: 使用一系列提示词来获得复杂的回答。
- 示例:「首先,描述半导体制造流程。接下来,列出三类半导体以及它们的制造方式。」
## 更多提示词工程资源
> 要点:进一步学习的官方材料。
如需进一步了解提示词相关内容,可参考以下来源的相关文档:
- Anthropic: 提示词工程概览 ↗
- Google: 提示词工程白皮书 ↗
- Microsoft: 提示词工程技术 ↗
- OpenAI: 使用 OpenAI API 进行提示词工程的最佳实践 ↗
### 常见问题速答 · FAQ
关于「提示词工程最佳实践」,读者最常问的几个问题。
有效提示词的关键策略是什么? 可直接照做的一套写法。有效的提示词工程是一个动态且迭代的过程,它结合了清晰性、具体性和上下文相关性。通过遵循这些最佳实践并加入示例,用户可以最大化大语言模型的效果。随着 AI 技术的演进,持续了解新策略将进一步提升提示词质量和输出的准确性。
还有哪些提示词工程资源? 进一步学习的官方材料。如需进一步了解提示词相关内容,可参考以下来源的相关文档。
---
## 自带模型(BYOM):把外部模型接进 AIP
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-bring-your-own-model.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/bring-your-own-model/
- 主题分组:自带模型(一)
循序渐进 · AIP 教学 · 自带模型(一)
# 自带模型(BYOM):把外部模型接进 AIP
平台自带模型不够用?自带模型(Bring-your-own-model,BYOM)让你把自己的 LLM 或账号接进 AIP,成为一等公民资源。这一篇是总览与选路指南。
## 先记住这几条
① BYOM = 注册模型 接入后就是平台里的一等公民资源。
② 有多条接入路径 REST API、compute module、自托管、代理层。
③ 按场景选路径 模型在哪、要不要自定义逻辑,决定选哪条。
## 写在前面
自带模型(Bring-your-own-model,BYOM)在 Palantir 平台中也称为注册模型(registered models),是一项为希望将自己的 LLM 或账号接入 AIP 的客户提供一等公民(first-class)支持的能力,覆盖 Palantir 的各类开发者产品。这些产品包括 AI FDE、AIP Analyst、AIP Chatbot Studio、AIP Logic、Workshop、Code Repositories 中的 TypeScript functions、Pipeline Builder(即将支持)等。
为了提供更大的灵活性并支持诸如用于数据主权的自托管模型等能力,平台支持多种方式为注册模型提供后端;请查阅下方的模型来源小节了解更多。
## 什么时候该用
> 要点:判断是否真的需要 BYOM。
基于 LLM 的支持情况与可行性,我们通常建议使用来自模型供应商(例如 OpenAI、Azure OpenAI、AWS Bedrock、xAI、GCP Vertex)的 Palantir 提供的模型,或使用由 Palantir 自托管的开源模型(例如 Llama 系列模型)。
不过,你可能更希望将自己的模型或账号接入 AIP。我们建议仅在你出于法律或合规原因无法使用 Palantir 提供的模型时,或当你拥有自己的微调模型或其他独特 LLM 并希望在 AIP 中加以利用时,才使用注册模型。
> 我们于 2026 年 3 月引入了注册模型的新实现,针对最常见的模型供应商 API 提供了精简优化的集成,本页描述的就是该实现。这一新实现在更多 AIP 应用(例如 AI FDE 和 AIP Analyst)中提供了更佳的性能与运维功能。它还支持原生工具调用与推理能力,同时为 AIP 提供基础设施工具,例如限流启用、Resource Management 中的用量可观测性、Control Panel 中的权限控制以及模型选择器。由于这些增强,我们建议使用这一新实现,而不是此前通过函数接口注册 LLM 的方式。
如果你此前通过函数接口注册了模型,请查阅[使用函数接口注册 LLM \[Legacy\] 文档](/docs/foundry/aip/chat-completion-function-interface-quickstart/)。如果你的用例无法由注册模型很好地满足,请联系 Palantir 支持团队。
## 支持的应用与特性
> 要点:接入后哪些地方能用。
注册模型的 BYOM 实现支持以下 AIP 应用及其他平台能力:
- AI FDE
- AIP Analyst
- AIP Chatbot Studio
- AIP Logic
- Workshop(通过 AIP Chatbot Studio 或 AIP Logic)
- Code Repositories中的 TypeScript functions
此外,该实现还提供以下 AIP 基础设施工具:
- 跨 AIP 应用的模型选择器
- Control Panel 权限与启用开关
- Resource Management 应用级限流与用量可观测性
## 不支持的应用与特性
> 要点:哪些地方还不能用 —— 动手前必看。
注册模型的 BYOM 实现目前不支持以下应用或功能:
- AIP Assist,包括 Code Repository 中的代码辅助
- Pipeline Builder 的 Generate 和 Explain 功能
## 模型来源
> 要点:几种接入路径的差异对照。
你可以通过以下任一来源为注册模型提供后端:
- REST API source: 通过 Data Connection 中的 REST API 来源连接外部托管的模型供应商或账号。当你的模型暴露标准的供应商 API 时,这是推荐的路径。更多信息请参阅如何注册并使用你自己的模型文档。
- Compute module: 使用你托管在 compute module 中的模型服务器作为模型后端,可运行在你自己的硬件与 GPU 上,支持本地部署或气隙(air-gapped)环境,也可作为自定义代理层。请查阅由 compute module 提供后端的模型文档了解更多。
## 注册模型支持的特性
> 要点:能力边界清单。
### LLM rate limits
注册模型与 Palantir 提供的模型一样支持 LLM 限流。Enrollment administrators(注册管理员)必须在模型注册期间定义 enrollment 级和用户级限流。
- Enrollment rate limits 适用于项目级别的所有限流。
- Project-level rate limits 默认为 enrollment 限额的 70%,但可在 Resource Management 应用的 AIP usage and limits 标签页中配置。
- User rate limits 管控 AI FDE、AIP Analyst 以及其他按用户归属的应用中的单用户消耗量。

> 图:配置限流。
### Permissions and enablement
- Registering models: 只有 Enrollment administrators 可以在 Control Panel 中注册新模型或编辑注册信息。管理员还必须对关联的 Data Connection 来源拥有 Owner 或 Editor 权限,才能注册、编辑或删除注册模型。
- Source permissions are severed at registration: 模型一经注册,其与底层 Data Connection 来源的关联便与最终用户访问权限解耦。最终用户无需对来源拥有任何权限即可使用注册模型;访问权限完全由 Control Panel 中配置的注册模型启用开关管控。
- Using registered models: 使用注册模型进行构建或以最终用户身份使用注册模型的权限,通过 Control Panel 中的注册模型启用设置来管理。访问权限可以授予整个 enrollment 或特定用户组,与标准 AIP 启用方式类似。
- Disabling a model: 注册模型可随时在 Control Panel 的 AIP settings 扩展中禁用,从而阻止其在各 AIP 应用中被使用。

> 图:在 Control Panel 中管控注册模型的访问权限。
## 常见问题
> 要点:BYOM 的常见疑问。
### Is it possible to use a self-hosted model?
可以。你可以在 compute module 中自托管模型,并将其注册为由 compute module 提供后端的模型。请遵循自托管模型指南中的说明操作。
### Do registered models support markings?
目前注册模型不支持 markings(标记)。Enrollment administrators 可以在 Control Panel 中限制谁可以使用注册模型,也可以在 Resource Management 应用中限制哪些项目获得这些模型的容量。
### How are costs handled for registered models?
Palantir 不会对注册模型的使用收取额外的平台费用。调用你外部托管的模型所产生的费用由你的模型供应商直接计费。注册模型的成本不会显示在 Resource Management 应用中。
### Why are AIP Assist and Pipeline Builder's Generate and Explain features not supported?
这些是原生平台功能,依赖于对 Palantir 提供的模型的评估与测试,我们无法保证它们在不熟悉的客户模型上能够正常工作或提供高质量的服务。目前没有计划让这些原生助手能力支持注册模型。
### 常见问题速答 · FAQ
关于「自带模型(BYOM):把外部模型接进 AIP」,读者最常问的几个问题。
什么时候该用? 判断是否真的需要 BYOM。基于 LLM 的支持情况与可行性,我们通常建议使用来自模型供应商(例如 OpenAI、Azure OpenAI、AWS Bedrock、xAI、GCP Vertex)的 Palantir 提供的模型,或使用由 Palantir 自托…
支持的应用与特性是什么? 接入后哪些地方能用。注册模型的 BYOM 实现支持以下 AIP 应用及其他平台能力。
不支持的应用与特性是什么? 哪些地方还不能用 —— 动手前必看。注册模型的 BYOM 实现目前不支持以下应用或功能。
模型来源是什么? 几种接入路径的差异对照。你可以通过以下任一来源为注册模型提供后端。
---
## 构建代理层或联邦层
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-build-a-proxy-or-federation-layer.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/build-a-proxy-or-federation-layer/
- 主题分组:自带模型(五)
循序渐进 · AIP 教学 · 自带模型(五)
# 构建代理层或联邦层
代理层夹在 AIP 与外部模型供应商之间,让你精确控制哪些数据会离开你的环境,以及请求怎么转发。
## 先记住这几条
① 代理层的职责是拦截与改写 收到请求,施加自定义逻辑,再转发。
② 核心价值是数据控制 决定什么能出境、什么必须脱敏。
③ 可做多供应商联邦 按规则路由到不同供应商。
## 写在前面
代理或联邦层位于 AIP 与一个或多个外部模型供应商之间。你的 compute module 接收来自 AIP 的推理请求,施加自定义逻辑,然后将其转发给外部供应商。这让你能够精确控制哪些数据会离开你的环境,以及请求如何被路由。
## 适用场景
> 要点:什么时候需要这一层。
- PII redaction(PII 脱敏): 在提示词到达外部供应商之前,剥离或掩蔽其中的敏感数据。
- Prompt injection(提示词注入): 在转发之前,前置系统提示词、追加指令或转换请求内容。
- API format remapping(API 格式重映射): 在 AIP 所期望的供应商 API 格式与使用不同格式的供应商之间进行转换。
- Multi-provider federation(多供应商联邦): 在单个注册模型背后,基于成本、延迟或模型可用性将请求路由到多个供应商。
## 额外前置条件
> 要点:比基础接入多需要的准备。
除了由 compute module 提供后端的模型的通用先决条件外,将 compute module 用作代理或联邦层还需要:
- Network egress(网络出口): 你的 compute module 必须能够访问外部模型供应商。请通过 Data Connection 中的来源并配合适当的网络策略来配置出口。
- Secrets(密钥): 外部供应商的 API 密钥或其他凭据必须附加到该来源上。你的容器在运行时通过 SOURCE_CREDENTIALS 环境变量来访问这些凭据。关于配置和读取密钥的详情,请查阅来源。
## 如何构建代理层或联邦层
> 要点:架构与实现要点。
- 构建一个实现受支持的供应商 API 格式的容器。该容器应接收来自 AIP 的请求,施加你的自定义逻辑(例如脱敏、路由或提示词注入),然后将其转发给一个或多个外部供应商。
- 在 Data Connection 中创建一个来源,并使用允许出口到你外部供应商的网络策略。将 API 密钥或其他凭据作为密钥附加。
- 在你的 Dockerfile 中设置 application.port 标签,并将镜像发布到 Artifacts。关于容器的通用指引,请查阅 compute module 容器文档。
- 使用已发布的镜像创建一个 compute module,并附加你创建的来源。将最小副本数设置为至少一个。
- 在 Control Panel 中注册模型并配置能力。
- 在任意受支持的 AIP 应用中选择该模型。
---
## 用 compute module 支撑模型
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-compute-module-backed-models.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/compute-module-backed-models/
- 主题分组:自带模型(三)
循序渐进 · AIP 教学 · 自带模型(三)
# 用 compute module 支撑模型
把 LLM 服务跑在 compute module 里,再注册给 AIP —— 这条路径适合需要自定义推理逻辑或私有部署的场景。
## 先记住这几条
① module 承载推理服务 你在 module 里跑一个模型服务器。
② 适合私有化 模型不离开你的基础设施。
③ 注册后用法一致 对上层而言和自带模型无异。
## 写在前面
由 compute module 提供后端的模型允许你在 compute module 中托管大型语言模型服务器,并将其注册为 AIP 中的一等公民模型。该注册模型会出现在所有受支持应用的模型选择器中,与 Palantir 提供的模型或通过 REST API 注册的模型完全一样。
这种方式适用于两类主要场景:
- 在你自己的算力上自托管模型: 你可以使用由 compute module 提供后端的模型,在你自己的 GPU 上运行开源或自定义模型,以实现数据主权、本地部署或气隙部署、成本控制,或抢先体验新发布的模型。
- 构建自定义代理或联邦层: 你可以使用由 compute module 提供后端的模型来重映射 API 格式、注入提示词、在数据到达外部供应商之前进行脱敏,或将请求联邦路由到一个注册模型背后的多个供应商。
## 前置条件
> 要点:需要先准备好什么。
在将你的 compute module 应用注册为模型来源之前,它必须满足以下要求:
- Serve a supported provider API format: 你的容器必须暴露一个符合受支持供应商 API 格式之一的 API。诸如 vLLM 和 Ollama 之类的推理服务器默认就会暴露兼容的 API。
- Set the application port: 你必须在 Dockerfile 中添加一个 application.port 标签,指向你的模型服务器所监听的端口。例如 LABEL application.port='8000'。关于容器的通用指引,请查阅 compute modules 容器文档。

- Set minimum replicas to at least one: 将你的 compute module 配置为至少一个副本。详情请查阅最小副本数文档。

## 注册并使用模型
> 要点:核心步骤。
你必须是一名 Enrollment administrator(注册管理员)才能注册模型。
在你的 compute module 运行之后,在 Control Panel 中将其注册为模型:
- 导航到 AIP settings 扩展并选择 Registered models 标签页。

- 选择 Register a model。
- 选择你的 compute module 作为来源。

- 配置 Model ID。将其设置为你的模型服务器所期望的标识符,例如你的推理服务器所使用的模型名称。
- 定义模型的能力。启用 Reasoning、Structured outputs 和 Tool calling 可确保 AI FDE 和 AIP Analyst 能够使用该模型。
- 定义模型的限流。关于 enrollment 级和用户级限流的详情,请查阅注册模型支持的功能。
- 为你的 enrollment 或特定用户组启用注册模型访问权限。
你的注册模型现在会出现在所有受支持应用的模型选择器中。

> 图:模型选择器展示一个由 compute module 提供后端的注册模型及其能力。
## 下一步
> 要点:完成后可以做什么。
既然你已经拥有了一个由 compute module 提供后端的注册模型,你可以使用该 compute module 来用 AIP 自托管模型,也可以使用该 compute module 来构建代理或联邦层。
### 常见问题速答 · FAQ
关于「用 compute module 支撑模型」,读者最常问的几个问题。
前置条件是什么? 需要先准备好什么。在将你的 compute module 应用注册为模型来源之前,它必须满足以下要求。
注册并使用模型是什么? 核心步骤。你必须是一名 Enrollment administrator(注册管理员)才能注册模型。
---
## 管理员:开启 AIP 能力
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-enable-aip-features.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/enable-aip-features/
- 主题分组:核心平台(十一)
循序渐进 · AIP 教学 · 核心平台(十一)
# 管理员:开启 AIP 能力
AIP 能力默认可能并未全部开启。这一篇是管理员的操作指南:在哪些界面、按什么顺序把能力开出来。
## 先记住这几条
① 能力需要显式开启 不是装好就自动可用。
② 入口在 Control Panel 平台管理的统一入口。
③ 可精细控制范围 限定到具体环境、用户组。
## 写在前面
Palantir AIP(人工智能平台,Artificial Intelligence Platform)在新的注册(enrollment)中默认启用。在 2024 年之前开始的注册可能需要手动在 Control Panel 中开启对 AIP 功能的访问。如果你是注册管理员,可以在 Control Panel > AIP settings 中管理你的 AIP 配置。

> 图:启用 AIP 开关
启用 AIP 可能产生额外的计算用量。
查看支持的模型列表。
## AIP 与自定义工作流能力
> 要点:哪些能力可供自定义流程使用。
AIP 的 AI 功能可以分为三类:
- AIP Assist: 一个由 LLM 驱动的支持工具,旨在帮助用户浏览、理解 Palantir 平台并借助它创造价值。用户可以用自然语言向 AIP Assist 提问,并获得针对其问题的实时帮助。
- 平台应用中的 AIP 助手功能: 由 LLM 支持的原生功能,旨在帮助终端用户在 Palantir 平台中完成日常工作流。这些是高度专门化的功能,利用对平台的了解来加速用户的日常操作。
- 用于自定义工作流的 AIP 能力: 一组能力,允许开发者构建自己的由 LLM 支持的工作流或应用。这些是为开发者或数据科学家构建的开放式功能。
## AIP 权限
> 要点:用哪些权限控制谁能用 AI。
Palantir 平台上的 AIP 使用受两级权限管控:
- AIP 与核心助手功能: 开启 AIP、AIP Assist,以及 Code Repositories、Pipeline Builder 和 Workshop 中相关的助手功能。

- 用于自定义工作流的 AIP 能力: 在启用 AIP 后,平台管理员可以启用额外一层能力,赋能开发者和应用构建者创建自定义 AIP 工作流,并授予用户使用这些自定义 AIP 工作流所需的权限。授予权限后解锁的能力如下:
- 在点击式界面中支持 LLM 的能力
- AIP Logic:使用 LLM Board
- Pipeline Builder:使用 LLM 节点与文本转嵌入
- AIP Automate
- AIP 模型目录
- AIP Chatbot Studio(前身为 AIP Agent Studio)
- AIP Workshop 组件:AIP Chatbot、AIP 生成内容
- AIP Workshop 翻译
- Quiver
- AIP Threads
- 使用基于代码的工具进行开发的能力
- 使用 LLM 的转换
- 使用 LLM 的函数
- 在 Code Workspaces 中使用 LLM 的 Jupyter®
## 限制 AIP 使用范围
> 要点:怎么收窄可用范围。
平台管理员可以在两个不同层级上限制 AIP 的使用:用户组和组织(Organization)。
### User groups
要在用户组层面限制 AIP 使用,平台管理员可以选择 Everyone、指定的 User Groups,或者通过选择 Nobody 来限制使用。

> 图:为自定义工作流启用 AIP 能力
某些应用(例如 AIP Logic)可能需要先在 Control Panel > Application access 中启用后才能使用。
### Organizations
要在组织层面限制 AIP,平台管理员可以启用 Restrict AIP To Organizations 选项,然后从下拉菜单中选择所需的组织。请记住,此设置会限制 AIP 只能用于所选的组织。因此,AIP 将对任何未被选中的组织禁用。此外,如果某个注册未启用 AIP,则任何组织都无法访问 AIP。
> 只有当资源的项目上所有组织标记(organization marking)都启用了 AIP 时,该资源才被视为已启用 AIP。

> 图:将 AIP 限制到特定组织。
## 启用 LLM
> 要点:把需要的模型开出来。
注册管理员可以在 Control Panel 的 AIP settings 扩展中的 Model enablement 标签页下管理 LLM 的使用。启用某个模型系列包括接受适用的条款与条件,其中包含提供这些模型的子处理者的相关条款。

> 图:AIP Settings Control Panel 扩展中的 Model enablement 标签页。
### Understanding model states
Model enablement 界面中的每个模型系列都会显示三种状态之一:
- Enabled(已启用): 该模型系列处于活动状态,可供用户和工作流使用。无需进一步操作。
- Disabled(已禁用): 该模型系列在你的注册中可用,但尚未被管理员激活。要启用它,请选择 Manage 并接受条款与条件。
- Disallowed(不允许): 该模型系列因法律、地理或基础设施方面的限制而受到限制。请联系 Palantir 支持以讨论可用性方案。
在首次启用来自某个子处理者的模型之前,注册管理员必须接受适用的条款与条件。处于 disabled 状态的模型系列可以直接通过 Control Panel 启用,而 disallowed 的模型则需要 Palantir 支持进行手动配置后才能使用。
当某个子处理者被启用时,Palantir 可能会启用其他符合已接受条款与条件下资格要求的模型系列。启用额外的模型系列不会产生额外费用。新的子处理者需要管理员单独接受。注册管理员可以在 Control Panel 中查看并禁用模型系列。

> 图:模型系列免责声明与条款接受提示。
禁用某个模型系列分组会破坏依赖该特定分组中模型的工作流。
查看所有支持的模型列表。
了解如何将你自己的模型带到 Palantir 平台上运行。
此外,注册管理员可以在组织层级启用或禁用模型系列,从而允许同一注册内的某些组织访问特定的模型系列,同时限制其他组织。
在下面的示例中,此注册中只有 Test1 组织可以访问 Amazon Bedrock Claude 模型。

> 图:组织层级的模型系列启用。
### Experimental models
实验性模型的使用可以由注册管理员启用和禁用。要使某个实验性模型在工作流中可见并可使用,必须同时启用 Enable experimental models 开关以及该实验性模型所属的模型系列。

> 图:实验性模型开关
## 进一步了解
> 要点:相关文档入口。
- 可用的 LLM
- LLM 可用性前提条件
- LLM 容量管理
- 模型可用性的地理限制
注意:AIP 功能的可用性可能发生变化,且不同客户之间可能存在差异。
“OpenAI”名称与“GPT”品牌是 OpenAI 的财产。
Jupyter®、JupyterLab® 以及 Jupyter® 标识是 NumFOCUS 的商标或注册商标。
本文提到的所有第三方商标(包括标识与图标)均归其各自所有者所有。不暗示任何关联或背书。
### 常见问题速答 · FAQ
关于「管理员:开启 AIP 能力」,读者最常问的几个问题。
AIP 与自定义工作流能力是什么? 哪些能力可供自定义流程使用。AIP 的 AI 功能可以分为三类。
AIP 权限是什么? 用哪些权限控制谁能用 AI。Palantir 平台上的 AIP 使用受两级权限管控。
限制 AIP 使用范围是什么? 怎么收窄可用范围。平台管理员可以在两个不同层级上限制 AIP 的使用:用户组和组织(Organization)。
启用 LLM是什么? 把需要的模型开出来。注册管理员可以在 Control Panel 的 AIP settings 扩展中的 Model enablement 标签页下管理 LLM 的使用。启用某个模型系列包括接受适用的条款与条件,其中包含提供这些模型的子处理者的相关条款。
---
## AI 伦理与治理
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-ethics-governance.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/ethics-governance/
- 主题分组:核心平台(七)
循序渐进 · AIP 教学 · 核心平台(七)
# AI 伦理与治理
Palantir 把负责任 AI 当作构建方式本身,而不是事后补丁。这一篇讲他们的伦理原则与治理机制。
## 先记住这几条
① 伦理要贯穿生命周期 不止模型开发阶段,而是系统全生命周期。
② 原则要能落地成机制 不是口号,要有对应的产品能力支撑。
③ 公平、可解释、可追责 这是企业 AI 落地绕不开的三件事。
## 写在前面
在 Palantir,我们相信负责任的 AI 不是事后才考虑的附加项,而是我们构建技术方式的根本所在。我们的方法核心是开发这样的软件:让负责任的 AI 使用贯穿整个系统生命周期;因为我们认识到,伦理考量不止于模型开发本身,而是涵盖完整的技术体系——从数据基础和加工 pipeline,到用户界面和人类决策工作流。我们的平台不把伦理考量当作单独的合规要求,而是将负责任的 AI 能力融入整个开发生命周期。
本文阐述 Palantir 的 AI 平台(AIP)如何积极支持负责任 AI 开发的八大核心主题。每个主题不仅代表一项原则,还代表一组具体的能力和工作流,旨在帮助用户构建值得信赖的 AI 系统——负责任、合乎伦理,并且在实际中有效。这种全面的方法确保用户拥有所需的工具和工作流,能够系统性地满足负责任 AI 的要求,无论他们处理的是传统机器学习模型还是生成式 AI 系统。
## 公平:公正、无偏见、无歧视
> 要点:AI 的责任原则之一。
AI 系统应当具有包容性和可及性,不应导致对个人或群体的不公平歧视。
### Platform capabilities
AIP 提供用于识别数据中偏见来源、评估模型偏见,以及在模型使用过程中监控公平性问题的功能。
- Sensitive Data Scanner 可以自动识别数据集中的受保护属性和潜在偏见来源,从而在公平性风险影响模型训练、评估或使用之前主动进行评估。
- Modeling Objectives 中的子集评估允许在评估数据集内系统性地评估模型在不同群体上的表现,揭示聚合指标可能掩盖的潜在差异化影响。例如,子集评估可用于运行模型评估,并轻松比较模型在评估数据集中不同人口群体上的表现。
- AIP Evals允许你在多样化的测试用例上评估 AIP Logic 函数的性能。借助 AIP Evals 中的实验(experiment),用户还可以进一步调整模型的输入参数,以了解模型某些输入的变化如何改变模型的回答。
- 数据健康监控持续评估数据的代表性和质量,帮助识别数据集何时可能系统性地低估或过度代表特定人群。
### Implementation workflow
团队可以在数据准备流程的早期,使用 Sensitive Data Scanner 和数据健康监控来识别公平性风险,在模型开发开始之前就发现数据基础中的受保护属性和失衡情况。这解决的是数据层面的潜在偏见。然而,即使数据质量很高,偏见也可能来自模型本身,因此通过 Modeling Objectives 进行的子集评估以及 AIP Evals 都提供了系统性测试,用于检测模型在不同人口群体上表现的不平等。当在任一层面检测到偏见时,团队可以实施有针对性的缓解策略,例如重新采样、收集更多具有代表性的数据,或调整算法方法。
## 可解释:可阐释、可理解、透明
> 要点:决策依据要能说清。
AI 系统不应是黑箱。相反,为建立对 AI 系统的信任,用户应尽可能理解它们是如何工作的。
### Platform capabilities
AIP 提供工具帮助用户理解 AI 系统如何工作,从调试生成式 AI 的推理过程到评估传统模型的性能。
- Modeling Objectives 评估仪表板通过特征重要性分析、性能细分和评估结果,提供详细的模型可解释性,且技术与非技术相关方都能理解。
- AIP Evals支持使用默认和自定义评估库进行系统性测试与评估,使团队能够以契合其特定领域要求的方式评估模型行为。
- AIP Logic 工具可将特定任务委托给专门构建、可解释的工具,而不必完全依赖 LLM 处理,从而通过可组合、可审计的组件构建更可解释的 AI 系统。
- AIP Logic 调试视图让你可以观察基于 LLM 的系统中的思维链推理(chain-of-thought)和工具编排,展示系统如何通过向可解释组件的透明交接来委派任务和做出决策。
- Ontology 与 AIP 可观测性在 AI 工作流中提供全面的监控和调试能力,给出详细的执行轨迹、性能指标和系统行为洞察,帮助团队理解和排查其 AI 系统。
### Implementation workflow
版本控制系统会在整个开发过程中自动记录模型开发的决策及其依据。对于生成式 AI 系统,AIP Logic 中的调试视图可实时展示 LLM 如何编排任务并委托给可解释的工具,而 Ontology 与 AIP 可观测性则提供全面的执行轨迹,帮助团队理解系统行为。团队可以利用 AIP Logic 工具将特定任务委托给可解释的组件,而不必完全依赖 LLM 处理,从而设计出更透明的系统。通过 AIP Evals 和 Modeling Objectives 进行的测试与评估方法,以技术团队和业务相关方都能获取的形式呈现模型性能指标,与上述能力相辅相成。
## 可靠:安全、稳固、有韧性、健壮
> 要点:系统要经得起异常。
AI 系统的构建应具备在其整个生命周期中评估安全性、保密性和有效性的能力。
### Platform capabilities
AIP 支持 AI 系统的安全、受控部署与持续监控,以确保其在整个生命周期中的安全性和可靠性。
- 针对传统 AI/ML 的模型部署包括直接部署和 Modeling Objectives 实时部署,两者都提供受控流程,并可根据治理需要选择自动或手动升级。
- 面向生成式 AI 的 Functions 版本管理与发布管理 通过语义化版本、向后兼容性检查和版本控制工作流,实现 AIP Logic 的受控部署。
- 回滚机制 允许在检测到问题时立即恢复到先前的模型版本,从而将模型故障或安全事件的影响降至最低。
- 全面的监控通过推理历史、系统告警和持续评估确保能快速检测到模型性能下降或安全问题。
- 访问控制与数据标记 基于用户角色、数据敏感性和地理要求提供精细的安全限制,确保 AI 系统尊重隐私和安全边界。
- 地理限制确保模型的请求和响应保持在指定司法管辖区之内,支持不同地区和法律框架下的监管合规要求。
- 静态和传输中加密是我们共同安全责任模型的核心部分,另有可在 AI 开发生命周期中全程应用的、更高级的数据保护能力。
- 容量限制使管理员能够管理 LLM 使用量,防止意外负载高峰造成的服务中断,确保 AI 工作流即使在需求多变的条件下也保持稳健和稳定。
### Implementation workflow
访问控制和数据标记从一开始就确立了安全边界,地理限制则确保模型的请求和响应保持在合规的司法管辖区内。静态和传输中加密在整个 AI 开发生命周期中保护信息。模型部署和预发布函数可以在正式发布前强制执行分阶段测试流程,而容量限制可防止意外 LLM 使用高峰造成的服务中断。实时监控系统在安全、性能和运营指标上提供持续监督,回滚能力则可在检测到问题时立即响应。
## 可追溯:可审计、可治理
> 要点:行为留痕,责任可查。
AI 系统应具备记录相关开发流程、数据来源,以及用于构建模型的所有数据出处(provenance)的能力。
### Platform capabilities
AIP 在 AI 开发生命周期中自动记录全面的文档和审计轨迹,从数据出处到部署决策。
- 数据血缘提供对 AI 系统所使用数据源、转换和依赖关系的完整可见性。
- 工作流血缘让你了解 AI 如何被用于支撑应用中进行决策的逻辑和操作。
- 审计日志捕获所有系统交互、模型评估和部署决策,形成用于合规与监督的全面审计轨迹。
- Modeling Objectives 文档集中汇集所有项目信息、评估结果和决策依据,以支持多方相关方协作。
- Notepad 中的文档模板可支持创建标准化、详细的模型用途、方法和局限性记录,并可与监管机构、监督者和其他相关方共享。
- 通过 Resource Management 进行 LLM 成本治理让你了解 AI 使用成本和资源消耗,使组织能够追踪、监控和管理与 LLM 部署相关的费用。
### Implementation workflow
数据血缘在数据流经加工 pipeline 时自动捕获出处信息,提供对数据源和转换的完整可见性。工作流血缘让你了解 AI 如何支撑应用逻辑和决策工作流。审计日志记录所有系统交互和决策,而 LLM 成本治理追踪资源消耗和费用,为 AI 系统运营增加透明度。Notepad 中的文档模板和 Modeling Objectives 文档使团队能够创建标准化记录,集中汇集项目信息、评估结果和决策依据,且其形式适合监管审查和内部审计。
## 协作性:多方参与、跨学科
> 要点:不是技术团队单方面的事。
构建 AI 系统应当是一个跨学科的过程,科学家、工程师、领域专家和其他相关方需要共同协作。
### Platform capabilities
AIP 通过灵活的访问控制、共享开发环境,以及不同技能水平的用户都可使用的评估框架,支持多方相关方协作。
- 基于角色的权限使组织能够配置与其治理结构相匹配的访问控制,确保在每一阶段都有适当的相关方参与。
- Code Workspaces 与 Code Repositories 提供协作式开发环境,同时支持技术与非技术贡献者。
- Workshop 与协作分析工具 支持实时协作式数据分析,让来自不同学科的相关方能够围绕共享的分析和洞察共同工作。
- 外部数据共享与协作控制在与外部伙伴安全协作的同时,维持治理监督和数据保护标准。
- 无代码、低代码和专业代码评估框架适应不同相关方的技能水平,使领域专家能够在标准技术指标之外定义自定义的评估标准。
### Implementation workflow
基于角色的权限和结构化审批工作流从项目启动时就建立起清晰的协作框架。Code Workspaces 和 Code Repositories 提供技术与非技术贡献者可以共同开展 AI 开发的环境。Workshop 工具支持跨学科的实时协作分析,而外部数据共享控制则促进安全的伙伴关系。灵活的评估框架确保领域专家、合规官员和技术团队各自在开发流程中的适当节点贡献其专业所长,而不是彼此孤立地工作。
## 可问责:有责任主体
> 要点:出了问题找得到人。
应当为负责 AI 系统不同部分的人员明确界定角色和工作流。
### Platform capabilities
AIP 通过精细权限、全面的审计轨迹和结构化审批工作流,建立起清晰的责任链。
- 通过组和角色进行的精细化权限管理为 AI 开发、部署和使用的每个方面建立清晰的责任链。
- 全面的审计轨迹记录谁在何时做出了哪些决策,从而能够对系统结果进行明确问责。
- 结构化审批工作流通过检查(check)确保由适当的权威方审查并批准关键决策。
- Checkpoints支持集中式的确认与说明工作流,确保相关方在运营工作流中对 AI 建议的关键决策进行审查和签核。
### Implementation workflow
精细化权限管理从一开始就建立起清晰的问责结构,界定在 AI 生命周期中谁可以执行哪些操作。完整的审计轨迹会自动记录决策者及其依据,而通过检查和 Checkpoints 实现的结构化审批工作流则建立起系统性的审查流程。Checkpoints 尤其使相关方能够确认并说明运营工作流中 AI 建议的决策。由此形成透明、可审计且可验证的责任链,而无需额外的手工追踪工作。
## 以人为本:参与式、对社会有益
> 要点:技术服务于人。
AI 系统应当整体上惠及个人、社会和环境。它们应增强而非取代人类决策。
### Platform capabilities
AIP 通过结构化的决策支持框架和强制性的人工监督机制,确保 AI 增强而非取代人类决策。
- 基于 Ontology 的决策支持 为人类与 AI 协作提供结构化框架,确保 AI 建议在能够增强而非取代人类判断的语境中呈现。
- 通过 Ontology 操作和审批流程实现的人工监督工作流确保关键决策仍由人类掌控,同时利用 AI 洞察。
- Dashboard 与可视化能力 以人类可理解的形式呈现 AI 输出,使相关方能够理解复杂的分析结果,并基于 AI 建议做出明智决策。
- 结合 Checkpoints 的工作流自动化提供系统化的自动化方法,在关键决策阶段包含强制性的人工审查节点,确保适当监督的同时保持运营效率。
- 选择退出与回退机制可以内置于应用中,确保用户对 AI 辅助流程保有控制权。
- 反馈循环集成支持从人类决策中持续学习,以随时间改进 AI 建议。
### Implementation workflow
基于 Ontology 的决策支持框架在结构化工作流中呈现 AI 洞察,从而保留人的能动性和决策权。通过操作和审批流程实现的人工监督工作流确保关键决策仍由人类掌控。Dashboard 与可视化能力将复杂的 AI 输出转化为能够支持明智人类判断的形式,而带人工 Checkpoints 的工作流自动化则确保在关键决策阶段有适当监督。选择退出与回退机制可被设计进应用中,确保用户对 AI 辅助流程保有控制权。反馈循环集成捕获人类决策以持续改进 AI 建议,形成一种增强而非取代人类专业能力的协作智能方法。
## 开始实践负责任 AI
> 要点:从哪里入手。
Palantir 的 AI 平台让负责任的 AI 走向系统化,而非临时应对。平台通过既定的工作流引导各技能水平和专业领域的用户落实负责任 AI 原则:
- 关注完整集成的系统,而不仅是其组成工具: 从数据基础和加工 pipeline,到用户界面和人类决策工作流,整体地考虑你的 AI 系统。使用数据血缘和 Pipeline Builder 等能力来理解各组件在你的系统中如何连接。
- 承认技术的局限: 首先清晰评估你的 AI 系统能做什么、不能做什么,以及它应被允许做什么、不应被允许做什么。在开发开始之前,采用问题优先的建模方法界定适当的范围和限制。
- 不要解决不该解决的问题: 评估你的用例是否适合由 AI 介入。在启动开发前考虑法律、伦理和社区规范。有些问题在技术上可行,但并不适合进行数学优化。
- 遵循合理数据科学的方法论最佳实践: 利用平台内置的评估框架、偏见检测能力和公平性评估工具。使用 Sensitive Data Scanner 识别受保护属性,采用子集评估来评估差异化影响,并遵循已确立的方法论来负责任地使用特征。
- 让 AI 保持负责任、可问责并以人为本: 设计增强而非取代人类决策的 AI 系统。使用基于 Ontology 的决策支持、人工监督工作流和反馈循环,确保 AI 建议与人类判断相辅相成,同时通过审计轨迹和审批工作流保持清晰的问责。
- 促进多方相关方参与: 配置与你组织治理结构相匹配的检查和审批工作流。使用 Workshop 和基于角色的权限等协作工具,确保领域专家、合规官员、技术团队和其他相关方在整个 AI 生命周期中贡献其专业所长。
- 确保技术、治理和文化方面的意识: 将平台的技术能力(加密、访问控制、监控)与治理框架(审批工作流、审计轨迹)以及文化实践(培训、相关方参与)相结合,打造契合你组织情境的、包容性的负责任 AI 实践。
## 小结
> 要点:整体结论。
负责任的 AI 并不是对创新的约束。相反,正是它使 AI 系统足够可信,可用于关键决策。Palantir 将负责任 AI 原则融入开发生命周期的每一个方面,使组织能够构建不仅在技术上成熟、而且在伦理上健全、在运营上可靠的 AI 系统。
通过采取考虑 AI 部署完整情境的集成式方法,我们帮助用户解决其最具挑战性的问题,同时使他们能够保持最高标准的责任与治理。
### 常见问题速答 · FAQ
关于「AI 伦理与治理」,读者最常问的几个问题。
公平:公正、无偏见、无歧视是什么? AI 的责任原则之一。AI 系统应当具有包容性和可及性,不应导致对个人或群体的不公平歧视。
可解释:可阐释、可理解、透明是什么? 决策依据要能说清。AI 系统不应是黑箱。相反,为建立对 AI 系统的信任,用户应尽可能理解它们是如何工作的。
可靠:安全、稳固、有韧性、健壮是什么? 系统要经得起异常。AI 系统的构建应具备在其整个生命周期中评估安全性、保密性和有效性的能力。
可追溯:可审计、可治理是什么? 行为留痕,责任可查。AI 系统应具备记录相关开发流程、数据来源,以及用于构建模型的所有数据出处(provenance)的能力。
---
## 分析运行结果
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evals-analyze-run-results.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evals/analyze-run-results/
- 主题分组:AIP Evals(九)
循序渐进 · AIP 教学 · AIP Evals(九)
# 分析运行结果
结果视图告诉你:函数在各测试用例与评估标准上的表现具体如何。可以在 Evals 应用里看,也能在 Logic / Chatbot Studio 的侧边栏里看。
## 先记住这几条
① 结果按用例与标准展开 能看到每条用例的判定情况。
② 三个查看入口 Evals 应用、Logic 侧边栏、Chatbot Studio 侧边栏。
③ 关注聚合与个体 整体指标和单条表现都要看。
## 写在前面
运行结果显示你的函数在测试用例和评估标准方面的表现如何。结果视图可在 AIP Evals 应用中查看,也可在 AIP Logic 和 AIP Chatbot Studio 中集成的 AIP Evals 侧边栏中查看。
如果你在评估器上配置了通过标准(pass criteria),AIP Evals 将自动为每个测试用例判定 Passed 或 Failed 状态。结果页面会显示所有测试用例的整体通过百分比。
## 测试用例调试视图
> 要点:单条用例的细节查看。
在某些情况下,你可能想进一步调查某个特定的测试用例结果。针对这些情况,可以使用调试视图(debug view)。该视图提供单个测试用例的执行轨迹、输入/输出数据和错误消息,让你能够理解你的函数输出和评估器结果。
### Access the debug view
有多种方式可以打开测试用例的调试视图。你可以从 AIP Evals、AIP Logic 或 AIP Chatbot Studio 中打开。
In AIP Evals
- 在你的评估套件页面上打开 Results 标签页。
- 选择一次运行并切换到 Test cases。
- 将鼠标悬停在某个测试用例结果上。
- 选择出现在测试用例行右侧的 Open 选项。

> 图:AIP Evals 应用结果视图。
In AIP Logic or AIP Chatbot Studio
- 在运行结果对话框视图中,将鼠标悬停在某个测试用例结果上。
- 选择出现在测试用例卡片右上角的 Debugger 选项。
- 调试视图将打开,显示详细的执行信息。

> 图:AIP Logic 中的 AIP Evals 运行结果视图。
### Debug view capabilities
调试视图提供有关受测函数执行和评估器结果的详细信息。它允许你:
- 检查某个测试用例的受测函数输入和输出。
- TypeScript/Python 函数: 访问已执行代码的语法高亮代码预览。
- AIP Logic 函数: 使用原生 Logic 调试器逐步跟踪函数执行过程。
- 评估器: 查看输入和输出值、评估器的期望值与实际值结果,以及来自自定义函数评估器和部分内置评估器的调试输出。

> 图:AIP Evals 调试视图中的函数输出。

> 图:AIP Evals 调试视图中的评估器标签页。
某些评估器会在评估器标签页中将额外上下文作为 Debug outputs 展示。例如,内置的 LLM-as-a-judge 评估器会返回模型的推理过程作为调试输出,帮助你理解它为何得出特定的判定。
如果你编写了自定义评估器,它们也可以产生调试输出。自定义评估器在其指标输出之外返回的任何字符串值都会显示为 Debug outputs,提供诸如推理、中间值或诊断信息之类的额外上下文。

> 图:来自自定义函数评估器的调试输出。
如果你使用 AIP Logic 构建自定义函数评估器,你还可以额外访问原生 Logic 调试器。这有助于你理解评估为何产生特定结果,在使用 LLM-as-a-judge 作为评估器时特别有帮助。
在下方截图所示的示例中,自定义函数评分标准评估器(rubric grader evaluator)未通过,因为结果 8 没有达到所定义的最小阈值 9。查看 Logic 调试器,我们可以看到 LLM 评判者只给出了 8 分,因为回答被引号包裹着。要获得更高的分数,我们需要改进我们的提示词。

> 图:使用 AIP Evals 调试视图理解评估器结果的示例。
## 跨目标函数比较结果
> 要点:同套件下多函数横向比。
当你的评估套件配置了多个目标函数时,你可以在 AIP Evals 中选择并比较跨不同目标的运行结果。这对于分析不同函数实现在同一批测试用例上的表现非常有用。

> 图:多目标结果对比视图。
## 用 AI FDE 分析结果
> 要点:对话式分析评测数据。
你可以使用 AI FDE 来分析失败的测试用例、识别根本原因模式,并获得改进提示词的建议。
### Analyze from AIP Evals
- 在你的评估套件页面上打开 Results 标签页。
- 选择一次包含失败测试用例的运行,然后选择 Test cases 标签页。
- 选择 Analyze with AI FDE。
### Analyze from AIP Logic
- 从 AIP Evals 侧边栏打开运行结果对话框视图。
- 选择 Analyze with AI FDE。
AI FDE 将在新标签页中打开,并带有你的运行结果的上下文。有关 AI FDE 的更多信息,请参阅 AI FDE 文档。
### 常见问题速答 · FAQ
关于「分析运行结果」,读者最常问的几个问题。
测试用例调试视图是什么? 单条用例的细节查看。在某些情况下,你可能想进一步调查某个特定的测试用例结果。针对这些情况,可以使用调试视图(debug view)。该视图提供单个测试用例的执行轨迹、输入/输出数据和错误消息,让你能够理解你的函数输出和评估器结果。
跨目标函数比较结果是什么? 同套件下多函数横向比。当你的评估套件配置了多个目标函数时,你可以在 AIP Evals 中选择并比较跨不同目标的运行结果。这对于分析不同函数实现在同一批测试用例上的表现非常有用。
用 AI FDE 分析结果是什么? 对话式分析评测数据。你可以使用 AI FDE 来分析失败的测试用例、识别根本原因模式,并获得改进提示词的建议。
---
## 创建评估套件
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evals-create-suite.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evals/create-suite/
- 主题分组:AIP Evals(三)
循序渐进 · AIP 教学 · AIP Evals(三)
# 创建评估套件
评估套件 = 测试用例 + 目标函数 + 评估函数。这篇讲怎么把它搭起来,包括同时测多个目标函数的做法。
## 先记住这几条
① 套件是配置容器 把三样东西绑在一起。
② 目标函数可多个 一个套件能同时评测多个函数。
③ 评估函数决定判定方式 精确匹配、语义比对、自定义函数都行。
④ 测试用例是输入+期望 每个用例一条。
## 写在前面
评估套件是用于对目标函数表现进行基准测试的测试用例与评估函数的集合。运行评估套件将对每个测试用例执行目标函数,并使用与该套件关联的评估方法。
你可以为诸如 AIP Logic 函数、AIP Chatbot 函数以及代码编写的函数等目标函数创建评估套件:
AIP Logic 函数: 要开始在 AIP Logic 中使用评估套件,请参阅逻辑函数的评估套件。

> 图:AIP Logic 函数中的评估侧边面板。
AIP Chatbot 函数: 要测试 AIP Chatbot 函数,你需要先将聊天机器人发布为函数。然后你可以在左侧边栏的 Evaluation 标签页中创建评估套件。由于侧边栏相似,你可以参考逻辑函数的评估套件一节了解更多信息。

> 图:AIP Chatbot Studio 中的评估侧边面板。
代码编写的函数: 你可以直接从 Published 标签页,通过导航到 Code Repositories > Code > Functions > Published,为在代码仓库(Code Repositories)中编写的函数创建并打开评估套件。

> 图:代码仓库中的 AIP Evals 链接。
## 附加目标函数
> 要点:一个套件同时评测多个函数。
你可以添加额外的目标函数,以使用同一个评估套件测试多个函数。这使你能够一次性针对不同的已发布 Foundry 函数或 Logic 函数运行评估。它对于比较不同实现之间的表现,或在同一批测试用例上评估相似函数非常有用。
要添加目标函数,请在 AIP Evals 中打开你的评估套件并选择 Add target function。每个目标函数可以有不同的输入/输出签名,且评估器按目标分别配置。

> 图:向你的评估套件添加目标函数。
当你配置了多个目标后,你可以在运行评估套件时选择要包含哪些目标。
## 添加测试用例
> 要点:输入与期望输出的组合。
你可以通过手动定义单个测试用例、使用对象集(object set)生成多个测试用例,或在同一个套件中结合两种方式,来为评估套件创建测试用例。这种灵活性使你能够利用现有的对象集,同时按需添加特定的手动测试用例。
你可以通过选择 Edit test case parameters 来编辑评估套件列。然后,你可以添加、移除测试用例列及其各自的类型,或重新排序。

> 图:配置测试用例参数。
### Manual test cases
要手动定义测试用例,请在评估套件视图的左下角选择 Add test case。为每个测试用例命名,然后在相应的列中定义输入及其期望值。你可以选择测试用例名称旁的紫色 AIP 星形图标来生成建议名称。

> 图:生成建议的测试用例名称。
在本示例中,建议名称 Negative Review On Food Quality 比 Test case 1 提供了更多信息:

> 图:建议名称简要描述了测试用例的参数。
手动测试用例非常适合测试特定的边缘情况、在你的对象集中可能代表性不足的场景,或者当你希望对测试输入和期望输出进行精确控制时。
### Object set test cases
你也可以从对象集添加测试用例,此时每个测试用例将由所选对象集中的一个对象表示。要添加对象集测试用例,请选择 Add object set,并在对象集选择对话框中选择你要使用的对象集和对象属性。

> 图:添加由对象集支持的测试用例。
对象集测试用例对于使用真实数据进行大规模测试特别有用,可确保你的函数在你实际数据的代表性样本上正常工作。你可以向同一个评估套件添加多个对象集,并将它们与手动测试用例结合,以创建全面的测试覆盖。

> 图:编辑对象集属性。
支持对象集可以通过在配置对话框中选择 Edit object set configuration 图标来编辑。属性也可以使用对象集标题列单独编辑。
对象集可以配置为向评估套件列提供不同类型的数据。这些包括:
- 支持对象集的对象
- 支持对象集的对象属性
- 链接到支持对象集的对象或对象集
- 链接对象或链接对象集的属性(仅在 Object Storage v2 中可用)
- 应用于支持对象集每一行的静态值
## 评估器
> 要点:判定方式:精确匹配、语义比对、自定义函数。
评估器是一种用于将受测函数的输出与期望输出进行评估的方法。评估器可以返回简单的 true/false 结果,但也可以产生诸如语义距离之类的数值。没有评估器的评估套件可用于在多种场景中执行函数并手动审查每个输出。然而,评估器使得大规模衡量并客观化运行结果成为可能,因为它们会产生可比较的表现指标。
AIP Evals 提供了一些内置评估器,将在下一节中描述。你也可以定义自定义评估函数,以基于特定标准衡量表现。
### Add an evaluator
要添加评估器,请在测试用例表格顶部选择 + Add。这将打开一个选择面板,你可以在其中从内置评估器或自定义评估器列表中进行选择。

> 图:为你的测试用例选择评估器。
一旦你选择了评估器并选择 + Add,该评估器将被添加到你的测试用例表格中。然后,你可以通过将函数输出映射到测试用例表格中的 Actual value 列、将期望值映射到 Expected value 列,来配置该评估器。

> 图:配置你的评估器。
配置评估器时,你可以为每个指标定义一个目标。对于布尔型指标,指定指标应为 true 还是 false。对于数值型指标,设置优化方向;指定为最大化(值越高越好)或最小化(值越低越好)目标。你还可以定义一个阈值:
- 对于最大化目标,设置最小阈值(例如,"score must be at least 10")。
- 对于最小化目标,设置最大阈值(例如,"score must be at most 0.05")。
如果某个测试用例迭代中的指标满足所配置的目标,则该指标被视为通过。对于布尔型指标,这取决于指标是 true 还是 false。对于数值型指标,这取决于指标是否高于或低于阈值(若已定义)。如果所有指标都满足所配置的目标,则整个测试用例迭代被视为通过。具有多次迭代的测试用例,如果所有迭代都通过,则被视为通过。

> 图:配置你的评估器。
### Built-in evaluators
内置评估函数的示例包括:
- Exact boolean match: 检查实际布尔值是否与期望布尔值完全相等。
- Exact Boolean array match: 检查两个布尔数组是否包含相同的元素。默认情况下比较与顺序有关,但这可以配置。
- Exact string match: 检查实际字符串是否与期望字符串完全匹配。默认情况下匹配区分大小写且包含空白字符,但这可以配置。
- Exact string array match: 检查两个字符串数组是否包含相同的元素。默认情况下比较与顺序有关、区分大小写且包含空白字符,但这可以配置。
- Regex match: 检查实际字符串是否与期望的正则表达式匹配。
- Levenshtein distance: 一种用于衡量两个序列之间差异的字符串度量。计算将一个词转换为另一个词所需的最小单字符编辑次数(插入、删除或替换)。
- String length: 检查实际字符串的长度是否落在期望范围内。
- Keyword checker: 检查实际文本中是否存在特定关键词。
- Exact object match: 检查实际对象是否与期望对象完全相等。
- Object set contains: 检查实际对象是否与目标对象集中的某个对象完全相等。
- Object set size range: 检查所提供对象集的大小是否落在期望范围内。
- Integer range: 检查实际值是否落在期望值的范围内。仅支持整数。
- Exact numeric match: 检查两个数字是否完全相等。支持 integer、long、float、double 和 short 类型。
- Exact numeric array match: 检查两个数值数组是否包含相同的元素。支持 integer、long、float、double 和 short 类型。默认情况下比较与顺序有关,但这可以配置。
- Floating-point range: 检查实际值是否落在期望值的范围内。所有数值类型均可作为参数。
- Temporal range: 检查实际值是否落在期望值的范围内。仅支持 Date 和 Timestamp 值。
- Generic exact match: 检查实际值是否与期望值相同。数值类型在比较时会被强制转换(例如,整数可以与相同数值的 double 匹配),日期和时间戳类型也是如此。对象和对象集按引用比较,struct 和 map 按无序键值对比较,list 按有序元素比较,模型按标识符和参数比较。如果你的数据类型存在特定类型的评估器,则应使用它,因为它们提供细粒度的比较选项和更好的类型安全性。
- LLM-as-a-judge: 使用 LLM 来评估用户定义的条件对给定值是否成立。当条件满足时返回 true,否则返回 false。接受任何类型(引用类型除外:对象定位符、对象 RID、对象集或模型)作为实际值。需要以清晰、可验证的断言形式编写的条件参数,以及一个可用于评估的模型。
- ROUGE score: 衡量实际(生成)文本中的措辞与期望(目标)文本的重叠程度,对于摘要和翻译等任务特别有用。返回 precision、recall 和 f-measure,每个值在 0-1 范围内,分数越高表示与目标越接近。
### Custom evaluation functions
自定义评估函数允许你选择之前已发布的函数。这些可以是代码仓库中编写的对象上的函数或其他 AIP Logic 函数。自定义评估函数必须至少返回一个布尔型或数值型指标。它们也可以返回字符串值,这些值会作为调试输出显示在调试视图中,用于诊断目的。一个评估函数也可以通过返回由布尔型或数值型组成的 struct 来返回多个指标。
创建评估套件后,请进一步了解评估套件运行配置。
### 常见问题速答 · FAQ
关于「创建评估套件」,读者最常问的几个问题。
附加目标函数是什么? 一个套件同时评测多个函数。你可以添加额外的目标函数,以使用同一个评估套件测试多个函数。这使你能够一次性针对不同的已发布 Foundry 函数或 Logic 函数运行评估。它对于比较不同实现之间的表现,或在同一批测试用例上评估相似函数非常有用。
添加测试用例是什么? 输入与期望输出的组合。你可以通过手动定义单个测试用例、使用对象集(object set)生成多个测试用例,或在同一个套件中结合两种方式,来为评估套件创建测试用例。这种灵活性使你能够利用现有的对象集,同时按需添加特定的手动测试用例。
评估器是什么? 判定方式:精确匹配、语义比对、自定义函数。评估器是一种用于将受测函数的输出与期望输出进行评估的方法。评估器可以返回简单的 true/false 结果,但也可以产生诸如语义距离之类的数值。没有评估器的评估套件可用于在多种场景中执行函数并手动审查每个输出。
---
## 运行实验:系统对比参数组合
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evals-experiments.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evals/experiments/
- 主题分组:AIP Evals(七)
循序渐进 · AIP 教学 · AIP Evals(七)
# 运行实验:系统对比参数组合
想知道哪个模型性价比最高、哪版提示词效果最好?用实验系统性地跑多个参数组合,而不是靠猜。
## 先记住这几条
① 实验是批量对比 一次跑多组参数,横向比结果。
② 典型问题 哪组模型最省钱且够好、哪版提示词最优。
③ 结论要有数据支撑 LLM 应用调优不能凭感觉。
## 写在前面
系统性地测试多个参数值的不同组合,是评估和优化 LLM 驱动函数的重要一环。你可能希望确定哪些模型表现最好同时成本最低,或者哪些提示词能产生最佳结果。
实验(Experiments)让你能够优化受测函数的性能和成本。你可以使用网格搜索(grid search)在多个独立的评估套件运行中,为 AIP Evals 定义要测试的所有可能组合的参数值。之后,你可以分析实验结果,找出表现最佳的参数值。

> 图:说明实验流程的示意图。
## 配置实验
> 要点:定义要对比的参数组合。
### Prepare your function
在本示例中,我们有一个用于总结文章的 Logic 函数,我们想确定哪种模型和提示词组合表现最好。实验并不限于 Logic 函数。
首先,我们需要将模型和提示词都参数化。这意味着将它们添加为输入,并在 Logic 函数的某个地方使用它们。在本例中,我们想试验提示词措辞上的细微差异,看哪一种能产生最好的摘要。我们将使用 extraPromptContext 来在原始提示词后追加额外的上下文。

> 图:将模型添加为可选输入,并将 extraPromptContext 添加为 Logic 函数的必需输入。
对于模型,我们建议将该变量从 Required 改为 Optional。你还需要配置每个 Use LLM 模块以使用该模型变量。你可以通过选择 UseLLM 模块中的模型选择器,并导航到 Registered 标签页下的模型变量来完成此操作。

> 图:UseLLM 模块中的模型选择器,在 "Registered" 标签页下显示模型变量。
### Enable experiments
将 Logic 函数参数化后,通过在 Run configuration 对话框中打开开关来启用实验。

> 图:在 "Run configuration" 对话框中启用 "Experiments" 开关。
### Define your experiment
你可以为实验命名,以便之后轻松定位结果。接下来,添加 Experiment parameters(实验参数)。这些是你想用不同值进行测试的参数。对于每个参数,你可以指定多个值选项,以在实验中进行探索。这将覆盖评估套件中按测试用例配置的任何现有值。

> 图:带有实验名称和参数输入的 "Run configuration" 对话框。
在该区域的底部,你可以看到将发生多少次评估运行,并打开预览以查看使用网格搜索将在你的实验中测试的所有参数组合。

> 图:总评估运行次数的预览。
## 运行实验
> 要点:批量执行。
要运行实验,请关闭该对话框并选择 Run experiment 选项。
![图]()
## 查看并分析实验结果
> 要点:横向对比读数。
实验完成后,选择侧边面板底部的 Results 选项。这将带你进入 AIP Evals 应用,你可以在其中分析结果。
> AIP Logic 中的 Most recent run 卡片仅显示该集合中最后一次评估运行的结果(在本例中为 6 次运行中的第 6 次)。要查看完整结果,我们建议通过 AIP Evals 访问它们。
![图]()
### Compare runs
在 AIP Evals 中,可以在 Results > Runs 标签页下查看单次评估运行和实验运行。当从 AIP Logic 中的 Results(如上所示)进入时,Runs 表格将自动筛选为刚刚运行的实验。

> 图:Evals 中的 "Runs" 表格,筛选为最新的实验。
Group by 选项允许你选择表格中的某一列对运行进行分组,并查看每个分组的聚合指标。例如,我们可以按模型分组,以便轻松比较每个模型在所有指标上的表现。

> 图:按模型分组以查看聚合指标。
使用表格标题最右侧的列图标来控制表格中显示哪些列。
### Compare test cases
你可以从 Runs 表格中选择最多 4 次运行进行比较,然后选择 View test cases 选项或 Test cases 子标签页,继续深入查看你的结果。

> 图: "View test cases" 选项。
测试用例对比对于调试测试用例输出和指标在多次运行之间如何比较,以及不同参数之间可能存在的性能和成本权衡非常有用。你可以将鼠标悬停在所选运行上,查看所使用的具体参数值,也可以在表格中找到它们。

> 图:悬停在模型提示词实验标签上时看到的实验元数据。
你可以通过将相关的测试用例和/或迭代分组在一起,来改变行的显示方式。
- Group test cases: 将同一测试用例在多次运行中的所有实例合并为一行,而不是在单独的行中显示每个实例。
- Group iterations: 将所有迭代折叠为单个选择器,而不是在单行中显示每个迭代。
列选择器可用于以对你而言有意义的方式隐藏和显示列。例如,如果你想要一个数据密集的指标视图,你可以选择隐藏包含输入和函数输出的列。

> 图:在测试用例表格中隐藏和显示列。
### Debug test cases
将鼠标悬停在某一行上时,会显示 Open 选项,让你能够进一步深入查看并调试该测试用例的执行。

> 图:悬停在某一行上时显示的 "Open" 选项。
这将打开一个抽屉,显示函数执行以及套件上任何评估器的输入、输出和日志。
对比视图将取决于你如何对表格进行分组。当对比运行显示为单独的行时,调试器将仅针对所选行上的那次运行显示。

> 图:测试用例调试器。
### 常见问题速答 · FAQ
关于「运行实验:系统对比参数组合」,读者最常问的几个问题。
配置实验是什么? 定义要对比的参数组合。在本示例中,我们有一个用于总结文章的 Logic 函数,我们想确定哪种模型和提示词组合表现最好。实验并不限于 Logic 函数。
运行实验是什么? 批量执行。要运行实验,请关闭该对话框并选择 Run experiment 选项。
查看并分析实验结果是什么? 横向对比读数。实验完成后,选择侧边面板底部的 Results 选项。这将带你进入 AIP Evals 应用,你可以在其中分析结果。
---
## 为 Logic 函数建立评估套件
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evals-getting-started.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evals/getting-started/
- 主题分组:AIP Evals(二)
循序渐进 · AIP 教学 · AIP Evals(二)
# 为 Logic 函数建立评估套件
Logic 的 Preview 面板适合一次性试跑;但要建立真正的信心,必须拿大量输入去测。这篇是入门路径。
## 先记住这几条
① Preview 只够试跑 手动点几次不等于验证过。
② 要覆盖大量输入 测试用例越多,结论越可靠。
③ 从 Logic 侧边栏起步 评测能力就集成在 Logic 里。
## 写在前面
Logic 的 Preview 面板非常适合一次性测试,但若想对 Logic 函数获得更高的信心,针对大量输入进行测试非常重要。
本教程将带你使用 AIP Evals 为一个简单的 Logic 函数创建评估套件。
## 从 Logic 创建评估套件
> 要点:入口就在 Logic 里,动手第一步。
在本示例中,我们有一个 Logic 函数,它以餐厅评论作为输入,并根据评论情感将其分类为正面或负面。我们希望创建带有评论输入和期望情感输出的测试用例,以验证我们的函数。
保存 Logic 函数后,有几种方式可以创建评估套件:
- 在 Preview 面板中,你可以创建新的评估套件,并通过选择 Add as test case 同时添加第一个测试用例。
- 在 Evals 面板中,你可以选择 Set up tests manually 来创建一个空的评估套件,或者,如果你的 Logic 函数符合条件,选择 Generate evals,让 AIP 为你引导生成有用的测试和评估器。
> 选择 View limitations 可了解 AIP 无法自动生成测试和评估器的情况。如果你的 Logic 函数不符合 AIP 生成 evals 的条件,那么 Generate evals 按钮将被禁用,并显示说明以帮助你理解原因。

> 图:从 AIP Logic 创建你的评估套件。
创建或生成评估套件后,你可以通过在 AIP Evals 面板中选择 Edit tests 来添加或修改测试用例。这将打开测试用例编辑器,你可以在其中为每个测试用例配置输入并保存评估套件。

> 图:向评估套件添加测试用例。
当你在 Preview 面板中选择 Add as test case,或在 Evals 面板中选择 Generate evals 时,AIP 会尝试根据输入参数为你的测试用例提供一个描述性的名称。你也可以选择测试用例名称旁的紫色 AIP 星形图标来生成建议名称。

> 图:生成建议的测试用例名称。
在本示例中,建议名称 Negative Review On Food Quality 比 Test case 1 提供了更多信息:

> 图:建议名称简要描述了测试用例的参数。
添加测试用例后,你可以通过在 Evals 面板中选择 Run evaluation suite 来运行评估套件。这将运行套件中的所有测试用例。套件运行完成后,通过选择 Most recent run 区域中的卡片来查看结果。

> 图:运行评估套件并查看结果
如果你是通过 Evals 面板中的 Set up tests manually,或 Preview 面板中的 Add as test case 创建评估套件,AIP Evals 将输出函数的返回值,但不会提供聚合的表现指标。若要扩展你的评估套件,请添加一个评估器(evaluator),以将 Logic 函数产生的输出与期望值进行比较并计算聚合指标。在本示例中,请使用内置的 Exact string match 评估器。在实践中,根据函数性质的不同,你可能需要使用其他评估器或编写自定义评估器。
要添加评估器,请在测试用例配置标题中选择 + Add,然后选择 Exact string match > Add。这将添加评估器并打开评估器编辑器,你可以在其中将评估器输入映射到函数输出和测试用例列。在这种情况下,将函数输出映射到实际值,并为期望值创建一个新参数。这将向测试用例编辑器添加一个新列,你可以在其中为每个测试用例输入期望的情感。
你可以为每个指标配置目标(objective)。对于布尔型指标,选择 true 还是 false 值被视为通过结果。对于数值型指标,选择更高的值更好还是更低的值更好,并在需要时设置阈值。评估套件将根据这些目标自动为每个测试用例判定 passed 或 failed 状态。

> 图:添加 exact string match 评估器。
保存后,你可以再次运行评估套件,以查看你函数的聚合指标,以及基于你所配置目标得出的每个测试用例的 passed 或 failed 结果。

> 图:使用 string match 评估器查看结果。
你并非每次修改函数时都必须运行整个套件。你可以通过选择侧边栏中测试用例旁的播放图标来运行单个测试用例。这对于调试和快速迭代你的函数非常有用。
创建评估套件后,请进一步了解评估套件运行配置。
---
## 用中间参数评估 block 输出
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evals-intermediate-parameters.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evals/intermediate-parameters/
- 主题分组:AIP Evals(四)
循序渐进 · AIP 教学 · AIP Evals(四)
# 用中间参数评估 block 输出
LLM 函数往往包含多个步骤,只看最终结果可能看不出是哪一步出了问题。这篇讲怎么评测中间 block 的输出。
## 先记住这几条
① 只看终局不够 最终错误可能源于中间某一步。
② 中间输出可单独评 把中间 block 的输出暴露成参数来测。
③ 能定位问题环节 哪一步偏了,一目了然。
## 写在前面
LLM 驱动的功能通常包含多个复杂操作,仅评估最终结果可能不足以判断提示词的表现。
借助 AIP Logic 和 AIP Evals,你可以设置中间参数(intermediate parameters)用于评估。与最终函数输出类似,中间输出可用于设置自动化的评估器,或者仅用于查看结果。如果设置了评估套件结果数据集(results dataset),中间参数的输出值也将被包含其中。
## 配置中间参数
> 要点:把中间 block 的输出暴露出来单独评。
要设置用于评估的中间参数,请按以下步骤操作:
- 选择 AIP Logic 模块上的烧瓶图标,以将该输出暴露为中间参数。
- 在评估器配置面板中选择新的中间参数,以评估该输出。

> 图:设置用于评估的中间参数。
---
## 在指标仪表盘查看结果
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evals-metrics-dashboard.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evals/metrics-dashboard/
- 主题分组:AIP Evals(十)
循序渐进 · AIP 教学 · AIP Evals(十)
# 在指标仪表盘查看结果
把多次运行的结果收拢到一处,用图表和统计呈现,还能比较聚合结果或单个测试用例的表现。
## 先记住这几条
① 仪表盘适合看趋势 比逐条读结果更直观。
② 可比较聚合与个体 整体指标和单用例都能切。
③ 跨运行对比 看改动前后是否真的变好了。
## 写在前面
评估套件运行的指标会被收集到报告中,可在 AIP Evals 指标仪表盘(metrics dashboard)中查看。在这里,你可以查看图表和统计数据,或比较来自评估函数的聚合结果和/或来自单个测试用例的结果。仪表盘视图中不支持指标目标(metric objectives)。

> 图:评估指标仪表盘中的聚合指标视图
要访问仪表盘,请在 Logic 侧边栏的运行结果视图中选择 View metrics dashboard,或在评估套件页面上选择 Run tests 标签页。

> 图:访问指标仪表盘
如需更深入的分析和调试,你可以访问 LLM 轨迹查看器(LLM trace viewer)。导航到 View tests 标签页,然后双击某个测试用例以打开轨迹查看器。在这里,你将能够查看概述函数结果如何计算出来的执行信息。如果你使用的是自定义 LLM 作为评判者的评估器,LLM 轨迹查看器还将包含有关 LLM 评判者决策过程的信息。

> 图:从指标仪表盘导航到 LLM 轨迹查看器。
---
## 评估 Ontology 编辑
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evals-ontology-edits.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evals/ontology-edits/
- 主题分组:AIP Evals(五)
循序渐进 · AIP 教学 · AIP Evals(五)
# 评估 Ontology 编辑
测一个会写 Ontology 的函数,难道每次都要真改数据?不用 —— 每个测试用例在 Ontology 模拟环境里跑,真实数据毫发无损。
## 先记住这几条
① 写入也能安全地测 不用怕污染生产数据。
② 用模拟环境隔离 每个用例跑在自己的沙盒里。
③ 真实 Ontology 保持不变 这点至关重要。
## 写在前面
运行评估套件时,会为每个测试用例执行其 Logic 函数。对于涉及本体(Ontology)编辑的函数(例如创建、编辑或删除对象),每个测试用例都在一个本体模拟环境中执行。这确保了实际本体在测试和评估期间保持不变。
## 针对 Ontology 编辑的自定义评估函数
> 要点:怎么判定写入是否正确。
对于会产生本体编辑结果的 AIP Logic 函数,用户必须用 TypeScript 配置自定义评估函数,或使用中间参数。自定义评估函数必须返回布尔型或数值型。一个评估函数也可以通过返回由布尔型或数值型组成的 struct 来返回多个指标。
在 Evaluations 应用中添加评估函数时,系统会提示你在代码仓库中编写函数,或选择现有的已发布函数。借助下文提供的指南,探索各种类型的本体编辑,并学习如何有效地使用 TypeScript 函数对其进行评估。
### Created objects
在涉及创建对象的本体编辑情形中,所创建的对象仅存在于模拟本体中。因此,这些创建的对象无法直接配置为测试用例参数进行传入。相反,应使用一个可标识的属性来搜索它,并检查其属性。
typescript @Function()
public async checkTicketWasCreated(
expectedRequester: string,
expectedDate: LocalDate,
expectedClassification: string,
): Promise {
const matches = Objects.search().supportTicket()
.filter(ticket => ticket.ticketRequester.exactMatch(expectedRequester))
.filter(ticket => ticket.ticketCreationDate.exactMatch(expectedDate))
.all();
if (matches.length !== 1) {
return false;
}
return matches[0].classification === expectedClassification;
}
### Edited objects
对于对象编辑的输出类型,被编辑的对象已经存在于真实本体中。在模拟本体中,你可以直接将它传入函数并检查其属性,如下所示:
typescript @Function()
public checkTicketClassification(
ticket: SupportTicket,
expectedClassification: string,
): boolean {
return ticket.classification === expectedClassification;
}
### Deleted objects
在涉及删除对象的本体编辑情形中,该对象预期已在模拟本体中被删除,因此它无法被传入评估函数。要验证对象确实已被删除,请传入该对象的一个可标识属性并搜索它,以确保没有结果。
typescript @Function()
public async checkTicketWasDeleted(ticketId: string): Promise {
const count = await Objects.search().supportTicket()
.filter(ticket => ticket.ticketId.exactMatch(ticketId))
.count();
return count === 0;
}
---
## AIP Evals 总览:给 AI 函数做测试
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evals-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evals/overview/
- 主题分组:AIP Evals(一)
循序渐进 · AIP 教学 · AIP Evals(一)
# AIP Evals 总览:给 AI 函数做测试
LLM 的输出是不确定的(non-deterministic),传统单元测试不够用。AIP Evals 是专门为此设计的测试环境:建测试用例、定评估标准、跟历史版本比。
## 先记住这几条
① 解决"不确定"这个根本问题 同一个输入,LLM 每次输出可能不同。
② 五个核心概念 评估套件、目标函数、评估函数、测试用例、指标。
③ 目的是建立信心 有评测才敢把 LLM 函数推上生产。
④ 也能在 AI FDE 里用 通过对话式命令创建和运行评测。
## 写在前面
AIP Evals 是一个测试环境,用于评估 AIP Logic 函数(AIP Logic functions)、AIP Chatbot 函数(AIP Chatbot functions)或代码编写的函数(code-authored functions)的表现。它专门用于帮助你应对 LLM 的非确定性特征。借助 AIP Evals,你可以创建测试用例(test case)、定义评估函数(evaluation function)来衡量表现,并将结果与函数的早期版本进行对比。它使你能够建立必要的信心,从而将 LLM 驱动的函数投入生产环境,或对既有实现进行修改。
你可以使用 AIP Evals 来:
- 创建测试用例并定义评估标准。
- 调试、迭代并改进函数与提示词。
- 对比不同模型在你的函数上的表现。
- 考察多次运行之间的差异。
AIP Evals 也可作为 AI FDE 中的集成工具使用,让你能够通过对话式指令创建并运行评估套件(evaluation suite)。

> 图:Evals 概览
## 核心概念
> 要点:五个术语一次讲清:评估套件、目标函数、评估函数、测试用例、指标。
评估套件(Evaluation suite): 用于对函数表现进行基准测试的测试用例、目标函数(target function)与评估函数的集合。
目标函数(Target function): 被评估的函数。一个套件可以配置为同时测试多个目标函数。
评估函数(Evaluation function): 将目标函数的实际输出与期望输出进行比较或评估时所使用的方法。
测试用例(Test cases): 定义好的输入与期望输出集合,在评估套件运行时被传入评估函数。
指标(Metrics): 评估函数的结果。指标按每个测试用例生成,可以在多次运行之间进行聚合对比或单独对比。
要开始使用,请为逻辑函数创建评估套件,或为通用函数创建评估套件,并进一步了解评估运行配置。
---
## 把运行结果写入数据集
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evals-results-dataset.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evals/results-dataset/
- 主题分组:AIP Evals(八)
循序渐进 · AIP 教学 · AIP Evals(八)
# 把运行结果写入数据集
Evals 界面不是给所有人用的。把结果写进数据集,就能在 Workshop 等应用里跟其他信息一起展示,让领域专家也能看到。
## 先记住这几条
① 结果需要被更多人看到 领域专家未必会用 Evals 界面。
② 写进数据集就能复用 结果成为平台里的一等数据。
③ 可嵌入业务应用 在 Workshop 里与业务信息并列展示。
## 写在前面
根据被评估的函数和工作流,评估套件运行结果可能需要在平台的其他部分中呈现。例如,领域专家可能不够技术化,无法在 AIP Evals 中分析结果,他们可能希望运行数据与其他信息一起显示在专门的 Workshop 应用中。
为满足这一需求,AIP Evals 支持将运行结果写入数据集(dataset)。
当配置了运行结果数据集,且评估套件以项目范围执行模式运行时,该运行产生的所有信息都将自动写入所配置的数据集。这包括函数输出、评估器结果、用户指定和自动捕获的元数据以及错误。基于你所配置目标的每个指标的 passed 和 failed 结果目前尚不支持,并且编辑本体的受测函数不会产生函数输出。
运行结果数据集对于生成数据可以做什么提供了最大的灵活性。使用现有的 Foundry 工具,数据可用于更复杂的计算,例如将其写入对象并在 Workshop 中呈现,或在 Contour 中执行更深入的分析。
要将运行结果写入数据集,评估套件需要以项目范围执行模式运行,并且运行结果数据集需要与评估套件位于同一个项目中。否则,AIP Evals 将无法把数据写入该数据集。
## 配置运行结果数据集
> 要点:把结果写去哪里、怎么写。
要配置运行结果数据集,请按以下步骤操作:
- 打开评估套件页面。
- 在 AIP Logic 中,选择 AIP Logic 侧边栏中的 View。
- 或者,从文件系统中打开该评估套件。
- 在运行历史数据集区域中,选择 Create dataset。
- 定义数据集的名称和保存位置,并确认。
完成这些步骤后,数据集即可使用,以项目范围执行模式运行评估套件将把结果写入该数据集。
如果你移除了某个运行结果数据集,你将无法再次选择它。你需要创建一个新的数据集。

> 图:设置运行结果数据集。
---
## 运行评估套件
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evals-run-suite.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evals/run-suite/
- 主题分组:AIP Evals(六)
循序渐进 · AIP 教学 · AIP Evals(六)
# 运行评估套件
套件可以从多个地方运行:AIP Logic 的 Evals 侧边栏、AIP Evals 应用。可以整跑,也可以只跑单个用例 —— 后者是调试的利器。
## 先记住这几条
① 多个运行入口 Logic 侧边栏 / Evals 应用都能跑。
② 可整跑可单跑 单跑单个用例方便快速迭代。
③ 运行有配置项 决定测什么、怎么测。
## 写在前面
评估套件可以从不同位置运行,包括 AIP Logic 的 Evals 侧边栏和 AIP Evals 应用。你可以选择运行完整的评估套件,或只执行单个测试用例。后者对于调试和快速迭代函数非常有用。
## 完整套件运行
> 要点:所有用例一次性跑完。
在 AIP Logic 中,导航到 AIP Evals 侧边面板并选择 Run evaluation suite。如果你有未保存的更改,则会改为显示 Save and run,以确保在运行评估套件之前保存更改。
或者,你可以从 AIP Evals 应用运行评估套件。要打开该应用,请在 AIP Logic 侧边栏中选择 View,或从文件系统中打开该评估套件。在 Evals 应用中,你可以通过选择右上角的 Run evaluation suite 来运行评估套件。
### Run configuration
运行评估套件时有多个配置选项可用。要访问运行配置选项,请选择 Run evaluation suite 旁的齿轮图标。这将打开一个包含以下选项的对话框:

> 图:AIP Evals 运行配置。
Function to test
评估套件可以针对在 AIP Logic 中编写的函数以及在代码仓库(Code repositories) 中编写的函数运行。取决于该函数的来源,你可以针对函数的不同版本:
- AIP Logic 函数: 最后保存(默认)和已发布的版本。
- 非 AIP Logic 函数: 已发布的版本。
Testing multiple functions
如果你的评估套件配置了多个目标函数,你可以在 AIP Evals 中同时针对多个函数运行评估。选择 Test multiple functions 切换到多目标模式,然后选择要包含在本次运行中的目标。

> 图:多目标函数选择。
> 在多目标模式下运行时,实验配置不可用。
Input mapping
需要提供输入映射,以将评估套件列中的值映射到被评估函数所期望的输入。你将能够选择类型与期望函数输入匹配的套件列。
通常,评估套件列名与函数输入会一致,但这并非必需。
Execution mode
运行评估套件时,你可以在两种执行模式之间选择:User-scoped execution(用户范围执行)和 Project-scoped execution(项目范围执行)。用户范围执行是默认模式,它使用发起运行的用户的权限来执行评估套件。
用户范围执行:
- 套件以用户权限执行。
- 结果仅对你可见,并将在 24 小时后删除。
- 结果将不会持久化到结果数据集中。
项目范围执行 \[Beta]:
> Beta
项目范围执行处于开发的 beta 阶段,可能并非在你的注册环境中可用。功能在活跃开发期间可能会发生变化。如果你在使用此执行模式时遇到问题,请尝试改用用户范围执行来运行评估套件。
- 评估套件以项目范围执行。这意味着在函数或评估器执行期间使用的所有资源都需要导入到同一个项目中。
- 运行结果将对所有拥有项目访问权限的人可见。
- 结果将无限期持久化。
- 如果配置了结果数据集,结果将被写入其中。
Number of iterations
你可以指定每个测试用例应运行的次数。由于 LLM 的非确定性特征,我们建议对 LLM 驱动的函数至少运行测试用例三次。每次迭代的结果会被聚合,以提供函数表现的全面概览。
像 ROUGE score 这类数值评估器中出现高方差,可能表明该测试用例和评估器没有意义,需要进一步改进。
Test parallelization
默认情况下,十个测试用例并行执行。你可以调整并行测试用例执行的数量,以优化评估套件运行的性能。在遇到速率限制时,减少该数量可能是有益的。
Run metadata
除了自动捕获的运行元数据(如 used branch、version 或 model)之外,你还可以向评估套件运行添加自定义元数据。 这些元数据以键值对的形式提供,可用于在评估套件运行历史中区分不同的运行。
### View results
评估套件运行完成后,你可以通过选择 Most recent result 区域中的卡片来查看结果。这将打开结果视图,你可以在其中看到评估套件运行的聚合指标,以及每个单独测试用例的结果。每个指标的 passed 或 failed 状态会根据你所配置的目标(布尔型或数值型、方向、阈值)显示。将鼠标悬停在单个测试用例上时,你将能够看到测试用例结果右下角的调试器按钮。选择它将在一个新标签页中打开该测试用例的调试视图。调试视图将显示该测试用例所执行的 Logic 函数和评估器的各个步骤。
此外,结果视图还提供了通过选择 Click to compare another run 来比较运行的功能。这将在当前运行旁并排打开另一次运行,让你能够比较两次运行的结果。默认情况下,View diff 开关将被启用,从而高亮显示两次运行之间的输出差异。

> 图:比较你的结果。
## 单测试用例执行
> 要点:只跑一条 —— 调试时最有用。
运行单个测试用例时,也会根据你所设置的目标(布尔型或数值型、方向、阈值)显示每个指标的 passed 或 failed 状态。
AIP Logic 中的 AIP Evals 侧边栏提供了一种运行单个测试用例的快捷方式。这在构建你的 Logic 函数时,或在完整评估套件运行后对失败的测试用例进行迭代时特别有用。
要运行单个测试用例,请选择侧边栏中测试用例名称旁的播放图标。这将立即执行该测试用例并打开调试器侧边面板。在这里,你将能够跟踪针对测试用例结果所运行的 Logic 函数和评估器的执行过程。此外,该测试用例将在侧边栏中被标记为已执行。

> 图:执行单个测试用例。
执行后,侧边栏和结果面板将根据你所配置的目标,指示每个指标是通过还是失败。
### 常见问题速答 · FAQ
关于「运行评估套件」,读者最常问的几个问题。
完整套件运行是什么? 所有用例一次性跑完。在 AIP Logic 中,导航到 AIP Evals 侧边面板并选择 Run evaluation suite。如果你有未保存的更改,则会改为显示 Save and run,以确保在运行评估套件之前保存更改。
单测试用例执行是什么? 只跑一条 —— 调试时最有用。运行单个测试用例时,也会根据你所设置的目标(布尔型或数值型、方向、阈值)显示每个指标的 passed 或 failed 状态。
---
## AIP Evolve 总览
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-evolve-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/aip-evolve/overview/
- 主题分组:其他应用(一)
循序渐进 · AIP 教学 · 其他应用(一)
# AIP Evolve 总览
AIP Evolve 负责编排成群的 AI FDE 智能体,用于持续改进 Foundry 里的 AI 系统 —— 从"一个智能体帮你做事"升级为"一群智能体协同优化系统"。
## 先记住这几条
① 编排多个智能体 不是单个,而是成群协同。
② 需要先定义目标 一次"进化"要有明确的目标与目的。
③ 目的是改进 AI 系统 面向系统的持续优化。
## 写在前面
AIP Evolve 负责编排成群的 AI FDE 智能体,以改进 Foundry 中的 AI 系统。你为一次进化(evolution)定义目标、目的、验证策略和限制。随后 AIP Evolve 会启动 AI FDE 来探索并验证可能的改动,并呈现由此产生的提议和智能体活动供审阅。
使用 AIP Evolve 可以迁移模型、降低成本或延迟、提升评估得分,或追求某个自定义目标。
## 要求
> 要点:使用前提。
在使用 AIP Evolve 之前:
- 启用 AIP,并确保你能够访问 AI FDE。
- 在某个 Ontology 中安装 AIP Evolve Marketplace 产品。
- 确保你能够访问目标资源,以及用于验证改动的任何数据或评估套件。
## 示例工作流
> 要点:一次"进化"是怎么跑的。
设想这样一家组织:它使用一个由 AI 驱动的库存分配工作流来解释客户订单并确定如何履约。该组织希望在引入明显回归(regression)的前提下降低该工作流的算力成本。
在 New 标签页中,选择该工作流作为目标,并选择 Optimize cost。对于这次进化,AIP Evolve 被配置为选取 10 个有代表性的测试用例并并排比较输出。智能体可以在最多五次迭代中替换模型并调整提示词。审阅生成的提示词,然后选择 Evolve 打开 AI FDE 并开始进化。

> 图:Review 步骤展示了一个成本优化目标、一个 10 个测试用例的验证策略,以及模型和提示词改动约束。
AIP Evolve 编排智能体来检查工作流、创建测试用例、做出候选改动,并针对基线评估候选输出。打开 Agent graph 可以跟踪这一活动,并查看各智能体的目标、洞察和产物。在此例中,智能体完成了三次迭代。

> 图:展开的智能体图展示了三次编排器迭代,以及负责分析、测试创建、模型替换、评估、提示词工程和提议撰写的专家智能体。
当智能体完成后,打开 Proposal 审阅推荐的改动及支撑证据。在此例中,提议推荐将 GPT-4o 替换为 GPT-5.4 Mini,并为两条提示词添加护栏(guardrails)。基线和候选方案的 10 个测试用例全部通过,而平均算力成本下降了 65%,从每次调用 204.6 算力秒降至 72.4 算力秒。

> 图:提议推荐将 GPT-4o 替换为 GPT-5.4 Mini,并报告算力成本降低 65%,同时 10 个测试用例全部通过。
在接受提议之前,请审阅验证结果、输出比较、置信度评估和局限说明。在适用时,选择 Review in Branching 以在 Global Branching 中检查分支提议。选择 Resume 可通过可选的附加指令在 AI FDE 中继续该进化。
### 常见问题速答 · FAQ
关于「AIP Evolve 总览」,读者最常问的几个问题。
要求是什么? 使用前提。在使用 AIP Evolve 之前。
示例工作流是什么? 一次"进化"是怎么跑的。设想这样一家组织:它使用一个由 AI 驱动的库存分配工作流来解释客户订单并确定如何履约。该组织希望在引入明显回归(regression)的前提下降低该工作流的算力成本。
---
## 开始使用 AIP:学习路径
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-getting-started-with-aip.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/getting-started-with-aip/
- 主题分组:核心平台(三)
循序渐进 · AIP 教学 · 核心平台(三)
# 开始使用 AIP:学习路径
这一篇很短,只回答一个问题:该按什么顺序学 AIP。
## 先记住这几条
① 先补 Foundry 基础 AIP 长在 Foundry 上,不懂平台概念会处处卡壳。
② 官方学习门户 Palantir 提供了体系化的免费课程。
③ 再按角色深入 平台 Q&A、AIP Logic、各应用按需选学。
## 写在前面
为帮助你理解 Foundry 和 AIP 的概念基础,我们建议你学习 Palantir Learning 门户 learn.palantir.com ↗ 上的相关教学内容。其中包括:
- Foundry 与 AIP 企业组织入门 ↗:本课程旨在让你对该平台以及 Palantir 演进数据管理系统的方法形成基础性理解。
- 为 Foundry 与 AIP 界定用例范围 ↗:这门 15 分钟的短课程介绍如何在该平台中界定用例范围并排定优先级。
- 速通:你的第一个 AIP 工作流 ↗:这门动手实践课程将带领你体验在 60–90 分钟内用 AIP 构建一个 AI 助手的过程。课程涵盖如何从 PDF 中提取信息、将数据纳入 Ontology、基于你的知识图谱配置 AIP Chatbot(原名 AIP Agent),以及构建一个可与你的聊天机器人配合使用的交互式应用。
---
## 管理员:LLM 容量管理
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-llm-capacity-management.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/llm-capacity-management/
- 主题分组:核心平台(十二)
循序渐进 · AIP 教学 · 核心平台(十二)
# 管理员:LLM 容量管理
LLM 容量在行业层面是有限资源,所有提供商都会限制账户的最大可用容量。这一篇讲 AIP 如何在组织内分配这份稀缺资源。
## 先记住这几条
① 容量是稀缺的 不是想用多少就有多少。
② 需要组织内分配 不同团队/环境之间如何切分。
③ 超限有降级机制 容量不足时的行为要事先知道。
## 写在前面
LLM 容量在行业层面是一种有限资源,所有提供商(Azure、OpenAI、AWS Bedrock、Google Cloud Vertex 等)都会限制每个账户可用的最大容量。因此,Palantir AIP 遵循 LLM 提供商所设定的市场级约束。业界通用的计量单位是每分钟 token 数(TPM)和每分钟请求数(RPM)。
## 注册容量与速率限制
> 要点:容量和限流的基本机制。
Palantir 为每个注册设定了特定的最大容量,称为「注册级速率限制(enrollment-level rate limits)」。该容量按模型使用 TPM 和 RPM 计量,涵盖你注册上启用的所有提供商的所有模型,包括 GPT、Claude、Gemini、Llama、Mixtral 等。这样一来,每个模型都拥有独立的容量,不受其他模型使用情况的影响。
AIP 中的 LLM 容量在三个层级上进行管理:注册级限制设定总体上限,项目速率限制控制每个项目可以使用多少该容量,用户速率限制则管控未归属于项目的流量中单个用户的消耗量。
默认情况下,所有客户都处于 medium 层级,该层级足够构建原型并扩展到少数用例,即便有数百名用户和大型数据集(例如包含数百万份文档)也是如此。
此外,如果你需要更多容量,AIP 提供了将注册容量从 medium 层级升级到 large 或 XL 层级的选项。如果你不断触及注册速率限制,阻碍了你扩展 AIP 使用,或者预计会增加流水线规模或用户总数,请联系 Palantir 支持。
注册限制现在显示在 Resource Management 应用的 AIP rate limits 标签页中,同时显示注册层级。

> 图:Resource Management 应用中的 AIP rate limits 概览展示了注册限制,旁边是项目与用户速率限制管理卡片。
借助注册层级(尤其是 XL 层级),AIP 提供了足够的容量来构建大规模工作流。这些层级已为数百家大规模使用 LLM 的 Palantir 客户提供了足够的容量,并且我们会继续提高这些限制。
关于按模型和层级划分的完整注册速率限制明细,请参阅 LLM 注册速率限制。
## AIP 用量与限制
> 要点:用量如何受限。
注册管理员可以导航到 Resource Management 应用中的 AIP usage & limits 页面,以便:
- 查看用量:查看你注册中所有项目和资源对 Palantir 提供的所有模型的 LLM token 与请求用量。
- 管理速率限制:管理你注册的项目与用户速率限制。
- 项目速率限制: 按模型配置给定项目内所有资源在任意一分钟合计可以使用的 TPM 和 RPM 的最大百分比。
- 用户速率限制: 按模型配置任意单个用户在任意一分钟可以使用的最大 TPM 和 RPM。
### View usage
View usage 标签页让你可以洞察你注册中所有项目、资源和用户对 Palantir 提供的所有模型的 LLM token 与请求用量。管理员可以使用此视图来更好地管理 LLM 容量并处理速率限制。

> 图:AIP token 用量视图页面。
此视图让你可以:
- 查看跨所有模型的聚合用量,以及按单个模型划分的用量明细。
- 按分钟追踪 token 与请求用量,因为 LLM 容量是在每分钟 token(TPM)和每分钟请求(RPM)层级上管理的。
- 一次下钻到单个模型,因为容量是按每个模型分别管理的。
- 既查看注册用量总览,也放大到项目级用量,因为如前所述,LLM 容量既有注册级限制,也有每个项目的项目级限制。
- 查看每个模型的用户归属用量总计。
- 查看速率限制阈值。 右上角的开关会通过显示虚线来可视化何时触及项目或注册限制。限制因模型和项目而异。会显示两条速率限制线:注册/项目限制,以及「批量限制(batch limit)」——后者被限制为特定项目和整个注册总容量的 80%。可在下文进一步了解优先处理交互式查询。
- 下钻到特定时间范围,最长两周数据,最小到分钟级。用户可以通过左侧边栏的日期范围筛选器,或在图表上直接拖拽选择时间范围,来下钻到特定时间段。当时间范围短于 6 小时时,图表会包含按项目(在注册层级)或按资源(在项目层级)的分段。
- 以表格查看用量总览。 图表下方,表格包含按项目(或筛选到单个项目时按资源)聚合的 token 与请求数。表格会受所有筛选器影响(时间范围、模型、若应用了项目筛选器)。
此视图并未针对 LLM 用量的成本管理进行优化。了解如何通过 Analysis 标签页查看已启用 AIP 的注册上的 LLM 成本。
### Taking action based on AIP usage
如果你在注册或项目层级触及速率限制,可以考虑采取以下任一措施:
- 调整项目限制,为可能占满你注册容量的某个资源或项目设定用量上限。
- 追踪交互式用量,确保它没有被流水线施加速率限制。如果有,你可以在项目层级限制这些流水线,或者把该资源迁移到一个限制更高的独立项目中。
- 将构建调度到一天中的不同时间,将大型构建安排在周末——尽可能避免同时运行多个大型构建,并在可能时将常规构建安排在不同时间或频率,以避免冲突。
- 将你的工作流切换到你的注册当前未使用、因而有充裕容量的另一个模型。
- 申请升级到更大的层级。
## 管理速率限制
> 要点:怎么调整与分配。
LLM 请求以两种方式之一进行归属,且两者互斥——每个请求都恰好受其中一种限制类型管控:
- 项目归属的请求(Project-attributed requests) 受注册限制和相关项目限制管控。这涵盖请求源自已配置项目资源的工作流(例如 Pipeline Builder 流水线、AIP Logic、Automate、Chatbot Studio 和 Workshop 应用)。按用户限制不适用于这些请求。
- 用户归属的请求(User-attributed requests) 受注册限制和调用用户的按用户限制管控。这涵盖请求直接源自用户会话而非项目资源的工作流(例如 AI FDE、AIP Assist、AIP Analyst,Pipeline Builder Explain 和 Generate 等原生助手功能,以及连接到 Foundry 提供的模型的 Continue(VS Code)和 Claude Code 等 IDE 集成)。

> 图:Manage rate limits 标签页展示了管理项目速率限制和用户速率限制的选项。
### Manage project rate limits
在 Resource Management 中 AIP usage & limits 页面下的 Manage rate limits 标签页上,管理员可以灵活地为 AIP 中宏大的用例最大化生产用例的 LLM 使用,同时限制或禁止实验性项目占满整个注册容量。注册管理员可以按模型配置给定项目内所有资源在任意一分钟合计可以使用的 TPM 和 RPM 的最大百分比。

> 图:在 Resource Management 应用的 AIP rate limits 页面查看你各模型的速率限制。
默认情况下,所有项目都会被赋予一个用于运行的特定限制。管理员可以创建额外的项目限制、定义每个限制包含哪些项目,以及可以使用注册容量的百分比。
Model overrides
在每个项目限制内,你可以配置针对特定模型的覆盖设置,以在模型层级进一步控制容量分配。模型覆盖允许你为单个模型设置不同的百分比限制,从而覆盖基础项目限制。这些覆盖仅适用于该特定项目限制所包含的项目(对于默认限制,则适用于所有未分配到其他手动创建的项目限制的项目)。
模型覆盖支持更细粒度的容量管理,并允许你创建模型「允许列表」;你可以将基础项目限制设为 0%,然后仅为已批准的模型添加带有特定百分比的模型覆盖。你也可以通过将某个模型的覆盖限制百分比设为 0% 来明确禁止该模型。
例如,以下步骤说明了如何将某个项目限制中的项目限定为只能使用 Claude Sonnet 4 和 GPT-4.1:
- 将基础项目限制设为 0%。
- 为 Claude Sonnet 4 添加一个 30% 的模型覆盖。
- 为 GPT-4.1 添加一个 25% 的模型覆盖。
该一项目限制中所有项目里的用户将只能在其分配到的容量限制内访问指定的模型。

> 图:添加模型覆盖以控制项目上的模型级用量。
### User rate limits
按用户速率限制管控单个用户可用于用户归属请求的容量。它们确保没有任何单个用户能够通过交互式工作流耗尽注册中某个模型的全部容量。
用户速率限制在 Resource Management 中 AIP usage & limits 页面下的 Manage rate limits 标签页上管理。注册管理员可以查看默认的按用户限制、创建用户组覆盖,以及配置按模型的覆盖。

> 图:用户速率限制配置页面展示了默认按用户限制与用户组覆盖设置。
Default per-user limits
每个模型的默认按用户限制显示在 Resource Management 的 User rate limits 标签页中,或注册速率限制表的 Per-user Limits 列中。这些默认值由 Palantir 设定,适用于所有用户,除非被管理员在 User rate limits 标签页中覆盖。 每个模型的默认按用户限制显示在 Resource Management 的 user rate limits 标签页中,或注册速率限制表的 Per-user Limits 列中。这些默认值由 Palantir 设定,适用于所有用户,除非被管理员在 user rate limits 标签页中覆盖。
> 我们建议使用 Palantir 的默认用户速率限制。我们定义这些默认值是为了平衡以下两点:(a)保护注册限制不被单个用户占满;(b)使用户能够高效使用 Foundry 中最新的 AIP 工具,最大化其生产力。如果管理员选择为所有模型设置新的自定义限制,那么在新模型发布时应重新审视该限制,以确保不会无意中限制了自己的用户。
Per-user overrides
注册管理员可以覆盖按用户默认值,为特定用户(作为特定用户组的一部分)授予不同的按用户限制。这对于高级用户、交互式应用背后的服务账户,或用户归属工作流需要持续高吞吐的团队很有用,且无需提高注册的整体容量层级。它也是一种工具,可以保护生产工作流中使用的某个模型的容量,避免被用户意外占满。
按用户覆盖可以用以下两种方式之一表示:
- 注册限制的百分比: 介于 1 到 100 之间的值,表示注册级速率限制的百分比。例如,如果某个注册为某个模型设有 400 万 TPM,而管理员配置了 25% 的覆盖,那么该覆盖涵盖的每个用户都会获得 100 万 TPM 的有效限制。
- 绝对 TPM 和 RPM 值: 显式的每分钟 token 数和每分钟请求数。当基于百分比的方式不符合所需限制时,这为管理员提供了精确的控制。
配置覆盖后,它会取代已发布的按用户默认值;它不会与默认值混合,也不会以默认值为下限。
为某个模型设置低于 50,000 TPM 或 10 RPM 的按用户限制,可能会破坏受影响用户的某些 AIP 功能。当配置的限制低于这些建议最低值时,覆盖表单会显示警告。
Levels of override
按用户覆盖可以在三个层级上配置,按具体程度依次应用:
- 默认按用户覆盖: 一个适用于注册中每个用户、跨所有模型的单一百分比。它会成为新的基线,取代 Palantir 已发布的按模型默认值。
- 按模型覆盖: 在默认值之上,为一个或多个特定模型设置不同的百分比或绝对限制。按模型覆盖允许管理员提高或降低单个模型的按用户限制,而无需在整个目录范围内更改。
- 用户组覆盖: 针对一个或多个 Foundry 用户组的覆盖。用户组覆盖定义自己的默认百分比,并可选地定义自己的按模型覆盖(百分比或绝对值)。当某个用户属于被某个覆盖涵盖的组时,将使用该组的配置,而非注册范围内的按用户默认值。
如果任何层级都未配置覆盖,则使用该模型已发布的按用户默认值。

> 图:用户速率限制覆盖配置允许管理员为特定用户组设置百分比或绝对限制覆盖。
How user-group overrides resolve
用户组覆盖适用于一组具名的 Foundry 用户组。每个覆盖都有一个名称、一个可选描述、一个可选默认百分比,以及一组可选的按模型限制。当某个用户属于该覆盖中列出的任何一个组时,就会与该覆盖匹配。
如果某个用户属于被多个覆盖涵盖的组,则对该用户和该模型而言,这些覆盖中产生的最高的限制胜出。这使覆盖具有可加性和可预测性:通过某个组授予用户更高的限制,不会因为该用户同时属于另一个配置较低的组而被悄然取消。例如,假设某个注册的默认用户限制为 40%。用户 A 属于两个不同的用户限制覆盖下的两个组,其中一个将用户限制定义为 10%,另一个定义为注册容量的 35%。用户 A 将拥有 35% 的用户限制,即这些覆盖中最高的那个。
当某个用户组覆盖被移除时,受影响组的成员会回退到注册范围内的按用户配置。如果该注册自身没有按用户配置,则回退到已发布的按用户默认值。
### AIP reserved capacity
预留容量(Reserved capacity)是 Resource Management 中的一款 AIP LLM 容量管理工具。预留容量保证为某个模型保留一定份额的每分钟 token(TPM)和每分钟请求(RPM)。请将其用于关键的生产工作流,这些工作流绝不能因项目速率限制、注册限制或其他资源对同一资源池的争用而被降速。

> 图:某个特定模型已分配的预留容量示例,展示了已分配预留容量的项目以及这些项目之间的百分比分布。
Key features
- 预留容量在模型层级配置,从该模型可用的总容量中预留特定数量的 TPM 和 RPM。
- 可以为项目分配总预留容量的某个百分比,让你能够优先保障最关键资源的容量,并自定义 LLM 分配以符合你的组织需求。
- 当预留容量用尽时,被分配到该项目会自动回退到由现有项目和注册限制所管控的共享容量。
Availability and costs
预留容量适用于所有模型。你最多可以预留某个模型总容量的 50%。如果总容量之后下降,你的预留量会得到保留,最多为新的总容量的 95%。
根据 AIP 过去一年的表现,预留容量足以实现 99.9% 的正常运行时间。我们无法保证 100% 的容量可用性,但根据过去一年的使用模式,超过 99% 的 LLM 请求失败是由注册和项目速率限制导致的。这些问题可以通过预留容量工具来解决和处理。
作为一项服务,预留容量不额外收费;额外费用将取决于额外的 token 用量,与 AIP 中所有其他 LLM 用法一样。这一点在未来可能会因新用例或特定模型而发生变化。如果此政策变更,我们不会针对使用预留容量对现有工作流进行追溯收费;这些工作流将继续仅根据额外的 token 用量产生费用。
拥有 resource management administrator 权限的用户可以为某个模型预留容量,并将其分配到特定项目。
Example usage
考虑以下示例,以进一步理解预留容量的用法:
- 你的注册为某个模型拥有 100 万 TPM 的容量。对于一个包含生产应用的项目,该应用的默认限制为注册容量的 70%,即 70 万 TPM。
- 要提升这个生产应用的容量,你可以通过提高项目速率限制,将所属项目的容量增加到注册容量的 100%,即 100 万 TPM。
- 尽管该应用的限制现在为注册限制的 100%,但这个应用仍在与其他资源争夺这份共享容量。你可以在 Resource Management 应用的 AIP usage & limits 部分的 View usage 标签页中识别出竞争资源。然后,你可以调整竞争资源的调度时间,或将资源迁移到不同的模型上。
- 为确保这个生产应用即便是在你优化了调度和模型使用之后仍能获得所需容量,你可以使用预留容量。假设你从可用的 100 万 TPM 中预留 25 万 TPM,剩下 75 万 TPM 作为共享容量。
- 你可以将这部分预留容量分配给关键资源,例如你的生产应用。该应用会先使用其预留的 25 万 TPM。在该容量用尽后,它会使用 75 万 TPM 的共享容量,并在其中与其他资源竞争。注册总量仍为 100 万 TPM:25 万 TPM 专为该应用预留,其余 75 万 TPM 在所有资源之间共享。
## 查看注册下的 LLM 成本
> 要点:成本可见性。
使用 Analysis 页面查看你已启用 AIP 的注册上的 LLM 使用成本。
在 Analysis 页面中,选择 Filter by source: All LLMs 和 Group by source。这将生成一张按模型分段的每日 LLM 成本图表。

> 图:Resource Management 的 Analysis 标签页允许你将 LLM 筛选进视图,以查看按模型分段的每日 LLM 成本图表。
## 交互式查询的优先级
> 要点:容量紧张时谁先跑。
通常,AIP 会优先处理交互式请求,而非带有批量请求的流水线。交互式查询定义为用户与 LLM 的任何实时交互,例如 Workshop、Chatbot Studio、AIP Logic LLM board 中的预览,以及 Pipeline Builder LLM 节点中的预览。批量查询定义为在用户不期望立即响应的情况下发送的大量请求,例如 Transforms 流水线、Pipeline Builder、Automate(用于 Logic)。
此原则目前保证在注册和项目层级始终为交互式查询预留 20% 的容量。这意味着对于某个模型 100,000 TPM 的容量,在任意给定分钟,最多只能有 80,000 TPM 用于流水线,而至少有 20,000 TPM(最多可达 100,000 TPM)可用于交互式查询。
## 常见问题
> 要点:容量相关的常见疑问。
### What is an example of how project-level and user-level rate limits are expected to be used?
考虑以下示例:
- 某个注册在生产环境中只有一个 AIP 用例,因此包含该用例的项目被移到「Production」限制之下,以访问最多 100% 的注册限制。
- 除了这个生产用例之外,还有一个处于测试阶段的第二用例需要考虑。这个测试阶段的用例应该能够运行测试,而不会占用整个生产用量。可以将这个用例加入一个「Testing」限制,最多可用 30% 的容量。「Production」限制则降低到 90%,以确保始终有一些容量可用于测试。
- 在上述用例之外,我们在生产中增加第二个用例。然而,与第一个使用 GPT-5 的用例不同,这个用例使用 Claude Sonnet 4.6。我们可以安全地将这个新用例加入「Production」限制,与第一个生产用例并列。
- 同一个注册希望让一组用户能够试验 LLM。注册管理员将两个项目加入一个「Experimentation」限制,最多可用 20% 的容量。
- 从技术上讲,测试项目和这两个实验项目合计最多可以消耗 70% 的容量,但历史数据表明实际用量通常低于此值。
- 最后,这个注册希望保护其生产用例不被单个用户占用。管理员为 GPT-5 和 Claude Sonnet 4.6 设置覆盖,将默认用户速率限制改为注册容量的 10%,同时提高 Claude Opus 4.6 和 GPT-5.4 的容量。此外,他们将用户主文件夹的容量设为 0%(以抑制在私有文件夹中构建、鼓励协作),并在 Control Panel AIP 设置中为这些指定用户授予 LLM builder 权限。
### Why is the percent enforced on each project in a limit category rather than shared across projects and users?
- 多个项目和资源之所以可以共享同一个 100% 容量,是因为基于过去一年多来数百家客户的历史 LLM 使用模式,大多数项目和资源并不会调用 LLM。因此,多个资源可以共享同一个 100% 容量。
- 如果某个限制类别中的所有项目都共享同一使用百分比,那就会实施用量的硬性上限。然而,基于现有使用情况,这对 99.9% 的情况来说都不合理。多个资源在同一分钟使用最大容量的情况非常罕见,即使发生,请求也会重试直到成功。
### Why are there AIP usage limits?
- 首先,不同提供商在 TPM、RPM 和区域可用性方面的供给存在显著差异。虽然 AIP 确实利用了所有提供商的容量,但 Palantir 无法绕开各个云服务提供商施加的限制。
- 除此之外,与大多数提供商的常见供给相比,Palantir 提供给客户的 LLM 容量具有更高的合规要求门槛。Palantir 保证零数据留存(ZDR)以及对数据路由到特定区域的控制(地理限制)。
- 大多数提供商,即 Azure OpenAI、AWS Bedrock、GCP Vertex 和 Palantir 托管的模型,都支持地理限制,但对于地理受限的请求,它们能保证的 LLM 容量也更小。其他提供商,例如 OpenAI direct、Anthropic direct 和 xAI,则在较少的地区提供其模型。
- 客户在 Control Panel 的 AIP Settings 下启用的模型提供商越多,所获得的容量就越高。
- 我们为用量水平更高的客户提供升级到容量更大的更大层级的选项。
- 没有地理限制的 AIP 客户可以使用更大的容量池。
- 某些模型在某些地区仍未广泛可用。有时 Palantir 能提前获得它们,但这并非总能做到。
- 某些能力仍然不可用,例如批量 API。批量 API 支持在 24 小时内处理数十亿 token,但需要在此期间存储数据,这不符合 Palantir 的合规要求。
- 如上所述,我们的 medium 到 XL 层级对于大规模生产工作流已经足够。请联系 Palantir 支持以更改你的层级。
### What are the biggest obstacles to solving the capacity problem?
- 地理限制是容量问题最强的成因。如果你的注册受地理限制,而你在法律层面能够移除地理限制,你应当与你的 Palantir 团队合作来完成这一点。
- 新模型在早期阶段通常容量有限。
- 对于运行在数百万乃至数千万条目上的大型流水线,容量问题要困难得多。
### 常见问题速答 · FAQ
关于「管理员:LLM 容量管理」,读者最常问的几个问题。
注册容量与速率限制是什么? 容量和限流的基本机制。Palantir 为每个注册设定了特定的最大容量,称为「注册级速率限制(enrollment-level rate limits)」。
AIP 用量与限制是什么? 用量如何受限。注册管理员可以导航到 Resource Management 应用中的 AIP usage & limits 页面,以便。
管理速率限制是什么? 怎么调整与分配。LLM 请求以两种方式之一进行归属,且两者互斥——每个请求都恰好受其中一种限制类型管控。
查看注册下的 LLM 成本是什么? 成本可见性。使用 Analysis 页面查看你已启用 AIP 的注册上的 LLM 使用成本。
---
## 管理员:LLM 注册速率限制
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-llm-enrollment-rate-limits.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/llm-enrollment-rate-limits/
- 主题分组:核心平台(十三)
循序渐进 · AIP 教学 · 核心平台(十三)
# 管理员:LLM 注册速率限制
这一篇是纯数值参照表:各注册层级在商业环境与政府环境下的 TPM(每分钟 token 数)与 RPM(每分钟请求数)上限。
## 先记住这几条
① 限制按注册层级划分 不同档位的配额不同。
② 双指标:TPM 与 RPM token 速率和请求数速率都要满足。
③ 商业与政府环境不同 USG 环境有独立的一套数值。
## 写在前面
下表包含商业环境和美国政府(USG)环境中各注册层级的每分钟 token 数(TPM)和每分钟请求数(RPM)注册限制。对于同时启用 Azure 和 OpenAI 的注册,Azure 和 OpenAI 的注册限制将比下表所示翻倍。此外,对于地理限制在单个区域的注册,在 Large 和 X-large 层级下,TPM 和 RPM 可能低于表中所示值。
> 如果启用了多个后端,速率限制为所有后端的总和。
模型名称 模型后端 按用户限制 Small 层级 Medium 层级 Large 层级 XLarge 层级 Claude Haiku 4.5 Anthropic 1,000,000 TPM
100 RPM 600,000 TPM
600 RPM 1,500,000 TPM
750 RPM 2,000,000 TPM
875 RPM 2,500,000 TPM
1,000 RPM Claude Haiku 4.5 Amazon Bedrock 1,000,000 TPM
100 RPM 200,000 TPM
150 RPM 1,100,000 TPM
300 RPM 2,600,000 TPM
600 RPM 5,100,000 TPM
1,100 RPM Claude Haiku 4.5 Azure 1,000,000 TPM
100 RPM 550,000 TPM
550 RPM 5,000,000 TPM
5,000 RPM 7,500,000 TPM
7,500 RPM 10,000,000 TPM
10,000 RPM Claude Haiku 4.5 Google Vertex 1,000,000 TPM
100 RPM 100,000 TPM
50 RPM 4,000,000 TPM
2,000 RPM 6,000,000 TPM
3,000 RPM 8,000,000 TPM
4,000 RPM Claude Haiku 4.5 Google Vertex (USG) 1,000,000 TPM
100 RPM 100,000 TPM
50 RPM 4,000,000 TPM
2,000 RPM 6,000,000 TPM
3,000 RPM 8,000,000 TPM
4,000 RPM Claude Opus 4.1 Amazon Bedrock 400,000 TPM
5 RPM 100,000 TPM
25 RPM 500,000 TPM
100 RPM 1,000,000 TPM
150 RPM 2,000,000 TPM
200 RPM Claude Opus 4.1 Google Vertex 400,000 TPM
5 RPM 100,000 TPM
25 RPM 400,000 TPM
100 RPM 600,000 TPM
150 RPM 800,000 TPM
200 RPM Claude Opus 4.5 Anthropic 1,000,000 TPM
100 RPM 600,000 TPM
525 RPM 1,500,000 TPM
700 RPM 2,000,000 TPM
800 RPM 2,500,000 TPM
900 RPM Claude Opus 4.5 Amazon Bedrock 1,000,000 TPM
100 RPM 100,000 TPM
25 RPM 1,000,000 TPM
100 RPM 2,000,000 TPM
200 RPM 4,000,000 TPM
400 RPM Claude Opus 4.5 Azure 1,000,000 TPM
100 RPM 550,000 TPM
550 RPM 1,500,000 TPM
600 RPM 2,500,000 TPM
700 RPM 3,500,000 TPM
800 RPM Claude Opus 4.5 Google Vertex 1,000,000 TPM
100 RPM 100,000 TPM
25 RPM 1,000,000 TPM
100 RPM 1,500,000 TPM
150 RPM 2,000,000 TPM
200 RPM Claude Opus 4.5 Google Vertex (USG) 1,000,000 TPM
100 RPM 100,000 TPM
25 RPM 1,000,000 TPM
100 RPM 1,500,000 TPM
150 RPM 2,000,000 TPM
200 RPM Claude Opus 4.6 Anthropic 1,500,000 TPM
150 RPM 100,000 TPM
10 RPM 1,000,000 TPM
200 RPM 1,500,000 TPM
300 RPM 2,000,000 TPM
400 RPM Claude Opus 4.6 Amazon Bedrock 1,500,000 TPM
150 RPM 200,000 TPM
20 RPM 3,000,000 TPM
300 RPM 4,000,000 TPM
400 RPM 6,000,000 TPM
600 RPM Claude Opus 4.6 Azure 1,500,000 TPM
150 RPM 550,000 TPM
550 RPM 1,500,000 TPM
600 RPM 2,500,000 TPM
700 RPM 3,500,000 TPM
800 RPM Claude Opus 4.6 Google Vertex 1,500,000 TPM
150 RPM 200,000 TPM
25 RPM 5,000,000 TPM
2,000 RPM 8,000,000 TPM
3,000 RPM 10,000,000 TPM
4,000 RPM Claude Opus 4.6 Google Vertex (USG) 1,500,000 TPM
150 RPM 200,000 TPM
25 RPM 5,000,000 TPM
2,000 RPM 8,000,000 TPM
3,000 RPM 10,000,000 TPM
4,000 RPM Claude Opus 4.7 Anthropic 1,500,000 TPM
150 RPM 100,000 TPM
10 RPM 1,000,000 TPM
200 RPM 1,500,000 TPM
300 RPM 2,000,000 TPM
400 RPM Claude Opus 4.7 Amazon Bedrock 1,500,000 TPM
150 RPM 200,000 TPM
20 RPM 3,000,000 TPM
300 RPM 4,000,000 TPM
400 RPM 6,000,000 TPM
600 RPM Claude Opus 4.7 Azure 1,500,000 TPM
150 RPM 50,000 TPM
50 RPM 1,000,000 TPM
100 RPM 2,000,000 TPM
200 RPM 3,000,000 TPM
300 RPM Claude Opus 4.7 Google Vertex 1,500,000 TPM
150 RPM 200,000 TPM
25 RPM 5,000,000 TPM
2,000 RPM 8,000,000 TPM
3,000 RPM 10,000,000 TPM
4,000 RPM Claude Opus 4.7 Google Vertex (USG) 1,500,000 TPM
150 RPM 200,000 TPM
25 RPM 5,000,000 TPM
2,000 RPM 8,000,000 TPM
3,000 RPM 10,000,000 TPM
4,000 RPM Claude Opus 4.8 Anthropic 1,500,000 TPM
150 RPM 100,000 TPM
10 RPM 1,000,000 TPM
200 RPM 1,500,000 TPM
300 RPM 2,000,000 TPM
400 RPM Claude Opus 4.8 Amazon Bedrock 1,500,000 TPM
150 RPM 200,000 TPM
20 RPM 3,000,000 TPM
300 RPM 4,000,000 TPM
400 RPM 6,000,000 TPM
600 RPM Claude Opus 4.8 Amazon Bedrock (USG) 1,500,000 TPM
150 RPM 100,000 TPM
25 RPM 2,500,000 TPM
1,250 RPM 5,000,000 TPM
2,500 RPM 7,500,000 TPM
3,750 RPM Claude Opus 4.8 Azure 1,500,000 TPM
150 RPM 50,000 TPM
50 RPM 1,000,000 TPM
100 RPM 2,000,000 TPM
200 RPM 3,000,000 TPM
300 RPM Claude Opus 4.8 Google Vertex 1,500,000 TPM
150 RPM 200,000 TPM
25 RPM 5,000,000 TPM
2,000 RPM 8,000,000 TPM
3,000 RPM 10,000,000 TPM
4,000 RPM Claude Opus 4.8 Google Vertex (USG) 1,500,000 TPM
150 RPM 200,000 TPM
25 RPM 5,000,000 TPM
2,000 RPM 8,000,000 TPM
3,000 RPM 10,000,000 TPM
4,000 RPM Claude Opus 5 Anthropic 1,500,000 TPM
150 RPM 100,000 TPM
10 RPM 1,000,000 TPM
200 RPM 1,500,000 TPM
300 RPM 2,000,000 TPM
400 RPM Claude Opus 5 Amazon Bedrock 1,500,000 TPM
150 RPM 200,000 TPM
20 RPM 3,000,000 TPM
300 RPM 4,000,000 TPM
400 RPM 6,000,000 TPM
600 RPM Claude Opus 5 Azure 1,500,000 TPM
150 RPM 50,000 TPM
50 RPM 1,000,000 TPM
100 RPM 2,000,000 TPM
200 RPM 3,000,000 TPM
300 RPM Claude Opus 5 Google Vertex 1,500,000 TPM
150 RPM 200,000 TPM
25 RPM 5,000,000 TPM
2,000 RPM 8,000,000 TPM
3,000 RPM 10,000,000 TPM
4,000 RPM Claude Opus 5 Google Vertex (USG) 1,500,000 TPM
150 RPM 200,000 TPM
25 RPM 5,000,000 TPM
2,000 RPM 8,000,000 TPM
3,000 RPM 10,000,000 TPM
4,000 RPM Claude Sonnet 4 Google Vertex (USG) 400,000 TPM
25 RPM 100,000 TPM
25 RPM 250,000 TPM
50 RPM 375,000 TPM
75 RPM 500,000 TPM
100 RPM Claude Sonnet 4.5 Anthropic 1,000,000 TPM
100 RPM 600,000 TPM
525 RPM 1,500,000 TPM
700 RPM 2,000,000 TPM
800 RPM 2,500,000 TPM
900 RPM Claude Sonnet 4.5 Amazon Bedrock 1,000,000 TPM
100 RPM 200,000 TPM
125 RPM 1,100,000 TPM
300 RPM 4,100,000 TPM
600 RPM 8,100,000 TPM
1,100 RPM Claude Sonnet 4.5 Amazon Bedrock (USG) 1,000,000 TPM
100 RPM 100,000 TPM
25 RPM 5,000,000 TPM
2,500 RPM 7,500,000 TPM
3,750 RPM 10,000,000 TPM
5,000 RPM Claude Sonnet 4.5 Azure 1,000,000 TPM
100 RPM 550,000 TPM
550 RPM 1,500,000 TPM
600 RPM 2,500,000 TPM
700 RPM 3,500,000 TPM
800 RPM Claude Sonnet 4.5 Google Vertex 1,000,000 TPM
100 RPM 100,000 TPM
25 RPM 1,000,000 TPM
500 RPM 1,500,000 TPM
750 RPM 2,000,000 TPM
1,000 RPM Claude Sonnet 4.5 Google Vertex (USG) 1,000,000 TPM
100 RPM 100,000 TPM
25 RPM 500,000 TPM
500 RPM 750,000 TPM
750 RPM 1,000,000 TPM
1,000 RPM Claude Sonnet 4.6 Anthropic 1,000,000 TPM
100 RPM 600,000 TPM
510 RPM 1,500,000 TPM
700 RPM 2,000,000 TPM
800 RPM 2,500,000 TPM
900 RPM Claude Sonnet 4.6 Amazon Bedrock 1,000,000 TPM
100 RPM 300,000 TPM
120 RPM 3,000,000 TPM
750 RPM 6,000,000 TPM
1,500 RPM 9,000,000 TPM
2,250 RPM Claude Sonnet 4.6 Azure 1,000,000 TPM
100 RPM 550,000 TPM
550 RPM 1,500,000 TPM
600 RPM 2,500,000 TPM
700 RPM 3,500,000 TPM
800 RPM Claude Sonnet 4.6 Google Vertex 1,000,000 TPM
100 RPM 200,000 TPM
20 RPM 4,000,000 TPM
2,000 RPM 6,000,000 TPM
3,000 RPM 8,000,000 TPM
4,000 RPM Claude Sonnet 4.6 Google Vertex (USG) 1,000,000 TPM
100 RPM 100,000 TPM
25 RPM 4,000,000 TPM
2,000 RPM 6,000,000 TPM
3,000 RPM 8,000,000 TPM
4,000 RPM Claude Sonnet 5 Anthropic 1,000,000 TPM
100 RPM 600,000 TPM
510 RPM 1,500,000 TPM
700 RPM 2,000,000 TPM
800 RPM 2,500,000 TPM
900 RPM Claude Sonnet 5 Amazon Bedrock 1,000,000 TPM
100 RPM 300,000 TPM
120 RPM 3,000,000 TPM
750 RPM 6,000,000 TPM
1,500 RPM 9,000,000 TPM
2,250 RPM Claude Sonnet 5 Amazon Bedrock (USG) 1,000,000 TPM
100 RPM 100,000 TPM
25 RPM 1,000,000 TPM
500 RPM 2,000,000 TPM
1,000 RPM 3,000,000 TPM
1,500 RPM Claude Sonnet 5 Azure 1,000,000 TPM
100 RPM 1,050,000 TPM
1,050 RPM 2,500,000 TPM
1,250 RPM 5,000,000 TPM
2,500 RPM 7,500,000 TPM
3,750 RPM Claude Sonnet 5 Google Vertex 1,000,000 TPM
100 RPM 200,000 TPM
25 RPM 4,000,000 TPM
2,000 RPM 6,000,000 TPM
3,000 RPM 8,000,000 TPM
4,000 RPM Claude Sonnet 5 Google Vertex (USG) 1,000,000 TPM
100 RPM 200,000 TPM
25 RPM 4,000,000 TPM
2,000 RPM 6,000,000 TPM
3,000 RPM 8,000,000 TPM
4,000 RPM Gemini 3 Flash (Preview) Google Vertex 2,000,000 TPM
400 RPM 600,000 TPM
600 RPM 6,500,000 TPM
1,400 RPM 9,500,000 TPM
2,300 RPM 12,500,000 TPM
3,500 RPM Gemini 3 Flash (Preview) Google Vertex (USG) 2,000,000 TPM
400 RPM 100,000 TPM
25 RPM 1,000,000 TPM
300 RPM 1,500,000 TPM
600 RPM 2,000,000 TPM
1,000 RPM Gemini 3.1 Flash-Lite Google Vertex 2,000,000 TPM
400 RPM 600,000 TPM
600 RPM 6,500,000 TPM
1,400 RPM 9,500,000 TPM
2,300 RPM 12,500,000 TPM
3,500 RPM Gemini 3.1 Flash-Lite Google Vertex (USG) 2,000,000 TPM
400 RPM 100,000 TPM
100 RPM 6,000,000 TPM
900 RPM 9,000,000 TPM
1,800 RPM 12,000,000 TPM
3,000 RPM Gemini 3.1 Pro (Preview) Google Vertex 2,000,000 TPM
400 RPM 1,000,000 TPM
600 RPM 7,000,000 TPM
1,500 RPM 10,000,000 TPM
2,250 RPM 15,000,000 TPM
3,750 RPM Gemini 3.1 Pro (Preview) Google Vertex (USG) 2,000,000 TPM
400 RPM 1,000,000 TPM
600 RPM 7,000,000 TPM
1,500 RPM 10,000,000 TPM
2,250 RPM 15,000,000 TPM
3,750 RPM Gemini 3.5 Flash Google Vertex 2,000,000 TPM
400 RPM 1,000,000 TPM
600 RPM 6,500,000 TPM
1,400 RPM 9,500,000 TPM
2,300 RPM 12,500,000 TPM
3,500 RPM Gemini 3.5 Flash Google Vertex (USG) 2,000,000 TPM
400 RPM 500,000 TPM
100 RPM 6,000,000 TPM
900 RPM 9,000,000 TPM
1,800 RPM 12,000,000 TPM
3,000 RPM Gemini 3.5 Flash-Lite Google Vertex 2,000,000 TPM
400 RPM 1,000,000 TPM
600 RPM 7,000,000 TPM
3,000 RPM 10,000,000 TPM
4,500 RPM 15,000,000 TPM
7,500 RPM Gemini 3.5 Flash-Lite Google Vertex (USG) 2,000,000 TPM
400 RPM 1,000,000 TPM
600 RPM 7,000,000 TPM
3,000 RPM 10,000,000 TPM
4,500 RPM 15,000,000 TPM
7,500 RPM Gemini 3.6 Flash Google Vertex 2,000,000 TPM
400 RPM 1,000,000 TPM
600 RPM 7,000,000 TPM
3,000 RPM 10,000,000 TPM
4,500 RPM 15,000,000 TPM
7,500 RPM Gemini 3.6 Flash Google Vertex (USG) 2,000,000 TPM
400 RPM 1,000,000 TPM
600 RPM 7,000,000 TPM
3,000 RPM 10,000,000 TPM
4,500 RPM 15,000,000 TPM
7,500 RPM Gemini 3.7 Flash Google Vertex 2,000,000 TPM
400 RPM 1,000,000 TPM
600 RPM 7,000,000 TPM
3,000 RPM 10,000,000 TPM
4,500 RPM 15,000,000 TPM
7,500 RPM Gemini 3.7 Flash Google Vertex (USG) 2,000,000 TPM
400 RPM 1,000,000 TPM
600 RPM 7,000,000 TPM
3,000 RPM 10,000,000 TPM
4,500 RPM 15,000,000 TPM
7,500 RPM Llama 3.1 8b Instruct Amazon Bedrock 50,000 TPM
100 RPM 100,000 TPM
100 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Llama 3.1 8b Instruct Palantir-hosted 50,000 TPM
100 RPM 100,000 TPM
100 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Llama 3.3 70b Instruct Amazon Bedrock 50,000 TPM
100 RPM 100,000 TPM
25 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Llama 3.3 70b Instruct Palantir-hosted 50,000 TPM
100 RPM 100,000 TPM
25 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Llama 4 Maverick 17b 128E Instruct Amazon Bedrock 100,000 TPM
100 RPM 100,000 TPM
25 RPM 1,000,000 TPM
500 RPM 2,000,000 TPM
1,000 RPM 4,000,000 TPM
2,000 RPM Llama 4 Scout 17b 16E Instruct Amazon Bedrock 100,000 TPM
100 RPM 100,000 TPM
100 RPM 1,000,000 TPM
500 RPM 2,000,000 TPM
1,000 RPM 4,000,000 TPM
2,000 RPM Llama 4 Scout 17b 16E Instruct Palantir-hosted 100,000 TPM
100 RPM 100,000 TPM
100 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Llama 3.2 NV EmbedQA 1B v2 Palantir-hosted 50,000 TPM
100 RPM 60,000 TPM
150 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Llama 3.3 Nemotron Super 49b v1.5 Palantir-hosted 50,000 TPM
100 RPM 100,000 TPM
25 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM NVIDIA Nemotron 3 Nano 30B Amazon Bedrock 50,000 TPM
100 RPM 100,000 TPM
25 RPM 500,000 TPM
100 RPM 1,000,000 TPM
150 RPM 2,000,000 TPM
200 RPM NVIDIA Nemotron 3 Super 120B Amazon Bedrock 500,000 TPM
100 RPM 40,000 TPM
10 RPM 1,000,000 TPM
200 RPM 2,000,000 TPM
300 RPM 4,000,000 TPM
400 RPM GPT-4.1 Azure 400,000 TPM
1,000 RPM 600,000 TPM
525 RPM 2,000,000 TPM
1,500 RPM 3,500,000 TPM
2,500 RPM 5,500,000 TPM
4,500 RPM GPT-4.1 Azure (USG) 400,000 TPM
1,000 RPM 100,000 TPM
25 RPM 2,000,000 TPM
2,000 RPM 4,000,000 TPM
4,000 RPM 6,000,000 TPM
6,000 RPM GPT-4.1 OpenAI 400,000 TPM
1,000 RPM 600,000 TPM
525 RPM 2,000,000 TPM
1,500 RPM 3,500,000 TPM
2,500 RPM 5,500,000 TPM
4,500 RPM GPT-4.1 mini Azure 1,000,000 TPM
1,000 RPM 5,100,000 TPM
5,100 RPM 15,000,000 TPM
7,500 RPM 35,000,000 TPM
12,500 RPM 55,000,000 TPM
17,500 RPM GPT-4.1 mini Azure (USG) 1,000,000 TPM
1,000 RPM 100,000 TPM
100 RPM 2,000,000 TPM
2,000 RPM 3,000,000 TPM
3,000 RPM 4,000,000 TPM
4,000 RPM GPT-4.1 mini OpenAI 1,000,000 TPM
1,000 RPM 1,100,000 TPM
1,100 RPM 3,000,000 TPM
2,000 RPM 4,000,000 TPM
3,000 RPM 6,000,000 TPM
5,000 RPM GPT-4.1 nano Azure 1,000,000 TPM
1,000 RPM 5,100,000 TPM
5,100 RPM 15,000,000 TPM
7,500 RPM 35,000,000 TPM
12,500 RPM 55,000,000 TPM
17,500 RPM GPT-4o Azure 400,000 TPM
800 RPM 100,000 TPM
25 RPM 1,000,000 TPM
1,000 RPM 1,500,000 TPM
2,000 RPM 3,000,000 TPM
4,000 RPM GPT-4o Azure (USG) 400,000 TPM
800 RPM 100,000 TPM
25 RPM 1,000,000 TPM
1,000 RPM 1,500,000 TPM
2,000 RPM 3,000,000 TPM
4,000 RPM GPT-4o OpenAI 400,000 TPM
800 RPM 100,000 TPM
25 RPM 1,000,000 TPM
1,000 RPM 1,500,000 TPM
2,000 RPM 3,000,000 TPM
4,000 RPM GPT-5 Azure 1,000,000 TPM
1,000 RPM 600,000 TPM
525 RPM 3,500,000 TPM
1,500 RPM 5,500,000 TPM
3,000 RPM 10,500,000 TPM
5,500 RPM GPT-5 Codex Azure 1,000,000 TPM
1,000 RPM 100,000 TPM
25 RPM 2,000,000 TPM
1,000 RPM 3,000,000 TPM
2,000 RPM 5,000,000 TPM
4,000 RPM GPT-5 mini Azure 1,000,000 TPM
1,000 RPM 600,000 TPM
600 RPM 10,500,000 TPM
5,500 RPM 20,500,000 TPM
10,500 RPM 30,500,000 TPM
15,500 RPM GPT-5 nano Azure 1,000,000 TPM
1,000 RPM 1,100,000 TPM
1,100 RPM 11,000,000 TPM
6,000 RPM 31,000,000 TPM
16,000 RPM 51,000,000 TPM
26,000 RPM GPT-5.1 Azure 1,000,000 TPM
2,000 RPM 100,000 TPM
25 RPM 2,000,000 TPM
500 RPM 4,000,000 TPM
1,000 RPM 6,000,000 TPM
2,000 RPM GPT-5.1 Azure (USG) 1,000,000 TPM
2,000 RPM 100,000 TPM
25 RPM 3,000,000 TPM
3,000 RPM 5,250,000 TPM
5,250 RPM 7,500,000 TPM
7,500 RPM GPT-5.1 OpenAI 1,000,000 TPM
2,000 RPM 100,000 TPM
25 RPM 1,500,000 TPM
1,000 RPM 3,000,000 TPM
2,000 RPM 5,000,000 TPM
4,000 RPM GPT-5.1 Codex Azure 1,000,000 TPM
1,000 RPM 100,000 TPM
25 RPM 2,000,000 TPM
1,000 RPM 3,000,000 TPM
2,000 RPM 4,000,000 TPM
4,000 RPM GPT-5.1 Codex mini Azure 1,000,000 TPM
500 RPM 100,000 TPM
100 RPM 2,000,000 TPM
1,000 RPM 3,000,000 TPM
2,000 RPM 5,000,000 TPM
4,000 RPM GPT-5.2 Azure 500,000 TPM
1,000 RPM 250,000 TPM
50 RPM 2,000,000 TPM
500 RPM 4,000,000 TPM
1,000 RPM 6,000,000 TPM
2,000 RPM GPT-5.2 OpenAI 500,000 TPM
1,000 RPM 250,000 TPM
50 RPM 3,000,000 TPM
1,500 RPM 6,000,000 TPM
3,000 RPM 10,000,000 TPM
5,000 RPM GPT-5.2 Pro OpenAI 400,000 TPM
1,000 RPM 100,000 TPM
25 RPM 1,500,000 TPM
1,000 RPM 3,000,000 TPM
2,000 RPM 5,000,000 TPM
4,000 RPM GPT-5.3 Codex Azure 1,000,000 TPM
1,000 RPM 100,000 TPM
100 RPM 4,000,000 TPM
2,000 RPM 6,000,000 TPM
4,000 RPM 8,000,000 TPM
8,000 RPM GPT-5.3 Codex OpenAI 1,000,000 TPM
1,000 RPM 100,000 TPM
25 RPM 3,000,000 TPM
1,000 RPM 4,000,000 TPM
2,000 RPM 5,000,000 TPM
4,000 RPM GPT-5.4 Azure 1,000,000 TPM
1,000 RPM 250,000 TPM
50 RPM 4,000,000 TPM
2,000 RPM 6,000,000 TPM
3,000 RPM 8,000,000 TPM
4,000 RPM GPT-5.4 OpenAI 1,000,000 TPM
1,000 RPM 250,000 TPM
50 RPM 3,000,000 TPM
1,500 RPM 6,000,000 TPM
3,000 RPM 10,000,000 TPM
5,000 RPM GPT-5.4 Pro OpenAI 400,000 TPM
1,000 RPM 100,000 TPM
25 RPM 1,500,000 TPM
1,000 RPM 3,000,000 TPM
2,000 RPM 5,000,000 TPM
4,000 RPM GPT-5.4 mini Azure 1,000,000 TPM
1,000 RPM 100,000 TPM
100 RPM 4,500,000 TPM
2,250 RPM 9,000,000 TPM
4,500 RPM 15,000,000 TPM
7,500 RPM GPT-5.4 mini OpenAI 1,000,000 TPM
1,000 RPM 100,000 TPM
100 RPM 3,000,000 TPM
1,500 RPM 6,000,000 TPM
3,000 RPM 10,000,000 TPM
5,000 RPM GPT-5.4 nano Azure 1,000,000 TPM
1,000 RPM 100,000 TPM
100 RPM 4,500,000 TPM
2,250 RPM 9,000,000 TPM
4,500 RPM 15,000,000 TPM
7,500 RPM GPT-5.4 nano OpenAI 1,000,000 TPM
1,000 RPM 100,000 TPM
100 RPM 3,000,000 TPM
1,500 RPM 6,000,000 TPM
3,000 RPM 10,000,000 TPM
5,000 RPM GPT-5.5 Azure 1,000,000 TPM
1,000 RPM 250,000 TPM
50 RPM 4,000,000 TPM
2,000 RPM 6,000,000 TPM
3,000 RPM 8,000,000 TPM
4,000 RPM GPT-5.5 OpenAI 1,000,000 TPM
1,000 RPM 250,000 TPM
50 RPM 3,000,000 TPM
1,500 RPM 6,000,000 TPM
3,000 RPM 10,000,000 TPM
5,000 RPM GPT-5.6 Luna Azure 3,000,000 TPM
1,500 RPM 250,000 TPM
125 RPM 5,000,000 TPM
2,500 RPM 6,000,000 TPM
3,000 RPM 7,000,000 TPM
3,500 RPM GPT-5.6 Luna OpenAI 3,000,000 TPM
1,500 RPM 250,000 TPM
50 RPM 5,000,000 TPM
2,500 RPM 10,000,000 TPM
5,000 RPM 15,000,000 TPM
7,500 RPM GPT-5.6 Sol Azure 5,000,000 TPM
2,500 RPM 250,000 TPM
125 RPM 9,000,000 TPM
4,500 RPM 10,000,000 TPM
5,000 RPM 11,000,000 TPM
5,500 RPM GPT-5.6 Sol OpenAI 5,000,000 TPM
2,500 RPM 250,000 TPM
50 RPM 10,000,000 TPM
5,000 RPM 20,000,000 TPM
10,000 RPM 30,000,000 TPM
15,000 RPM GPT-5.6 Terra Azure 3,000,000 TPM
1,500 RPM 250,000 TPM
125 RPM 5,000,000 TPM
2,500 RPM 6,000,000 TPM
3,000 RPM 7,000,000 TPM
3,500 RPM GPT-5.6 Terra OpenAI 3,000,000 TPM
1,500 RPM 250,000 TPM
50 RPM 5,000,000 TPM
2,500 RPM 10,000,000 TPM
5,000 RPM 15,000,000 TPM
7,500 RPM GPT-OSS-120B Palantir-hosted 50,000 TPM
100 RPM 100,000 TPM
25 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM GPT-OSS-20B Palantir-hosted 50,000 TPM
100 RPM 100,000 TPM
100 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Text Embedding 3 Large Azure 1,000,000 TPM
1,500 RPM 1,060,000 TPM
1,400 RPM 2,250,000 TPM
3,500 RPM 3,500,000 TPM
4,750 RPM 4,750,000 TPM
8,500 RPM Text Embedding 3 Large Azure (USG) 1,000,000 TPM
1,500 RPM 60,000 TPM
400 RPM 1,000,000 TPM
2,000 RPM 2,000,000 TPM
3,000 RPM 3,000,000 TPM
6,000 RPM Text Embedding 3 Large OpenAI 1,000,000 TPM
1,500 RPM 60,000 TPM
400 RPM 1,250,000 TPM
2,500 RPM 2,500,000 TPM
3,750 RPM 3,750,000 TPM
7,500 RPM Text Embedding 3 Small Azure 1,000,000 TPM
1,500 RPM 1,060,000 TPM
1,400 RPM 1,625,000 TPM
3,500 RPM 2,250,000 TPM
4,750 RPM 2,875,000 TPM
8,500 RPM Text Embedding 3 Small Azure (USG) 1,000,000 TPM
1,500 RPM 60,000 TPM
400 RPM 500,000 TPM
2,000 RPM 1,000,000 TPM
3,000 RPM 1,500,000 TPM
6,000 RPM Text Embedding 3 Small OpenAI 1,000,000 TPM
1,500 RPM 60,000 TPM
400 RPM 625,000 TPM
2,500 RPM 1,250,000 TPM
3,750 RPM 1,875,000 TPM
7,500 RPM Whisper 1 OpenAI 1 TPM
50 RPM 1 TPM
100 RPM 2 TPM
500 RPM 3 TPM
1,000 RPM 4 TPM
2,000 RPM o1 Azure 600,000 TPM
5 RPM 100,000 TPM
25 RPM 250,000 TPM
50 RPM 400,000 TPM
60 RPM 750,000 TPM
75 RPM o3 Azure 400,000 TPM
100 RPM 600,000 TPM
525 RPM 1,500,000 TPM
1,500 RPM 2,500,000 TPM
2,500 RPM 4,500,000 TPM
4,500 RPM o3-mini Azure (USG) 300,000 TPM
30 RPM 100,000 TPM
25 RPM 1,000,000 TPM
100 RPM 2,000,000 TPM
200 RPM 4,000,000 TPM
400 RPM o4-mini Azure 300,000 TPM
100 RPM 1,100,000 TPM
1,025 RPM 2,000,000 TPM
2,000 RPM 3,000,000 TPM
3,000 RPM 5,000,000 TPM
5,000 RPM text-embedding-ada-002 Azure 1,000,000 TPM
1,500 RPM 1,450,000 TPM
1,450 RPM 3,625,000 TPM
3,625 RPM 4,875,000 TPM
4,875 RPM 6,250,000 TPM
6,250 RPM text-embedding-ada-002 Azure (USG) 1,000,000 TPM
1,500 RPM 450,000 TPM
450 RPM 3,000,000 TPM
3,500 RPM 4,000,000 TPM
4,500 RPM 5,000,000 TPM
5,500 RPM text-embedding-ada-002 OpenAI 1,000,000 TPM
1,500 RPM 950,000 TPM
950 RPM 3,125,000 TPM
3,125 RPM 4,437,500 TPM
4,438 RPM 5,750,000 TPM
5,750 RPM Document Information Extraction Palantir-hosted 1,000,000 TPM
40 RPM 1,000,000 TPM
40 RPM 1,500,000 TPM
300 RPM 2,000,000 TPM
450 RPM 3,000,000 TPM
600 RPM Gemma 4 26B A4B Amazon Bedrock 50,000 TPM
100 RPM 250,000 TPM
25 RPM 5,000,000 TPM
500 RPM 10,000,000 TPM
1,000 RPM 20,000,000 TPM
2,000 RPM Gemma 4 26B A4B Palantir-hosted 50,000 TPM
100 RPM 100,000 TPM
25 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Schematic 7B Palantir-hosted 50,000 TPM
100 RPM 60,000 TPM
150 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Whisper Large V3 Palantir-hosted 50,000 TPM
100 RPM 60,000 TPM
150 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Snowflake Arctic Embed Medium Palantir-hosted 500,000 TPM
500 RPM 60,000 TPM
150 RPM 300,000 TPM
450 RPM 450,000 TPM
675 RPM 600,000 TPM
900 RPM Grok 4.3 xAI 500,000 TPM
100 RPM 50,000 TPM
20 RPM 1,000,000 TPM
200 RPM 1,500,000 TPM
300 RPM 2,000,000 TPM
400 RPM Grok 4.5 xAI 1,000,000 TPM
200 RPM 100,000 TPM
40 RPM 3,000,000 TPM
800 RPM 4,000,000 TPM
1,200 RPM 5,000,000 TPM
1,600 RPM Grok 420 Non-Reasoning Latest xAI 500,000 TPM
100 RPM 50,000 TPM
20 RPM 1,000,000 TPM
200 RPM 1,500,000 TPM
300 RPM 2,000,000 TPM
400 RPM Grok 420 Reasoning Latest xAI 500,000 TPM
100 RPM 50,000 TPM
20 RPM 1,000,000 TPM
200 RPM 1,500,000 TPM
300 RPM 2,000,000 TPM
400 RPM Grok Build 0.1 xAI 400,000 TPM
100 RPM 50,000 TPM
20 RPM 1,000,000 TPM
200 RPM 1,500,000 TPM
300 RPM 2,000,000 TPM
400 RPM
---
## 兼容各提供商的原生 API 端点
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-llm-provider-compatible-apis.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/llm-provider-compatible-apis/
- 主题分组:核心平台(六)
循序渐进 · AIP 教学 · 核心平台(六)
# 兼容各提供商的原生 API 端点
Foundry 为主流 LLM 提供商提供代理端点,按各提供商原生 API 的格式接收请求 —— 你可以继续用熟悉的开源 SDK,同时白拿平台的限流、数据保护能力。
## 先记住这几条
① 格式兼容 请求体与各家原生 API 一致,不用改代码。
② 白拿平台能力 速率限制、数据治理、审计都由平台兜底。
③ 适合已有代码迁移 现成的 OpenAI/Anthropic 客户端直接指过来。
## 写在前面
Foundry 为主流 LLM 提供商提供代理端点(proxy endpoint),以与各提供商原生 API 相同的格式接收请求。这使你既可以使用开源 SDK 和工具,又能享受 Foundry 的能力,例如速率限制、数据治理和使用量追踪。
当前支持的提供商 API 及对应的 Foundry 端点如下:
- Anthropic messages ↗: /api/v2/llm/proxy/anthropic/v1/messages
- OpenAI chat completions ↗: /api/v2/llm/proxy/openai/v1/chat/completions
- OpenAI responses ↗: /api/v2/llm/proxy/openai/v1/responses
- OpenAI embeddings ↗: /api/v2/llm/proxy/openai/v1/embeddings
- [Beta] xAI chat completions ↗: /api/v2/llm/proxy/xai/v1/chat/completions
- [Beta] xAI responses ↗: /api/v2/llm/proxy/xai/v1/responses
- [Beta] Google generateContent ↗: /api/v2/llm/proxy/google/v1/models/{model}:generateContent
- [Beta] Google streamGenerateContent ↗: /api/v2/llm/proxy/google/v1/models/{model}:streamGenerateContent?alt=sse
Beta 端点 xAI 和 Google(Gemini)端点目前处于 beta 阶段,正在积极开发中。可能尚未支持所有功能或字段。
## 前置条件
> 要点:动手前要先具备什么。
要使用 Palantir 提供的语言模型,请确保:
- 你的 enrollment 上已启用 AIP。
- 你拥有使用 AIP 构建能力的权限。
## 请求格式
> 要点:各提供商原生 API 的请求体形态。
身份认证通过以下 bearer token 请求头发送:
Code Authorization: Bearer {FOUNDRY_TOKEN}
对这些端点的请求应与对应提供商端点的请求结构相同。有关期望的请求格式,请参阅提供商的文档。
Google 的 streamGenerateContent 代理端点目前仅支持 SSE 响应格式,因此你必须提供 alt=sse 查询参数。
> 某些提供商(例如 Anthropic)使用非标准的身份认证请求头。使用它们的 SDK 时,你可能需要将认证方式配置为使用 bearer token。而已经使用 bearer token 认证的提供商(例如 OpenAI)则无需特殊配置。
## AIP 集成与数据治理
> 要点:白拿平台的治理能力:限流、数据保护、审计。
这些端点执行与其他 AIP 用法相同的数据治理,例如零数据保留(zero data retention,ZDR)和地理限制要求。我们会有选择地启用与这些要求兼容的提供商 API 功能。
只有已在你的 enrollment 上启用的模型和提供商才可通过这些端点使用。对于由多个提供商提供的模型,请求只会路由到已启用的提供商。端点使用情况可在 Resource Management 应用中查看,并受到速率限制。
### 常见问题速答 · FAQ
关于「兼容各提供商的原生 API 端点」,读者最常问的几个问题。
前置条件是什么? 动手前要先具备什么。要使用 Palantir 提供的语言模型,请确保。
请求格式是什么? 各提供商原生 API 的请求体形态。身份认证通过以下 bearer token 请求头发送。
AIP 集成与数据治理是什么? 白拿平台的治理能力:限流、数据保护、审计。这些端点执行与其他 AIP 用法相同的数据治理,例如零数据保留(zero data retention,ZDR)和地理限制要求。我们会有选择地启用与这些要求兼容的提供商 API 功能。
---
## AIP 总览:把 AI 接进你的数据与运营
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/overview/
- 主题分组:核心平台(一)
循序渐进 · AIP 教学 · 核心平台(一)
# AIP 总览:把 AI 接进你的数据与运营
AIP(Artificial Intelligence Platform)不是孤立的模型平台,它长在你的数据与 Ontology 之上,目标是把 AI 变成可运营、可治理的业务能力。这一篇是整站的起点。
## 先记住这几条
① AIP 是连接层 它把 AI 与你的数据、运营流程接起来,而不是另起炉灶。
② 目标是流程自动化 让 AI 驱动跨系统的业务流程,而不只是回答问题。
③ 治理内建 AI 的使用受平台既有权限体系约束。
④ 面向组织所有人 不只是给算法工程师用的。
## 写在前面

> 图:AIP 页头配图。
Palantir 的人工智能平台(Artificial Intelligence Platform,AIP)将 AI 与你的数据和运营连接起来。AIP 旨在推动跨运营流程的自动化,提供一整套全面的工具,组织中的每个人——从开发者到一线用户——都可以使用。
AIP 的构建工具(例如 AIP Logic、AIP Chatbot Studio(原名 AIP Agent Studio)和 AIP Evals)支持在 Ontology 和开发者工具链之上开发可用于生产环境的 AI 驱动工作流、智能体(agent)和函数。此外,AIP 还通过允许沙箱化、自动扩缩容的应用在现有的安全、审计和资源管理框架内无缝集成生成式 AI,从而改变应用环境。
AIP 与 Foundry(Palantir 的数据运营平台)和 Apollo(Palantir 用于自主软件部署的任务控制平台)一起,构成了一个操作系统,能够交付全方位的 AI 驱动产品——从由 LLM 驱动的 Web 应用,到使用视觉语言模型的移动应用,再到内嵌本地化 AI 的边缘应用。
本页余下部分简要概述 AIP 的关键优势。如需了解 AIP 能力的更多细节,我们建议查阅 AIP 文档,包括 AIP 应用参考。如需动手实践,请在 learn.palantir.com ↗ 上参加「速通:你的第一个 AIP 工作流」 ↗课程。
## 无缝集成
> 要点:与 Ontology、应用、工作流的集成方式 —— AIP 不是孤岛。
Palantir AIP 可以与你的组织在 Foundry enrollment 上已有的数据无缝集成。这使你能够构建并使用由 LLM 驱动的智能体和工作流,并与其交互,充分利用来自各类数据源和格式的数据。
## 安全与治理
> 要点:AI 场景下权限与合规如何保证,沿用平台既有体系。
AIP 纳入了 Palantir 所有先进的安全措施(security measures),以按照行业法规保护敏感数据。AIP 提供强大的访问控制、加密和审计能力,以维护数据完整性和透明度。此外,内置的治理工具可帮助组织在 AI 运营中保持问责性和历史沿革记录。
如需进一步了解 LLM 如何在平台上安全地处理用户提示词(prompt),请选择 Palantir AIP FAQs,查阅 常见问题:Palantir AIP 使用第三方托管的 LLM 时的安全性与隐私 ↗。
## 模型管理
> 要点:模型的接入、版本与使用如何统一管理。
AIP 提供了一整套全面的工具,用于构建、训练和部署大语言模型。支持多种不同的大语言模型,使数据科学家和工程师能够使用自己偏好的工具,并为每个用例挑选最合适的模型。此外,AIP 还提供版本控制和协作功能,使团队能够在模型的整个生命周期中高效地管理模型。
## 可扩展性与性能
> 要点:规模化支撑能力。
AIP 专为处理大规模数据运营而设计,确保 AI 模型能够根据组织需求进行部署和扩缩容。该平台的架构支持分布式计算,可实现高性能处理和实时分析,这对关键任务应用至关重要。AIP 还提供对资源使用和限额设置的精细化控制。
如需进一步了解开发者可用于监控和优化平台上构建的智能体与应用性能的工具,请查阅 Ontology 与 AIP 可观测性文档。
## 可解释性与透明度
> 要点:企业落地的关键:AI 结果要能追溯、能解释。
在为生产环境部署构建 AI 工作流时,信任至关重要;对于 LLM 而言,信任来自可解释性和透明度,以及严格的评估。AIP 提供用于生成详细审计轨迹、解释和模型决策评估的工具,帮助用户理解和信任所得结果。这种信任对于组织在真实场景中安全部署 AI,并基于 AI 洞察做出明智且合乎伦理的决策至关重要。
注意:AIP 功能的可用性可能会发生变化,且可能因客户而异。
### 常见问题速答 · FAQ
关于「AIP 总览:把 AI 接进你的数据与运营」,读者最常问的几个问题。
无缝集成是什么? 与 Ontology、应用、工作流的集成方式 —— AIP 不是孤岛。
安全与治理是什么? AI 场景下权限与合规如何保证,沿用平台既有体系。AIP 纳入了 Palantir 所有先进的安全措施(security measures),以按照行业法规保护敏感数据。AIP 提供强大的访问控制、加密和审计能力,以维护数据完整性和透明度。
如何模型管理? 模型的接入、版本与使用如何统一管理。AIP 提供了一整套全面的工具,用于构建、训练和部署大语言模型。支持多种不同的大语言模型,使数据科学家和工程师能够使用自己偏好的工具,并为每个用例挑选最合适的模型。
可扩展性与性能是什么? 规模化支撑能力。AIP 专为处理大规模数据运营而设计,确保 AI 模型能够根据组织需求进行部署和扩缩容。该平台的架构支持分布式计算,可实现高性能处理和实时分析,这对关键任务应用至关重要。AIP 还提供对资源使用和限额设置的精细化控制。
---
## 用 REST API 来源支撑模型
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-rest-api-backed-models.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/rest-api-backed-models/
- 主题分组:自带模型(二)
循序渐进 · AIP 教学 · 自带模型(二)
# 用 REST API 来源支撑模型
当你的模型暴露标准供应商 API时,通过 Data Connection 里的 REST API 来源接入是最省事的路径。
## 先记住这几条
① 适用标准 API 模型接口与主流供应商格式一致时选这条。
② 走 Data Connection 复用平台既有的连接器与凭据管理。
③ 推荐路径 官方明确说这是首选方案。
## 写在前面
你可以通过 Data Connection 中的 REST API 来源为注册模型提供后端,从而将 AIP 连接到外部托管的模型供应商或账号。当你的模型暴露标准的供应商 API 时,这是推荐的路径。
## 如何注册并使用自己的模型
> 要点:从建连接器到完成注册的完整步骤。
你必须是一名 Enrollment administrator(注册管理员),并且对你按以下步骤配置的 Data Connection 来源拥有 Owner 或 Editor 权限。
### Create REST API source in Data Connection
首先,按以下步骤在 Data Connection 中创建 REST API 来源:
- 打开 Data Connection 应用,针对你的模型供应商端点选择 New source > REST API。
- 为你的来源输入一个 Name(名称),并选择一个你能够保留 Owner 或 Editor 权限的 Source location(来源位置)。
- 为你的模型供应商配置 Domain base URL(域名基础 URL)、Authentication(认证)方式和 Port(端口)。
- 确保你在 Export configuration(导出配置)小节中打开了 Enable exports to this source 和 Enable exports to this source without markings validations 两个开关。
- 完成你的 REST API 来源配置。更多细节可参考 REST API 连接器文档。

> 图:Export configuration 小节,其中 Enable exports to this source 和 Enable exports to this source without markings validations 两个开关均已开启。
### Register the model in Control Panel
接下来,按以下步骤在 Control Panel 中注册模型:
- 打开 Control Panel,导航到 AIP settings 扩展,然后选择 Registered models 标签页。
- 选择 Register a model。
- 在 Source configuration 页面的 Select source rid 下拉菜单中搜索并选择 REST API 来源的 RID。
- 在 Configure source API 和 Model API configuration 小节中填写你的模型详情,例如模型供应商名称、模型名称和 API 端点路径。
- 按端点定义模型的能力。你声明的能力决定了该模型能够驱动哪些 AIP 功能。启用 Reasoning、Structured outputs 和 Tool calling 可确保 AI FDE 和 AIP Analyst 能够使用该模型。
- 定义模型的限流,这是在 Resource Management 应用中启用容量管理和用量可观测性所必需的:
- Enrollment rate limits: 定义 enrollment 可用的每分钟最大请求数或每分钟令牌数。项目级限额按这些 enrollment 限额的百分比计算。
- User rate limits: 定义适用于 AI FDE、AIP Analyst 以及其他按用户归属的应用中用量情况的单用户限额。
- 返回 Control Panel 中的 AIP settings 扩展,为你的 enrollment 启用注册模型访问权限。你可以将访问权限授予整个 enrollment 或特定用户组。
### Next steps
你的注册模型现已在各 AIP 应用中可用。它会出现在所有受支持应用中模型选择器的 Registered models 标签页下。

> 图:来源配置与模型信息。
---
## 自托管模型
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-self-host-models.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/self-host-models/
- 主题分组:自带模型(四)
循序渐进 · AIP 教学 · 自带模型(四)
# 自托管模型
在自己的基础设施上跑开源或私有模型,数据完全不出环境。这篇说明自托管的做法与代价。
## 先记住这几条
① 自托管的动机是控制 数据不出境、模型可定制。
② 实现方式沿用 module 通过 compute module 提供后端。
③ 要自己承担运维 容量、可用性、升级都是你的责任。
## 写在前面
你可以通过用 compute module 为注册模型提供后端来自托管模型。自托管让你可以在自己的基础设施上运行开源或自定义的大型语言模型,并将它们作为 AIP 中的一等公民模型使用。当你需要以下条件时,这非常有用:
- Data sovereignty(数据主权): 将所有推理流量保留在你自己的网络边界内。
- On-premise or air-gapped deployments(本地部署或气隙部署): 在完全没有外部连接的情况下运行模型。
- Cost control(成本控制): 使用你自己的 GPU,而不必按 token 向托管供应商付费。
- Early access to new models(抢先体验新模型): 在托管供应商提供之前就部署新发布的开源模型。
## 前置条件
> 要点:自托管需要的基础设施与准备。
在开始之前,请查阅由 compute module 提供后端的模型的通用先决条件和注册步骤。
## 如何用 AIP 自托管模型
> 要点:实现路径与注意事项。
- 构建一个运行推理服务器(例如 vLLM 或 Ollama)的容器镜像,该服务器提供你的模型权重,并暴露受支持的供应商 API 格式。
- 在你的 Dockerfile 中设置 application.port 标签,并将镜像发布到 Artifacts。关于容器的通用指引,请查阅 compute modules 容器文档。
- 使用已发布的镜像创建一个 compute module。将最小副本数设置为至少一个。
- 在 Control Panel 中注册模型并配置能力。
- 在任意受支持的 AIP 应用中选择该模型。
---
## 平台支持的 LLM 清单
- 页面:https://www.hanzhongpin.xyz/ontology/aip-aip-supported-llms.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/supported-llms/
- 主题分组:核心平台(五)
循序渐进 · AIP 教学 · 核心平台(五)
# 平台支持的 LLM 清单
AIP 支持来自 xAI、OpenAI、Anthropic、Meta、Google 等提供商的多种 LLM 与文本嵌入模型。这一篇是选型参照表。
## 先记住这几条
① 多提供商策略(k-LLM) 不绑定单一供应商,可按任务挑模型。
② 模型分两类 对话/生成类 LLM,与文本嵌入(embedding)模型。
③ 能力与成本不同 上下文长度、模态支持、单价都有差异。
④ 清单会变 模型上下线频繁,动手前先查本页。
## 写在前面
Palantir AIP 支持来自领先提供商(包括 xAI、OpenAI、Anthropic、Meta 和 Google)的多种 LLM(大语言模型)和文本嵌入模型。受支持的模型列于本页,可在整个 Palantir 平台中使用,以驱动 AIP 工作流;不过各 enrollment 的可用性可能不同(例如因地理限制而不同)。
Enrollment 管理员通过 Control Panel 管理模型家族。当启用某个子处理者(subprocessor)时,Palantir 可能会在已接受条款和条件的前提下,启用符合资格要求的其他模型家族。了解如何配置你的 enrollment 上可供使用的 LLM 选择。
## 可用的 LLM
> 要点:对话/生成类模型清单与能力对照。
以下 LLM 受支持,可与 AIP 配合使用,具体取决于 enrollment 的可用性。
- Grok-3 ↗
- Grok-3-Mini-Reasoning ↗
- Grok-4 ↗
- Grok-4-Fast (Reasoning) ↗
- Grok-4-Fast (Non-Reasoning) ↗
- Grok-4-1-Fast (Reasoning) ↗
- Grok-4-1-Fast (Non-Reasoning) ↗
- Grok-Code-Fast-1 ↗
- GPT-4o ↗
- GPT-4o mini ↗
- GPT-4.1 ↗
- GPT-4.1 mini ↗
- GPT-4.1 nano ↗
- GPT-5 ↗
- GPT-5 Pro ↗
- GPT-5 Codex ↗
- GPT-5 mini ↗
- GPT-5 nano ↗
- GPT-5.1 ↗
- GPT-5.1 Codex↗
- GPT-5.1 Codex Max↗
- GPT-5.1 Codex Mini↗
- GPT-5.2 ↗
- GPT-5.2 Codex ↗
- GPT-5.3 Codex ↗
- GPT-5.4 ↗
- GPT-5.4 mini ↗
- GPT-5.4 nano ↗
- GPT-5.5 ↗
- o1 ↗
- o3-mini ↗
- o3 ↗
- o4-mini ↗
- Anthropic Claude 3 Haiku ↗
- Anthropic Claude 3.5 Haiku ↗
- Anthropic Claude 3.5 Sonnet ↗
- Anthropic Claude 3.5 Sonnet v2 ↗
- Anthropic Claude 3.7 Sonnet ↗
- Anthropic Claude 4 Sonnet ↗
- Anthropic Claude 4 Opus ↗
- Anthropic Claude 4.1 Opus ↗
- Anthropic Claude 4.5 Haiku ↗
- Anthropic Claude 4.5 Sonnet ↗
- Anthropic Claude 4.5 Opus ↗
- Anthropic Claude 4.6 Sonnet ↗
- Anthropic Claude 4.6 Opus ↗
- Anthropic Claude 4.7 Opus ↗
- Anthropic Claude 4.8 Opus ↗
- Mistral 7B ↗
- Mixtral 8X7B ↗
- Mistral Small 24B ↗
- Llama 3_8B ↗
- Llama 3_70B ↗
- Llama 3.1_8B ↗
- Llama 3.1_70B ↗
- Llama 3.2 NV EmbedQA 1B v2 ↗
- Llama 3.3_70B ↗
- Llama 3.3 Nemotron Super 49b v1.5 ↗
- Llama 4_16B Scout ↗
- Llama 4_128B Maverick ↗
- Gemma 4 26B A4B ↗
- Gemini 2.0 Flash ↗
- Gemini 2.5 Pro ↗
- Gemini 2.5 Flash ↗
- Gemini 2.5 Flash Lite ↗
- Gemini 3 Flash ↗
- Gemini 3.1 Pro ↗
- Gemini 3.1 Flash-Lite ↗
- Gemini 3.5 Flash ↗
- Gemini 3.5 Flash-Lite ↗
- Gemini 3.6 Flash ↗
- Gemini 3.7 Flash ↗
## 可用的文本嵌入模型
> 要点:做检索、语义搜索要选这类模型。
Palantir AIP 还支持以下文本嵌入模型:
- ada embedding ↗
- text-embedding-3-large ↗
- text-embedding-3-small ↗
- Snowflake Arctic Embed ↗
## 可用的音频模型
> 要点:语音相关场景用。
录音与征得同意由你负责 在部署任何录制或转写人类语音的应用之前,请确保已通知参与者,并在你所在司法管辖区要求的情况下准备好同意确认流程。无论被录音者是应用用户、通话中的第三方,还是其他任何被采集到声音的人,这一点都可能适用。参见录音、转写与同意。
Palantir AIP 支持两类音频模型:用于构建对话式语音应用的实时语音到语音(speech-to-speech)模型,以及用于将音频转换为文本的转写模型。如需了解如何在以 Foundry 用户身份认证的浏览器应用中使用音频模型,请参见构建支持语音的 OSDK 应用。如需了解 Foundry 上音频的总体概况,请参见实时音频。
Mode 列指明每个模型支持哪些使用路径:
- Realtime: 流式双向 WebSocket。模型负责语音活动检测、轮流发言和流式输出;应用在采集音频时即发送原始音频。
- Static: 请求-响应式 HTTP。应用发送一段有界的音频负载,并收到转写结果。适用于转写此前录制的音频文件。如果应用自行进行音频分块,也可用于实时转写——这是一种权衡:以增加应用复杂度换取更低且更可预测的每分钟成本。当你的 enrollment 上没有可用的实时模型时,这种方式也有帮助。延迟取决于分块大小和模型,因此请针对你的用例进行评估。
### Realtime speech-to-speech
实时语音到语音模型接受流式音频输入,在对话过程中进行工具调用,并通过 WebSocket 连接返回流式音频输出。
Model API name Provider Mode GPT Realtime 1.5 ↗ gpt-realtime-1.5 OpenAI Direct, Azure OpenAI Realtime GPT Realtime 2.0 ↗ gpt-realtime-2 OpenAI Direct Realtime
### Transcription
转写模型将音频转换为文本。大多数模型同时支持实时(流式 WebSocket)和静态(请求-响应式 HTTP)模式;Whisper_large_v3 由 Palantir 托管,仅支持静态模式。
Model API name Provider Mode Whisper 1 ↗ whisper-1 OpenAI Direct, Azure OpenAI Realtime, Static GPT-4o Transcribe ↗ gpt-4o-transcribe OpenAI Direct, Azure OpenAI Realtime, Static GPT-4o Mini Transcribe ↗ gpt-4o-mini-transcribe OpenAI Direct, Azure OpenAI Realtime, Static GPT-4o Transcribe Diarize ↗ gpt-4o-transcribe-diarize OpenAI Direct, Azure OpenAI Realtime, Static Whisper Large V3 ↗ Whisper_large_v3 Palantir-hosted Static
当你需要对会议等多说话人音频进行说话人分离(diarization)时,请使用 gpt-4o-transcribe-diarize。对于不需要说话人分离的通用转写,可根据最适合你用例的质量、成本和延迟权衡,使用 gpt-4o-transcribe、gpt-4o-mini-transcribe 或 whisper-1。在无法使用 OpenAI Direct 或 Azure OpenAI 集成的环境中,请使用 Whisper_large_v3。
关于各地理区域下按 enrollment 划分的可用性,请参见下文的 LLM 地理可用性表。
## LLM 可用性前提
> 要点:哪些条件下这些模型才可用。
AIP 与模型无关,为 LLM 驱动的用例提供了多样化的模型选择;更多信息请参阅 AIP 中所有可用模型的列表。
不过,具体模型能否在某个 enrollment 上可用取决于某些前提条件,因此 LLM 的选择和可用性会因 enrollment 而异。这些前提条件决定了某个模型家族在 Control Panel 中显示为 enabled(已启用)、disabled(已禁用)还是 disallowed(不允许)。进一步了解模型启用界面中的模型状态。
相关标准如下:
- 模型已与 AIP 集成: Palantir 的目标是支持业界最新的旗舰模型,并会随着模型的发布和更新积极推进支持。
- 在需要时已完成法律确认: Enrollment 管理员必须接受提供商的法律要求和使用条款,才能启用某些模型。这通常可以在 Control Panel 的 Model enablement 选项卡中完成。等待法律确认的模型会显示为 disabled 状态。
- 已在 enrollment 上启用 AIP 以使用 LLM: 若要在 AIP Logic、Transforms、Functions 和 Pipeline Builder 等产品中使用,必须为目标用户组启用自定义工作流的 AIP 能力权限。
- 区域可用性兼容(针对外部提供商的模型): 对于 GPT、Claude 和 Gemini 这类模型,如果你的 enrollment 受地理限制,则可能需要考虑区域可用性。例如,GPT4o 和 Claude 3 Sonnet 在各自模型提供商发布时都仅在美国可用,之后才在欧盟、英国和其他地区推出。详情请查阅模型地理限制章节。因地理限制而不可用的模型会显示为 disallowed 状态。
- 已完成额外的审查(针对某些 Palantir 提供的模型): 开源模型(如 Llama 和 Mixtral)可能需要额外的 Palantir 工程审查以支持你的环境。需要此类审查的模型会显示为 disallowed 状态。
- 与特定 AIP 前端产品集成需要足够时间: 新的 LLM 需要一定时间才能在所有 AIP 产品上得到完整支持(例如在 AIP Logic 中以及 Pipeline Builder 的 Use LLM 节点功能中)。
- 风险考量(针对实验性模型): 由于实验性模型可能会失效或需要手动迁移到更新的模型,我们会限制其推广,客户可能需要在启用使用前予以确认。「experimental(实验性)」一词依模型提供商的描述而定,并非用于生产运营用途。
## LLM 速率限制
> 要点:各模型/层级的调用上限。
关于 LLM 速率限制的信息,请查阅 LLM 容量管理文档。
### LLM availability by geography
由于地理限制(简称 georestriction),某些 enrollment 可能只能访问有限的模型集合;某一区域的地理限制意味着发往 LLM 的任何 AIP 请求都保持在该区域边界内。例如,如果某个 enrollment 被定义为欧盟地理受限,则所有 LLM 请求都将在欧盟境内处理。未受地理限制的 enrollment 可以访问 Palantir 支持的全部模型。
下表列出了 AIP 所支持各模型可采用的地理限制区域选项。区域地理限制指的是 enrollment 的设置,而非特定用户所在的位置。
Model Provider Model US EU UK CA AU JP KSA IL2 IL4 IL5 Anthropic Claude Haiku 4.5 ✅ Amazon Bedrock Claude Haiku 4.5 ✅ ✅ ✅ ✅ Azure Claude Haiku 4.5 Google Vertex Claude Haiku 4.5 ✅ ✅ ✅ ✅ Amazon Bedrock Claude Opus 4.1 ✅ Google Vertex Claude Opus 4.1 ✅ ✅ Anthropic Claude Opus 4.5 ✅ Amazon Bedrock Claude Opus 4.5 ✅ ✅ Azure Claude Opus 4.5 Google Vertex Claude Opus 4.5 ✅ ✅ ✅ ✅ Anthropic Claude Opus 4.6 ✅ Amazon Bedrock Claude Opus 4.6 ✅ ✅ ✅ Azure Claude Opus 4.6 Google Vertex Claude Opus 4.6 ✅ ✅ ✅ ✅ Anthropic Claude Opus 4.7 ✅ Amazon Bedrock Claude Opus 4.7 ✅ ✅ ✅ Azure Claude Opus 4.7 Google Vertex Claude Opus 4.7 ✅ ✅ ✅ ✅ Anthropic Claude Opus 4.8 ✅ Amazon Bedrock Claude Opus 4.8 ✅ ✅ ✅ ✅ ✅ Azure Claude Opus 4.8 Google Vertex Claude Opus 4.8 ✅ ✅ ✅ ✅ Anthropic Claude Opus 5 ✅ Amazon Bedrock Claude Opus 5 ✅ ✅ ✅ Azure Claude Opus 5 Google Vertex Claude Opus 5 ✅ ✅ ✅ ✅ Google Vertex Claude Sonnet 4 ✅ ✅ ✅ ✅ Anthropic Claude Sonnet 4.5 ✅ Amazon Bedrock Claude Sonnet 4.5 ✅ ✅ ✅ Azure Claude Sonnet 4.5 Google Vertex Claude Sonnet 4.5 ✅ ✅ ✅ ✅ Anthropic Claude Sonnet 4.6 ✅ Amazon Bedrock Claude Sonnet 4.6 ✅ ✅ ✅ ✅ ✅ Azure Claude Sonnet 4.6 Google Vertex Claude Sonnet 4.6 ✅ ✅ ✅ ✅ Anthropic Claude Sonnet 5 ✅ Amazon Bedrock Claude Sonnet 5 ✅ ✅ ✅ Azure Claude Sonnet 5 Google Vertex Claude Sonnet 5 ✅ ✅ ✅ ✅ Google Vertex Gemini 3 Flash (Preview) ✅ ✅ ✅ ✅ Google Vertex Gemini 3.1 Flash Lite ✅ ✅ ✅ ✅ ✅ Google Vertex Gemini 3.1 Pro (Preview) ✅ ✅ ✅ ✅ Google Vertex Gemini 3.5 Flash ✅ ✅ ✅ ✅ ✅ Google Vertex Gemini 3.5 Flash-Lite ✅ ✅ ✅ ✅ ✅ Google Vertex Gemini 3.6 Flash ✅ ✅ ✅ ✅ ✅ Google Vertex Gemini 3.7 Flash ✅ ✅ ✅ ✅ ✅ Amazon Bedrock Gemma 4 26B A4B ✅ ✅ Amazon Bedrock Llama 3.1 8b Instruct ✅ Palantir-hosted Llama 3.1 8b Instruct Amazon Bedrock Llama 3.3 70b Instruct ✅ Palantir-hosted Llama 3.3 70b Instruct Amazon Bedrock Llama 4 Maverick 17b 128E Instruct ✅ Amazon Bedrock Llama 4 Scout 17b 16E Instruct ✅ Palantir-hosted Llama 4 Scout 17b 16E Instruct Palantir-hosted Llama 3.2 NV EmbedQA 1B v2 Palantir-hosted Llama 3.3 Nemotron Super 49b v1.5 Amazon Bedrock NVIDIA Nemotron 3 Nano 30B ✅ Amazon Bedrock NVIDIA Nemotron 3 Super 120B ✅ ✅ ✅ ✅ Azure GPT-4.1 ✅ ✅ ✅ ✅ ✅ OpenAI GPT-4.1 ✅ Azure GPT-4.1 mini ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ OpenAI GPT-4.1 mini ✅ Azure GPT-4.1 nano ✅ ✅ Azure GPT-4o ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ OpenAI GPT-4o ✅ Azure GPT-5 ✅ ✅ Azure GPT-5 Codex Azure GPT-5 mini ✅ ✅ Azure GPT-5 nano ✅ ✅ Azure GPT-5.1 ✅ ✅ ✅ ✅ ✅ ✅ OpenAI GPT-5.1 ✅ Azure GPT-5.1 Codex Azure GPT-5.1 Codex mini Azure GPT-5.2 ✅ OpenAI GPT-5.2 ✅ OpenAI GPT-5.2 Pro ✅ Azure GPT-5.3 Codex ✅ OpenAI GPT-5.3 Codex Azure GPT-5.4 ✅ ✅ OpenAI GPT-5.4 ✅ OpenAI GPT-5.4 Pro ✅ Azure GPT-5.4 mini ✅ OpenAI GPT-5.4 mini ✅ Azure GPT-5.4 nano ✅ OpenAI GPT-5.4 nano ✅ Azure GPT-5.5 ✅ ✅ OpenAI GPT-5.5 ✅ Azure GPT-5.6 Luna ✅ ✅ OpenAI GPT-5.6 Luna ✅ Azure GPT-5.6 Sol ✅ ✅ OpenAI GPT-5.6 Sol ✅ Azure GPT-5.6 Terra ✅ ✅ OpenAI GPT-5.6 Terra ✅ Palantir-hosted GPT-OSS-120B ✅ ✅ ✅ ✅ Palantir-hosted GPT-OSS-20B ✅ ✅ ✅ ✅ Azure Text Embedding 3 Large ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ OpenAI Text Embedding 3 Large ✅ Azure Text Embedding 3 Small ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ OpenAI Text Embedding 3 Small ✅ OpenAI Whisper 1 ✅ Azure o1 ✅ ✅ Azure o3 ✅ ✅ Azure o3-mini ✅ ✅ ✅ ✅ ✅ Azure o4-mini ✅ ✅ Azure text-embedding-ada-002 ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ OpenAI text-embedding-ada-002 ✅ Palantir-hosted Document Information Extraction ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ Palantir-hosted Gemma 4 26B A4B ✅ ✅ ✅ ✅ Palantir-hosted Schematic 7B ✅ ✅ ✅ Palantir-hosted Whisper Large V3 ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ Palantir-hosted Snowflake Arctic Embed Medium xAI Grok 4.3 ✅ xAI Grok 4.5 ✅ xAI Grok 420 Non-Reasoning Latest ✅ xAI Grok 420 Reasoning Latest ✅ xAI Grok Build 0.1 ✅
## 自带模型(LLM)
> 要点:平台模型不够用时,怎么接自己的。
自带模型(Bring your own model)是一项能力,为希望连接自己的 LLM 或账号、以便在 AIP 中与所有 Palantir 开发者产品(AIP Logic、Pipeline Builder、Chatbot Studio、Workshop 等)一起使用的客户提供一等支持。
请查阅自带模型文档,了解如何注册模型以便在 AIP 中使用。
注意:AIP 功能的可用性可能会发生变化,且可能因客户而异。
「OpenAI」名称与「GPT」品牌归 OpenAI 所有。
本文提及的所有第三方商标(包括徽标和图标)均归其各自所有者所有。不暗示任何关联或背书关系。
### 常见问题速答 · FAQ
关于「平台支持的 LLM 清单」,读者最常问的几个问题。
可用的 LLM是什么? 对话/生成类模型清单与能力对照。以下 LLM 受支持,可与 AIP 配合使用,具体取决于 enrollment 的可用性。
可用的文本嵌入模型是什么? 做检索、语义搜索要选这类模型。Palantir AIP 还支持以下文本嵌入模型。
可用的音频模型是什么? 语音相关场景用。在部署任何录制或转写人类语音的应用之前,请确保已通知参与者,并在你所在司法管辖区要求的情况下准备好同意确认流程。无论被录音者是应用用户、通话中的第三方,还是其他任何被采集到声音的人,这一点都可能适用。参见录音、转写与同意。
LLM 可用性前提是什么? 哪些条件下这些模型才可用。AIP 与模型无关,为 LLM 驱动的用例提供了多样化的模型选择;更多信息请参阅 AIP 中所有可用模型的列表。
---
## 把自定义内容源投递给用户
- 页面:https://www.hanzhongpin.xyz/ontology/aip-assist-adding-documentation-to-aip-assist.html
- 官方原文:https://www.palantir.com/docs/foundry/assist/adding-documentation-to-aip-assist/
- 主题分组:AIP Assist(五)
循序渐进 · AIP 教学 · AIP Assist(五)
# 把自定义内容源投递给用户
注册完还不够,要在 Control Panel 里配置它对哪些用户可见,才能真正用上。
## 先记住这几条
① 注册 ≠ 可用 还要配置可见性。
② 入口在 Control Panel 管理员在统一控制台配置。
③ 可精细控制范围 按用户组分配,避免信息越权。
## 写在前面
在自定义内容源注册后,你可以通过在 Control Panel 中配置其对用户的可用性,来用 AIP Assist 提供该自定义内容源。此功能会将自定义源加入到现有的、AIP Assist 在默认模式下用于回答所有问题的较大搜索上下文中。
在使自定义源可供 AIP Assist 使用时,你可以选择它是仅在特定资源或一组资源打开时才被提供,还是始终被提供。如果你选择始终向用户提供内容,则无论用户在使用 AIP Assist 时正在查看何种资源,AIP Assist 都会使用该自定义源来回答用户查询。我们建议将这一功能用于自定义的、平台级的内容,这类内容在与 AIP Assist 在默认模式下存储于其搜索上下文中的平台文档和开发者文档一起使用时会有价值。
## 向 AIP Assist 注册内容源
> 要点:登记这一步。
第一步是注册你的内容源,并使其在 AIP Assist 中可用。根据你的需求,查阅从 Notepad 或平台内自定义文档注册内容的说明。
## 为你的用户开启内容源可见性
> 要点:控制谁能看到 —— 别越权。
一旦你的自定义源注册到 AIP Assist,你将需要为你的 enrollment 上的用户配置其可见性。
以下步骤必须由具有 Control Panel 访问权限的平台管理员完成。
- 导航到 Control Panel,选择你的 enrollment,然后打开 AIP Assist 页面。

- 选择 + Add,这将打开一个列出当前已摄取文档的对话框。

- 找到相关文档,选中它并添加。默认情况下,添加的源仅在用于创建它的仓库或 Notepad 文档中可见。这一可见性级别可用于测试 AIP Assist 的回答是否按预期工作。

- 在包含你内容的自定义文档仓库或 Notepad 文档中,打开 AIP Assist 并输入与你的产品具体相关的问题,以确认 AIP Assist 按预期作答。

- 当你对回答有信心并希望更广泛地公开它们时,通过导航到 Control Panel > AIP Assist 重新配置可见性。找到你的内容源并选择 Manage。

- 如果内容对你的用户在 Foundry 中的任何位置都相关,请选择 Always。

- 如果内容仅在特定上下文中相关,例如在某个 Workshop 应用中,请选择 By resource 并添加一个或多个相关资源。

- 保存你的更改。
现在,当 AIP Assist 被问及相关主题时,用户将能够根据可见性设置访问你的内容。
### 常见问题速答 · FAQ
关于「把自定义内容源投递给用户」,读者最常问的几个问题。
向 AIP Assist 注册内容源是什么? 登记这一步。第一步是注册你的内容源,并使其在 AIP Assist 中可用。根据你的需求,查阅从 Notepad 或平台内自定义文档注册内容的说明。
为你的用户开启内容源可见性是什么? 控制谁能看到 —— 别越权。一旦你的自定义源注册到 AIP Assist,你将需要为你的 enrollment 上的用户配置其可见性。
---
## 部署由自定义源驱动的 AIP Chatbot
- 页面:https://www.hanzhongpin.xyz/ontology/aip-assist-agents-in-aip-assist.html
- 官方原文:https://www.palantir.com/docs/foundry/assist/agents-in-aip-assist/
- 主题分组:AIP Assist(六)
循序渐进 · AIP 教学 · AIP Assist(六)
# 部署由自定义源驱动的 AIP Chatbot
自定义内容源还能进一步变成独立的对话机器人(通过 AIP Chatbot Studio),面向特定场景提供聚焦的协助。
## 先记住这几条
① 从"助手的一个源"升级为"独立机器人" 场景更聚焦,体验更专一。
② 与 Chatbot Studio 打通 用同一套内容源驱动。
③ 适合特定业务场景 不必让用户在海量文档里找答案。
## 写在前面
用 AIP Assist 提供自定义内容源,能极大地扩展可供用户使用的应用协助。此功能还与 AIP Chatbot Studio(前身为 AIP Agent Studio)集成,允许用户设置使用自定义内容源、来自 Ontology 的上下文或函数等工具的专用 LLM 驱动助手。开发者现在无需编写代码或具备 LLM 专业知识,即可创建量身定制的助手。
举个示例用例,设想开发者正在构建一个需要向数百或数千名用户推广的应用。通过 AIP Chatbot Studio 与 AIP Assist 的集成,开发者现在可以快速配置并交付由 LLM 驱动的自定义助手(即 AIP Chatbot),以基于自定义内容源提供即时、交互式的支持。
## AIP Chatbot 与 Chatbot Studio
> 要点:两者关系说明。
要理解此功能,请先熟悉 AIP Chatbot 的概念以及 AIP Chatbot Studio 应用:
AIP Chatbots: 配备企业专属信息和工具的交互式、由 LLM 驱动的助手。
AIP Chatbot Studio: 允许用户构建无代码的 AIP Chatbot,并将其在 Palantir 平台内部署,以及通过我们的 OSDK 在外部部署。
## 创建内容并注册自定义源
> 要点:准备工作。
创建基于自定义源的 AIP Chatbot 的第一步,是将你的自定义内容放到 Palantir 平台上。目前有两种添加可注册到 AIP Assist 的自定义内容源的方法:
- (推荐) Notepad 文档
- 平台内的自定义文档(Code Repositories 中 documentation 类型仓库里的 Markdown 文件)。
在本教程中,我们将探讨第一种方式。有关此功能的更多信息,请参阅向 AIP Assist 注册内容源。
> 此功能目前可能并非在所有 enrollment 上都可用。如果你没有看到将 Notepad 文档添加到 AIP Assist 的选项,请联系你的 Palantir 代表,确认你的 enrollment 是否符合条件。
- 在 Notepad 中,通过选择 + New document 创建新文档。编写或粘贴你的内容,并为你的文档设置标题和对其内容的简要描述。在下文示例中,我们添加了关于示例应用——Inventory Management Application 的信息。

> 图:Inventory Management Application Documentation
- 确保将你的内容组织成标题和小节。拥有标题结构能显著提升回答的准确性,因为内容会基于标题进行分段。更多信息请参阅自定义内容源最佳实践。
- 将你的内容注册到 AIP Assist。你可以通过选择 Actions > Add to AIP Assist 来完成。该选项可能需要一些时间才会出现,因为文档需要先被 AIP Assist 发现。

> 图:The "Add to AIP Assist" option in the Notepad actions dropdown menu.
- 为你的文档设置标题和简要说明文档内容的描述,然后保存。AIP Assist 和 AIP Chatbot 现在将知晓此文档。

> 图:Configure the "Add to AIP Assist" menu.
注意: 这不会以任何方式影响 AIP Assist 或 AIP Chatbot 的行为。这只是使内容可供 AIP Assist 使用。你仍然需要构建并部署一个利用它的 AIP Chatbot。
## 创建 AIP Chatbot 并部署到 AIP Assist
> 要点:核心操作。
- 导航到 AIP Chatbot Studio 应用,并选择 + New AIP Chatbot。
- 你将看到一个设置向导,用于协助创建 AIP Chatbot。首先为你的 chatbot 设置名称和描述。当用户发现并使用你的 chatbot 时,这些内容会展示给他们,因此请确保其具有描述性。你还可以为你的 chatbot 提供一个图标,以帮助被发现:

> 图:Configure the AIP Chatbot Name and Location.
注意: AIP Chatbot 是 Palantir 文件系统资源。它们将按其保存所在的文件系统位置进行权限管理。只有当用户对 chatbot 保存的位置具有读取权限,并且对支撑它的自定义内容源具有访问权限时,才能访问你的 chatbot。
- 保存 chatbot 后,你将被重定向到 AIP Chatbot Studio 编辑器。导航到 Chatbot configuration 部分,然后在 Retrieval context 下选择 Custom documentation context 并选择你之前已索引的文档。如果它没有出现在列表中,请回到第一步,确保你已将其添加到 AIP Assist。你可以选择许多不同的文档作为 AIP Chatbot 的搜索上下文。有关其他 AIP Chatbot 功能的更多信息,请参阅 AIP Chatbot Studio 文档。

> 图:Add context to AIP Chatbot.
- 你还可以选择希望 chatbot 使用的模型。你的 chatbot 的用户应有权访问该模型。此外,你可以通过提供自定义指令来定制 AIP Chatbot 的行为。

> 图:Configure Model and System Prompt.
- 通过选择右上角的蓝色对勾图标来发布你的 AIP Chatbot。这将发布你 chatbot 的第一个版本(1.0)。此后你所做的任何更改都需要发布新版本才能生效。

> 图:Publish AIP Chatbot.
- 使该 chatbot 可在 AIP Assist 中使用。为此,请打开 Usage 部分,并启用 AIP Assist 开关。

> 图:Deploy AIP Chatbot.
## 与新建的 AIP Chatbot 交互
> 要点:验证效果。
现在你已创建了一个 AIP Assist Chatbot 并为其提供了对你 Notepad 内容的访问权限,你可以开始在 AIP Assist 中与它交互了。
- 在 AIP Assist 中开始一段新对话。你应该能在 AIP Assist 的 Modes 选择器中看到你的新 chatbot。

> 图:Select AIP Chatbot from Modes selector.
- 选择你的 chatbot,然后发出你的第一个问题!

> 图:First AIP Chatbot Response.
### 常见问题速答 · FAQ
关于「部署由自定义源驱动的 AIP Chatbot」,读者最常问的几个问题。
创建内容并注册自定义源是什么? 准备工作。创建基于自定义源的 AIP Chatbot 的第一步,是将你的自定义内容放到 Palantir 平台上。目前有两种添加可注册到 AIP Assist 的自定义内容源的方法。
与新建的 AIP Chatbot 交互是什么? 验证效果。现在你已创建了一个 AIP Assist Chatbot 并为其提供了对你 Notepad 内容的访问权限,你可以开始在 AIP Assist 中与它交互了。
---
## 用自定义内容源驱动 AIP Assist
- 页面:https://www.hanzhongpin.xyz/ontology/aip-assist-aip-assist-custom-docs-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/assist/aip-assist-custom-docs-overview/
- 主题分组:AIP Assist(三)
循序渐进 · AIP 教学 · AIP Assist(三)
# 用自定义内容源驱动 AIP Assist
官方文档回答不了你公司内部的问题。这一组讲怎么把私有文档接进去,让助手也能回答运营与流程类问题。
## 先记住这几条
① 自定义源扩展回答范围 覆盖内部流程与专有知识。
② 聚焦的内容更有效 不是文档越多越好。
③ 注册与投递是两步 先注册内容源,再配置对用户可见。
## 写在前面
你可以使用自定义内容源来驱动 AIP Assist 的回答并提升平台可用性。自定义源可增强 AIP Assist 回应运营工作流程和平台导航等主题的能力,并根据你的运营需求提供量身定制的支持与资源。聚焦的内容对用户入门、培训课程以及推广自助服务和自动化尤为有益。你可以在 Control Panel 中管理和配置 AIP Assist 的访问级别,授予其在平台上任意位置的访问权限,或仅限选定的资源。
要向 AIP Assist 提供自定义源,你必须先使用两种可用方式之一引入它、将其注册到 AIP Assist,并在 Control Panel 中配置可见性和 AIP Assist 访问权限。
以下是可用于优化 AIP Assist 回答的内容示例:
- 项目文档
- 标准操作流程(Standard operating procedures,SOP)
- 公司 wiki
- 权限申请流程
- 数据摄取流程
- 最佳实践
- 用例和工作流程文档
## 要求
> 要点:内容源需要满足什么条件。
AIP Assist 中的自定义源是 Palantir AIP 产品的一部分,要求你的 enrollment 已在 Control Panel 中启用 AIP。
## 向 AIP Assist 注册自定义内容源
> 要点:第一步:登记内容。
目前有两种添加可注册到 AIP Assist 的自定义内容源的方法:
- (推荐) Notepad 文档
- 平台内的自定义文档(Code Repositories 中 documentation 类型仓库里的 Markdown 文件)。
更多信息请参阅向 AIP Assist 注册自定义内容源。
## 在 AIP Assist 中使用自定义内容源
> 要点:第二步:让用户能用上。
自定义源注册后,有两种将其与 AIP Assist 配合使用的方式。第一种是将其添加到你的 enrollment 的默认 AIP Assist 知识库中,或者另一种是在 Chatbot Studio 中创建一个 AIP Chatbot。以下小节将概述这两者的区别。
### Add a content source to the default AIP Assist knowledge base
在将自定义源添加到默认的 AIP Assist 知识库时,自定义内容会被加入到 AIP Assist 用于回答所有问题的更大搜索上下文中。这种方式提供了如下选项:使内容始终可用,无论用户正在查看何种资源;或仅当用户正在查看某个特定资源或一组资源时才可用。
更多信息请参阅向用户提供自定义内容源。
### Create a custom source-backed AIP Assist chatbot
在 AIP Assist 中使用自定义源的另一种方式,是创建一个 AIP Assist chatbot(即由 LLM 驱动的助手),它仅使用所提供的内容来回答查询。每个 chatbot 可以在其搜索上下文中添加一个或多个文档,当被选中时,它的回答将仅基于这些内容。因此,回答将限于所提供的内容源,但会更加精确和有针对性。
请参阅部署基于自定义源的 AIP Chatbots 以了解更多信息。
---
## 注册自定义内容源
- 页面:https://www.hanzhongpin.xyz/ontology/aip-assist-aip-assist-registering-content.html
- 官方原文:https://www.palantir.com/docs/foundry/assist/aip-assist-registering-content/
- 主题分组:AIP Assist(四)
循序渐进 · AIP 教学 · AIP Assist(四)
# 注册自定义内容源
这一步是把内部文档登记进平台,让 AIP Assist 能检索到它。用它可以加速工作流、改善新人上手、自动回答支持类问题。
## 先记住这几条
① 注册是前置动作 不注册,助手就看不到你的内容。
② 内容源有格式要求 要按规范组织。
③ 目的很务实 降支持成本、加速上手。
## 写在前面
利用 AIP Assist,通过让它从自定义内容源传递有针对性的指引,来加速工作流程、用户入门并自动化支持。你可以让 AIP Assist 提供来自平台内自定义文档或 Notepad 文档的现有内容,方法是注册你的内容源,使其可供 AIP Assist 使用。为此,请根据你的内容源,按以下步骤操作 Notepad 或平台内自定义文档。之后,还需要在 Control Panel 中进行额外配置,以允许 AIP Assist 在回答用户查询时提供你的内容。
在大多数情况下,我们推荐使用 Notepad,因为通过在 Workshop 等其他应用中嵌入,它在 Palantir 平台上具有广泛的用途。要了解更多信息,请查阅 Notepad 文档。如果平台内自定义文档更适合你的用例,但尚未启用,请联系你的 Palantir 代表为你的 enrollment 启用它。
我们强烈建议你在编写和更新内容时,查阅自定义内容源最佳实践。
## 用 Notepad 作为内容源
> 要点:轻量做法,适合小规模内容。
> 此功能目前可能并非在所有 enrollment 上都可用。如果你没有看到将 Notepad 文档添加到 AIP Assist 的选项,请联系你的 Palantir 代表,确认你的 enrollment 是否符合条件。
以下说明详细介绍了如何将 Notepad 文档添加为 AIP Assist 自定义内容源:
- 通过选择 + New Document 创建 Notepad 文档,或导航至现有文档。确保你的文档属于某个项目。
- 打开 Notepad 文档右上角的 Actions 下拉菜单,然后选择 Add to AIP Assist。这将打开一个对话框,你可以在其中授予 AIP Assist 对你的文档的访问权限。该选项可能需要一些时间才会出现,因为文档需要先被 AIP Assist 发现。

> 图:The "Add to AIP Assist" option in the Notepad actions dropdown menu.
- 在对话框中切换 Add to AIP Assist 选项,并填写 Documentation title 和 Description 字段。这些字段应具有描述性,并具体针对你文档中的内容。

> 图:The "Add to AIP Assist toggle, Documentation title, and Description fields.
- 选择 Save,并确保显示成功消息,确认文档已被摄取到 AIP Assist 中。

> 图:A sample success message after ingesting a Notepad document.
你的内容现已摄取到 AIP Assist 中,并将在 Control Panel 中可供可见性配置。请确保你首先按用户和组为 Notepad 文档配置可见性设置,因为 AIP Assist 会遵循现有权限。
## 用平台内自定义文档作为内容源
> 要点:正式做法,适合体系化文档。
> 要使用此功能,你必须在 Code Repositories 中已有一个 documentation 仓库。如果此功能对你的 enrollment 不可用,请联系你的 Palantir 代表启用 documentation 类型仓库,或者如果该功能已启用,则在创建后将该仓库加入白名单。

> 图:Initialize a Documentation repository from the Documentation template.
要授予 AIP Assist 对你平台内自定义文档的访问权限,请向你的 documentation 仓库添加内容,并选择加入以将信息提供给 AIP Assist。
- 确保你已在 Code Repositories 中初始化了一个 documentation 仓库。通过在 docs 文件夹中创建新文件夹(即 "product")来填充内容。

> 图:Create a product folder.
- 在一个 "product" 文件夹中(下文的 "Custom\_Docs\_Support\_Alert\_Example"),创建一个包含 @name 和 @description 的 overview.md 文件,随后以 Markdown 格式编写你的文档。

> 图:Create your @name, @description followed by documentation in your new product folder.
- 当你完成向 documentation 仓库填充内容后,将仓库顶层现有的 _aip-assist.json 文件重命名为 aip-assist.json。原始文件可能会在一段时间后重新生成;无需进行任何操作。
- 在该文件中,列出你想要选择加入 AIP Assist 的 "product" 文件夹及其描述。该描述将提供给 AIP Assist,以便它评估何时查询自定义文档。确保描述全面且简洁。提交你的更改,并确保文档作为检查的一部分被发布。

> 图:Opt-in to ingesting it to AIP Assist.
## 常见问题
> 要点:注册相关的疑问。
### Will content updates in custom documentation or Notepad documents be reflected in the information AIP Assist provides to users?
平台内自定义文档或 Notepad 文档中的每一次更新都会自动传播并更新我们的数据库。无需进一步操作即可更新 AIP Assist 中的内容。
### Why are images not visible in AIP Assist responses?
目前,AIP Assist 仅显示来自 Palantir 公共文档和平台内自定义文档的图片,但我们正在努力使其也支持 Notepad 图片。在此之前,我们建议在图片下方添加描述。这些文本将在 AIP Assist 中呈现,并且答案中会添加行内引用。当用户选择引用时,他们将被重定向到你的内容,在那里可以查看任何相关图片。
### Why is the AIP Assist button not visible under actions in Notepad?
目前,你无法将空的 Notepad 文档添加到 AIP Assist,因此请确保你的文档包含内容。如果你刚刚添加了内容或向 Notepad 粘贴了一份大型文档,请给它一些时间来更新,因为新资源可能需要一些时间才能传播。
请确保你的 enrollment 已启用 AIP,你的 Notepad 文档位于某个项目中,并且该项目具有组织标记(Markings)。
### 常见问题速答 · FAQ
关于「注册自定义内容源」,读者最常问的几个问题。
用平台内自定义文档作为内容源是什么? 正式做法,适合体系化文档。要使用此功能,你必须在 Code Repositories 中已有一个 documentation 仓库。如果此功能对你的 enrollment 不可用,请联系你的 Palantir 代表启用 documentation 类型仓库,或…
还有哪些问题? 注册相关的疑问。平台内自定义文档或 Notepad 文档中的每一次更新都会自动传播并更新我们的数据库。无需进一步操作即可更新 AIP Assist 中的内容。
---
## AIP Assist 的建议动作
- 页面:https://www.hanzhongpin.xyz/ontology/aip-assist-aip-assist-suggested-actions.html
- 官方原文:https://www.palantir.com/docs/foundry/assist/aip-assist-suggested-actions/
- 主题分组:AIP Assist(九)
循序渐进 · AIP 教学 · AIP Assist(九)
# AIP Assist 的建议动作
助手会主动推荐"下一步可以做什么",包括导航类和操作类建议 —— 对新人尤其友好。
## 先记住这几条
① 从被动问答到主动引导 不等你问,先告诉你下一步。
② 两类建议 导航类(去哪)与操作类(做什么)。
③ 新人友好 降低首次使用的摸索成本。
## 写在前面
AIP Assist 可以提供导航性和应用内的操作建议,以更好地引导和支持用户在 Foundry 中的使用。这对首次使用的用户尤其有用,他们可以在与 AIP Assist 交互后了解各项操作,或收到应用及功能建议。

> 图:Example suggested action in AIP Assist
## 与 Palantir 开发者社区论坛的集成
> 要点:从这里直达社区求助。
AIP Assist 与 Palantir Developer Community ↗ 集成,当 AIP Assist 没有所需信息时,会引导用户创建论坛帖子。此操作会打开一个对话框,其中包含基于当前对话的建议标题和描述,可用于论坛帖子。

> 图:Suggested action in AIP Assist that directs users to the Palantir Developer Community forum
引导用户前往 Palantir Developer Community 论坛的建议操作,可以由 enrollment 管理员在 Control Panel 的 AIP Assist 页面上禁用。

> 图:View in Control Panel to manage the suggested action in AIP Assist that directs users to the Palantir Developer Community forum
---
## AIP Assist 最佳实践
- 页面:https://www.hanzhongpin.xyz/ontology/aip-assist-aip-best-practices.html
- 官方原文:https://www.palantir.com/docs/foundry/assist/aip-best-practices/
- 主题分组:AIP Assist(二)
循序渐进 · AIP 教学 · AIP Assist(二)
# AIP Assist 最佳实践
同样一个助手,会问的人和不会问的人拿到的答案质量差很多。这一篇讲怎么高效跟它打交道。
## 先记住这几条
① 它具备上下文感知 利用好这一点,问题可以更简短。
② 提问要具体 模糊的问题只能得到模糊的答案。
③ 迭代式追问 一轮问不明白就追问,别重开。
## 写在前面
AIP Assist 是一款由 LLM 驱动的支持工具,它熟知 Palantir 产品文档及相关信息。你可以与 AIP Assist 交互,以获取针对 Foundry 平台的帮助与支持。AIP Assist 具备上下文感知能力,知晓你当前所处的应用,但无法访问你正在使用的任何数据或元数据。
## 与 AIP Assist 交互的最佳实践
> 要点:怎么问才问得准。
以下是一些改善你使用 AIP Assist 体验的建议:
- 具体明确: 提问时,尽量做到尽可能具体。提供你所要询问的产品或功能的细节。这将帮助 AIP Assist 更好地理解你的问题,并给出更准确的回答。
- 提出清晰的问题: 避免在一句话中提出多个问题。相反,一次只问一个问题,以免造成混淆。
- 提出追问: 如果你不理解 AIP Assist 的回答,或需要更多信息,请提出额外的问题以澄清查询。尝试换一种措辞重新表述你的问题,看看能否得到更准确的回答。
- 使用完整句子: 与 AIP Assist 交互时使用完整句子,以提供更多关于你究竟希望得到何种解答的上下文。
- 提供示例: 提供关于你所寻找内容的示例。当给出具体的格式要求时,AIP Assist 的回答会更好。
## AIP Assist 的问题示例
> 要点:可直接照抄的提问模板。
你可以通过提出带有具体细节的清晰、聚焦的问题,从 AIP 获得最佳结果。以下示例问题更有可能从 AIP Assist 得到有用且有益的回应:
- 聚焦的问题: 我该如何排查这条错误信息"Cannot solve for environment specs"?
- 聚焦的问题: 你能解释一下如何为 Contour 配置时区设置吗?
- 聚焦的问题: 你能提供一个关于如何在 Functions on Objects 中编写 Aggregate Function 的示例吗?
- 聚焦的问题: 我该如何在 Slate 中配置 CSS 样式?
- 聚焦的问题: 你能编写一个 Python transform,处理一个名为 "id" 的列,提取连字符前面的两个字符吗?例如,"AB-02" 应返回 "AB","cd-1" 应返回 "cd",而 "123-MA" 不应匹配。
以下示例问题由于缺乏具体性、清晰度或细节,不太可能从 AIP Assist 得到有用的回答。
- 不聚焦的问题: 这个东西不管用了,哪里出问题了?
- 不聚焦的问题: 这个按钮是做什么的?
- 不聚焦的问题: 我该怎么用这个东西?
- 不聚焦的问题: 我怎样才能让它看起来更好?
- 不聚焦的问题: Python 提取 2 个字符的字符串
注意:AIP 功能可用性可能会发生变化,并且可能因客户而异。
### 常见问题速答 · FAQ
关于「AIP Assist 最佳实践」,读者最常问的几个问题。
与 AIP Assist 交互的最佳实践是什么? 怎么问才问得准。以下是一些改善你使用 AIP Assist 体验的建议。
AIP Assist 的问题示例是什么? 可直接照抄的提问模板。你可以通过提出带有具体细节的清晰、聚焦的问题,从 AIP 获得最佳结果。以下示例问题更有可能从 AIP Assist 得到有用且有益的回应。
---
## AIP Assist 的应用集成
- 页面:https://www.hanzhongpin.xyz/ontology/aip-assist-application-integrations.html
- 官方原文:https://www.palantir.com/docs/foundry/assist/application-integrations/
- 主题分组:AIP Assist(八)
循序渐进 · AIP 教学 · AIP Assist(八)
# AIP Assist 的应用集成
AIP Assist 不只是个浮窗,它与平台各应用有多处集成点,让你在具体应用里就能拿到针对性帮助。
## 先记住这几条
① 集成点遍布各应用 在哪个应用就能问哪个应用的问题。
② 降低获取帮助的成本 不用跳出当前工作。
③ 集成在持续扩展 官方仍在评估新的集成。
## 写在前面
AIP Assist 提供了与 Palantir 平台上其他应用的各种集成点,我们也在持续评估这些集成,以改进和扩展 AIP Assist 的覆盖面。这些集成简化了常见工作流程,并降低了从 AIP Assist 获取帮助的阻力成本。如果你对额外的、高价值的集成有任何想法,请在我们的开发者社区论坛的 Get Involved ↗ 版块发帖告知我们。AIP Assist 应用集成旨在平台内高度可见,但你也可以查阅以下参考,以探索可用的集成。
## Code Repositories 中的 AIP Assist
> 要点:写代码时的助手。
### Ask AIP Assist
在 Code Repositories 中查看代码文件时,你会看到 Ask AIP Assist 助手,它提供了一系列预配置的、与代码相关的操作,AIP Assist 可以执行这些操作来协助开发。
![图]()
### Code repository attachments
在 Code Repositories 中,AIP Assist 侧边栏会显示配置选项,允许你添加附件,为 AIP Assist 提供额外的上下文。你可以选择包含多种不同的组件,包括整个仓库、一个或多个文件,或一段高亮显示的代码片段。

> 图:The AIP Assist attachment options in Code Repositories.
借助此功能,你可以让 AIP Assist:
- 解释不同文件之间的关系。
- 优化代码片段。
- 在整个仓库中搜索特定代码。
- 总结或解释代码片段、文件或整个仓库。

> 图:A sample question to AIP Assist asking for optimized code.
AIP Assist 还可以访问附件中所引用数据集和对象的元数据,使用户能够就 Ontology 对象以及输入或输出数据集提出具体问题。

> 图:A sample question asking AIP Assist about dataset metadata.
## Carbon 工作区中的 AIP Assist
> 要点:工作区场景。
你可以在 Carbon 工作区中选择 Enable AIP Assist,以允许用户与专为支持特定用户群而定制的 AIP Assist chatbot(前身为 AIP Assist agent)交互。这要求在 AIP Chatbot Studio 中配置专用的 AIP Assist chatbot 供用户交互。
更多信息请参阅在 Carbon 工作区中启用 AIP Assist。
## Contour 中的 AIP Assist
> 要点:分析场景。
在使用 Contour 中的表达式看板(expression board)时,你可以让 AIP Assist 执行若干与编写表达式相关的不同操作,例如解释代码、查找缺陷以及将代码转换为表达式。

> 图:AIP Assist options in Contour.
## Workshop 中的 AIP Assist
> 要点:应用搭建场景。
### Send to AIP Assist
Workshop 的 Button 微件允许开发者添加 Send to AIP Assist 事件,该事件将打开 AIP Assist 并向其发送一个预配置的提示,该提示基于静态文本或动态变量值。
当与基于自定义文档训练的 AIP Assist Agent 配合使用时,此功能非常强大,这些自定义文档描述的是使用 Send to AIP Assist 按钮微件的那个 Workshop 应用。在 Workshop 中配置 Send to AIP Assist 事件时,可以设置用于响应所配置提示的默认 AIP Assist Agent。
更多信息请参阅 Send to AIP Assist 事件的文档。
## Slate 中的 AIP Assist
> 要点:定制前端场景。
### Ask AIP Assist
你可以使用 slate.askAIPAssist 操作来打开 AIP Assist,并指定一个可选的 prompt 字符串参数,该参数将作为用户的消息发送给 AIP Assist。prompt 可以从当前用户的应用状态中派生,以便向 AIP Assist 提出有针对性的问题。
更多信息请参阅 Slate Ask AIP Assist 文档。
## Issues 中的 AIP Assist
> 要点:问题跟踪场景。
### AIP Assist in the issue submission form
为方便平台内支持,AIP Assist 已被整合到 Issues 应用的问题提交流程中。用户可以在提交问题之前选择 Open AIP Assist and get immediate help 来咨询 AIP Assist。

> 图:AIP Assist in the issue submission flow.
### AIP Assist in issues
如果你已经创建了一个问题,可以使用集成的 AIP Assist 工具来获取即时支持。AIP Assist 既可以根据问题信息和用户提问来提供对该问题的回答,也可以总结冗长的问题以优化问题解决。

> 图:The option to ask AIP Assist to answer or summarize an issue.
## Ontology Manager 中的 AIP Assist
> 要点:本体建模场景。
AIP Assist 已与 Ontology Manager 集成,以协助解决 Ontology 更新期间的错误。在更新 Ontology 时,导航到 Errors 选项卡,并在某个错误上选择 Explain with AIP Assist,让 AIP Assist 提供错误解决的建议操作和错误解释。

> 图:The AIP Assist option in Ontology Manager.
### 常见问题速答 · FAQ
关于「AIP Assist 的应用集成」,读者最常问的几个问题。
Slate 中的 AIP Assist是什么? 定制前端场景。你可以使用 slate.askAIPAssist 操作来打开 AIP Assist,并指定一个可选的 prompt 字符串参数,该参数将作为用户的消息发送给 AIP Assist。
Issues 中的 AIP Assist是什么? 问题跟踪场景。为方便平台内支持,AIP Assist 已被整合到 Issues 应用的问题提交流程中。用户可以在提交问题之前选择 Open AIP Assist and get immediate help 来咨询 AIP Assist。
---
## 自定义内容源最佳实践
- 页面:https://www.hanzhongpin.xyz/ontology/aip-assist-custom-documentation-best-practices.html
- 官方原文:https://www.palantir.com/docs/foundry/assist/custom-documentation-best-practices/
- 主题分组:AIP Assist(七)
循序渐进 · AIP 教学 · AIP Assist(七)
# 自定义内容源最佳实践
要让答案好,先得懂原理:AIP Assist 底层用的是检索增强生成(RAG)。这一篇从 RAG 机制反推内容该怎么写。
## 先记住这几条
① 底层机制是 RAG 检索相关内容 → 拼进提示词 → 生成回答。
② 内容要便于检索 结构清晰、颗粒度合适。
③ 写得烂 = 答案烂 垃圾进,垃圾出。
## 写在前面
为改善 AIP Assist 的回答,理解其底层机制检索增强生成 ↗(retrieval augmented generation,RAG)至关重要。该过程会将你的内容拆分为简洁、聚焦的段落。当提出问题后,RAG 会识别并检索与问题最相关的段落。AIP Assist 随后使用这些选定的段落,连同来自公共文档的信息,来构建回答。
鉴于这种方式,你内容的粒度会显著影响回答的质量。最佳实践是基于标题和子标题将内容组织成离散的章节。每个标题最好专注于单一主题或问题,确保其下的内容与该主题高度相关且具体。
## 结构清晰
> 要点:便于检索的组织方式。
假设你内容中的某个章节讨论了某个软件产品的各项功能。与其创建像这样又长又涉及多个主题的段落:
Feature A helps with productivity by automating tasks. Feature B enhances security through encryption. Feature C offers real-time collaboration tools, and Feature D provides detailed analytics.
不如将其拆分为聚焦的小节:
markdown ## Feature A: Automation
Feature A boosts productivity by automating repetitive tasks, streamlining workflows.
## Feature B: Security
Feature B secures data with advanced encryption techniques, protecting against unauthorized access.
## Feature C: Collaboration
Feature C enables real-time collaboration, allowing teams to work together seamlessly.
## Feature D: Analytics
Feature D offers comprehensive analytics, giving insights into performance metrics.
以这种方式组织你的内容,能让 AIP Assist 更高效地检索与具体询问相关的信息,从而提升其回答的准确性和有用性。
## 避免与公开文档冲突
> 要点:内容重叠会降低检索准确度。
AIP Assist 还会搜索 Palantir 平台的公共文档来构建回答。因此,确保你的自定义内容不会无意中与这些公共文档中的信息重叠或冲突至关重要。当使用与公共文档中常见或相似的术语时(例如 "build"、"code repository"),务必在你的上下文中清晰地定义或区分它们。这种澄清有助于 AIP Assist 区分名称相似的概念,并提供更准确、更具上下文针对性的回答。
## 避免弃用或覆盖内容
> 要点:别留下过时信息。
当流程或工作流程发生更新时,避免将过时文档标记为已弃用或添加覆盖说明。相反,应在源处更新内容,或删除任何无效的文档。
例如,与其使用以下内容:
markdown (Note: This document is now deprecated.)
In case of a high priority issue, contact abx@xyz.com directly.
或
markdown In case of a high priority issue, contact abx@xyz.com directly.
...
...
(Update: As of July 31, create a service ticket on the management system instead of sending an email to abx@xyz.com.)
不如将内容更新为精炼且最新的形式,例如:
markdown In case of a high priority issue, create a service ticket on the management system.
### 常见问题速答 · FAQ
关于「自定义内容源最佳实践」,读者最常问的几个问题。
结构清晰是什么? 便于检索的组织方式。假设你内容中的某个章节讨论了某个软件产品的各项功能。与其创建像这样又长又涉及多个主题的段落。
避免与公开文档冲突是什么? 内容重叠会降低检索准确度。AIP Assist 还会搜索 Palantir 平台的公共文档来构建回答。因此,确保你的自定义内容不会无意中与这些公共文档中的信息重叠或冲突至关重要。
避免弃用或覆盖内容是什么? 别留下过时信息。当流程或工作流程发生更新时,避免将过时文档标记为已弃用或添加覆盖说明。相反,应在源处更新内容,或删除任何无效的文档。
---
## AIP Assist 总览:平台里的 AI 助手
- 页面:https://www.hanzhongpin.xyz/ontology/aip-assist-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/assist/overview/
- 主题分组:AIP Assist(一)
循序渐进 · AIP 教学 · AIP Assist(一)
# AIP Assist 总览:平台里的 AI 助手
AIP Assist 是内建在平台里的 LLM 支持工具:用自然语言问它怎么用 Palantir,实时拿到答案。它同时是"产品文档的对话式入口"。
## 先记住这几条
① 定位是产品内助手 帮用户导航、理解、用好平台。
② 有上下文感知 知道你当前在哪个应用、在做什么。
③ 熟悉官方文档 答案基于 Palantir 产品文档。
④ 可以被私有内容增强 把你的内部文档喂给它。
## 写在前面
AIP Assist 是一款由 LLM 驱动的支持工具,旨在帮助用户使用 Palantir 平台进行导航、理解并创造价值。用户可以用自然语言向 AIP Assist 提问,并实时获得针对其问题的帮助。
使用 AIP Assist 的好处包括:
- 用户友好的界面: 由 LLM 驱动,AIP Assist 拥有直观的界面,使用户能够轻松提问并获得相关、自然且易于理解的回答。
- 实时协助: AIP Assist 提供实时协助,帮助用户快速解决问题和疑问,在提高用户生产力的同时减少对支持团队的依赖。
- 多语言支持: AIP 可以用所有常见语言回答查询。
- 上下文感知: AIP Assist 旨在保持对话的上下文,并知晓你当前所处的 Foundry 应用。
- Foundry 级安全性: AIP Assist 完全遵守 Palantir 的 AI Ethics Principles ↗,且不会访问你的数据。
- 迭代改进: 用户可以对 AIP Assist 回答的质量提供反馈,以在持续开发过程中帮助改进该工具。
## 进入 AIP Assist
> 要点:在哪里找到这个助手。
> 仅当你的平台管理员已在 Control Panel 中启用 AIP 时,AIP Assist 才可用。
你可以通过在工作区导航栏底部选择 AIP Assist,或使用键盘快捷键(MacOS 上为 Cmd+Shift+U,Windows 上为 Ctrl+Shift+U)来访问 AIP Assist。AIP Assist 将如下方截图所示出现在一个面板中:

> 图:AIP Sidebar overview screenshot
## 从 AIP Assist 获取支持
> 要点:怎么提问、能得到什么。
用户可以在 Ask a question... 输入框中以纯文本形式输入查询。AIP Assist 基于 Palantir 的平台文档进行了训练,并使用自然语言处理(Natural Language Processing,NLP)和第三方大语言模型(Large Language Models,LLM)来解析用户的查询,并在符合 Palantir 安全标准的前提下提供最相关的回答。

> 图:AIP Sidebar overview screenshot
## 用模式和 AIP Chatbot 聚焦助手体验
> 要点:把通用助手变成专用助手。
AIP Assist 开箱即提供了若干预配置模式(mode),以便根据你的工作流程提供更贴合需求的体验。以下是可用模式的概述:
- AIP Assist(默认): 在平台文档、开发者文档和自定义内容源之间动态选择。
- Platform Documentation Assist: 基于平台文档回答问题。
- Developer Assist: 专精于 Foundry API 和常见开发者示例。
- AIP Chatbots: 由用户开发的、由 LLM 驱动的交互式助手,配备了企业专属信息。更多信息请参阅 AIP Chatbots in Assist。

> 图:Mode Selector
## 添加自定义内容源增强 AIP Assist
> 要点:让它也能回答你公司内部的问题。
你可以添加自定义内容源(custom content source)并用它们来改进 AIP Assist 体验。目前有两种添加可注册到 AIP Assist 的自定义内容源的方法:
- (推荐) Notepad 文档
- 平台内的自定义文档(Code Repositories 中 documentation 类型仓库里的 Markdown 文件)。
更多信息请参阅向 AIP Assist 注册自定义内容源。
### Use custom sources with AIP Assist
自定义源创建并注册后,有两种使用它来增强 AIP Assist 体验的方式:
- 将其添加到默认的 AIP Assist 知识库。
- 创建一个 AIP Chatbot。
将内容源添加到默认的 AIP Assist 知识库,会将其与你 enrollment 上为 AIP Assist 预加载的更大搜索上下文一起纳入。相比之下,AIP Assist chatbot 是交互式、由 LLM 驱动的助手,它们仅将所提供的自定义内容源用作搜索上下文,从而成为针对你在 Palantir 平台上工作流程的、聚焦且量身定制的支持工具。
注意:AIP 功能可用性可能会发生变化,并且可能因客户而异。
### 常见问题速答 · FAQ
关于「AIP Assist 总览:平台里的 AI 助手」,读者最常问的几个问题。
进入 AIP Assist是什么? 在哪里找到这个助手。仅当你的平台管理员已在 Control Panel 中启用 AIP 时,AIP Assist 才可用。
从 AIP Assist 获取支持是什么? 怎么提问、能得到什么。用户可以在 Ask a question... 输入框中以纯文本形式输入查询。AIP Assist 基于 Palantir 的平台文档进行了训练,并使用自然语言处理(Natural Language Processing,NLP)和第三方…
---
## 应用状态(Application state)
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-application-state.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/application-state/
- 主题分组:Chatbot Studio(四)
循序渐进 · AIP 教学 · Chatbot Studio(四)
# 应用状态(Application state)
聊天机器人要记住会话里的信息,才能做多轮推理。应用状态就是它的"工作记忆"。
## 先记住这几条
① 状态让多轮对话成为可能 没有状态,每轮都是全新的。
② 状态可被工具读写 工具能更新状态,模型能读状态。
③ 要设计好状态结构 存什么、什么时候清,影响效果与成本。
## 写在前面
> AIP Chatbot 的 application state 此前称为参数。
你可以在 AIP Chatbot 上配置多个字符串或对象集应用变量,以配置 application state。当带有应用变量的 AIP Chatbot 被嵌入到 Workshop 中的 AIP Chatbot widget 时,变量列表将会显示出来。随后,你可以将每个应用变量映射到对应类型的 Workshop variable,以便在其他 widget 中展示输出。
## 在 Chatbot Studio 中配置应用状态
> 要点:状态变量的定义方式。
在设置 AIP Chatbot 的 application state 时,请配置以下内容:
- 标识应用变量: 确定 LLM 应与哪些对象集或字符串变量交互。这些变量可以是 LLM 写入结果的新变量,也可能已存在于你的工作流中,例如表示用户当前选择内容的变量。
- 为变量命名并描述: 为每个变量编写一段说明其作用的描述。该描述将被注入聊天机器人的提示词中,为 LLM 提供关于何时使用给定变量的上下文。
- 设置值可见性: 你可以通过设置值可见性来选择聊天机器人是否可以看到变量的值。我们建议仅在必要时才允许 LLM 读取值,以减少混淆。例如,如果你使用一个对象集变量作为 Ontology context 的输入,则该变量无需对 LLM 可见;对象集值的相关内容会在每一轮循环中出现在系统提示词里。但是,如果你有一个字符串变量包含系统提示词中的动态部分,则该变量必须设置为可见,以便 LLM 能够读取该变量的内容。
- 将变量添加为输入: 你可以选择将变量配置为 Ontology retrieval context 的输入,从而为语义搜索提供确定性输入,或将完整对象集提供给 LLM。此外,function-backed context 可以接收多个输入变量,以便在运行函数时包含有状态的信息。 Object query 工具还可以按对象类型接收一个初始对象集变量,为 LLM 应用额外的筛选或聚合提供起点。

> 图:application state 配置面板的示例外观。
application state 也可以在用户自定义的 System prompt 中通过键盘上的斜杠命令 / 来引用。

> 图:在提示词中引用应用变量的示例。
application state 可以使用 Debug application state 部分进行测试。你可以手动覆盖每个变量的值,并且当聊天机器人更新变量值时,调试部分会提供可视化反馈。

> 图:Debug application state 部分的示例外观。
## 用聊天机器人更新应用变量
> 要点:运行时怎么写状态。
你配置的应用变量可以通过聊天机器人 tools 或添加到 application state 配置中的 retrieval context 进行修改。变量既可以根据工具或上下文的输出进行确定性更新,也可以通过 Update application variable 工具进行非确定性更新。
### Automatic variable updates
变量可以配置为使用 Object query 工具、function-backed context 或 Ontology context 输出的值进行确定性更新。在每次执行上下文或工具后,Chatbot Studio 会记录最新的输出,并在 LLM 完成流式输出时,将映射的应用变量更新为该输出值。我们建议采用确定性更新而非非确定性更新,以避免 LLM 混淆。在某些情况下,你可能希望完全对 LLM 隐藏变量的值。

> 图:为 object query 工具配置 AIP Chatbot 的输出变量。
### Deterministic tool inputs
Action 和 Function 工具可以配置为使用来自应用变量的输入,而不是通过 LLM 动态生成输入。此功能允许你将预先确定的值直接传递给工具,从而提高一致性并减少 token 用量。
此功能仅支持字符串和对象集输入类型。所传递的值会被固定为推理循环开始时变量的初始值,这意味着同一次查询中先前工具调用产生的更新不会反映在作为确定性输入传递的值中。

> 图:配置确定性工具输入。
### Update variables with an LLM
如果你希望由 LLM 配置一个新变量来更新,或根据当前用户查询有条件地应用更新,请添加 Update application variable 工具。该工具支持一个可供 LLM 更新的变量列表。

> 图:为 AIP Chatbot 配置 Update application variable 工具。
### Variables as citations
你还可以配置一个对象集变量,使其在用户选择 citation 时更新。所配置的对象集变量将更新为一个包含被引用对象的静态对象集。

> 图:为 AIP Chatbot 配置 ontology context citation 输出变量。
## 在 Workshop 中配置
> 要点:在应用侧接收状态。
如果 AIP Chatbot 已配置了 application state,你可以在 Workshop 中配置该聊天机器人的应用变量。更多信息,请参阅 AIP Chatbot widget 文档。

> 图:在聊天机器人的 application state 部分将 AIP Chatbot 的应用变量配置为 Workshop 变量。
### 常见问题速答 · FAQ
关于「应用状态(Application state)」,读者最常问的几个问题。
用聊天机器人更新应用变量是什么? 运行时怎么写状态。你配置的应用变量可以通过聊天机器人 tools 或添加到 application state 配置中的 retrieval context 进行修改。
在 Workshop 中配置是什么? 在应用侧接收状态。如果 AIP Chatbot 已配置了 application state,你可以在 Workshop 中配置该聊天机器人的应用变量。更多信息,请参阅 AIP Chatbot widget 文档。
---
## 把聊天机器人发布为函数
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-chatbots-as-functions.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/chatbots-as-functions/
- 主题分组:Chatbot Studio(九)
循序渐进 · AIP 教学 · Chatbot Studio(九)
# 把聊天机器人发布为函数
发布为函数(Function)后,你的聊天机器人就能在平台里任何可执行函数的地方被调用 —— 复用性大幅提升。
## 先记住这几条
① 发布成函数即获得复用性 在平台各处被调用。
② 输入输出有契约 函数签名要设计好。
③ 可以嵌进更大流程 成为 Logic、动作的一环。
## 写在前面
AIP Chatbots 可以发布为 Functions,从而能够在平台中任何可执行 Functions 的地方使用。例如,构建者可以将 AIP Chatbots 发布为 Functions,以便在 AIP Evals 中对它们进行评估,使用 Automate 自动化聊天机器人工作流,或在 Code Repositories 中使用聊天机器人。你可以将函数版本配置为在每次发布聊天机器人时发布,或在每次保存聊天机器人时发布。
## 函数输入
> 要点:调用时能传什么。
以下是发布为 Functions 的聊天机器人所接受的输入:
- userInput: 聊天机器人将要回应的用户输入字符串。
- sessionRid(可选): 当前会话的字符串标识符,格式如下:
`` ri.aip-agents..session.{uuid} ``
- 若要与此聊天机器人开始新会话,请将 sessionRid 输入留空。不要提供空字符串;请完全省略此输入。
- 提供某个值即可使用该会话的 RID 继续一个已有会话。
- 此 RID 会在所有 Function 执行结果中返回。
- 用于 application state 的所有应用变量都会作为可选输入添加。这些变量可用于覆盖默认的 application state 值。
- 对于对象集变量,默认值是该对象类型的基础对象集,这意味着默认会包含该对象类型中的所有对象。
- 对于字符串变量,默认值在 Chatbot Studio 中显示并配置。
## 函数输出
> 要点:返回什么结构。
以下是发布为 Functions 的聊天机器人的输出:
- markdownResponse: 聊天机器人生成的最终文本回复,使用 markdown 格式化。
- sessionRid: 当前会话的字符串标识符,格式如下:
`` ri.aip-agents..session.{uuid} ``
- 此 RID 会在所有 Function 执行结果中返回。
- 将此值提供给下一次 Function 执行,以继续该会话。
- 用于 application state 的所有应用变量都会作为可选输出添加。
- 仅当这些变量的值被更新时,才会输出其值。未被更新的变量将为空。
## 把聊天机器人发布为函数
> 要点:操作步骤。
- 若要在 Chatbot Studio 中将聊天机器人发布为 Function,请选择右上角 Publish 按钮右侧的发布设置图标。这将打开 Publish settings 对话框。

- 打开 Publish function from chatbot 选项,这会显示已发布 Function 的附加配置选项。
- 在展开后的 Publish settings 对话框中,选择一个 Ontology,并填写 Function 详情,例如 Function 名称、API 名称和描述。你还可以选择在保存聊天机器人时发布次要 Function 版本,方法是勾选 Version configuration 下的复选框。
- 选择对话框底部的 Publish chatbot and function。
发布后,会有一条 toast 通知告知你聊天机器人和 Function 已发布,并附有一个可在 Ontology Manager 中查看已发布 Function 的链接。你也可以通过打开 Publish settings 并在 Published function 下选择该 Function 来查看它。
### Disable chatbot Function publishing
若要禁用 Function 发布,请打开 Publish settings,并将 Publish function from chatbot 选项关闭。如果你禁用此选项,在你重新启用之前,聊天机器人后续发布的版本将不会把你的聊天机器人注册为 Function。你可以随时重新启用此选项。若要在重新启用后发布 Function,请发布该聊天机器人。
## 用 AIP Evals 评测聊天机器人
> 要点:上线前的验证。
将聊天机器人发布为 Functions 后,它们就可以使用 AIP Evals 评估套件进行评估。若要从 Chatbot Studio 创建评估套件,请确保你的聊天机器人已发布为 Function,然后打开左侧工具栏上的 Evaluation 标签页。在这里,你可以选择 Create evaluation suite,它会提示你为套件命名,并选择与聊天机器人相同的 Project。

> 图:“Evaluation”标签页中创建评估套件的选项。
评估套件必须与聊天机器人在同一个 Project 中。创建后若要在 AIP Evals 中打开该评估套件,请选择已创建套件右侧的箭头图标。

> 图:已创建的套件,以及可用于在 AIP Evals 中打开该套件的箭头图标。
在 AIP Evals 中设置测试用例时,请记住以下几点:
- 若要与此聊天机器人开始新会话,请确保将 sessionRid 设置为 null。如果提供了会话 RID,聊天机器人将继续一个已有会话,这很可能不是测试时的本意。

> 图:在评估套件测试用例中将 sessionRid 设置为 null 的选项。
- 对象集变量必须设置为 null 或包含真实值。对象集变量不能为空。

> 图:在评估套件测试用例中选择对象集的选项。
有关评估套件的更多信息,请参阅 AIP Evals 文档。
### 常见问题速答 · FAQ
关于「把聊天机器人发布为函数」,读者最常问的几个问题。
函数输入是什么? 调用时能传什么。以下是发布为 Functions 的聊天机器人所接受的输入。
函数输出是什么? 返回什么结构。以下是发布为 Functions 的聊天机器人的输出。
把聊天机器人发布为函数是什么? 操作步骤。发布后,会有一条 toast 通知告知你聊天机器人和 Function 已发布,并附有一个可在 Ontology Manager 中查看已发布 Function 的链接。
用 AIP Evals 评测聊天机器人是什么? 上线前的验证。将聊天机器人发布为 Functions 后,它们就可以使用 AIP Evals 评估套件进行评估。若要从 Chatbot Studio 创建评估套件,请确保你的聊天机器人已发布为 Function,然后打开左侧工具栏上的 Evaluation 标…
---
## 引用(Citations)
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-citations.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/citations/
- 主题分组:Chatbot Studio(六)
循序渐进 · AIP 教学 · Chatbot Studio(六)
# 引用(Citations)
回答要可信,就得能指出来源。配置了文档或 Ontology 上下文的机器人会输出引用,点击可跳回原始材料。
## 先记住这几条
① 有上下文的机器人会输出引用 文档上下文、Ontology 上下文均可。
② 引用可点击溯源 直接跳到源材料,便于核验。
③ 消息底部也有引用区 方便集中查看。
④ 引用提升信任与可审计性 这是企业场景的硬需求。
## 写在前面
配置了 document context 或 Ontology context 的 AIP Chatbots 会输出 citations(引用),选中后会链接到源材料。这些 citations 还会出现在每条消息底部的 Sources 下拉菜单中,让用户清楚了解每次回复中所使用和引用的具体上下文。

> 图:一个配置了 Ontology context 并输出 citations 的聊天机器人截图。
对于其他类型的上下文,例如 function-backed context 或 tools,默认不提供 citations。不过,用户可以提示聊天机器人将其包含在内。如果 LLM 以正确的 citation 格式回复,对话用户界面就会渲染出该 citation。请参阅下文 citation 格式以了解完整格式列表,并参阅自定义 citation 提示词了解如何在你的聊天机器人中使用这些格式的示例。
## 引用格式
> 要点:引用长什么样。
AIP Chatbot 界面目前支持以下 citation 格式:
- Ontology object citations(Ontology 对象引用) 可以以下面两种格式之一返回。选中 citation 气泡将链接到该对象的 Object Explorer 视图。
``xml ri.phonograph2-objects.main.object.... ``
其中 标签封装了对象的 RID。
``xml ...... ``
其中 标签封装了对象类型 ID(可在 Ontology Manager 中找到),而 标签封装了该对象主键的值。
- Document (PDF) citations(文档(PDF)引用) 应以下列格式返回:
``xml ri.mio.main.media-set...ri.mio.main.media-item... ``
选中 citation 气泡将打开一个对话框,显示文档的第一页。如果你想在 citation 中指定文档的某一页,可以像下面这样提供一个 page 标签:
``xml ri.mio.main.media-set...ri.mio.main.media-item...12 ``
随后文档对话框将显示文档的该页。
- External URL citations(外部 URL 引用) 应以下列格式返回:
``xml My Websitewww.mywebsite.com ``
citation 气泡将显示所提供的名称,例如 My website,选中它将链接到所提供的 URL,例如 www.mywebsite.com。
你可以通过导航到 Ontology context 配置面板下的 Citations 标签页,设置一个带 Ontology context 的聊天机器人,以上述三种格式中的任意一种引用对象。
## 引用设置
> 要点:怎么控制引用的产生。
citation 设置允许你全局启用或禁用 citations,并覆盖默认的点击行为。

> 图:citation 设置全局禁用的截图。
对于 ontology 和 document citations,默认的点击行为是打开相应的文档或 ontology 对象。你可以针对每个对象类型,在细粒度层面覆盖默认的 ontology context 行为。可以通过以下方式实现:
- 打开外部 URL
- 打开 PDF 文档
- 更新变量
### Citation variable updates
配置了 Ontology object citations 的聊天机器人也可以配置为在选中对象 citation 时更新应用变量。这使 AIP Chatbots 的使用者可以在对话面板之外显示有关被引用对象的附加信息。
一个常见的例子是 Workshop 中的 AIP Chatbot Widget,你可以在其中使用 application state 来配置选中时弹出的悬浮层。你可以在下文与 Workshop 悬浮层集成一节中找到如何设置它的完整演练。
对于使用 function-backed context 的聊天机器人,你可以提示聊天机器人使用某个自定义提示词来返回对象 citations。
如果你的函数处理多个对象类型,它返回的 citations 可能有些对应对象类型 A,有些对应对象类型 B,依此类推。要处理这类情况,你可以在 citation 设置中为你的函数创建多个 citation variables。当某个 citation 被选中时,与对象类型匹配的那个 citation variable 将被设置为一个包含所引用对象的对象集,而所有其他 citation variables 将被设置为空对象集。这种做法确保在任何时候都只有最相关的 citation variable 被填充。

> 图:citation 设置中覆盖了两个对象类型以支持更新变量的截图。
### Integrate with Workshop overlays
在 AIP Chatbot Studio 中配置好变量更新后,你可以将它们连接到 Workshop 中的 AIP Chatbot widget。有关 AIP Chatbot widget 的更多信息,请参阅 application state 相关章节。
- 在 Workshop 中,为你在聊天机器人中配置的每个 citation variable 创建一个空对象集变量。每当 AIP Chatbot widget 中的某个 citation 被选中时,这些变量就会被填充。
- 在 Workshop 模块中创建一个悬浮层。
- 将该悬浮层设置为 Variable-based visibility,并创建一个布尔变量,用于检查你在第一步中配置的 Workshop 变量是否为空。如果你有多个 citation variables,你可以创建多个悬浮层,或创建单个悬浮层,其可见性由多个布尔变量的并集决定。

> 图:Workshop 悬浮层配置面板的截图。
在选中 citation 时出现的弹出悬浮层通常能为 AIP Chatbot widget 的用户提供最佳体验。不过,你也可以通过浏览 Workshop 文档来探索其他选项。

> 图:AIP Chatbot widget 在选中 citation 时配置了弹出悬浮层的截图。
## 自定义引用提示词
> 要点:进阶:让引用更贴合你的场景。
为确保 citations 能在 AIP Chatbot 用户界面中渲染,citations 必须包含在底层 LLM 的回复中。为此,需要使用上述格式之一来提示 LLM。对于带 document context 和 Ontology context 的聊天机器人,此提示词会自动提供。但对于其他聊天机器人,则需要针对具体用例量身定制的自定义提示词。
你可以通过几种不同方式为聊天机器人提供自定义提示词。第一种是使用聊天机器人的 LLM Settings 提供指令。你可以在下面这个聊天机器人示例中看到这种做法,它提示 LLM 在每次使用对象查询工具查询 drivers 时都回复 citations。

> 图:用于从 object query 工具输出 citations 的自定义提示词截图。
下面是上图中用于从带 object query 工具的聊天机器人输出对象 citations 的提示词:
xml Whenever the user asks a question about support tickets, use the object query tool to answer it. After using the object query tool, respond to the user query with inline citations that link to the objects returned by the object query tool.
WHENEVER you mention a support ticket, output a citation in the format below:
"titan-technologies-support-ticket..."
For example, if I wanted to cite the ticket titled Office Dress Code, I would get the primary key of the ticket, which is TICKET-015 (since the Ticket Id is TICKET-015), and then output the citation like so:
"The ticket about the office dress code says ... titan-technologies-support-ticketTICKET-015.""
另一种方式是使用 function-backed context,因为 context retrieval 函数的输出会被直接粘贴到 LLM 系统提示词中。在下面的示例中,context retrieval 函数生成了一段提示词,为 LLM 提供应包含在其回复中的相关对象,以及它应当用于提供 citations 的格式。

> 图:用于从 function-backed context 输出 citations 的自定义提示词截图
下面是上图中用于从带 function-backed context 的聊天机器人输出对象 citations 的提示词:
xml Incorporate a citation from the context source in your answer whenever the context content is used.
For example, if the message asks "What is X?"
A valid response would be "X is Y, according to Source 1ri.phonograph2-objects.main.object.abc-123, ..."
Another example: if the message asks "Why is X?"
A valid response would be: "X is Y because ... For more details or further clarification, please refer to the following sources: Source 2ri.phonograph2-objects.main.object.def-456 Source 3ri.phonograph2-objects.main.object.abc-123"
Remember, always include a citation in your answer by using the provided context sources.
Example context sources:
Source 1ri.phonograph2-objects.main.object.0c94f9b2-e0c5-4e90-a054-96e570cd11dd
Consistency is key when teaching commands to your dog.
Source 1ri.phonograph2-objects.main.object.0c94f9b2-e0c5-4e90-a054-96e570cd11dd
Source 2ri.phonograph2-objects.main.object.8c6adc92-cfc6-4b76-b729-2744e369dac3
Socialization is important for a dog's development and behavior.
Source 2ri.phonograph2-objects.main.object.8c6adc92-cfc6-4b76-b729-2744e369dac3
Example response with citation:
"Maintaining consistency is essential when training your dog to follow commands Source 1ri.phonograph2-objects.main.object.0c94f9b2-e0c5-4e90-a054-96e570cd11dd. Socializing your dog is crucial for its behavioral development Source 2ri.phonograph2-objects.main.object.8c6adc92-cfc6-4b76-b729-2744e369dac3."
[Context Sources Sorted by Relevancy]
ri.phonograph2-objects.main.object.60599f54-c745-412b-98a0-2c7f5f0fa9bf
.... The Titan Technologies dress code is business casual ....
ri.phonograph2-objects.main.object.60599f54-c745-412b-98a0-2c7f5f0fa9bf
ri.phonograph2-objects.main.object.35910c26-8a87-4eb5-8243-52afb88bba11
.... Titan Technologies Employee Handbook ....
ri.phonograph2-objects.main.object.35910c26-8a87-4eb5-8243-52afb88bba11
ri.phonograph2-objects.main.object.3f21b8a6-536b-4374-aaf5-cae641ca836c
.... At Titan Technologies, flexible work hours may be possible .....
ri.phonograph2-objects.main.object.3f21b8a6-536b-4374-aaf5-cae641ca836c
ri.phonograph2-objects.main.object.10b2d64a-4043-438d-894a-80c001ff26e2
.... The dress code for the office is business casual ....
ri.phonograph2-objects.main.object.10b2d64a-4043-438d-894a-80c001ff26e2
[/Context Sources Sorted by Relevancy]
REMINDER:
ALWAYS include citations in the correct format sourceNamesourceKey in all responses. ALWAYS include the source name and the source key in all citations.
Valid examples are Source 1ri.phonograph2-objects.main.object.0c94f9b2-e0c5-4e90-a054-96e570cd11dd, Source 2ri.phonograph2-objects.main.object.8c6adc92-cfc6-4b76-b729-2744e369dac3.
### 常见问题速答 · FAQ
关于「引用(Citations)」,读者最常问的几个问题。
引用格式是什么? 引用长什么样。AIP Chatbot 界面目前支持以下 citation 格式。
如何引用设置? 怎么控制引用的产生。citation 设置允许你全局启用或禁用 citations,并覆盖默认的点击行为。
自定义引用提示词是什么? 进阶:让引用更贴合你的场景。为确保 citations 能在 AIP Chatbot 用户界面中渲染,citations 必须包含在底层 LLM 的回复中。为此,需要使用上述格式之一来提示 LLM。
---
## 把命令用作工具
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-commands-as-tools.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/commands-as-tools/
- 主题分组:Chatbot Studio(八)
循序渐进 · AIP 教学 · Chatbot Studio(八)
# 把命令用作工具
平台里的命令(command)可以直接挂成机器人的工具 —— 用户一句自然语言,就能触发应用里的具体操作。
## 先记住这几条
① 命令即能力 平台内已有的操作可以直接复用。
② 自然语言触发操作 用户不必知道命令在哪、怎么点。
③ 涉及敏感操作要加审核 例如执行前需用户批准。
## 写在前面
你可以将 commands(命令)添加为聊天机器人的 tools,使聊天机器人能够代表用户在 Palantir 应用程序中进行交互和操作。commands 直接在用户所在的应用程序中运行,使其能够访问当前应用程序的状态和屏幕。这使得传统后端工具难以支持的集成成为可能。例如,聊天机器人可以使用 commands 来导航用户界面,比如将视图设置到地图上的特定位置。
> 你还可以配置 Workshop 的 Button Group、Metric Card 和 App Pairing widget,以触发任何会产生 commands 的应用程序中的操作。
## 给聊天机器人添加命令工具
> 要点:把平台命令挂成工具。
一旦某个应用程序声明并生成某个 command,聊天机器人就可以将其作为工具使用。要将 commands 作为工具添加到聊天机器人,请在 Chatbot configuration 面板中选择 Add tool > Commands。

> 图:聊天机器人配置面板显示 Tools 部分。
在 Search commands... 模态框中搜索并选择一个或多个 commands。如果你需要为该 command 的每个实例配置不同的提示词,可以多次选择同一个 command。将选中的 commands 添加到聊天机器人,并按需应用配置。
> 使用 commands 作为工具的 AIP Chatbots 具有一个保留窗口,该窗口会在闲置 24 小时后自动过期。
## 配置命令工具[Beta]
> 要点:详细配置项。
> Beta 版
将 command 配置为聊天机器人工具的能力处于开发的 beta 阶段。其配套界面在活跃开发期间可能发生变化。如对在 AIP Chatbot Studio 中将 commands 配置为工具有疑问,请联系 Palantir 支持团队。
在将一个或多个 commands 作为工具添加到聊天机器人后,你可以选择一个 command,打开一个模态框,其中包含聊天机器人用来指导其行为的附加配置。选择 Show more 以显示更多文档,帮助你进一步了解每个工具的可选配置项,例如其输入参数和被调用时的预期行为。

> 图:Render ephemeral feature command 工具显示其附加配置文档。
请查看以下各节,以进一步了解其他配置选项。
### Additional descriptions
在默认提供的文档之外,提供 command 专属的上下文,以帮助聊天机器人的底层模型理解它将执行的操作。虽然每个 command 都包含帮助聊天机器人将其用作工具的默认文档,但你可以在 Additional documentation 中提供更多细节,帮助聊天机器人准确判断何时以及如何调用该工具。例如,你可以指示 Remove all features command 在绘制新图形之前移除临时图形,前提是现有图形与新的图形以某种方式不相关。
### Input parameters
某些 commands 在你将其配置为工具时可以接受输入参数。使用 Input parameters 为 command 参数设置输入值,例如为 Draw polygon command 设置 Fill pattern 或 Stroke width。
默认情况下,聊天机器人会根据你的 Instructions 和用户提示词来确定所有必填参数的值。对于可选参数,聊天机器人可以选择性地根据你的 Instructions 和用户提示词来确定其值。
若要覆盖默认行为,请选择 Add parameter override,选择你要覆盖的参数,并使用以下覆盖选项之一进行配置:
- Chatbot decides(默认): 由聊天机器人确定该值。这是默认行为。
- Preset values: 硬编码一个静态值,以一致地将相同值用作输入参数。
- Application variable: 使用预先配置的字符串或对象集变量。
- Don't pass the parameter to chatbot: 指示聊天机器人不要为某个可选参数提供值。此选项仅适用于可选参数。
### Asks for user approval before execution
默认启用时,在你从提示词执行 command 之前,聊天机器人会要求用户查看 command 的载荷数据,并 Reject(拒绝)或 Approve(批准)该 command 的操作或输出。禁用时,聊天机器人将根据用户提示词直接执行 commands,无需人工批准干预。

> 图:AIP Chatbot 提示用户 Reject 或 Accept 某个 command 输出。
## 测试机器人使用命令工具的能力
> 要点:验证配置是否生效。
在 AIP Chatbot Studio 中配置好 commands 之后,你可以按照以下说明测试聊天机器人并验证其配置,然后再保存并发布,使其在生产应用程序中可用:
- 在另一个浏览器窗口中,打开生成你的聊天机器人 command 工具的那个应用程序,并将其与包含 AIP Chatbot Studio 中聊天机器人的窗口并排摆放。
- 对于在另一个浏览器窗口中启动的应用程序(例如 Gaia 地图),选择 Choose an app to pair with... > Pair。

> 图:用户将聊天机器人与 Gaia 地图配对。
- 在聊天机器人的聊天输入窗口中输入提示词,以测试其使用你添加为工具的 commands 的能力。
一旦你对聊天机器人的配置感到满意,即可发布该聊天机器人,使其可作为嵌入在 AIP Assist 中的助手使用,或通过 Workshop 在 AIP Chatbot widget 中使用。
> 如果你将聊天机器人发布为函数,并在不支持 commands 的环境中执行它(例如配置其在 Automate 中构建的自动化流程内运行),聊天机器人将忽略作为工具的 commands。如对你的环境有疑问,请联系 Palantir 支持团队。
## 让机器人对接多个应用
> 要点:跨应用场景。
通过 App Pairing,你的聊天机器人会自动发现你在浏览器中打开的其他应用程序。若要将聊天机器人与多个应用程序实例配对,请在 Discovered 应用程序旁选择 Add,以创建一个配对 Group。

> 图:App Pairing 弹窗显示用户可配对的多个 Gaia 地图。
如果你的聊天机器人未与某个应用程序配对以执行 command,它将提示用户选择一个要配对的应用程序。
## 把机器人嵌入 AIP Assist 或 Workshop
> 要点:落地到用户实际工作界面。
虽然你可以使用 AIP Chatbot Studio 配合已配对的应用程序来测试聊天机器人的表现,但为了获得更流畅的用户体验,你应将聊天机器人嵌入到 Workshop 模块或 AIP Assist 面板中。在这两种情况下,聊天机器人都会自动与其交互的应用程序配对。
### Publish your chatbot to AIP Assist
若要让你的聊天机器人可在 AIP Assist 中访问,请在 AIP Chatbot Studio 中选择屏幕左侧的火箭图标以打开 Usage 面板,然后选择 AIP Assist 开关。接着,选择屏幕右上角的 Publish。这会将最新发布的聊天机器人版本部署到 AIP Assist,之后你就可以在 AIP Assist 聊天面板的 Chat with an AIP Chatbot 菜单中选择它。

> 图:用户在 AIP Chatbot Studio 中打开 AIP Assist 开关,然后在 AIP Assist 聊天面板中选择其聊天机器人。
选择聊天机器人后,AIP Assist 会自动与目标应用程序配对,所有配置为工具的相关 commands 都会以该应用程序为目标。如果你的聊天机器人包含面向多个应用程序的工具,但未与这些应用程序配对,那么 AIP Assist 会提示你在已打开的浏览器标签页中选择一个要配对的应用程序。
### Add your chatbot to Workshop
使用 Workshop 的 AIP Chatbot widget 将你的聊天机器人嵌入到模块中,你还可以在其中使用 Iframe widget,将一个或多个应用程序嵌入到与 AIP Chatbot widget 相邻的区域(sections)中。Workshop 模块中的 AIP Chatbot widget 与被 iframe 嵌入的应用程序会自动配对,你配置为工具的所有相关 commands 都会以该被 iframe 嵌入的应用程序为目标。
### 常见问题速答 · FAQ
关于「把命令用作工具」,读者最常问的几个问题。
给聊天机器人添加命令工具是什么? 把平台命令挂成工具。一旦某个应用程序声明并生成某个 command,聊天机器人就可以将其作为工具使用。要将 commands 作为工具添加到聊天机器人,请在 Chatbot configuration 面板中选择 Add tool > Commands。
配置命令工具[Beta]是什么? 详细配置项。将 command 配置为聊天机器人工具的能力处于开发的 beta 阶段。其配套界面在活跃开发期间可能发生变化。如对在 AIP Chatbot Studio 中将 commands 配置为工具有疑问,请联系 Palantir 支持团队。
测试机器人使用命令工具的能力是什么? 验证配置是否生效。在 AIP Chatbot Studio 中配置好 commands 之后,你可以按照以下说明测试聊天机器人并验证其配置,然后再保存并发布,使其在生产应用程序中可用。
让机器人对接多个应用是什么? 跨应用场景。通过 App Pairing,你的聊天机器人会自动发现你在浏览器中打开的其他应用程序。若要将聊天机器人与多个应用程序实例配对,请在 Discovered 应用程序旁选择 Add,以创建一个配对 Group。
---
## Chatbot Studio 核心概念
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-core-concepts.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/core-concepts/
- 主题分组:Chatbot Studio(二)
循序渐进 · AIP 教学 · Chatbot Studio(二)
# Chatbot Studio 核心概念
这页把搭建聊天机器人要用到的关键概念一次讲全:应用状态、检索上下文、工具、引用等。
## 先记住这几条
① 应用状态贯穿会话 机器人能记住会话里的信息。
② 检索上下文每条消息都跑 确定性地检索,再喂给模型。
③ 工具体现"能做事" 让模型能调外部能力。
④ 引用提升可信度 回答能指向来源材料。
## 写在前面
以下核心概念对于理解和充分利用 AIP Chatbot Studio(此前称为 AIP Agent Studio)至关重要。你可以在入门教程中进一步了解如何应用这些概念。
## AIP 聊天机器人
> 要点:基本单位与定位。
AIP Chatbots(此前称为 AIP Agents)是配备了企业专属信息和工具的交互式助手。
## 应用状态
> 要点:机器人的工作记忆。
application state(应用状态),此前称为参数,是提示词中用于定制和控制 LLM 行为的应用变量。它们支持动态输入,并可根据任务需求进行调整。
## 指令与描述
> 要点:怎么写好角色设定。
指令、工具描述和变量描述会被编译进 LLM 的原始系统提示词中。这会教会 LLM 如何使用可用的上下文来完成任务。
对于指令,请从最重要的信息开始,例如任务概述。接下来提供必要的数据,以及有关如何使用 application state 和 tools 的指导。
对于每个工具和变量的描述,请向 LLM 提供具体步骤,说明如何以及何时使用该特定上下文。请记住,LLM 只能访问你明确提供的信息。
## 检索增强生成(RAG)
> 要点:底层机制,理解它才能调好上下文。
检索增强生成(retrieval-augmented generation)利用外部数据源动态地为 LLM 提供相关信息。这种方法通过确保 LLM 的回复基于最新且最贴合上下文的数据,来提升回复质量。
## 检索上下文
> 要点:每条消息都确定性检索。
retrieval context(检索上下文)指的是针对每条消息检索到的特定信息,这些信息用于生成回复。其过程如下:
- 用户发送一条新消息。
- 根据用户的消息,从已配置的数据源中获取相关内容。
- 将相关内容与用户的消息一并提供给 LLM。
更多详情,请参阅 retrieval context 文档。
## 工具
> 要点:让机器人从"能说"到"能做"。
tools(工具)是 LLM 可用于执行特定操作或获取超出其基础能力的信息的外部功能或 API。
更多详情,请参阅 tools 文档。
## 向量嵌入
> 要点:语义检索的基础。
向量嵌入(embeddings)是文本的数值表示,能够捕捉语义含义。它们用于高效地比较和检索相似的文本片段。在 AIP Chatbot Studio 中,嵌入有助于识别相关文档和上下文,从而提供准确的回复。
## 上下文窗口
> 要点:模型一次能看多少内容。
上下文窗口(context window)指的是 LLM 一次能够处理的文本量(通常以 token 计量)。在 AIP Chatbot Studio 中,上下文窗口包括系统提示词、对话历史,以及为辅助 LLM 而注入的信息(包括 retrieval context、application state 和 tools)。超出上下文窗口会导致错误,并提示用户创建新会话以继续交互。
## 聊天机器人作为函数
> 要点:发布后在平台各处复用。
聊天机器人可以发布为 Functions,从而能够在平台中任何可执行 Functions 的地方使用。例如,构建者可以将 AIP Chatbots 发布为 Functions,以便在 AIP Evals 中对它们进行评估,使用 Automate 自动化聊天机器人工作流,或在 Code Repositories 中使用聊天机器人。更多信息,请参阅 chatbots as Functions 文档。
### 常见问题速答 · FAQ
关于「Chatbot Studio 核心概念」,读者最常问的几个问题。
AIP 聊天机器人是什么? 基本单位与定位。AIP Chatbots(此前称为 AIP Agents)是配备了企业专属信息和工具的交互式助手。
应用状态是什么? 机器人的工作记忆。application state(应用状态),此前称为参数,是提示词中用于定制和控制 LLM 行为的应用变量。它们支持动态输入,并可根据任务需求进行调整。
指令与描述是什么? 怎么写好角色设定。指令、工具描述和变量描述会被编译进 LLM 的原始系统提示词中。这会教会 LLM 如何使用可用的上下文来完成任务。
检索增强生成(RAG)是什么? 底层机制,理解它才能调好上下文。检索增强生成(retrieval-augmented generation)利用外部数据源动态地为 LLM 提供相关信息。这种方法通过确保 LLM 的回复基于最新且最贴合上下文的数据,来提升回复质量。
---
## 通过 Foundry API 使用聊天机器人
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-foundry-apis.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/foundry-apis/
- 主题分组:Chatbot Studio(十二)
循序渐进 · AIP 教学 · Chatbot Studio(十二)
# 通过 Foundry API 使用聊天机器人
要在 Foundry 平台之上自建应用?这一篇讲用 Palantir API 调起会话、发消息、拿回复。
## 先记住这几条
① 有官方 API 可用 不必自己封装。
② 会话是最小单位 创建会话 → 发消息 → 取响应。
③ 适合自建前端 在平台之外集成你的机器人。
## 写在前面
若要在 Foundry 平台之上构建应用程序,你可以使用 Palantir APIs 将聊天机器人嵌入到你的应用程序中。
## 这些 API 能做什么
> 要点:能力范围。
通过 API 轻松与你的聊天机器人构建多轮交互,其选项可用于:
- 通过创建与聊天机器人的新会话来针对给定任务或上下文开始新的对话。
- 使用流式或阻塞式 API 编排复杂的往返任务提示词,其内置的状态管理会为你追踪会话的这些更新。
- 通过 API 中的 application state 选项向聊天机器人提供自定义应用输入。它们使用此前在 Chatbot Studio 中使用的 parameter,现在作为 Application state/variables 提供。在请求中使用 parameterInputs 字段来提供输入。使用 parameterUpdates 字段处理阻塞式响应(或者在流式传输后加载会话交换)以读取自定义输出。
对于不需要大量会话管理的简单、一次性任务,请考虑使用 chatbots as functions。你可以使用 Palantir OSDK 从第三方应用程序以函数的方式访问聊天机器人。
## 把聊天机器人部署到 Developer Console 应用
> 要点:完整集成步骤。
配置并发布 AIP Chatbot 后,你可以创建并配置一个 Developer Console 应用程序,以便在自定义应用程序中与该 AIP Chatbot 交互。
若要让你在 Developer Console 应用程序能够使用平台 API 与你的 AIP Chatbot 交互,请按照创建新的 Developer Console 应用程序中的步骤,创建一个可访问 Platform SDK 资源的新 SDK 应用程序:
若要从 Ontology SDK 应用程序中使用 AIP Chatbot,你必须将该 AIP Chatbot 配置为仅使用来自单个 Ontology 的对象类型、action 类型或 function 类型。
- 在 Resources 页面上,选择你的 AIP Chatbot 所使用的 Ontology,然后选择你的 AIP Chatbot 配置中所使用的所有对象类型、action 类型和 function 类型。请确保选择用于 application state 的类型,以及为你的 AIP Chatbot 配置的所有工具和 retrieval context 所使用的类型。
- 接下来,选择 Platform SDK 标签页。在 Projects access 下,添加包含你的 AIP Chatbot 的项目。若要查找 AIP Chatbot 所属的项目,请在 Chatbot Studio 中打开该 AIP Chatbot,并查看页眉中 AIP Chatbot 名称旁边的文件系统路径详情。
- 如果你的 AIP Chatbot 配置为使用任何其他文件系统资源,例如用于 document context 的媒体集,请确保这些资源与你的 AIP Chatbot 在同一个项目中,或者将这些资源所属的所有其他项目添加到 Projects access 部分。

> 图:使用 Platform SDK 标签页为你的 AIP Chatbot 添加项目。
- 最后,在 Client allowed operations 表格中为 AIP Chatbots API 启用相关操作。若要查看不同 AIP Chatbot 平台 API 所需的操作,请参阅平台 API 文档。
若要允许你的 Developer Console 应用程序在 AIP Chatbot 的对话会话中创建并发送消息,你必须启用 AIP Chatbots write permission。

> 图:在 Client allowed operations 表格中启用 AIP Chatbot API 操作。
- 请参阅 Developer Console 文档中的步骤,以审查并完成应用程序的创建。
### Update an AIP Chatbot used in Developer Console applications
一旦你配置好了一个 Developer Console 应用程序,允许其通过 Platform SDK 资源与 AIP Chatbot 交互,那么当你的 AIP Chatbot 所使用的任何 Ontology 或平台资源被修改时,你都需要更新该应用程序。
例如,如果你向 AIP Chatbot 添加了任何新的对象类型、action 类型或 function 类型,你必须在 Developer Console 中将这些类型添加到你的应用程序的 Ontology SDK 资源中。同样地,如果你向 AIP Chatbot 添加了任何平台资源,例如用于 document context retrieval 的额外媒体集,你必须将这些资源添加到你的应用程序的 Platform SDK 资源中。当 AIP Chatbot 所使用的资源类型发生变化时,Developer Console 应用程序资源不会自动更新。
### Create conversations with AIP Chatbots in custom applications
若要开始引导创建一个新应用程序,请参阅 TypeScript 或 Python 的文档示例,或将 SDK 添加到现有应用程序。
创建好应用程序后,使用 Create Session 平台 API 与你的 AIP Chatbot 创建一个新对话。
> AIP Chatbots 的 Sessions API 要求你指定 AIP Chatbot 的 agentRid,以用于对话会话交互。
你可以通过打开你的 AIP Chatbot 所在的项目,选择该 AIP Chatbot,然后在文件概览中的 Metadata 下使用 RID 的 Copy to clipboard 选项来找到它。

> 图:从 AIP Chatbot 文件详情中复制 AIP Chatbot RID,以配合平台 API 使用。
创建新会话后,使用返回响应中的 sessionRid 值向 AIP Chatbot 发送新消息,并使用 Blocking continue session 或 Streaming continue session 平台 API 获取回复。使用阻塞式 API 等待在 AIP Chatbot 的回复完全生成后一次性收到完整回复,或使用流式 API 在 AIP Chatbot 的答案文本生成过程中接收其流。
你可以使用 Get Session API 加载某个会话的对话元数据,并使用 Get Content API 加载某个会话的交换历史(你的应用程序发送的消息和来自 AIP Chatbot 的回复)。
你可以使用 Get Session Trace API 检索 AIP Chatbot 所执行的步骤序列,这对于调试或理解该聊天机器人的推理过程很有用。该端点需要一个 sessionTraceId,你可以通过以下两种方式获得:
- 对于新的交换:
- 生成一个随机的 UUIDv4,作为 Blocking continue session 或 Streaming continue session API 请求中的 sessionTraceId。此选项允许你轮询 'Get Session Trace' API,以查看聊天机器人答案生成过程的实时 trace。
- 查看 Blocking continue session API 响应中的 sessionTraceId 字段。
- 对于已有的交换:
- 查看 Get Content API 响应中交换结果上的 sessionTraceId 字段。
请参阅平台 API 文档,了解如何在你目标应用程序语言中使用这些 API 的代码示例。
---
## Chatbot Studio 快速入门
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-getting-started.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/getting-started/
- 主题分组:Chatbot Studio(三)
循序渐进 · AIP 教学 · Chatbot Studio(三)
# Chatbot Studio 快速入门
这一篇带你从零搭一个基础聊天机器人:认识界面、配置信息与工具,然后部署到生产并监控。
## 先记住这几条
① 先搭最小的可用版本 信息 + 工具,够用就好。
② 界面分区各司其职 配置、预览、发布分开。
③ 部署后还要监控 上线不是终点。
## 写在前面
本指南演示如何访问 AIP Chatbot Studio,介绍 AIP Chatbot Studio 的界面,说明如何设置一个配备了你所选信息和工具的基础 AIP Chatbot,以及如何在生产环境中部署和监控该 AIP Chatbot。
## 进入 Chatbot Studio
> 要点:从哪里打开。
可以通过平台的工作区导航栏访问 AIP Chatbot Studio,也可以使用快速搜索快捷键 CMD + J(macOS)或 CTRL + J(Windows)。此外,你还可以在 Files 中通过选择 + New,然后选择 AIP Chatbot 来新建 AIP Chatbot,如下所示。

> 图:创建新 AIP Chatbot 的窗口。
打开 AIP Chatbot Studio 后,你可以新建一个 AIP Chatbot 文件。
## 创建聊天机器人
> 要点:从空白开始搭一个。
AIP Chatbots 是 Palantir 文件系统资源,具备细粒度的访问控制,可以像任何其他文件系统资源一样创建,如上一节中的上图所示。
你也可以在 AIP Chatbot Studio 内部选择 New AIP Chatbot 选项。

> 图:AIP Chatbot Studio 起始页面,其中包含 New AIP Chatbot 选项。
此外,还可以在 AIP Threads 中创建 AIP Chatbot。
## 配置聊天机器人
> 要点:信息源、工具与行为的设置。

> 图:AIP Chatbot Studio 创建页面,展示聊天机器人名称、描述和文件位置选项。
为你的 AIP Chatbot 添加名称、描述,以及一张图片作为头像。这使你能够对聊天机器人进行白标定制,以契合你的应用程序场景。如果未提供头像,将默认使用灰色的机器人图标。
接下来,你需要配置将配备给 AIP Chatbot 的企业专属信息和工具,详见以下各节。
### Types of information and tools
- Retrieval context: 简单且快速,推荐用于大多数用例。
- Application state: 用于在 Workshop 中为聊天机器人提供上下文。
- Tools: 用于复杂且需要执行操作的聊天机器人。
正是这些配置让 LLM 能够对你的企业、你的工作流和你的任务真正有用。
### Choose a large language model (LLM)
你可使用的模型是在你的 enrollment 上启用的模型的一个子集。

> 图:AIP Chatbot Studio 编辑视图,高亮显示了更改模型的选项。
### Modify the system prompt
系统提示词应概述 AIP Chatbot 在当前应用程序上下文中的功能。在键盘上按下 /,你可以引用已配置的 tools 和 application state,并指导 AIP Chatbot 如何协调使用它们。请务必描述底层业务逻辑,以及在上下文中使用合适工具的正确情形。

> 图:AIP Chatbot Studio 编辑视图,高亮显示了更改系统提示词的选项。
### Set the temperature
用户可以修改模型温度,以确定聚焦、确定性的输出(默认值 0)与随机输出(最大值 1)之间的平衡。

> 图:AIP Chatbot Studio 编辑视图,高亮显示了设置模型温度的选项。
### Add conversation starters
你还可以设置输入占位符和建议提示词,以针对你预期的工作流定制聊天机器人。

> 图:AIP Chatbot Studio 编辑视图,高亮显示了更改输入占位符和建议提示词的选项。
### Save, view, and publish an AIP Chatbot
配置好 AIP Chatbot 后,你可以使用界面右上角的 Save 保存进度。你可以使用 Save 选项旁边的向下箭头图标,为保存的版本添加描述。
若要从最终用户交互的角度查看 AIP Chatbot 的实际运行效果,请使用 View 并选择所需的版本。
当你准备好部署 AIP Chatbot 时,选择 Publish,让你的聊天机器人可在生产环境中使用。你还可以通过选择 Publish 选项旁边的配置图标,将聊天机器人发布为函数。这样你就可以通过 AIP Automate 和 AIP Evals 运行你的聊天机器人。

> 图:AIP Chatbot Studio 的保存、查看和发布选项。
### Track AIP Chatbot feedback and usage
你可以通过 Monitoring 和 Usage 标签页监控聊天机器人的性能和用量,在其中查看指标和用户反馈。反馈数据来自用户在对话中为聊天机器人点赞或点踩。
可在 AIP Threads、Workshop、查看模式中使用,也可通过 OSDK 配合 Developer Console 和平台 API 使用。

> 图:AIP Chatbot Studio 编辑模式的 usage 标签页。
### 常见问题速答 · FAQ
关于「Chatbot Studio 快速入门」,读者最常问的几个问题。
进入 Chatbot Studio是什么? 从哪里打开。可以通过平台的工作区导航栏访问 AIP Chatbot Studio,也可以使用快速搜索快捷键 CMD + J(macOS)或 CTRL + J(Windows)。
创建聊天机器人是什么? 从空白开始搭一个。AIP Chatbots 是 Palantir 文件系统资源,具备细粒度的访问控制,可以像任何其他文件系统资源一样创建,如上一节中的上图所示。
配置聊天机器人是什么? 信息源、工具与行为的设置。为你的 AIP Chatbot 添加名称、描述,以及一张图片作为头像。这使你能够对聊天机器人进行白标定制,以契合你的应用程序场景。如果未提供头像,将默认使用灰色的机器人图标。
---
## 用 Marketplace 分发聊天机器人
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-marketplace.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/marketplace/
- 主题分组:Chatbot Studio(十一)
循序渐进 · AIP 教学 · Chatbot Studio(十一)
# 用 Marketplace 分发聊天机器人
把聊天机器人打包成产品,分发给别的团队/环境安装使用 —— 这是从"自己用"到"组织内复用"的一步。
## 先记住这几条
① 打包成产品 借助 Foundry DevOps 的打包能力。
② 分发靠 Marketplace 别人可以安装复用。
③ 适合沉淀通用能力 一次构建,多处受益。
## 写在前面
使用 Foundry DevOps 将你的 AIP Chatbots 纳入 Marketplace 产品,供其他用户安装和复用。了解如何创建你的第一个产品。
## 支持的特性
> 要点:打包分发时哪些能力会保留。
Marketplace 产品支持所有 AIP Chatbots 功能,但以下除外:
- Assist agents
## 把聊天机器人加入 Marketplace 产品
> 要点:打包操作。
要将 AIP Chatbot 添加到产品中,请先创建一个产品。在 Add resources 步骤中,通过 Add files 选项搜索并选择你的 AIP Chatbot。
另外,如果你有一个通过 AIP Chatbot widget 嵌入式使用 AIP Chatbot 的 Workshop 应用程序,你可以将该 Workshop 模块添加到产品中,AIP Chatbot 会自动被包含在内。
## 带文档上下文的聊天机器人
> 要点:分发时的注意点。
在打包一个配置为使用 document context retrieval 的 AIP Chatbot 时,包含这些文档的媒体集(media set)会被自动纳入产品。这确保了该 AIP Chatbot 在安装后能够访问所需的文档。
媒体集内容 整个媒体集,包括任何未被该 AIP Chatbot 使用的条目,都会被打包进产品中。如果你希望只包含该 AIP Chatbot 所使用的文档,你应当新建一个仅包含必要文档的媒体集,并重新配置该 AIP Chatbot 以使用它。
### 常见问题速答 · FAQ
关于「用 Marketplace 分发聊天机器人」,读者最常问的几个问题。
支持的特性是什么? 打包分发时哪些能力会保留。Marketplace 产品支持所有 AIP Chatbots 功能,但以下除外。
带文档上下文的聊天机器人是什么? 分发时的注意点。在打包一个配置为使用 document context retrieval 的 AIP Chatbot 时,包含这些文档的媒体集(media set)会被自动纳入产品。这确保了该 AIP Chatbot 在安装后能够访问所需的文档。
---
## AIP Chatbot Studio 总览
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/overview/
- 主题分组:Chatbot Studio(一)
循序渐进 · AIP 教学 · Chatbot Studio(一)
# AIP Chatbot Studio 总览
想做一个懂你业务、能引用出处、能调工具的对话机器人?AIP Chatbot Studio(原名 AIP Agent Studio)就是干这个的。
## 先记住这几条
① 面向业务的对话机器人 不是通用聊天,而是接你数据的助手。
② 核心是上下文 检索什么、怎么检索,决定回答质量。
③ 能调工具 不只是聊天,还能触发实际操作。
④ 可发布可复用 变成函数或 Marketplace 产品。
## 写在前面
> AIP Chatbot Studio 此前称为 AIP Agent Studio,AIP Chatbots 此前称为 AIP Agents。
AIP Chatbot Studio 允许用户构建交互式助手(称为 AIP Chatbots),这些助手配备了企业专属的信息和工具,既可在平台内部署,也可通过 Ontology SDK 和 平台 API 在外部部署。
在 AIP Chatbot Studio 中构建的聊天机器人由大语言模型(large language models,LLM)、Ontology、文档和自定义工具驱动。AIP Chatbots 可以集成到应用程序中,以支持动态的、具备上下文感知能力的读取和写入工作流,从而帮助你自动执行任务并减少手动操作应用程序的交互。
下面的示例展示了一个 AIP Chatbot,它使用一个 application variable(应用变量)将经过筛选的视频转录对象集作为上下文,来回答用户关于美联储近期新闻发布会的问题。

> 图:AIP Chatbot Studio 编辑页面的截图,其中包含上述 AIP Chatbot。
上述 AIP Chatbot 还可以部署到一个 Workshop 应用程序中,让用户能够与所选视频进行交互。

> 图:上述 AIP Chatbot 部署在 Workshop 应用程序中的截图。
AIP Chatbot Studio 构建在与 Palantir 平台其余部分相同的严格安全模型之上。这些平台安全控制只会授予 LLM 完成任务所必需的内容的访问权限。
---
## 检索上下文类型(Context types)
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-retrieval-context.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/retrieval-context/
- 主题分组:Chatbot Studio(五)
循序渐进 · AIP 教学 · Chatbot Studio(五)
# 检索上下文类型(Context types)
机器人回答得好不好,八成取决于喂给它的上下文。检索上下文针对每一条新消息确定性地运行,把相关内容塞进模型。
## 先记住这几条
① 每条消息都会检索 不是只在第一轮做。
② 确定性执行 不会随机跳过,行为可预期。
③ 上下文的类型可配 文档上下文、Ontology 上下文等。
④ 检索质量决定回答质量 这是调优的主战场。
## 写在前面
AIP Chatbots 可以配置 retrieval context。retrieval context 会针对每一条新的用户消息确定性地运行,检索到的信息会被传入 LLM。
你可以为聊天机器人配置以下任意数量的 retrieval context 类型:
- Ontology context
- Document context
- Function-backed context

> 图:AIP Chatbot Studio 编辑模式中显示的 retrieval context 选项。
## Ontology 上下文
> 要点:从本体对象里检索相关内容。
Ontology context 为聊天机器人提供来自 Ontology 中对象的上下文。你可以提供固定的 N 个对象,也可以执行语义搜索来找出与用户查询最相关的 K 个对象,前提是你的对象类型具有向量嵌入属性。
在配置 Ontology context 时,你可以选择起始对象集为 Static input(静态输入,包含完整对象类型),或 Variable input(变量输入,可以由作为 application state 变量传入的经过筛选的对象集组成)。

> 图:AIP Chatbot Studio 编辑模式中 Ontology context 配置的示例。
你还可以配置一个对象属性列表,以决定每个检索到的对象有哪些属性会被打印并作为上下文传递给 LLM。默认情况下会选中所有属性,但无法打印的属性除外(例如媒体引用或向量嵌入)。

> 图:AIP Chatbot Studio 编辑模式中 Ontology context 属性配置的示例。
此外,你还可以通过为对象集输出和 citation variable 输出配置变量,将 Ontology context 与你的 application state 集成。更多信息,请参阅 application state 和 citation variable updates 相关章节。
## 文档上下文
> 要点:从文档里检索相关内容。
document context 允许用户在每条发送给 LLM 的消息中附带文档中的相关文本。文档的选择与添加方式,与在 AIP Threads 中向对话添加文档的方式相同。
提供 document context 有两种模式:
- Full document text mode(完整文档文本模式): 此模式将文档的完整文本内容提供给 LLM 作为上下文。
- Relevant chunks mode(相关分块模式): 此模式对文档执行语义搜索,将最相关的 K 个分块作为上下文返回给 LLM。
> Beta 版
Relevant chunks mode 处于开发的 beta 阶段,你的 enrollment 上可能尚不可用。功能在活跃开发期间可能发生变化。请联系你的 Palantir 代表或 Palantir 支持团队以申请使用此功能。

> 图:配置了 document context 的 AIP Chatbot Studio 编辑页面截图。
## 函数支撑的上下文
> 要点:用函数动态产出上下文。
function-backed context 使用户能够在每次查询时执行自己的检索。这非常适用于 Ontology context 或 document context 所提供的开箱即用检索方法无法满足某个用例的场景。例如,如果用户想要组合不同的检索方法,比如关键词搜索和语义搜索,那么他们可以编写一个函数来实现,因为 Chatbot Studio 目前尚不支持这种组合。
你可以在 Code Repositories 中用 TypeScript v1 编写这些函数。为此,请导航到一个 TypeScript v1 仓库并导入 AipAgentsContextRetrieval 函数接口。TypeScript v2 仓库不支持函数接口。

> 图:Code Repositories 中的函数接口对话框
然后,编写一个满足该接口的函数,如下所示。为了满足契约,该函数必须将 messages 作为唯一必需的输入。
typescript @AipAgentsContextRetrieval()
public exampleRetrievalFunction(messages: MessageList): RetrievedContext {
let combinedText: string[] = [];
messages.forEach((message) => {
...
})
return {
retrievedPrompt: "..."
}
}
检索函数必须输出一个 retrievedPrompt 字符串,AIP Chatbots 会将其粘贴到 LLM 系统提示词中,用于回答用户查询。
发布函数后,在 Chatbot Studio 的 Retrieval context 面板下选择 Function-backed context,以选择一个用于检索的函数。

> 图:AIP Chatbot Studio 中 function-backed context 选择的截图
### Application variables in retrieval functions
检索函数还可以接收聊天机器人上 application variables 的值作为输入。要进行此配置,请在函数定义中添加可选参数。目前仅支持字符串和对象集类型的应用变量,因此函数输入必须是这两种类型之一。
typescript @AipAgentsContextRetrieval()
public movieRetrievalFunction(messages: MessageList, movieTitle?: string, movieSet?: ObjectSet): RetrievedContext {
...
}
对象类型请使用 API 名称。该名称可在 Ontology Manager 中找到。然后,你可以在聊天机器人上的应用变量与类型相匹配的函数输入之间配置映射。

> 图:AIP Chatbot Studio 编辑页面中检索函数输入映射的截图。
要创建应用变量,请导航到 Chatbot Studio 中的 Application variables 面板。
### Write retrieval functions in AIP Logic
用户很快将能够在 AIP Logic 中编写这些函数,后者提供了一个可随时上手使用的界面,用于开发无代码的 LLM 驱动函数。在此期间若要使用检索函数,我们建议编写一个满足该接口的 TypeScript 函数,并在底层调用 Logic 函数。
### Custom citations
如果 LLM 以特定的 XML 格式返回 citations,AIP Chatbot 界面将渲染出 citation 气泡。借助 function-backed context,用户可以通过让函数返回一段提示 LLM 按给定格式编写 citations 的字符串,来渲染这些 citations。请参阅 citation formats 了解所提供的格式列表,并参阅 citation variable updates 了解如何在每次选择对象 citation 时更新 Workshop 变量。

> 图:AIP Chatbot Studio 配置了 function-backed context 以返回自定义文档 citations 的截图。
在上面的示例中,该函数接收一组表示为 Ontology 对象的文档分块。随后它对这些对象执行语义搜索,并返回最相关的五个对象,且按上述 citation 样式进行格式化。
### 常见问题速答 · FAQ
关于「检索上下文类型(Context types)」,读者最常问的几个问题。
Ontology 上下文是什么? 从本体对象里检索相关内容。Ontology context 为聊天机器人提供来自 Ontology 中对象的上下文。你可以提供固定的 N 个对象,也可以执行语义搜索来找出与用户查询最相关的 K 个对象,前提是你的对象类型具有向量嵌入属性。
文档上下文是什么? 从文档里检索相关内容。document context 允许用户在每条发送给 LLM 的消息中附带文档中的相关文本。文档的选择与添加方式,与在 AIP Threads 中向对话添加文档的方式相同。
函数支撑的上下文是什么? 用函数动态产出上下文。function-backed context 使用户能够在每次查询时执行自己的检索。这非常适用于 Ontology context 或 document context 所提供的开箱即用检索方法无法满足某个用例的场景。
---
## 会话日志
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-session-logging.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/session-logging/
- 主题分组:Chatbot Studio(十)
循序渐进 · AIP 教学 · Chatbot Studio(十)
# 会话日志
每次聊天机器人的执行都会被结构化成事件记录下来,可导出到流式数据集,用于监控与分析。
## 先记住这几条
① 每条消息算一次执行 每次执行有唯一标识。
② 日志是结构化事件 便于程序化分析,而非纯文本。
③ 可导出到流式数据集 接入平台的数据管道。
④ 用途是监控与分析 看用量、查问题、理解用户行为。
## 写在前面
AIP Chatbot Studio 中的聊天机器人执行会以结构化事件的形式记录日志,这些事件可以导出到 Foundry 流式数据集,用于监控和分析。每条发送给聊天机器人的消息算作一次执行,每次执行都会被分配一个唯一的 trace 标识符,用于关联所有相关的日志条目。
> 聊天机器人会话日志导出使用配置日志记录功能。事件 schema 和事件类型可能会发生变化。可能会新增事件,现有 schema 也可能被修改。
## 前置条件
> 要点:开启日志前要准备什么。
导出聊天机器人会话日志需要日志导出功能。有关所需的角色,请参阅导出权限。聊天机器人执行日志包含可追溯到发送消息的用户的用户标识符,因此应当谨慎管理对导出日志数据的访问。
若要设置日志导出,请按照配置日志记录文档中的步骤操作,其中包括建议的 Apply markings 步骤,即对输出流式数据集应用安全标记,以控制对日志数据的访问。
了解如何在平台中通过 Ontology 和 AIP 可观测性查看日志。
## 理解聊天机器人执行日志
> 要点:日志的结构与含义。
每个日志条目都包含由日志 schema 提供的通用字段,以及聊天机器人特有的事件数据。聊天机器人特有的数据由一个 event_name 和一个描述执行期间所发生情况的 payload 组成。
### Common log fields
以下字段包含在每个日志条目中,可用于筛选和关联日志。执行流程中来自各产品的日志(例如函数执行和语言模型使用)也共享这些字段,因此你可以用它们来追踪完整的执行请求:
Field Type Description traceId String 分配给每次执行的 Foundry trace 标识符。同一次执行的所有日志条目共享相同的 traceId。用它来端到端地追踪一个请求。 uid String 发送消息的用户的标识符。 owning_rid String 发起此次执行的源执行器的资源标识符,例如聊天机器人、函数或 Workshop 应用程序。例如,如果 Chatbot A 调用了一个函数,而该函数又调用了 Chatbot B,那么由此产生的所有日志的 owning_rid 都是 Chatbot A 的 RID。用它来查找来自某个特定源执行器的所有日志,无论调用链有多深。
### Chatbot event data
每个聊天机器人事件都包含一个标识事件类型的 event_name,以及一个带事件专属字段的 payload。每个事件 payload 都包含一个 session_rid,用于标识聊天机器人会话。用它来把单次对话中的所有事件归组到一起。
### Sample log structure
以下是 user_request 事件日志条目的简化示例:
json {
"time": "2024-01-15T09:30:00.000Z",
"uid": "",
"traceId": "",
"content": {
"event_name": "user_request",
"payload": {
"session_rid": "ri.aip-agents..session.",
"user_query": {
"content": [
{
"text": {
"content": "Summarize the key points from the latest press conference transcript."
}
}
]
}
}
}
}
## 事件类型
> 要点:记录了哪些种类的事件。
聊天机器人执行期间会记录以下事件类型:
Event name Description session_metadata 在执行开始时记录聊天机器人 RID、聊天机器人版本、会话 RID 和调用方标识符。 user_request 捕获用户的消息,以及所有 retrieval context 和应用变量。 system_chat_message 包含发送给 LLM 的已编译系统提示词,其中包括工具定义。 user_chat_message 包含发送给 LLM 的用户消息内容。 assistant_chat_message 包含 LLM 的回复内容,其中可能包括文本或工具调用。 tool_call 记录一次工具调用,包括工具名称和解析后的输入。 tool_call_result 记录一次工具调用的结果,包括其成功或失败,以及耗时。 final_response 包含聊天机器人返回给用户的最终回复。 execution_error 记录执行期间发生的错误。
### Session metadata
在每次执行开始时记录一次,包含有关聊天机器人和会话的标识信息。
Field Type Description agent_rid String 聊天机器人的资源标识符。 agent_version String 聊天机器人的版本。 session_rid String 会话的资源标识符。 caller_identifier String 发起此次执行的调用方的标识符。
### User request
捕获用户消息的完整上下文,包括为此次执行解析出的所有 retrieval context 和应用变量。
Field Type Description session_rid String 会话标识符。 user_query UserQuery 用户的消息内容,可能包括文本和媒体。 contexts_from_profile List\ 从聊天机器人已配置的上下文源解析出的 retrieval contexts。每个 context 代表一种特定的上下文类型,例如 Ontology、document、function-backed 或自定义文档。 contexts_from_user_input List\ 从用户输入解析出的 retrieval contexts。 application_variables List\ 请求时的应用变量及其值。每个变量都包含其标识符、名称、值和提示词可见性设置。 node_id String 执行节点的标识符。 parent_node_id String(可选) 此执行所延续的会话节点的标识符。
### Chat messages
system_chat_message、user_chat_message 和 assistant_chat_message 事件具有相似的结构。
Field Type Description session_rid String 会话标识符。 content List\ 消息内容,可能包括文本、媒体引用或工具调用。 native_tools List\ 使用 native tool calling 模式时 LLM 可用的工具。仅存在于 system_chat_message 中。在 prompted tool calling 模式下配置的工具则包含在 content 字段中。
### Tool calls
tool_call 事件记录聊天机器人调用某个工具的情况。
Field Type Description session_rid String 会话标识符。 tool_name String 被调用工具的名称。 parsed_tool_input Map\ 输入参数名称到其值的映射。
### Tool call results
tool_call_result 事件记录一次工具调用的结果。
Field Type Description session_rid String 会话标识符。 tool_name String 被调用工具的名称。 tool_call_id String(可选) 该次具体工具调用的标识符。 duration_milliseconds Long 该次工具调用执行所花费的时间,以毫秒为单位。 result ToolResult 该次工具调用的结果,为以下之一:
ToolResult 类型为以下之一:
- Success: 包含一个 llm_value(String),即返回给 LLM 的值;以及一个 variable_updates 列表,其中包含所有被更新的应用变量的变量名和新值。
- Failure: 包含一个 error_message(String)和一个说明工具调用失败原因的 reason(String)。
### Final response
包含聊天机器人对用户的最终回复。
Field Type Description session_rid String 会话标识符。 response FinalResponse 回复内容,为以下之一:
FinalResponse 类型为以下之一:
- Chatbot response: 包含一个内容项列表,其中可能包括文本和媒体。
- Client tool call: 表示聊天机器人将交由客户端操作处理,而不是返回直接回复。
### Execution errors
在执行期间发生错误时记录。
Field Type Description session_rid String 会话标识符。 error_name String 错误的名称或类型。
## 示例
> 要点:实际日志长什么样。
### Reconstruct a conversation
若要重建与某个特定聊天机器人的聊天对话:
- 筛选 owning_rid 与该聊天机器人 RID 匹配的日志。
- 进一步按 session_rid 筛选,以隔离出单次对话。
- 对于用户消息,查找 event_name 为 user_request 的条目,并从 payload 中提取 user_query。
- 对于聊天机器人的回复,查找 event_name 为 final_response 的条目,并从 payload 中提取 response。
### Evaluate tool performance
若要分析工具的表现:
- 查找 event_name 为 tool_call_result 的条目。每个条目都包含 tool_name、duration_milliseconds,以及该次调用是成功还是失败。
- 若要衡量可靠性,请按工具比较成功结果与失败结果的数量。
- 若要找出较慢的工具,请按 duration_milliseconds 排序。
- 若要检测重试,请在单个 traceId 内查找具有相同 tool_name 的多组 tool_call 和 tool_call_result 配对。一次失败之后又对同一工具发起另一次调用,即表明聊天机器人进行了重试。
### 常见问题速答 · FAQ
关于「会话日志」,读者最常问的几个问题。
前置条件是什么? 开启日志前要准备什么。导出聊天机器人会话日志需要日志导出功能。有关所需的角色,请参阅导出权限。聊天机器人执行日志包含可追溯到发送消息的用户的用户标识符,因此应当谨慎管理对导出日志数据的访问。
理解聊天机器人执行日志是什么? 日志的结构与含义。每个日志条目都包含由日志 schema 提供的通用字段,以及聊天机器人特有的事件数据。聊天机器人特有的数据由一个 event_name 和一个描述执行期间所发生情况的 payload 组成。
事件类型是什么? 记录了哪些种类的事件。聊天机器人执行期间会记录以下事件类型。
示例是什么? 实际日志长什么样。若要重建与某个特定聊天机器人的聊天对话。
---
## 工具(Tools)
- 页面:https://www.hanzhongpin.xyz/ontology/aip-chatbot-studio-tools.html
- 官方原文:https://www.palantir.com/docs/foundry/chatbot-studio/tools/
- 主题分组:Chatbot Studio(七)
循序渐进 · AIP 教学 · Chatbot Studio(七)
# 工具(Tools)
工具是外部功能或 API,让 LLM 能执行操作或获取自身不具备的信息。有了工具,机器人从"能说"变成"能做"。
## 先记住这几条
① 工具 = 外部能力 LLM 超出自身知识范围时的出口。
② 由模型决定何时调用 模型自己判断控制流与输入。
③ 工具要有清晰描述 描述不清模型就不会用或用错。
## 写在前面
tools(工具)是外部功能或 API,可由大语言模型(large language model,LLM)使用,以执行特定操作或获取超出其固有能力的信息。工具在让 LLM 决定控制流并构造输入方面尤其有用。

> 图:AIP Chatbot Studio 编辑模式的截图,其中的聊天机器人配置了一个 Action、Object Query 工具和一个 Ontology Semantic Search 工具。
## 工具类型
> 要点:有哪些工具可用。
共有六种类型的工具可用:
- Action: 让你的聊天机器人能够执行 ontology edit。可将其配置为自动运行,或在用户确认后运行。
- Object query: 此工具指定 LLM 可以访问的对象类型。你可以添加多个对象类型,并指定可访问的属性,使查询更加节省 token。object query 工具支持对所配置对象的筛选、聚合、检查以及沿链接的遍历。
- Function: 这允许 LLM 调用任何 Foundry function,包括已发布的 AIP Logic 函数。默认会自动使用函数的最新版本,但你也可以指定某个已发布版本,以获得更细粒度的控制。
- Update application variable: 此工具用于更新在 Application state 标签页中配置的某个应用变量的值。
- Command: 这些工具让你的聊天机器人能够使用一个或多个 commands 触发其他 Palantir 应用程序中的操作。
- Request clarification: 此工具允许聊天机器人暂停执行,并向用户请求澄清。
- (旧版)Ontology semantic search: 此工具可以使用向量属性检索相关的 Ontology context。此工具为旧版,不包含 citations 或输入/输出变量,也不会将结果对象集返回给 LLM。我们建议改用 Ontology context。
## 工具模式
> 要点:模型决定何时调用工具的方式。
使用 tool mode 设置来控制已配置的工具如何提供给 LLM,以及 LLM 如何调用这些工具。可用的 tool mode 设置有:
- Prompted tool calling: 此模式向提示词中插入指令来提供工具,并允许 LLM 使用这些工具。处于此 tool mode 的聊天机器人一次只能调用一个工具,因此在回答需要多次工具调用的复杂查询时可能耗时更长。此模式支持所有工具类型和所有可用模型。
- Native tool calling: 此模式使用受支持模型的内置能力来提供工具,并让 LLM 直接调用这些工具。由于更高的 token 效率以及处于此模式的聊天机器人能够并行调用多个工具,相比 prompted tool calling,它提供了更好的速度和性能。此模式目前只能用于 Palantir 提供的模型的一个子集,且仅支持以下工具类型:actions、object query、function 和 update application variable。如果你需要使用 native tool calling 模式不支持的模型或工具类型,请改用 prompted tool calling 模式。

> 图:AIP Chatbot Studio 编辑模式中的 tool mode 选择,可选项包括 prompted tool calling 和 native tool calling 模式。
## 查看推理过程
> 要点:看模型为什么选了这个工具。
当部署在编辑模式、查看模式、Workshop 或 AIP Threads 中时,你可以在回复下方选择 View reasoning,以查看用于生成该回复的 LLM 推理过程。

> 图:AIP Chatbot Studio 的编辑模式,右侧显示给定回复的 LLM 推理过程。
### 常见问题速答 · FAQ
关于「工具(Tools)」,读者最常问的几个问题。
工具类型是什么? 有哪些工具可用。共有六种类型的工具可用。
工具模式是什么? 模型决定何时调用工具的方式。使用 tool mode 设置来控制已配置的工具如何提供给 LLM,以及 LLM 如何调用这些工具。可用的 tool mode 设置有。
查看推理过程是什么? 看模型为什么选了这个工具。当部署在编辑模式、查看模式、Workshop 或 AIP Threads 中时,你可以在回复下方选择 View reasoning,以查看用于生成该回复的 LLM 推理过程。
---
## 文档智能核心概念
- 页面:https://www.hanzhongpin.xyz/ontology/aip-document-intelligence-core-concepts.html
- 官方原文:https://www.palantir.com/docs/foundry/document-intelligence/core-concepts/
- 主题分组:文档智能(二)
循序渐进 · AIP 教学 · 文档智能(二)
# 文档智能核心概念
搞清传统抽取与 LLM 驱动抽取的本质区别,才能选对策略。这一篇把概念讲透。
## 先记住这几条
① 传统抽取基于算法 PDF 元数据、OCR、布局检测等。
② LLM 驱动抽取更灵活 能处理格式不规整的文档。
③ 两者结合使用 不是非此即彼。
④ 策略是要设计的 抽取策略决定输出质量。
## 写在前面
## 传统抽取
> 要点:基于算法的方式,快但不灵活。
传统抽取配置基于并非由大语言模型支撑的算法,例如 PDF 元数据抽取、光学字符识别(OCR)检测以及布局检测。AIP Document Intelligence 中的这些配置由 transform media item 端点支撑。
进一步了解如何在 AIP Document Intelligence 中使用文档抽取媒体变换。
## 预处理
> 要点:正式抽取前的准备步骤。
对于需要处理更复杂文档的用例,将 VLM 与预处理技术相结合已被证明相当成功。在 Configuration > Generative AI 下,打开 Preprocess document 开关。文档预处理本质上是在文档上运行传统 OCR(光学字符识别),然后将该输出连同文档页面本身一起传给 VLM,从而为模型提供更多上下文,以便成功分析文档。

> 图:AIP Document Intelligence 中的预处理配置区域。
## 评测
> 要点:怎么判断抽取质量。
目前,只有当你的注册(enrollment)可使用 Anthropic Claude 4 Sonnet 时,才能执行抽取评估。
对于抽取策略的每次运行,你可以选择查看一份定性评分表(rubric),它会利用你所选的 VLM 作为评判者。我们对提示词进行了微调,使其针对多种维度从 1(最差)到 5(最佳)进行排名,包括给定策略对表格、标题等的抽取效果如何。评估让你能够在测试不同提示词和策略时快速迭代并做出判断。
## 部署路径
> 要点:transform 与函数两条路的差异。
当你对某个特定策略满意后,可以将其部署到批处理管道中,以便在更大范围的数据集上运行;也可以部署为逐页抽取的 Python functions。逐页 function 让你能够构建自己的抽取工作流,按用例所需的结构化方式消费 Ontology(本体)。
### Python transform
你可以将策略导出为 Python transform 仓库模板,该模板完全动态化;数据集 RID/路径、模型 RID/路径、自定义提示词以及所选配置都会自动配置好。我们建议你在触发构建前先验证这项工作。
### Python functions

> 图:AIP Document Intelligence 应用中的 Deploy to functions 按钮。
按照平台内的指南并利用生成的代码片段,使用你的抽取策略搭建一个 Python functions 仓库。这些 functions 一次抽取一页。结合 Automate 等工具使用你自己的编排策略,以配合你的 Ontology 定制此工作流。
进一步了解 AIP Document Intelligence 的功能以及如何开始使用。
### 常见问题速答 · FAQ
关于「文档智能核心概念」,读者最常问的几个问题。
传统抽取是什么? 基于算法的方式,快但不灵活。传统抽取配置基于并非由大语言模型支撑的算法,例如 PDF 元数据抽取、光学字符识别(OCR)检测以及布局检测。AIP Document Intelligence 中的这些配置由 transform media item 端点支撑。
预处理是什么? 正式抽取前的准备步骤。对于需要处理更复杂文档的用例,将 VLM 与预处理技术相结合已被证明相当成功。在 Configuration > Generative AI 下,打开 Preprocess document 开关。
评测是什么? 怎么判断抽取质量。目前,只有当你的注册(enrollment)可使用 Anthropic Claude 4 Sonnet 时,才能执行抽取评估。
部署路径是什么? transform 与函数两条路的差异。当你对某个特定策略满意后,可以将其部署到批处理管道中,以便在更大范围的数据集上运行;也可以部署为逐页抽取的 Python functions。
---
## 把抽取策略部署到 Python 函数
- 页面:https://www.hanzhongpin.xyz/ontology/aip-document-intelligence-deploy-to-python-functions.html
- 官方原文:https://www.palantir.com/docs/foundry/document-intelligence/deploy-to-python-functions/
- 主题分组:文档智能(四)
循序渐进 · AIP 教学 · 文档智能(四)
# 把抽取策略部署到 Python 函数
如果需要按需、单次抽取(而不是批量跑),部署成函数更合适。这篇给出操作路径与生成的代码。
## 先记住这几条
① 适用按需场景 一次处理一份文档,而非批量。
② 用生成的代码起步 官方给出可参考的代码片段。
③ 与 transform 是互补关系 按业务形态选。
## 写在前面
按照 AIP Document Intelligence 中的 Deploy to functions 指南进行操作,并使用生成的代码片段,用你的抽取策略搭建一个 Python functions 仓库。
## 配置
> 要点:代码与参数设置。
要在 functions 中开始文档抽取,首先创建一个 Python functions 仓库,或使用已有的仓库。
使用正确的导入和权限来设置仓库,以便运行文档抽取:
- 安装平台 SDK(如果尚未安装):
- 在左侧面板中选择 Libraries 以添加一个库。
- 安装 foundry-platform-sdk 版本 >= 1.78。
- 如果你需要分块(chunking),安装 aip-workflows 版本 >= 0.40.0。
- 如果你想做嵌入(embedding),安装 openai。
- 对于基于 LLM 的抽取,将你选择的模型导入到仓库中。
- 将该 function 设置为具有更长的超时时间。我们建议选择你的注册所允许的最大值。要处理大量 PDF 以及页数很多的 PDF,你需要将这些 functions 作为抽取策略的一部分来使用。
以下各节解释了 Deploy to functions 指南中包含的各种代码片段。
## 辅助函数
> 要点:官方提供的工具函数。
辅助函数对所有抽取策略都相同。你可以将它们复制到与你的 function 相同的 Python 文件中,如果你有多个 function,也可以复制到一个共享的工具文件中。它们在平台内可用,下面也一并列出以供参考。
python from dataclasses import dataclass
from time import sleep
from typing import Optional
from foundry_sdk import FoundryClient
from foundry_sdk._errors import PalantirException, PalantirQoSException, PalantirRPCException
from foundry_sdk._errors.palantir_qos_exception import QoSRetryHint
from foundry_sdk.v2.media_sets import models
from functions.api import function
@dataclass
class TransformResult:
"""The outcome of a transform. Functions return this instead of raising on failure so your
orchestration can branch on the result.
result: The extracted content (Markdown or JSON, depending on your configuration) on success,
otherwise None.
error: The specific error name on failure (or a human-readable reason for rate-limit and
availability errors), otherwise None.
retryable: True when the failure is transient (rate limits or service availability) and worth
retrying, False when it is not, and None on success.
"""
result: Optional[str]
error: Optional[str]
retryable: Optional[bool]
def _create_transform_job(
media_set_rid: str, media_item_rid: str, transformation: models.DocumentToTextTransformation
) -> str:
fc = FoundryClient()
job_initiation_resp = fc.media_sets.MediaSet.transform(
media_set_rid=media_set_rid,
media_item_rid=media_item_rid,
transformation=transformation,
preview=True,
)
job_id = job_initiation_resp.job_id
return job_id
def _is_transform_finished(media_set_rid: str, media_item_rid: str, job_id: str) -> bool:
fc = FoundryClient()
status = fc.media_sets.MediaSet.get_status(media_set_rid, media_item_rid, job_id, preview=True)
return status.status in ("SUCCESSFUL", "FAILED")
def _get_transform_result(media_set_rid: str, media_item_rid: str, job_id: str) -> str:
fc = FoundryClient()
result = fc.media_sets.MediaSet.get_result(media_set_rid, media_item_rid, job_id, preview=True)
return result.decode("utf-8")
def _run_transform_blocking(
media_set_rid: str, media_item_rid: str, transformation: models.DocumentToTextTransformation
) -> str:
job_id = _create_transform_job(media_set_rid, media_item_rid, transformation)
while not _is_transform_finished(media_set_rid, media_item_rid, job_id):
sleep(0.5)
return _get_transform_result(media_set_rid, media_item_rid, job_id)
def _run_transform_error_handled(
media_set_rid: str, media_item_rid: str, transformation: models.DocumentToTextTransformation
) -> TransformResult:
try:
result_text = _run_transform_blocking(media_set_rid, media_item_rid, transformation)
return TransformResult(result=result_text, error=None, retryable=None)
except PalantirQoSException as e:
retryable = e.retry_hint != QoSRetryHint.DO_NOT_RETRY
return TransformResult(result=None, error=e.reason, retryable=retryable)
except PalantirRPCException as e:
return TransformResult(result=None, error=e.name or type(e).__name__, retryable=False)
except PalantirException as e:
return TransformResult(result=None, error=type(e).__name__, retryable=False)
## 你的抽取策略
> 要点:核心逻辑怎么写。
此 function 对应你的抽取策略,需要一个媒体输入以及给定的页面。由于该 function 是动态生成的,请从应用内复制代码。你以任何名称发布它都会按该名称注册,因此你可以按需重命名。你可以将媒体输入以「媒体集 RID + 媒体项 RID 字符串」组合的形式提供,也可以作为对象属性提供;使用左上角的选择器来选择模板。对象属性模板要求你导入你的对象。

> 图:AIP Document Intelligence 应用中展示的已部署 Python function 代码。
## 分块与嵌入函数
> 要点:为下游检索做准备的环节。
你可以选择性地对抽取出的文本进行分块并生成嵌入,以供搜索或检索工作流的下游使用。下面的 functions 是静态的;分块大小、分块重叠量和嵌入模型在应用中配置,因此请将默认参数值替换为你所选的值。
python from functions.api import function, Array, Boolean, Float, Integer, String
from aip_workflows.document_intelligence.transforms import DocumentChunker
@function(beta=True)
def chunk_text(
texts: Array[String],
chunk_size: Integer = 8192,
chunk_overlap: Integer = 0,
concat_before_chunk: Boolean = False,
chunk_mode: String = "markdown",
) -> Array[Array[String]]:
"""
Chunks a list of text strings.
Args:
texts: A list of text strings to chunk.
chunk_size: Maximum number of characters per chunk.
chunk_overlap: Number of overlapping characters between consecutive chunks.
concat_before_chunk: If True, concatenates all texts into a single string before chunking,
returning a single inner list. Recommended when input is per-page text of a document.
If False, chunks each text independently, returning one inner list per input text.
chunk_mode: The chunking strategy to use. Options:
- "markdown": Recommended for Markdown text.
- "recursive": Recommended for raw text without any format.
Returns:
A list of lists of chunk strings. Each inner list contains the chunks for one input text.
When concat_before_chunk is True, input texts are concatenated into a single string so the
output list has length of 1.
"""
chunks = DocumentChunker.create_chunks(
texts,
chunk_mode=chunk_mode,
chunk_size=chunk_size,
chunk_overlap=chunk_overlap,
strip_markdown=True,
concat_before_chunk=concat_before_chunk,
)
if concat_before_chunk:
return [chunks]
return chunks
from foundry_sdk.v2.language_models.utils import (
get_foundry_token,
get_openai_base_url,
get_http_client,
)
from openai import OpenAI
@function(beta=True)
def embed_text(
texts: Array[String],
embedding_model_rid: String = "",
) -> Array[Array[Float]]:
"""
Generates embeddings for a list of text strings using the configured embedding model.
Args:
texts: A list of text strings to embed.
embedding_model_rid: The RID of the embedding model to use.
Returns:
A list of vector embeddings, one per input text.
"""
client = OpenAI(
api_key=get_foundry_token(preview=True),
base_url=get_openai_base_url(preview=True),
http_client=get_http_client(preview=True),
)
response = client.embeddings.create(
input=texts,
model=embedding_model_rid,
)
return [response.data[i].embedding for i in range(len(texts))]
### 常见问题速答 · FAQ
关于「把抽取策略部署到 Python 函数」,读者最常问的几个问题。
如何配置? 代码与参数设置。要在 functions 中开始文档抽取,首先创建一个 Python functions 仓库,或使用已有的仓库。
辅助函数是什么? 官方提供的工具函数。辅助函数对所有抽取策略都相同。你可以将它们复制到与你的 function 相同的 Python 文件中,如果你有多个 function,也可以复制到一个共享的工具文件中。它们在平台内可用,下面也一并列出以供参考。
你的抽取策略是什么? 核心逻辑怎么写。此 function 对应你的抽取策略,需要一个媒体输入以及给定的页面。由于该 function 是动态生成的,请从应用内复制代码。你以任何名称发布它都会按该名称注册,因此你可以按需重命名。
分块与嵌入函数是什么? 为下游检索做准备的环节。你可以选择性地对抽取出的文本进行分块并生成嵌入,以供搜索或检索工作流的下游使用。下面的 functions 是静态的;分块大小、分块重叠量和嵌入模型在应用中配置,因此请将默认参数值替换为你所选的值。
---
## 把抽取策略部署到 Python transform
- 页面:https://www.hanzhongpin.xyz/ontology/aip-document-intelligence-deploy-to-python-transforms.html
- 官方原文:https://www.palantir.com/docs/foundry/document-intelligence/deploy-to-python-transforms/
- 主题分组:文档智能(三)
循序渐进 · AIP 教学 · 文档智能(三)
# 把抽取策略部署到 Python transform
验证好的策略可以部署成 Python transform,对媒体集里所有文档的所有页面跑批量抽取 —— 这是从"试验"到"规模化"的关键一步。
## 先记住这几条
① 部署后即可批量跑 覆盖整个媒体集与全部页面。
② 产出是一套模板 生成与交互式验证一致的结果。
③ 适合定期批处理 接到数据管道里,随新文档自动跑。
## 写在前面
在 AIP Document Intelligence 中验证抽取策略之后,你可以将其部署为一个 Python transform,以便对媒体集中所有文档的所有页面运行批量抽取。部署出的模板会产生与 AIP Document Intelligence 中对应配置相同的结果。
## 使用部署出的模板
> 要点:生成产物怎么用。
模板在 Code Repositories 中创建完成后:
- 在 src/myproject/document_extraction/my_extraction.py 文件中的 @transform.using 装饰器里指定你的输出数据集。
- 触发构建。
该模板使用轻量级 transforms(lightweight transforms)以获得最佳性能。旧版本使用的是基于 Spark 的 transforms,由于 Spark 开销,其速度要慢得多。如果你还没有迁移,我们建议迁移到轻量级 transforms。
该模板目前尚不支持预览模式(Preview mode)。使用预览时预计会出现错误,但实际构建会正常工作。
### Incremental processing
默认情况下,文档抽取 transform 是非增量的,这意味着每次运行都会处理所有文档。你可以通过取消注释 @incremental(...) 装饰器行,将 transform 配置为增量运行。对于增量 transform,当新文档被添加到输入媒体集时,重新运行该 transform 将只处理新文档,并将结果追加到输出数据集。
### Customizing the prompt
对于生成式 AI 配置,模板会继承你在 AIP Document Intelligence 中指定的提示词。你可以在 src/myproject/document_extraction/prompts.py 中查看提示词。
我们不建议直接在模板中编辑提示词,因为这会导致 Document Intelligence 结果与批处理作业结果之间出现差异。相反,应在 Document Intelligence 中调整提示词,在那里验证结果,然后重新部署以创建新模板。
Transform input type Customizable prompt VisionLLMDocumentsExtractorInput User prompt only (system prompt is fixed) VisionLLMLayoutDocumentsExtractorInput (layout-aware extraction) System prompt only (user prompt is fixed)
对于布局感知抽取配置,用户提示词必须保持固定,因为它包含一个特殊的 JSON schema,用于保留布局结构信息。修改此提示词会显著降低抽取成功率。
### Custom image preprocessing
对于在抽取前需要进行图像变换的文档,例如文本内容有旋转的文档,你应该:
- 创建一个单独的 transform 管道来应用图像变换。
- 将处理后的结果保存到一个新的媒体集。
- 在处理后的媒体集上使用 Document Intelligence 进行抽取。
### Run on a subset of media items
对于布局感知的生成式 AI 配置,视觉 LLM 必须生成符合特定 schema 的有效 JSON。如果响应是无效 JSON 或不符合该 schema,抽取会失败并报 ERROR_RESPONSE_JSON_PARSING 错误。
在实践中,使用顶级模型时大约 5% 的抽取可能会失败。对于失败的行,你仍然可以获得有效的 layoutInfo,其中只包含来自布局模型的抽取结果。
要对失败的行重新运行抽取:
- 使用 filter_on_media_items 参数并传入媒体项 ID 列表,以只处理特定的项。
- 移除 @incremental 装饰器,这样这些行会被重新处理,而不会被判定为已完成。
### Improve runtime performance
THREAD_NUMBER 参数控制并发线程数,其中每个线程一次从一页文档抽取数据。值越高,作业完成得越快。
Setting Value Notes Default 20 Conservative setting suitable for most environments Maximum tested 300 Achievable in development environments with abundant Vision LLM capacity
在容量受限的环境中把 THREAD_NUMBER 的值设得太高会导致速率限制错误。随后重试循环会消耗大量容量,影响使用同一模型的其他作业。调整此参数时,你应该监控用量。
### Find logs
要查看构建日志,请在构建详情页面上选择 Telemetry。要筛选文档抽取日志,请在 message 列中筛选以 aip_workflows 开头的值。
### Row-level vs. document-level chunking
抽取输出为每页一行。默认情况下,DocumentChunker.create_chunks_per_document 会在分块前将同一文档的所有页面合并为一个 Markdown 字符串。
要独立地对每一行进行分块而不合并页面,请改用 DocumentChunker.create_chunks_per_row:
````python
chunking_result = chunker.create_chunks_per_row( extraction_df, chunk_mode="markdown", # "recursive" for plain text, "markdown" for markdown text content_column="extractionResult", id_column="media_item_rid", # used as prefix for chunk_id chunk_size=8192, chunk_overlap=0, thread_number=20, strip_markdown=False, # set True to remove ``markdown and `` wrappers before chunking )
````
### Create embeddings without chunking
在创建嵌入之前建议先进行分块,因为嵌入模型有上下文限制。要在保留管道结构的同时跳过分块,请在 create_chunks_per_row 中把 chunk_size 设为一个非常大的值,例如 sys.maxsize。
## 模板示例
> 要点:可参考的代码。
以下示例展示了为每种抽取配置生成的 transform 代码。这些仅供参考。你应该使用 Document Intelligence 中的部署工具来创建 transform,而不是为文档抽取手写 transform 代码。
### Traditional extraction: Raw text
通过读取文档元数据来抽取文本。仅适用于电子生成的 PDF。
python import polars as pl
from concurrent.futures import ThreadPoolExecutor
from transforms.api import Output, incremental, transform
from transforms.mediasets import MediaSetInput
from transforms.mediasets.utils._constants import MEDIA_ITEM_RID, MEDIA_REFERENCE, PATH
THREAD_NUMBER = 20
# @incremental(v2_semantics=True) # uncomment this line if incremental is needed
@transform.using(
output=Output("ri.foundry.main.dataset.abc"),
media_input=MediaSetInput("ri.mio.main.media-set.abc"),
)
def extract(media_input, output):
"""
Extracts content from pdf documents with raw text extraction
"""
media_refs = pl.from_pandas(
media_input.list_media_items_by_path_with_media_reference().pandas(),
schema_overrides={MEDIA_ITEM_RID: pl.String, MEDIA_REFERENCE: pl.String, PATH: pl.String},
)
def process_batch(batch_df: pl.DataFrame) -> pl.DataFrame:
def create_page_tasks(row):
media_item_rid = row[MEDIA_ITEM_RID]
metadata = media_input.get_media_item_metadata(media_item_rid).document
if metadata is None:
raise ValueError(f"Media item {media_item_rid} is not a document")
if metadata.pages is None:
raise ValueError(f"Media item {media_item_rid} has no page count")
return [(row, page_num) for page_num in range(metadata.pages)]
def process_single_page(task):
row, page_num = task
media_item_rid = row[MEDIA_ITEM_RID]
media_reference = row[MEDIA_REFERENCE]
extraction_result = media_input.transform_document_to_text_raw(
media_item_rid, page_num
).read().decode("utf-8")
return {
"media_item_rid": media_item_rid,
"media_reference": media_reference,
"page_num": page_num,
"extraction_result": extraction_result
}
all_tasks = []
for row in batch_df.iter_rows(named=True):
all_tasks.extend(create_page_tasks(row))
with ThreadPoolExecutor(max_workers=THREAD_NUMBER) as executor:
results = list(executor.map(process_single_page, all_tasks))
return pl.DataFrame(results)
extracted_data = media_refs.lazy().map_batches(
process_batch,
schema={
"media_item_rid": pl.String,
"media_reference": pl.String,
"page_num": pl.Int64,
"extraction_result": pl.String,
},
streamable=True,
)
output.write_dataframe(extracted_data)
### Traditional extraction: OCR
使用传统光学字符识别(OCR)来抽取文本,但不保留布局信息。
python import polars as pl
from concurrent.futures import ThreadPoolExecutor
from transforms.api import Output, incremental, transform
from transforms.mediasets import MediaSetInput
from transforms.mediasets.utils._constants import MEDIA_ITEM_RID, MEDIA_REFERENCE, PATH
THREAD_NUMBER = 20
# @incremental(v2_semantics=True) # uncomment this line if incremental is needed
@transform.using(
output=Output("ri.foundry.main.dataset.abc"),
media_input=MediaSetInput("ri.mio.main.media-set.abc"),
)
def extract(media_input, output):
"""
Extracts content from pdf documents with OCR text extraction
"""
media_refs = pl.from_pandas(
media_input.list_media_items_by_path_with_media_reference().pandas(),
schema_overrides={MEDIA_ITEM_RID: pl.String, MEDIA_REFERENCE: pl.String, PATH: pl.String},
)
def process_batch(batch_df: pl.DataFrame) -> pl.DataFrame:
def create_page_tasks(row):
media_item_rid = row[MEDIA_ITEM_RID]
metadata = media_input.get_media_item_metadata(media_item_rid).document
if metadata is None:
raise ValueError(f"Media item {media_item_rid} is not a document")
if metadata.pages is None:
raise ValueError(f"Media item {media_item_rid} has no page count")
return [(row, page_num) for page_num in range(metadata.pages)]
def process_single_page(task):
row, page_num = task
media_item_rid = row[MEDIA_ITEM_RID]
media_reference = row[MEDIA_REFERENCE]
extraction_result = media_input.transform_document_to_text_ocr_output_text(
media_item_rid, page_num
).read().decode("utf-8")
return {
"media_item_rid": media_item_rid,
"media_reference": media_reference,
"page_num": page_num,
"extraction_result": extraction_result
}
all_tasks = []
for row in batch_df.iter_rows(named=True):
all_tasks.extend(create_page_tasks(row))
with ThreadPoolExecutor(max_workers=THREAD_NUMBER) as executor:
results = list(executor.map(process_single_page, all_tasks))
return pl.DataFrame(results)
extracted_data = media_refs.lazy().map_batches(
process_batch,
schema={
"media_item_rid": pl.String,
"media_reference": pl.String,
"page_num": pl.Int64,
"extraction_result": pl.String,
},
streamable=True,
)
output.write_dataframe(extracted_data)
### Traditional extraction: Layout-aware OCR
使用带边界框的高级 OCR,以保留文档布局和结构。
python import polars as pl
from concurrent.futures import ThreadPoolExecutor
from transforms.api import Output, incremental, transform
from transforms.mediasets import MediaSetInput
from transforms.mediasets.utils._constants import MEDIA_ITEM_RID, MEDIA_REFERENCE, PATH
THREAD_NUMBER = 20
# @incremental(v2_semantics=True) # uncomment this line if incremental is needed
@transform.using(
output=Output("ri.foundry.main.dataset.abc"),
media_input=MediaSetInput("ri.mio.main.media-set.abc"),
)
def extract(media_input, output):
"""
Extracts content from pdf documents with layout-aware OCR extraction
"""
media_refs = pl.from_pandas(
media_input.list_media_items_by_path_with_media_reference().pandas(),
schema_overrides={MEDIA_ITEM_RID: pl.String, MEDIA_REFERENCE: pl.String, PATH: pl.String},
)
def process_batch(batch_df: pl.DataFrame) -> pl.DataFrame:
def create_page_tasks(row):
media_item_rid = row[MEDIA_ITEM_RID]
metadata = media_input.get_media_item_metadata(media_item_rid).document
if metadata is None:
raise ValueError(f"Media item {media_item_rid} is not a document")
if metadata.pages is None:
raise ValueError(f"Media item {media_item_rid} has no page count")
return [(row, page_num) for page_num in range(metadata.pages)]
def process_single_page(task):
row, page_num = task
media_item_rid = row[MEDIA_ITEM_RID]
media_reference = row[MEDIA_REFERENCE]
extraction_result = media_input.transform_media_item(media_item_rid, str(page_num), {
"type": "documentToText",
"documentToText": {
"operation": {
"type": "extractLayoutAwareContent",
"extractLayoutAwareContent": {
"parameters": {
"languages": ["ENG"]
}
}
}
}
})
extraction_result = str(extraction_result.json())
return {
"media_item_rid": media_item_rid,
"media_reference": media_reference,
"page_num": page_num,
"extraction_result": extraction_result
}
all_tasks = []
for row in batch_df.iter_rows(named=True):
all_tasks.extend(create_page_tasks(row))
with ThreadPoolExecutor(max_workers=THREAD_NUMBER) as executor:
results = list(executor.map(process_single_page, all_tasks))
return pl.DataFrame(results)
extracted_data = media_refs.lazy().map_batches(
process_batch,
schema={
"media_item_rid": pl.String,
"media_reference": pl.String,
"page_num": pl.Int64,
"extraction_result": pl.String,
},
streamable=True,
)
output.write_dataframe(extracted_data)
### Generative AI extraction: Basic
使用视觉语言模型将内容抽取为 Markdown,不进行预处理。
python from transforms.api import Output, incremental, transform
from transforms.mediasets import MediaSetInput
from aip_workflows.document_intelligence.transforms import VisionLLMDocumentsExtractorInput
from .prompts import USER_PROMPT
THREAD_NUMBER = 20
# @incremental(v2_semantics=True, snapshot_inputs=["extractor"]) # uncomment this line if incremental is needed
@transform.using(
output=Output("ri.foundry.main.dataset.abc"),
media_input=MediaSetInput("ri.mio.main.media-set.abc"),
extractor=VisionLLMDocumentsExtractorInput(
"ri.language-model-service..language-model.anthropic-claude-xxx-sonnet"
),
)
def extract(media_input, output, extractor):
"""
Extracts content from pdf documents as markdown.
"""
extracted_data = extractor.create_extraction(
media_input, with_ocr=False, prompt=USER_PROMPT, thread_number=THREAD_NUMBER
)
output.write_dataframe(extracted_data)
### Generative AI extraction: With OCR preprocessing
使用带 OCR 预处理的视觉语言模型,以改善对复杂文档的抽取效果。
python from transforms.api import Output, incremental, transform
from transforms.mediasets import MediaSetInput
from aip_workflows.document_intelligence.transforms import VisionLLMDocumentsExtractorInput
from .prompts import USER_PROMPT
THREAD_NUMBER = 20
# @incremental(v2_semantics=True, snapshot_inputs=["extractor"]) # uncomment this line if incremental is needed
@transform.using(
output=Output("ri.foundry.main.dataset.abc"),
media_input=MediaSetInput("ri.mio.main.media-set.abc"),
extractor=VisionLLMDocumentsExtractorInput(
"ri.language-model-service..language-model.anthropic-claude-xxx-sonnet"
),
)
def extract(media_input, output, extractor):
"""
Extracts content from pdf documents as markdown.
"""
extracted_data = extractor.create_extraction(
media_input, with_ocr=True, prompt=USER_PROMPT, thread_number=THREAD_NUMBER
)
output.write_dataframe(extracted_data)
### Generative AI extraction: Layout-aware
使用带布局感知 OCR 预处理的视觉语言模型,在返回抽取内容的同时返回布局信息。
python from transforms.api import Output, incremental, transform
from transforms.mediasets import MediaSetInput
from aip_workflows.document_intelligence.transforms import VisionLLMLayoutDocumentsExtractorInput
from .prompts import SYSTEM_PROMPT
THREAD_NUMBER = 20
# @incremental(v2_semantics=True, snapshot_inputs=["extractor"]) # uncomment this line if incremental is needed
@transform.using(
output=Output("ri.foundry.main.dataset.abc"),
media_input=MediaSetInput("ri.mio.main.media-set.abc"),
extractor=VisionLLMLayoutDocumentsExtractorInput(
"ri.language-model-service..language-model.anthropic-claude-xxx-sonnet"
),
)
def extract(media_input, output, extractor):
"""
Extracts content from pdf documents as markdown.
"""
extracted_data = extractor.create_extraction(
media_input,
include_layout_info="no_overlay",
system_prompt=SYSTEM_PROMPT,
thread_number=THREAD_NUMBER
)
output.write_dataframe(extracted_data)
### Generative AI extraction: Layout-aware with table cropping
使用带布局感知 OCR 预处理和表格裁剪(table cropping)的视觉语言模型,以提高表格抽取的准确性。
python from transforms.api import Output, incremental, transform
from transforms.mediasets import MediaSetInput
from aip_workflows.document_intelligence.transforms import VisionLLMLayoutDocumentsExtractorInput
from .prompts import SYSTEM_PROMPT
THREAD_NUMBER = 20
# @incremental(v2_semantics=True, snapshot_inputs=["extractor"]) # uncomment this line if incremental is needed
@transform.using(
output=Output("ri.foundry.main.dataset.abc"),
media_input=MediaSetInput("ri.mio.main.media-set.abc"),
extractor=VisionLLMLayoutDocumentsExtractorInput(
"ri.language-model-service..language-model.anthropic-claude-xxx-sonnet"
),
)
def extract(media_input, output, extractor):
"""
Extracts content from pdf documents as markdown.
"""
extracted_data = extractor.create_extraction(
media_input,
include_layout_info="crop_tables",
system_prompt=SYSTEM_PROMPT,
thread_number=THREAD_NUMBER
)
output.write_dataframe(extracted_data)
### Chunk extracted text and generate embeddings
如果不需要嵌入,请从 transform 装饰器中移除 embedder,并移除 embedding_result 那一行。
````python
from transforms.api import Input, Output, incremental, transform from aip_workflows.document_intelligence.transforms import DocumentChunker, DocumentEmbedderInput
THREAD_NUMBER = 20
@transform.using( extraction_input=Input("ri.foundry.main.dataset.abc"), # typically the output dataset from the extraction transform output=Output("ri.foundry.main.dataset.xyz"), embedder=DocumentEmbedderInput("ri.language-model-service..language-model.text-embedding-3-large"), ) def chunk_and_embed(extraction_input, output, embedder): extraction_df = extraction_input.polars(lazy=True) chunker = DocumentChunker() chunking_result = chunker.create_chunks_per_document( extraction_df, chunk_mode="markdown", # "recursive" for raw text, "markdown" for markdown text content_column="extractionResult", # content column name id_column="media_item_rid", # id of the document, used to combine content (e.g. from different pages) of the single document page_column="page_num", # page number column name chunk_size=8192, chunk_overlap=0, thread_number=THREAD_NUMBER, strip_markdown=True, # when True, removes ``markdown prefix and `` suffix from the content before chunking ) embedding_result = embedder.create_embeddings( chunking_result, content_column="chunk_content", thread_number=THREAD_NUMBER, ) output.write_dataframe(embedding_result)
````
### 常见问题速答 · FAQ
关于「把抽取策略部署到 Python transform」,读者最常问的几个问题。
使用部署出的模板是什么? 生成产物怎么用。模板在 Code Repositories 中创建完成后。
模板示例是什么? 可参考的代码。以下示例展示了为每种抽取配置生成的 transform 代码。这些仅供参考。你应该使用 Document Intelligence 中的部署工具来创建 transform,而不是为文档抽取手写 transform 代码。
---
## 文档转文本(Document-to-text)变换
- 页面:https://www.hanzhongpin.xyz/ontology/aip-document-intelligence-document-to-text.html
- 官方原文:https://www.palantir.com/docs/foundry/document-intelligence/document-to-text/
- 主题分组:文档智能(五)
循序渐进 · AIP 教学 · 文档智能(五)
# 文档转文本(Document-to-text)变换
这是底层能力:把多种格式的文档转成文本,并且保留版面结构(段落、标题、表格)。抽取质量的上限由它决定。
## 先记住这几条
① 多格式支持 不只 PDF,覆盖多种常见文档格式。
② 保留版面结构 段落、标题、表格都能识别出来。
③ 兼顾灵活与性能 既能精细抽取,又能跑得动。
④ 是上层抽取的基础 抽不准往往是这一步没做好。
## 写在前面
Document-to-text 变换提供了一种灵活且高性能的方式来抽取多种格式的文档内容,包括抽取文档布局结构的能力,例如段落、标题和表格。
AIP Document Intelligence 提供两种 document-to-text 媒体变换操作:
- extractTextV2:返回一个字符串列表,包含抽取出的文档文本。
- extractLayoutAwareTextV2:返回跨页面的布局感知(layout-aware)文本块列表。
> 我们建议使用上面列出的操作,它们取代了 extractLayoutAwareContent 和 ocrOnPage 操作。
你可以参考下面的示例操作签名:
json {
"type": "documentToText",
"documentToText": {
"operation": {
"type": "{operation}", // {operation}: "extractTextV2" or "extractLayoutAwareTextV2"
"{operation}": {
"pageRange": {
"startPageInclusive": 0,
"endPageExclusive": 5
},
"config": {
"mode": "SCAN", // or "ELECTRONIC" or "AUTO"
"format": "TEXT", // or "MARKDOWN" or "HTML"
"languages": [
{
"type": "language",
"language": "KOR"
}
]
}
}
}
}
}
## 操作签名参数
> 要点:这个变换接收哪些参数。
- config.mode:控制文档页面如何被解读。
- ELECTRONIC:将所有页面视为电子 PDF 文件,并抽取内嵌/原始文本。当你确定文档包含内嵌文本时使用 ELECTRONIC。
- SCAN:将所有页面视为扫描图像,并执行光学字符识别(OCR)。当你确定文档是扫描图像时使用 SCAN。
- AUTO:自动按页判断是否需要 OCR。仅当你事先不知道 PDF 文件是电子的、扫描的,还是混合的时使用。AUTO 模式会带来少量计算开销。
- config.format:控制输出格式。
- TEXT
- MARKDOWN
- HTML
- config.languages:控制要检测的语言,用于 SCAN 或 AUTO 模式下的 OCR。
- language:语言代码,例如 KOR。
- type:始终设为 "language"。
- pageRange:控制要抽取的页面。在上面的操作签名中,页面范围会处理第 0、1、2、3 和 4 页。使用页面范围可以提升较大文档的构建性能。不必为每一页发起一次请求,你可以将多个页面批量合并处理。根据文档大小、模型限制和速率限制的不同,大约五到十页的页面范围是一个合适的起点。
### Parameter considerations
- 对于电子 PDF 文件,你无需指定语言。
- 如果文档语言是英语,你无需指定语言。
- 对于非英语的扫描文档,请指定相关的 OCR 语言。
## Python 示例
> 要点:可直接运行的代码。
参考以下示例,帮助你使用 Python transform 或 function 执行 document-to-text 变换。
### Transform
python import polars as pl
from concurrent.futures import ThreadPoolExecutor
from transforms.api import Output, transform
from transforms.mediasets import MediaSetInput
from transforms.mediasets.utils._constants import MEDIA_ITEM_RID, MEDIA_REFERENCE, PATH
THREAD_NUMBER = 20
# @incremental(v2_semantics=True) # Uncomment this line if incremental is needed.
@transform.using(
output=Output(OUTPUT_DATASET_RID),
media_input=MediaSetInput(INPUT_MEDIA_SET_RID),
)
def extract(media_input, output):
media_refs = pl.from_pandas(
media_input.list_media_items_by_path_with_media_reference().pandas(),
schema_overrides={
MEDIA_ITEM_RID: pl.String,
MEDIA_REFERENCE: pl.String,
PATH: pl.String,
},
)
def process_batch(batch_df: pl.DataFrame) -> pl.DataFrame:
def create_page_tasks(row):
media_item_rid = row[MEDIA_ITEM_RID]
metadata = media_input.get_media_item_metadata(media_item_rid).document
if metadata is None:
raise ValueError(f"Media item {media_item_rid} is not a document")
if metadata.pages is None:
raise ValueError(f"Media item {media_item_rid} has no page count")
return [(row, page_num) for page_num in range(metadata.pages)]
def process_single_page(task):
row, page_num = task
media_item_rid = row[MEDIA_ITEM_RID]
media_reference = row[MEDIA_REFERENCE]
extraction_result = media_input.transform_media_item(
media_item_rid,
str(page_num),
{
"type": "documentToText",
"documentToText": {
"operation": {
"type": "extractLayoutAwareTextV2",
"extractLayoutAwareTextV2": {
"pageRange": {
"startPageInclusive": page_num,
"endPageExclusive": page_num + 1,
},
"config": {
"mode": "ELECTRONIC",
"format": "TEXT",
},
},
},
},
},
)
return {
"media_item_rid": media_item_rid,
"media_reference": media_reference,
"page_num": page_num,
"extraction_result": str(extraction_result.json()),
}
all_tasks = []
for row in batch_df.iter_rows(named=True):
all_tasks.extend(create_page_tasks(row))
with ThreadPoolExecutor(max_workers=THREAD_NUMBER) as executor:
results = list(executor.map(process_single_page, all_tasks))
return pl.DataFrame(results)
extracted_data = media_refs.lazy().map_batches(
process_batch,
schema={
"media_item_rid": pl.String,
"media_reference": pl.String,
"page_num": pl.Int64,
"extraction_result": pl.String,
},
streamable=True,
)
output.write_dataframe(extracted_data)
### Function
python from time import sleep
from foundry_sdk import FoundryClient
from foundry_sdk.v2.media_sets import models
from functions.api import function
#### Helper functions
def _create_transform_job(
media_set_rid: str, media_item_rid: str, transformation: models.DocumentToTextTransformation
) -> str:
fc = FoundryClient()
job_initiation_resp = fc.media_sets.MediaSet.transform(
media_set_rid=media_set_rid,
media_item_rid=media_item_rid,
transformation=transformation,
preview=True,
)
job_id = job_initiation_resp.job_id
return job_id
def _is_transform_finished(media_set_rid: str, media_item_rid: str, job_id: str) -> bool:
fc = FoundryClient()
status = fc.media_sets.MediaSet.get_status(media_set_rid, media_item_rid, job_id, preview=True)
return status.status in ("SUCCESSFUL", "FAILED")
def _get_transform_result(media_set_rid: str, media_item_rid: str, job_id: str) -> str:
fc = FoundryClient()
result = fc.media_sets.MediaSet.get_result(media_set_rid, media_item_rid, job_id, preview=True)
return result.decode("utf-8")
def _run_transform_blocking(
media_set_rid: str, media_item_rid: str, transformation: models.DocumentToTextTransformation
) -> str:
job_id = _create_transform_job(media_set_rid, media_item_rid, transformation)
while not _is_transform_finished(media_set_rid, media_item_rid, job_id):
sleep(0.5)
return _get_transform_result(media_set_rid, media_item_rid, job_id)
# Use this function if your input is a media set
# We suggest running the function across batches of five to ten pages to avoid timeout
@function(beta=True)
def transform_vlm(media_set_rid: str, media_item_rid: str, start_page_inclusive: int, end_page_exclusive: int) -> str:
LANGUAGES: list[models.OcrLanguageOrScript] = [models.OcrLanguageWrapper(language="ENG")]
return _run_transform_blocking(
media_set_rid,
media_item_rid,
models.DocumentToTextTransformation(
operation=models.ExtractDocumentLayoutAwareTextV2Operation(
page_range=models.PageRange(start_page_inclusive=start_page_inclusive, end_page_exclusive=end_page_exclusive),
config=models.ExtractDocumentLayoutAwareTextV2Config(languages=LANGUAGES),
)
),
)
# Use this function if your input is an object
# We suggest running the function across batches of five to ten pages to avoid timeout
@function(beta=True, edits=[])
def transform_vlm_object(myObject: , start_page_inclusive: int, end_page_exclusive: int) -> str:
reference_view = myObject.media_reference.get_media_reference().reference.media_set_view_item
media_set_rid = reference_view.media_set_rid
media_item_rid = reference_view.media_item_rid
LANGUAGES: list[models.OcrLanguageOrScript] = [models.OcrLanguageWrapper(language="ENG")]
return _run_transform_blocking(
media_set_rid,
media_item_rid,
models.DocumentToTextTransformation(
operation=models.ExtractDocumentLayoutAwareTextV2Operation(
page_range=models.PageRange(start_page_inclusive=start_page_inclusive, end_page_exclusive=end_page_exclusive),
config=models.ExtractDocumentLayoutAwareTextV2Config(languages=LANGUAGES),
)
),
)
---
## AIP Document Intelligence 总览
- 页面:https://www.hanzhongpin.xyz/ontology/aip-document-intelligence-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/document-intelligence/overview/
- 主题分组:文档智能(一)
循序渐进 · AIP 教学 · 文档智能(一)
# AIP Document Intelligence 总览
企业里大量信息锁在文档里。AIP Document Intelligence 是 Foundry 中文档抽取的统一入口:打开文档、试验抽取策略、验证效果、再部署成批量流程。
## 先记住这几条
① 统一入口 所有文档抽取工作流从这里开始。
② 交互式验证 先看到抽取效果,再决定怎么部署。
③ 可从文档直通生产 验证好的策略能部署成 transform 或 function。
## 写在前面
AIP Document Intelligence 是 Foundry 中所有文档抽取(document extraction)工作流的入口。你可以使用 AIP Document Intelligence 打开一个企业文档的媒体集(media set),快速执行不同的最先进文档抽取策略(extraction strategy),并获取这些策略在质量、速度和 token 成本方面的评估结果。随后只需一次点击,即可将配置好的抽取策略部署为一个 Python transform,应用到媒体集上的批处理管道中。

> 图:一个来自媒体集的示例 PDF 文档,在 AIP Document Intelligence 中预览。
## 功能特性
> 要点:能做哪些抽取。
AIP Document Intelligence 提供多种抽取能力,并配有简化界面以支持高效的即时使用:
标出不同的抽取区域。)
> 图:一个在 Document Intelligence 中抽取文档的示例,使用边界框(bounding box)标出不同的抽取区域。
- 直观的用户界面: 轻松搜索并选择要处理的 Foundry 媒体集,并使用多种抽取策略。
- 快速确认闭环: 执行的策略结果易于确认,因为 Markdown 输出会映射到原始 PDF 上的边界框。
- 传统抽取: 利用已有策略从文档中抽取 Markdown:
- Raw text: 通过读取文档元数据来抽取文本。仅适用于电子生成的 PDF。
- OCR: 使用传统 OCR(光学字符识别)抽取文本,但不保留布局信息。
- Layout-aware OCR: 使用带边界框的高级 OCR,以保留文档布局和结构。
- 生成式 AI 抽取: 使用针对抽取 Markdown 微调过的提示词,执行视觉语言模型(vision language model,VLM)策略。默认提示词经过调优,可在我们的内部评估集上取得最佳表现。你也可以通过配置界面使用自定义逻辑修改提示词。
- 带 VLM 抽取的预处理: 对于更复杂的用例,你可以将文档预处理与传统方法(例如 layout-aware OCR)结合使用。然后,你可以将预处理结果传给 VLM 以获得更好表现。进一步了解文档预处理。
- 执行指标: 观察抽取质量、执行时间以及输入/输出 token 消耗的评分指标(rubric metric)。
- 评估: 使用 VLM 作为评判者,抽取结果会针对文档中可能包含的多种因素进行评分,包括列表、表格和代码块的质量。评估策略经过调优,可使其评估结果与我们的内部评估集中的标准答案(ground truth)相匹配。进一步了解抽取评估。
- 部署: 确认理想的抽取策略后,只需一次点击即可轻松地将该策略部署到 Python transforms 仓库中。该 transform 会按精确的抽取策略进行配置,包括模型选择和任何提示词修改。进一步了解抽取策略部署。
## 开始使用
> 要点:第一步怎么走。
AIP Document Intelligence 遵循一套测试工作流:用户导入媒体集、选择配置,并通过观察结果和评估反复迭代策略,直到满意后再进行部署。按照以下步骤开始:

> 图:使用 AIP Document Intelligence 时的标准工作流示意图。
- 上传媒体集: 在应用落地页中,选择从可用文件中选择一个媒体集,或上传一个新的媒体集。
- 选择配置: 媒体集打开后,打开 Configuration 标签页来设置你想使用的抽取方法。在传统方法与生成式 AI 方法之间进行选择,按需启用预处理,并自定义要用于 VLM 的提示词。选择 Save 以记住你的配置选择,以备将来使用。

- 在媒体集上执行策略: 配置好抽取方法后,在 Configuration 标签页右上角选择 Run。
- 预览抽取结果: 运行抽取后,导航到 Extraction result 标签页,查看基于所选策略的输出。
- 评估抽取结果(可选): 在结果标签页中,选择 Evaluate results 以使用 LLM 评估抽取结果。继续测试第 3 至第 5 步,直到你对抽取结果和评估都满意为止。

- 可视化分块(可选): 在 Extraction result 标签页中,选择某个抽取结果旁边的 Chunk 按钮,即可预览文本将如何被切分。你可以调整分块参数并查看结果。
- 部署抽取策略: 打开 Deployment 标签页,从下拉菜单中选择你保存的配置,然后选择 Create transform repository。系统会提示你为新 Python transforms 仓库选择名称和位置。可以选择性地启用分块(chunking)和嵌入(embedding)。仓库创建后,指定输出数据集并开始构建。详见该仓库的 README.md 获取详细说明。

### 常见问题速答 · FAQ
关于「AIP Document Intelligence 总览」,读者最常问的几个问题。
功能特性是什么? 能做哪些抽取。AIP Document Intelligence 提供多种抽取能力,并配有简化界面以支持高效的即时使用。
如何开始使用? 第一步怎么走。AIP Document Intelligence 遵循一套测试工作流:用户导入媒体集、选择配置,并通过观察结果和评估反复迭代策略,直到满意后再进行部署。按照以下步骤开始。
---
## 用 Automate 自动化 AIP Logic
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-aip-logic-integration-automate.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/aip-logic-integration-automate/
- 主题分组:AIP Logic(八)
循序渐进 · AIP 教学 · AIP Logic(八)
# 用 Automate 自动化 AIP Logic
Logic 函数可以被自动化触发,让 Ontology 编辑自动落地,或先暂存等人工审核 —— 触发源可以是已有对象,也可以是新建对象。
## 先记住这几条
① 可被自动化触发 不用人工点,按条件自动跑。
② 两种落地方式 直接应用,或暂存待审。
③ 触发源有两类 已有对象变化,或新对象创建。
## 写在前面
AIP Logic 现在可以被自动化,使得 Ontology 编辑可以被自动应用,或被暂存以供人工审核。这些自动化可以在现有对象上触发,也可以在创建新对象时触发。
AIP Logic 函数如何从 Automate 调用,取决于是否启用了暂存写入执行模式:
- 启用暂存写入: 该函数必须用 action type 包装,并通过 action effect 调用。AIP Logic 提供了一个 Create action 按钮来生成该 action type。更多信息请参见 AIP Logic 中的暂存写入。
- 禁用暂存写入: 该函数可以通过 Logic effect 直接调用,如使用 Logic effect 创建自动化中所述。
## 为暂存写入的 Logic 函数创建自动化
> 要点:写操作先暂存、待审后流转。
要从 Automate 调用暂存写入的 Logic 函数,你必须先创建一个由该函数支撑的 action type,然后在自动化中使用 action effect。
- 在你的 AIP Logic 文件中,导航到 Usage 标签页并选择 Create action,以生成一个由你的 Logic 函数支撑的 action type。
- 在 Automate 中使用 action effect 创建自动化,由它提交该 action。
由 Logic 函数生成的 action 支持与旧版自动化相同的审核工作流。你可以将自动化配置为把 action 暂存为供人工审核的提案,而不是自动应用它们。
关于创建和管理该 action type 的更多细节,请参见 AIP Logic 中的暂存写入。
## 使用 Logic effect 创建自动化
> 要点:另一种触发配置方式。
本节的工作流适用于那些输出为 Ontology 编辑列表的 Logic 函数,这是禁用暂存写入时的旧版行为。这些函数通过 Logic effect 直接调用。
你可以从你的 AIP Logic 文件出发,使用右侧的 Uses 选项开始创建新的自动化。

> 图:用于创建新自动化的 Uses 面板。
这样做会弹出一个新窗口,其中根据你的 Logic 指令预先填充好了自动化流程。

> 图:自动化配置界面
你设置的条件将监控一个对象集,并对每个新添加的对象触发 Logic effect,或自动运行编辑。了解如何设置自动化。
在确认新自动化的名称和设置后,选择 Save automation。
保存后你将被重定向到 Automation Overview 界面。

> 图:自动化概览页面,展示了可用于审核 agent 提案的选项。
Overview 界面会显示自动化流程、状态和事件图表,这些内容会在自动化被触发时自动更新。
如果你将自动化配置为把 Action 暂存以供审批,而不是自动运行编辑,你可以使用左侧导航栏导航到 Proposals 标签页,查看已生成且需要审核的 Agent 提案概览。
要审核这些 agent 提案,请执行以下任一操作:
- 从导航栏进入 Proposals 标签页。
- 在 Agent proposals 部分中选择 View。
在 Proposals 标签页中,选择某个具体提案,即可查看其被创建的原因。

> 图:Proposals 页面。
此外,拟议的 Action 会在屏幕底部预览。通过在 View proposal details 下选择 Agent decision log 标签页,你可以查看 LLM 为生成该拟议 Action 所遵循的决策过程。
当你接受某个提案时,该 Action 将被自动执行,该提案卡片会被移动到 Applied 列。
## 常见问题
> 要点:自动化相关的疑问。
以下是关于 AIP Logic 集成的一些常见问题。
### Why can I not see any proposals?
出于安全考虑,未处理的提案仅可见 24 小时,且仅对创建该自动化的用户可见。更早的提案将不可见。
### Why is the Create Automation button unavailable?
AIP Logic 的输出必须返回一个 Ontology 编辑,Automation 才能运行。
### What happens when staged writes are enabled on a Logic function used in an existing automation?
现有自动化会继续针对该函数先前发布的旧版版本运行。如果该函数的输出类型是一个 Ontology 编辑列表,启用或禁用暂存写入会发布一个新的主版本,因为根据 Logic 配置的不同,输出类型会变为另一种类型。自动化不会跨主版本自动升级。
要将该自动化迁移到暂存写入版本:
- 在你的 AIP Logic 文件中选择 Create action,以生成一个 action type。
- 在自动化中,将 Logic effect 替换为一个提交所生成 action 的 action effect。
- 保存该自动化。
更多细节请参见迁移现有自动化。
### Why is there no condition block in the Automation summary page?
请确保 AIP Logic 的输入是一个对象。
### 常见问题速答 · FAQ
关于「用 Automate 自动化 AIP Logic」,读者最常问的几个问题。
为暂存写入的 Logic 函数创建自动化是什么? 写操作先暂存、待审后流转。要从 Automate 调用暂存写入的 Logic 函数,你必须先创建一个由该函数支撑的 action type,然后在自动化中使用 action effect。
还有哪些问题? 自动化相关的疑问。以下是关于 AIP Logic 集成的一些常见问题。
---
## AIP Logic 的 block 全清单
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-blocks.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/blocks/
- 主题分组:AIP Logic(四)
循序渐进 · AIP 教学 · AIP Logic(四)
# AIP Logic 的 block 全清单
Block 是 AIP Logic 的积木,每块都有特定用途:读写 Ontology、做计算、聚合数据、调用函数、与 LLM 交互。这篇是积木图鉴。
## 先记住这几条
① Block 是函数的最小单元 输入 → 输出,可串联。
② 用途分几大类 读数据、写数据、计算、调函数、调 LLM。
③ Use LLM 是心脏 最重要的 block,由 prompt + tool + output 构成。
④ 输出可复用 前一个 block 的输出能喂给后面的。
## 写在前面
AIP Logic 函数由 block 组成。Block 接收输入、返回输出,并构成一次与你的数据的独立交互。Block 有许多不同的用途,例如读写 Ontology、执行计算、聚合数据、调用其他函数,或与 LLM 交互。一个 block 的输出可以在后续 block 中使用,从而通过将 block 串联起来构建复杂的操作。
Block 有许多不同的类型;下面介绍了一些常用的 block:
- Use LLM
- Apply action
- Execute function
- Loops
- Conditionals
- Create variable
## Use LLM(调用大模型)
> 要点:最核心的 block:由 prompt + tool + output 三部分构成。
Use LLM block 是 AIP Logic 的核心,它让你能够利用 LLM 来定义一个 Logic block。Logic block 由 prompt、工具(tools)和一个输出组成。Use LLM block 支持平台中任何可用的 LLM,这与 Palantir 的 k-LLM 理念一致。

> 图:LLM Block。
若要一次性替换多个 Logic 函数中所使用的模型,你可以在 Workflow Lineage 中批量替换模型。
### Prompts
Prompt 是用自然语言写给 LLM 的指令。我们建议从最重要的信息开始(例如对 LLM 应完成任务的概述),随后是 LLM 需要的数据,以及关于何时使用工具的指引。编写 prompt 时请记住,LLM 只能访问你明确提供的内容。
在下面这个示意性 prompt 中,我们使用 LLM 从以往的邮件往来中搜索信息,以便为寻求解决方案的客户提供回复。该示意性 prompt 以任务概述开头:
You are my complaint helper agent. Find other emails that describe similar events to those described in the input email. Look only at the email body. Determine the best solution based on what has worked in the past. Return your one solution recommendation, do not list findings from every email.
随后,prompt 指定了要查询的数据(在此例中为投诉邮件,以 complaint 对象表示)。输入 prompt 后,你可以在 prompt 字段中输入 /,并选择在该 Logic 函数中该位置可用的一个或多个变量(例如输入和 block 输出),从而让 LLM 访问你的输入。选择一个对象或对象集会打开一个子菜单,你可以在其中选择要插入的该对象的哪些属性;在下方的截图中,我们选择了 email 对象的属性。

> 图:示意性 prompt,共享了任务概述「You are my complaints helper agent. Find other emails that describe similar events to those described in the input email. Look only at the email body. Determine the best solution based on what has worked in the past. Return your one solution recommendation, do not list findings from every email.」
### Tools
工具是 AIP Logic 让 LLM 得以读写 Ontology 并支撑现实世界操作的机制。AIP Logic 利用三类由 Ontology 驱动的工具——数据、逻辑和 action——来有效地查询数据、执行逻辑操作并安全地采取行动。LLM 并不能直接访问工具;LLM 只能请求使用工具,随后这些工具调用会由 AIP Logic 在调用用户的权限范围内执行。
仅在读取时强制执行 行级和列级访问控制(包括受限视图、对象安全策略和属性安全策略)会在 Query objects 将数据读入 prompt 时,过滤用户所能读取的内容。这些控制不会延伸到模型的输出,也不会延伸到 Apply actions 编写的任何 Ontology 编辑。为了让数据在向下游流转时持续受到保护,请将这些控制与标记(marking)或基于分类的访问控制搭配使用。完整的模型说明参见访问控制传播。
Tool calling modes
AIP Logic 支持提示式(prompted)工具调用和原生(native)工具调用。原生工具调用利用底层 LLM 内置的能力来提升性能和 token 效率。提示式工具调用则使用 prompt 指示 LLM 如何使用工具。
当一个 Use LLM board 中的所有模型都支持原生工具调用时,AIP Logic 会自动从提示式升级为原生,并在 Debugger 中显示一条提示信息。如果任一模型缺少原生支持,AIP Logic 会继续使用提示式工具调用。

> 图:可供选择的 AIP Logic 工具:Apply actions、Call function、Query objects、Calculator tool。
可用的工具包括:
- Apply actions
- Call function
- Query objects
- Calculator tool
Apply actions
Apply actions 工具让 LLM 能够使用 Action 来编辑 Ontology。你可以描述 LLM 应在何时使用所提供的 Action。关于如何将更改应用到 Ontology 的更多细节,请查阅使用 Logic 函数进行 Ontology 编辑。

Call function
Call function 工具让你可以选择 LLM 可以调用的函数。函数可以是在代码仓库中定义的代码,也可以是现有的 Logic 函数。

> 图:Call function 工具,已从函数下拉菜单中选定「extractAnswer」函数。
Query objects
Query objects 工具指定 LLM 可以访问的对象类型。你可以按需添加任意数量的对象类型,并指定 LLM 可以访问哪些属性,以使查询更节省 token。

Calculator tool
Calculator tool 让你能够借助 LLM 执行精确的数学计算。
## Apply action(执行动作)
> 要点:让 LLM 触发 Ontology 写操作。
Apply action block 让你能够确定性地调用 action,而无需经过 LLM block。这个 block 让你可以精确控制参数如何填写,并加快执行速度。在此示例中,我们可以调用一个为某个给定事件赋予优先状态(priority status)的 action。
要编辑被写回 Ontology,必须从某个 action 中调用 AIP Logic 函数。除非该 Logic 函数是从 action 中执行的,否则 Ontology 不会被编辑,即使该函数包含 Apply action block 也是如此。

> 图:「Apply action」block。
## Execute function(调用函数)
> 要点:把已有函数当作工具给 LLM 用。
Execute function block 让你可以调用 Foundry 内其他现有的函数,例如 TypeScript、Python,甚至其他 Logic 函数。Execute block 让你能够复用那些已经实现你预期任务的现有函数,而不必自己重新实现该逻辑。在下面的示例中,Execute block 用于借助某个语义搜索函数的输出,帮助返回相似事件的解决文本。

> 图:Execute block1/2。

> 图:Execute block2/2。
## Conditionals(条件分支)
> 要点:按条件走不同路径。
条件(Conditionals)是评估某个条件、并根据该条件为真或为假来执行不同路径的 block。可以把条件看作传统编程中的「if-then-else」语句:
- 如果(If) 某个条件为真,那么(then) 执行一组操作
- 否则(Else) 执行另一组操作

> 图:AIP Logic 界面中的条件 block
当你需要根据特定条件以不同方式处理数据,或运行不同的 action 时,条件就很有用。
Branch return values
在「then」或「else」部分中,你可以定义该条件分支应返回什么值。共有 3 个选项:
- Define a Path: 创建一串要执行的 block。
- Return a Variable: 返回现有变量或先前的 block 输出。
- Take No Action: 将分支配置为不采取任何操作(当另一个分支会返回 ontology 编辑时可用)。
注意:你可以在一个条件 block 中配置多个分支,每个分支都有自己的「when」条件和「then」操作。
使用条件分支时,所有分支必须返回一致的输出。例如,如果某个分支输出字符串,那么所有其他分支(包括 else 分支)也必须输出字符串。如果分支通过 action 返回 ontology 编辑,那么所有分支都必须运行一个 action,或明确指定「take no action」。
## Loops(循环)
> 要点:对集合逐个处理。
循环(Loops)让 AIP Logic 能够遍历一个集合,并对每个元素运行一次转换和/或一个 action。循环对于在一组元素上执行操作,或对多个对象进行 ontology 编辑非常有用。
循环的输出可以是一个值列表,也可以是 ontology 编辑。

> 图:循环 block
在循环内部,你可以通过 element 变量访问当前元素,并通过 index 变量访问当前元素的索引(如有需要,这些变量可以重命名)。
循环只对 List 操作,不对 Array 操作。选择 array 作为循环的输入时,会自动在循环之前插入一个「Array to List」block,在将输入传入循环之前把它转换为 list。

> 图:循环转换
注意:如果你的循环不包含任何 action,则每次迭代都会并行执行。
## Create variable(创建变量)
> 要点:在 block 之间传递中间结果。
Create variable block 会创建一个可在后续 block 中使用的变量。该变量可以是以下类型:array、boolean、date、double、float、integer、long、object、short、string 或 timestamp。

> 图:Create variable 区域 block。
### 常见问题速答 · FAQ
关于「AIP Logic 的 block 全清单」,读者最常问的几个问题。
Use LLM(调用大模型)是什么? 最核心的 block:由 prompt + tool + output 三部分构成。
Apply action(执行动作)是什么? 让 LLM 触发 Ontology 写操作。Apply action block 让你能够确定性地调用 action,而无需经过 LLM block。这个 block 让你可以精确控制参数如何填写,并加快执行速度。
Conditionals(条件分支)是什么? 按条件走不同路径。条件(Conditionals)是评估某个条件、并根据该条件为真或为假来执行不同路径的 block。可以把条件看作传统编程中的「if-then-else」语句。
Loops(循环)是什么? 对集合逐个处理。循环(Loops)让 AIP Logic 能够遍历一个集合,并对每个元素运行一次转换和/或一个 action。循环对于在一组元素上执行操作,或对多个对象进行 ontology 编辑非常有用。
---
## 在分支上开发 AIP Logic
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-branching-logic.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/branching-logic/
- 主题分组:AIP Logic(六)
循序渐进 · AIP 教学 · AIP Logic(六)
# 在分支上开发 AIP Logic
AIP Logic 与 Global Branching 集成,让你在隔离的分支上安全地改 Logic 函数,改完再合并。
## 先记住这几条
① 分支提供隔离 改动不影响主线的生产和他人工作。
② 支持增改资源 在分支上新建或修改 Logic 资源。
③ 要处理 rebase 与审批 合并前的同步与评审流程。
④ 跨应用兼容性有边界 不是所有应用都完全支持分支。
## 写在前面
AIP Logic 与 Global Branching 集成,以便安全、隔离地开发 Logic 函数。本文档介绍如何在分支上使用 Logic,包括添加和修改资源、跨应用兼容性、rebase 以及审批流程。
关于 Global Branching 概念和工作流的通用信息,请参阅 Global Branching 文档。
## 增删改资源
> 要点:分支上能做什么操作。
### Add Logic functions to a branch
要将一个 Logic 函数添加到分支:
- 导航到分支上的该 Logic 文件,或使用页面右上角的分支选择器选择指定的分支。
- 对 Logic 文件做一次编辑并保存。该 Logic 函数此时已成为分支上已保存的资源。
### Remove Logic functions
要从分支上移除一个 Logic 函数,请使用右下方的侧边栏并选择 Remove from branch。

> 图:Remove from branch 按钮
### Modify Logic functions
要修改分支上的 Logic 函数,做任意更改并保存即可,就像你在 main 分支上所做的一样。
### Publish on a branch
你可以按照与 main 上相同的流程,在分支上发布一个 Logic 函数。在分支上成功发布该函数后,你就可以在 Workshop 和由函数支撑的 action 中使用你分支上的新函数版本。该函数版本会被标记为 Branched pre-release 标签。在你分支上发布的函数将无法从其他分支(包括 main)访问。
## 跨应用兼容性
> 要点:哪些应用支持分支开发。
### Using branched Logic functions
分支上的 Logic 函数可用于:
- Ontology 对象: 函数可以与同一分支上的 ontology 对象交互。
- 其他支持分支的应用: 任何使用 Logic 函数并支持分支的 Foundry 应用(例如 Workshop)。
## 合并要求
> 要点:合并回主线前要满足什么。
### Deployability checks
在 Logic 函数可以被部署之前,它必须:
- 与 main 保持最新(无需 rebase)
- 已在分支上发布
- 处于可发布状态(无错误)
- 没有待处理的审批
### Approvals and reviewer flow
Protected main branch
你可以保护你的 main 分支,以禁止对 main 上的 Logic 函数进行直接编辑。启用保护后,所有更改都必须在分支上进行、经过审核,并通过提案流程合并。
要保护某个分支,请在 Compass 中导航到该资源并选择 Branch protection > Protect with project policy。

> 图:Branch protection 标签页,展示了 protect with policy 选项。
如果要默认保护某个项目中的所有 Logic 文件,请在项目级别启用保护。在该项目中创建的任何新 Logic 文件都会自动受到保护。
Reviewer experience
创建提案后,审核者可以被添加到 Global Branching 应用中的该 Logic 文件。被添加为审核者的用户会收到一封请求其审核的电子邮件,其中包含指向该提案的链接。
在那里,审核者可以:
- 通过选择文件右上角的 Review 选项进入审核页面。当某个 Logic 函数需要审核时,该选项可见。
- 查看 main 与分支更改的并排对比。
- 查看对 Logic 函数的所有修改。
- 批准或拒绝这些更改。
- 编辑他们的审核。
## Rebase 与冲突解决
> 要点:与主线同步的做法。
当 main 分支自你的分支创建以来或自上次 rebase 以来被修改过时,就需要进行 rebase。如果你的 Logic 函数需要进行 rebase,你会在 Logic 文件顶部看到一条通知。

> 图:Rebase 通知
### How to rebase
- 导航到需要 rebase 的 Logic 函数,并选择 Rebase 选项。
- 查看更改,在分屏对比视图中查看。左侧显示当前的 main 版本,右侧显示你的分支版本。
- 对你的分支做必要的更改,如果存在合并冲突,可能需要纳入来自 main 的更改。
- 通过选择 Finish 完成 rebase。
## 已知限制
> 要点:当前做不到的事。
- 分支只能从 main 创建。你不能从其他分支创建分支。
- 分支上不能更改 API 名称。所有分支上的 Logic 函数共享同一个 API 名称。
- 在分支上时,已发布的 Logic 函数不能被删除。
- 合并冲突的解决需要人工干预。当 rebase 期间发生冲突时,你必须使用分屏对比视图,手动将来自 main 的更改纳入你的分支版本,并在完成 rebase 之前解决所有冲突性修改。
### 常见问题速答 · FAQ
关于「在分支上开发 AIP Logic」,读者最常问的几个问题。
增删改资源是什么? 分支上能做什么操作。要将一个 Logic 函数添加到分支。
跨应用兼容性是什么? 哪些应用支持分支开发。分支上的 Logic 函数可用于。
合并要求是什么? 合并回主线前要满足什么。在 Logic 函数可以被部署之前,它必须。
Rebase 与冲突解决是什么? 与主线同步的做法。当 main 分支自你的分支创建以来或自上次 rebase 以来被修改过时,就需要进行 rebase。如果你的 Logic 函数需要进行 rebase,你会在 Logic 文件顶部看到一条通知。
---
## AIP Logic 的计算用量
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-compute-usage.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/compute-usage/
- 主题分组:AIP Logic(九)
循序渐进 · AIP 教学 · AIP Logic(九)
# AIP Logic 的计算用量
Logic 函数跑一次,钱花在哪?这一篇把用量拆开算给你看,帮你预测成本、优化设计。
## 先记住这几条
① 用量主要来自 LLM 调用 block 越多、上下文越长,花费越高。
② 上下文是成本大头 喂给模型的每一段文本都要算钱。
③ 设计方式影响成本 合并调用、精简上下文能显著省。
## 写在前面
AIP Logic 是 Palantir 的一款工具,让你能够快速且可维护地构建由 LLM 驱动的流程,同时通过 Ontology 和计算能力与你的组织数据交互。AIP Logic 围绕 LLM 指令「block」的概念构建,这些 block 可以线性组合,形成思维链(chain-of-thought)工作流,从而查询数据、执行 action 和函数,并为你的用例生成全新的信息。在 AIP Logic 中,「block」是使用量度量的原子单位,不过每个 block 都可能触发 Foundry 内的其他系统,这些系统也可能消耗 compute-second 来向 AIP Logic block 返回信息。
> 如果你与 Palantir 签有企业合同,请在进行计算使用量估算之前联系你的 Palantir 代表。
## 核心概念:资源、block 与工具
> 要点:用量计量的基本单位。
一个 AIP Logic 资源(resource) 由一个或多个 AIP Logic block 组成。运行一个资源将运行实现期望输出所需的各个 block。Block 可以使用工具(tools)(例如 Ontology 查询、函数和 action)来产生输出。
## 用 AIP Logic 计量 Foundry 计算量
> 要点:哪些环节消耗计算资源。
### AIP LLM tokens
AIP 中的 LLM token 按照底层模型的方式计量(例如 OpenAI ↗),并取决于 prompt 和响应的大小,以及发出的 prompt 数量。更多信息请查阅各模型类型的使用量表。
### LLM block execution
当一个 AIP Logic block 执行或选择使用某个工具时,会有最低的 compute-second 使用量。
- 基础 LLM block 执行:4 compute-seconds
- LLM block 工具执行:8 compute-seconds
### Additional Foundry compute usage
当一个 AIP Logic block 将计算联邦到外部工具(例如 Ontology 查询或函数)时,这些应用的执行过程中可能会使用额外的计算资源。
## 管理 AIP Logic 的 Foundry 计算用量
> 要点:怎么把成本压下来。
AIP Logic 中的某些操作会显著影响计算使用量。下面我们提供指引,说明如何通过留意 token 使用量、logic block 执行总次数以及 Foundry 计算资源的使用来控制计算使用量。
### Token usage
- 处理大量文本会显著增加整体计算使用量。要注意与 LLM 一起使用的输入 prompt 的大小。当从 Ontology 中拉取大段文本时,这一点尤其重要。
- 为控制 token 使用量,你应当努力削减注入 prompt 的文本量,并确保 prompt 本身只包含相关文本。在处理大型文档时,这一点尤为重要。
### Total number of logic block executions
- 运行大量 logic block 会消耗大量计算资源,尤其是当这些 block 通过函数以编程方式触发时(即不是由人工操作触发的)。
- 为控制 logic block 的执行次数,可考虑(在适当情况下)将多个 block 合并为单个 prompt,并且仅在必要时才使用额外的 block。Action、function 和 data transformation block 本身不会产生计算使用量。
### Foundry compute
- 大量调用 Foundry 应用(例如 Ontology 查询、函数或 action)会消耗大量计算资源。当某个 logic 资源需要多次重试,或在每次执行时调用许多函数或 action 时,就可能出现这种情况。
- 为控制来自其他应用的计算使用量,请确保你了解你的 logic block 链中对外部工具的调用次数。可能调用 Foundry 其他部分的潜在工具包括:
- Ontology Query
- Action Execution
- Function Execution
- Data Transformation
## 计算用量示例
> 要点:用一个例子算给你看。
假设某个用户有一个包含两个 LLM block 的 AIP Logic 资源。其中一个 LLM block 配置了一个 action,并会在执行时调用它。该 logic 资源端到端运行两次。
Code Number of LLM blocks: 2
Number of LLM blocks that call actions: 1
Number of runs: 2
1 run compute-seconds = 2 LLM blocks * 4 compute-seconds + 1 action block * 8 compute-seconds
1 run compute-seconds = (2 * 4) + (1 * 8)
1 run compute-seconds = 16 compute-seconds
2 runs = 2 * 16 compute-seconds = 32 compute-seconds
Total = 32 compute-seconds
### 常见问题速答 · FAQ
关于「AIP Logic 的计算用量」,读者最常问的几个问题。
核心概念:资源、block 与工具是什么? 用量计量的基本单位。一个 AIP Logic 资源(resource)由一个或多个 AIP Logic block 组成。运行一个资源将运行实现期望输出所需的各个 block。
计算用量示例是什么? 用一个例子算给你看。假设某个用户有一个包含两个 LLM block 的 AIP Logic 资源。其中一个 LLM block 配置了一个 action,并会在执行时调用它。该 logic 资源端到端运行两次。
---
## AIP Logic 核心概念
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-core-concepts.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/core-concepts/
- 主题分组:AIP Logic(二)
循序渐进 · AIP 教学 · AIP Logic(二)
# AIP Logic 核心概念
读懂这一页,后面所有 Logic 文档都会顺畅很多。这里把 block、prompt、tool、output 等关键概念一次讲清。
## 先记住这几条
① Block 是基本单位 接收输入、返回输出,构成一次独立的数据交互。
② Prompt 是指令 用自然语言告诉 LLM 要做什么。
③ Tool 是能力外挂 让 LLM 能读数据、算东西、调函数。
④ Output 决定下游 block 的输出可以喂给后续 block。
## 写在前面
以下核心概念对于理解和充分发挥 AIP Logic 的作用至关重要。你可以在快速入门教程中进一步了解如何应用这些概念。
## Logic 函数
> 要点:AIP Logic 产出的基本单位。
Logic 函数接收诸如 Ontology 对象或文本字符串之类的输入,并返回输出,输出可以是某个值(例如字符串)、某个对象,或对 Ontology 本身的编辑。
Logic 函数可以像平台中的任何其他函数一样被利用和使用,例如在 Workshop 模块中。要编辑 Ontology,Logic 函数必须发布,并从某个 action 中调用。更多信息请参见如何在 action 中使用 Logic 函数。
## Block(块)
> 要点:函数由 block 组合而成。
Logic 函数由多个 block 组成。Block 可以读写 Ontology、执行计算、聚合数据、调用函数、对集合进行循环、评估条件,或与 LLM 交互。将 block 串联起来,即可把一个 block 的输出传递给后续 block,从而构建复杂的操作。
## 评测
> 要点:怎么验证函数好坏。
发布 Logic 函数后,你可以配置评估(Evaluations),它让你能为 Logic 函数编写详细的测试。AIP Logic 的评估可用于:
- 调试并改进 Logic 函数和 prompt。
- 在你的函数上比较不同的模型,例如 GPT-4 与 GPT-3.5。
- 考察 Logic 函数在多次运行之间的差异。
- 运行实验以测试函数参数,并找出在性能与成本之间取得最佳平衡的取值。
- 使用 Results 视图内置的结果分析器来诊断失败;该分析器会将失败的测试用例归入根因类别,并给出有针对性的 prompt 修改建议。
要引导生成一个评估套件,请在右侧边栏的 Evals 标签页中选择 Generate evals。AIP Evals 会分析你的 Logic 函数——包括所有被引用的对象类型,而不只是输入和输出类型——并创建可编辑的测试用例和指标供你进一步调整。参见 AIP Evals:快速入门。
评估还支持可选的评估器指标类型。如果某个可选指标不适用于某个测试用例,结果会显示为 No value,且 AIP Evals 会将其排除在聚合指标分数之外。
## 调试
> 要点:看思维链、定位问题。
编写完 Logic 函数后,你可以将该函数作为测试来运行。运行函数会打开 Debugger 面板,显示 Logic 函数中各组成 block 的 LLM 思维链(chain-of-thought,CoT)。查看 LLM 的 CoT 会展示 LLM「思考过程」的每一步,并提供 LLM 所用的任何辅助工具的信息,从而使调试更加容易。
## 执行模式
> 要点:以谁的身份、按谁的权限执行。
你可以将 Logic 函数配置为以两种执行模式之一运行:用户作用域(user-scoped)或项目作用域(project-scoped)。用户作用域执行会使用运行该函数的用户的权限来运行函数,而项目作用域执行则使用包含该函数的项目的权限。执行模式还会影响谁可以查看执行日志。更多信息请参见执行模式设置。
### 常见问题速答 · FAQ
关于「AIP Logic 核心概念」,读者最常问的几个问题。
Logic 函数是什么? AIP Logic 产出的基本单位。Logic 函数接收诸如 Ontology 对象或文本字符串之类的输入,并返回输出,输出可以是某个值(例如字符串)、某个对象,或对 Ontology 本身的编辑。
Block(块)是什么? 函数由 block 组合而成。Logic 函数由多个 block 组成。Block 可以读写 Ontology、执行计算、聚合数据、调用函数、对集合进行循环、评估条件,或与 LLM 交互。
评测是什么? 怎么验证函数好坏。发布 Logic 函数后,你可以配置评估(Evaluations),它让你能为 Logic 函数编写详细的测试。AIP Logic 的评估可用于。
调试是什么? 看思维链、定位问题。编写完 Logic 函数后,你可以将该函数作为测试来运行。运行函数会打开 Debugger 面板,显示 Logic 函数中各组成 block 的 LLM 思维链(chain-of-thought,CoT)。
---
## 执行模式设置:用户作用域 vs 项目作用域
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-execution-mode-settings.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/execution-mode-settings/
- 主题分组:AIP Logic(七)
循序渐进 · AIP 教学 · AIP Logic(七)
# 执行模式设置:用户作用域 vs 项目作用域
Logic 函数有两种执行模式,决定了"以谁的身份运行、数据权限从哪来" —— 这是个容易踩坑但很关键的选择。
## 先记住这几条
① 两种模式 用户作用域(user-scoped)与项目作用域(project-scoped)。
② 默认是用户作用域 按发起者的权限执行。
③ 选择影响权限结果 选错了要么用不了数据,要么越权。
## 写在前面
你可以为 Logic 函数在两种执行模式之间进行选择:用户作用域(user-scoped)执行和项目作用域(project-scoped)执行。用户作用域执行是默认模式。
## 用户作用域执行
> 要点:按发起者的权限运行 —— 默认模式。
配置为用户作用域模式时,该 Logic 函数将使用运行该 Logic 函数的用户的权限来运行。
在用户作用域模式下,每个用户只能看到自己的执行日志,而看不到运行该 Logic 函数的其他用户的日志。执行日志会保留 24 小时。
## 项目作用域执行
> 要点:按项目的权限运行,适合后台任务。
配置为项目作用域模式时,该 Logic 函数将使用包含该 Logic 函数的项目的权限来运行。在项目作用域模式下,执行日志对拥有项目访问权限的所有人可见。
项目作用域执行要求该 Logic 函数所使用的所有资源也必须导入到与 Logic 函数相同的项目中。用户还需额外拥有对这些资源上标记(markings)的访问权限。
你可以在执行模式设置中检查所有必需的资源是否都已导入;如果缺少某个资源,你可以直接从配置中导入它。

> 图:执行数据集
### Run history dataset
使用项目作用域执行时,你可以配置一个数据集,在其中记录所有运行历史。每次执行都会作为新的一行记录到该数据集中,并保留最近 10000 次运行。
### 常见问题速答 · FAQ
关于「执行模式设置:用户作用域 vs 项目作用域」,读者最常问的几个问题。
用户作用域执行是什么? 按发起者的权限运行 —— 默认模式。配置为用户作用域模式时,该 Logic 函数将使用运行该 Logic 函数的用户的权限来运行。
项目作用域执行是什么? 按项目的权限运行,适合后台任务。配置为项目作用域模式时,该 Logic 函数将使用包含该 Logic 函数的项目的权限来运行。在项目作用域模式下,执行日志对拥有项目访问权限的所有人可见。
---
## AIP Logic 常见问题
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-faq.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/faq/
- 主题分组:AIP Logic(十一)
循序渐进 · AIP 教学 · AIP Logic(十一)
# AIP Logic 常见问题
按问题组织的一页,适合当速查手册用。遇到具体疑问时先来这里翻一翻。
## 先记住这几条
① 按问题组织 每个 H2 就是一个常见疑问。
② 适合速查 不必顺读,直接搜关键词。
③ 覆盖边界情况 很多坑官方都在这里提前说明。
## 写在前面
本页详细介绍了关于 AIP Logic 应用的一些常见问题。
- How can I use AIP Logic with the rest of the platform?
- How do I reduce my token count?
- When should I keep my Logic function in one block versus splitting into multiple blocks?
- How do I improve the performance of an AIP Logic block?
- Is there a way to modify the temperature of the LLM or other model parameters?
- Is it possible to support semantic search workflows using Logic?
- How can an LLM “learn” from feedback?
- How can I ensure the output of my Logic is correct?
- How can you create test cases from previous executions?
## 如何让 AIP Logic 与平台其他部分协作?
> 要点:集成方式。
请查阅关于如何使用 Logic 函数的文档。
## 如何减少 token 消耗?
> 要点:省钱的实操问题。
AIP Logic 中的所有活动都会计入 token 限额,包括工具响应。Token 限额按 block 重置。你可以在 Debugger 中每条消息的末尾看到所使用的 token 数量。如果进度条显示为红色,请考虑减少你的 token 数量以确保性能可靠。
我们建议采取以下步骤来减少 token 数量:
- 从输入对象中选择所需的特定属性,或指定你想查询哪些对象属性,以缩减 LLM 发送和接收的字符串大小(OBJECT_NAME property1 property2 等);你可以在 Debugger 中选择 Show raw 来查看它。
- 使用 Query objects 工具时,选择要发送给 LLM 的属性子集。
- 考虑将单个 block 拆分为多个 Use LLM block;每个 block 都有 token 限额,因此你可以尝试将一个 block 拆分为多个中间步骤。
- 将你的 LLM 模型改为 32k。
- 尽可能使用确定性 block,例如 transform block、execute block 和 apply action block。这些 block 有助于产生更可预测的结果,并且不消耗任何 token,从而使你的 logic 更高效、更易管理。
## 什么时候该用单个 block,什么时候该拆成多个?
> 要点:设计粒度问题。
单个大 block 让你可以在试验 LLM 能力时快速迭代并轻松做出较大改动,但在以下情况下,你可能希望将你的 Logic 拆分为多个 block:
- 你希望 LLM 执行多个步骤,但得到的结果不一致。
- 该 block 正接近其上下文限制。
- 每次运行执行耗时过长。
由于每个 block 都有自己的上下文窗口,拆分为多个 block 可以带来以下优势:
- LLM 只能访问你传入的内容;单个大 block 中的中间结果可能是不相关的。
- 你不太可能耗尽 token。
- 若干较小的任务可能比一个长任务执行得更快。
## 如何提升 AIP Logic block 的性能?
> 要点:优化手段。
要改进 AIP Logic block 的性能,请尝试以下建议:
- 选择 5-10 个输入/输出对示例,并在每次修改 prompt 时运行它们。将它们保存为 AIP Logic 中的单元测试。
- 向 LLM 提供 few-shot 示例;通过让模型更容易理解任务,这可以显著提升 LLM 性能。你可以输入一个供 LLM 参考的 system prompt。
- 如果你看到意外的失败,请通过让 LLM 解释其计划和对问题的理解,来验证模型对你的数据有正确的「理解」——这可以让你了解缺失了哪些上下文。
- 考虑构建一个带有动态 few-shot 示例的反馈闭环。
- 使用确定性 transform board,例如 transform block、execute block 和 apply action block。
- 使用 AIP Evals 来运行评估。Results 视图中的结果分析器会将失败案例聚类为根因类别,并在你迭代 prompt 时提出有针对性的 prompt 修改建议。
## 能修改 LLM 的 temperature 或其他模型参数吗?
> 要点:模型参数的可控范围。
你可以通过编辑 Use LLM block 的 Configuration 文本字段中的 temperature,来修改 LLM 的 temperature,该参数表示 LLM 响应的随机性。默认 temperature 为 0。较低的 temperature 会返回更具确定性的输出。
示例代码:
json {
"temperature": 0.9
}
## Logic 能支持语义搜索工作流吗?
> 要点:相关能力说明。
可以,你目前可以添加一个工具,让 Logic 能够对 Ontology 执行语义搜索,这可以通过一个 action 或编写一个对象函数(function-on-object),然后再从 AIP Logic 调用它来实现。请查阅语义搜索工作流教程以了解更多。
## LLM 如何从反馈中"学习"?
> 要点:反馈闭环的做法。
如果它适合你的工作流,你可以用这种设计模式帮助 LLM 从反馈中「学习」:
- 每当 LLM 给出建议时,捕获 (1) 该建议以及 (2) 其推理。然后,在将该 Logic 函数连接到 Workshop 并构建人工审核流程时,写回 (3) 人工反馈以及 (4) 经人工验证的正确决策。为了方便举例,我们假设将这个写回对象称为「Suggestion」对象。
- 在你的 Logic 函数中,让 LLM 能够对「Suggestion」对象使用 Query objects 工具,搜索 LLM 曾给出相同建议的其他实例。让 LLM 处理人工反馈,然后就 LLM 的建议是否应当继续推进向 LLM 发起查询。
## 如何确保 Logic 的输出正确?
> 要点:验证思路。
添加单元测试,以检查该函数在给定输入上是否能成功运行。你还可以使用 AIP Evals 为你的 Logic 函数创建评估套件。要生成套件,请打开右侧边栏中的 Evals 标签页并选择 Generate evals。AIP Evals 会根据你的函数为套件引导生成测试用例、评估器和指标。在运行评估之前,请检查并完善所生成的测试用例和评估器。Results 视图包含一个内置的结果分析器,它会将失败案例聚类为根因类别、呈现具有代表性的示例,并提出有针对性的 prompt 修改建议以提高准确率。更多信息请参见 AIP Evals:快速入门。
## 如何从历史执行中创建测试用例?
> 要点:评测素材的来源。
在 Run history 中,使用 Add as test case 将历史执行结果转换为新评估套件或现有评估套件的测试用例。这有助于你从函数执行中构建全面的测试套件。
## 能看到 Logic 的历史版本吗?
> 要点:版本管理。
可以,你可以使用版本历史侧边栏查看并回滚到先前保存的版本。
从列表中选择一个较早的版本,即可与当前状态进行比较。

> 图:AIP Logic 历史版本面板和预览。
## 一个 LLM block 能返回多个值吗?
> 要点:输出结构设计。
可以。通过使用「Struct」输出类型,你可以返回多个具名值。

> 图:显示所请求的变量名和值的输出。
## 能配置工具一次性给 LLM block 多少个对象吗?
> 要点:上下文规模控制。
可以,当你在 LLM block 中为 Function 工具添加 Object Query 工具时,你可以选择 Configure object return limits 来选择你希望从任何工具使用中返回的对象数量。

> 图:Configure object return limits 选项。
## 为什么在调试器里成功,到 Workshop 或 API 就失败?
> 要点:经典权限/环境差异问题。
在 Debugger 中测试和开发你的 AIP Logic 函数时,该函数不受五分钟执行时间限制的约束。然而,当该函数从 Workshop 环境调用或通过函数执行 API 调用时,五分钟执行时间限制就会被强制执行。
### 常见问题速答 · FAQ
关于「AIP Logic 常见问题」,读者最常问的几个问题。
如何减少 token 消耗? 省钱的实操问题。AIP Logic 中的所有活动都会计入 token 限额,包括工具响应。Token 限额按 block 重置。你可以在 Debugger 中每条消息的末尾看到所使用的 token 数量。
Logic 能支持语义搜索工作流吗? 相关能力说明。可以,你目前可以添加一个工具,让 Logic 能够对 Ontology 执行语义搜索,这可以通过一个 action 或编写一个对象函数(function-on-object),然后再从 AIP Logic 调用它来实现。
LLM 如何从反馈中"学习"? 反馈闭环的做法。如果它适合你的工作流,你可以用这种设计模式帮助 LLM 从反馈中「学习」。
如何确保 Logic 的输出正确? 验证思路。添加单元测试,以检查该函数在给定输入上是否能成功运行。你还可以使用 AIP Evals 为你的 Logic 函数创建评估套件。要生成套件,请打开右侧边栏中的 Evals 标签页并选择 Generate evals。
---
## AIP Logic 快速入门
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-getting-started.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/getting-started/
- 主题分组:AIP Logic(三)
循序渐进 · AIP 教学 · AIP Logic(三)
# AIP Logic 快速入门
这一篇带你实际走一遍:进入 AIP Logic、认识界面、组合 LLM block、在调试器里看 LLM 的思维链(chain of thought)。
## 先记住这几条
① 从界面开始 先认识各区域分别做什么。
② 组合 block 成函数 输入 → LLM 处理 → 输出。
③ 调试器能看思维链 这比只看结果有用得多。
④ 逐步测试再发布 不要一步到位。
## 写在前面
本指南演示如何访问 AIP Logic,介绍 AIP Logic 界面,并说明如何通过组合 LLM block 并在 Debugger 中查看 LLM 的思维链(chain of thought,CoT)来搭建一个基本的 Logic 函数。
## 进入 AIP Logic
> 要点:从哪里打开这个应用。
可以从平台的工作区导航栏访问 AIP Logic,也可以使用快速搜索快捷键 CMD + J(macOS)或 CTRL + J(Windows)。或者,你可以在 Files 中通过选择 +New 然后选择 AIP Logic 来新建一个 Logic 函数,如下所示。

> 图:Create new AIP Logic 窗口。
打开 AIP Logic 后,你可以创建一个新的 Logic 文件,该文件必须保存在项目文件夹中,而不是你的主文件夹中。
## 应用界面
> 要点:各区域功能说明。
AIP Logic 的界面有三个主要组成部分,在下面的示意截图中按从左到右的顺序编号:
- 输入、block 和输出配置
- Debugger
- 运行面板

> 图:AIP Logic 界面
## 工作流概览
> 要点:一条完整链路的走向。
一个典型的 AIP Logic 工作流从在左侧面板(1)中配置输入(A)、block(B)和输出(C)开始。使用运行面板(3)生成一个示例输出。Logic 运行后,Debugger(2)会显示 LLM 为生成该输出所使用的思维链(CoT)提示和步骤。将 Debugger 与运行面板配合使用即可可视化最终输出。运行面板还会显示最近的 Logic 运行记录,并允许你创建单元测试。右侧边栏提供了与 Automate 和 AIP Evals 的集成。
## 输入、block 与输出的配置
> 要点:函数骨架的搭建方式。
当你初次开始使用 AIP 时,会看到右侧的 Run 面板,以及左侧的三种 board:输入(inputs),用于可选地选择某个对象及其属性;block,用于定义你的 Logic 指令;以及输出(outputs),表示期望的 Logic 函数结果。一个 block 的输出可以馈入后续 block。
下面的截图展示了在 Run 面板折叠状态下的输入、block 和输出配置区域。

> 图:输入、block 和输出配置视图。
## 输入
> 要点:函数接收什么。
AIP Logic 接受多种输入。在 Inputs block 中(在应用界面指南中标记为「A」),你可以指定输入的名称和类型。支持的输入包括 array、boolean、date、double、float、integer、long、media reference、model、object、object list、object set、short、string、struct 和 timestamp。要在 Use LLM block 中引用某个输入,参见 Prompts。
## Block(块)
> 要点:中间处理环节。
一个 AIP Logic 函数由多个 block 组成(在应用界面指南中标记为「B」)。Block 类型包括创建变量(create variable)、应用 action(apply action)、执行函数(execute function)、使用 LLM(use LLM)、循环(loops)和条件(conditionals)。一个 block 的输出可以在后续 block 中使用。更多信息请参见 Blocks。
## 输出
> 要点:函数返回什么。
你可以为每个 Logic block 定义中间输出。Logic 路径中的最后一个 block 就是该 Logic 函数的输出,在应用界面指南中标记为「C」。
- Block 输出: 在 block 之间传递的中间输出。你的 block 的输出可以是基本类型,也可以是供后续 block 使用的对象。
- Logic 函数输出: 你想要返回的 Logic 函数的输出。它可以是某个值(基本类型或对象),也可以是你函数所做的全部 Ontology 编辑。
## 调试器
> 要点:查看思维链、定位问题。
编写完 Logic 函数后,你可以通过选择视图右侧的 Run 来测试该 Logic 函数。Logic 运行后,Debugger 将打开并显示 LLM 的思维链(CoT)。

> 图:带示例的 Debugger 视图。
Debugger 允许你展开和折叠 block 卡片、清空工具调用,并轻松查看生成的 prompt,从而更易于理解思维链。
## 运行面板
> 要点:手动试跑的位置。
在 Run 面板中,你可以运行和评估你的 Logic,并查看最近的运行记录。右侧边栏让你可以设置单元测试、运行自动化,以及查看运行历史。

> 图:运行视图,结果框中为航班示例。
在 Run 面板底部,你还可以选择任一最近的运行记录来查看其输出和调试日志。

> 图:运行和运行历史视图
> 执行日志的可见性取决于该 Logic 函数的执行模式设置。在默认为用户作用域模式下,你只能看到自己的执行日志。在项目作用域模式下,日志对拥有项目访问权限的所有人可见。
选择单元测试图标(
)即可保存一份你的输入的版本,用于性能评估。

> 图:单元测试示例,包含示意性的航班变更。
要编辑测试用例的参数名称、类型和可选性,请选择 Modify columns。在 schema 编辑器中添加参数。
在 Run history 中,选择 Add as test case 即可将历史执行结果转换为新评估套件或现有评估套件的测试用例。
### Evaluate your Logic with AIP Evals
要为你的 Logic 函数生成评估套件,请打开右侧边栏中的 Evals 标签页,并选择 Generate evals。AIP Evals 会根据你的函数创建测试用例、配置评估器并设置指标。你可以编辑生成的测试用例和评估器,以细化覆盖范围和评分。更多信息请参见 AIP Evals:快速入门。
## 使用 Logic 函数
> 要点:写完之后怎么被别处调用。
Logic 函数的使用方式与你在平台中使用常规的对象函数(function on objects,FoO)相同。
- 你可以用 Logic 函数来支撑一个 action,然后从 Workshop 调用该 action。

> 图:Create a new action type 窗口,函数和输入已从下拉菜单中选定。
- 你还可以调用 Logic 函数来支撑 Workshop 中的 Markdown widget;在这种情况下,Logic 函数的输出类型必须是字符串。

> 图:示例展示了 Workshop 应用中的 Markdown widget 设置弹出框。
- 你可以通过 AIP Logic 中的 Ontology function 工具,在其他 Logic 函数中以及对象函数中调用 Logic 函数。
### Running a Logic function via the command line
在 Uses 标签页中,你可以复制一条 curl 请求,以便在终端中于 Foundry 之外运行该 logic。请注意,此功能不适用于会返回 ontology 编辑的 Logic。

> 图:命令行请求
## 用 Logic 函数写入 Ontology
> 要点:让 AI 改数据的机制。
在 Logic 中运行该函数时,你会在 Debugger 中看到你的 scenario 中的所有拟议 Ontology 编辑。这些编辑实际上不会被执行。如果你希望将编辑应用到 Ontology,可以采取以下任一方式:
- 从某个 action 中调用你的 Logic 函数;或,
- 从某个自动化中调用你的 Logic 函数。你可以使用位于右侧的 Automations
选项,从你的 Logic 仪表盘开始创建新的自动化。
要让 Logic 函数能够编辑 Ontology,你必须:
- 在 Logic 函数可以调用的 Use LLM block 中设置一个 Apply actions 工具。这允许 LLM 编辑 Ontology。

> 图:示例展示了 Apply actions 工具,其 prompt 为「Make changes to the flight as described」,并已从下拉菜单中预先选定了一个 action。
- 当你完成 Logic 函数的迭代后,找到并选择位于保存旁边的 Publish 选项来发布该 Logic 函数。
- 接下来,创建一个由你刚刚发布的 Logic function 支撑的新 action。

> 图:将你的 logic 函数包装为 action 的示例。
- 现在你就可以在 Workshop 模块中使用这个新 action 来驱动一个业务工作流。
## 分支
> 要点:在隔离分支上安全开发。
使用 Foundry branching 可以隔离地开发和测试 Logic 函数。你可以发布它们,以便在 Workshop 等支持分支的应用中使用,并通过审批提案来合并更改。更多信息请参见对 AIP Logic 使用分支。
## 对比视图
> 要点:比较版本差异。
在版本历史标签页中,你可以比较一个 logic 的两个版本,查看它们之间的变化,具体包括哪些 block 被编辑、添加或移除。

> 图:Logic 对比
## 下一步
> 要点:继续深入的方向。
如果你有 AIP Logic 的访问权限,我们建议你开始尝试用 LLM block 与你的 Ontology 交互,并构建你自己的用例。你可能会发现,查阅平台中关于函数(Functions)的文档会有所帮助。
### 常见问题速答 · FAQ
关于「AIP Logic 快速入门」,读者最常问的几个问题。
进入 AIP Logic是什么? 从哪里打开这个应用。可以从平台的工作区导航栏访问 AIP Logic,也可以使用快速搜索快捷键 CMD + J(macOS)或 CTRL + J(Windows)。
应用界面是什么? 各区域功能说明。AIP Logic 的界面有三个主要组成部分,在下面的示意截图中按从左到右的顺序编号。
工作流概览是什么? 一条完整链路的走向。一个典型的 AIP Logic 工作流从在左侧面板(1)中配置输入(A)、block(B)和输出(C)开始。使用运行面板(3)生成一个示例输出。
输入、block 与输出的配置是什么? 函数骨架的搭建方式。当你初次开始使用 AIP 时,会看到右侧的 Run 面板,以及左侧的三种 board:输入(inputs),用于可选地选择某个对象及其属性;block,用于定义你的 Logic 指令。
---
## AIP Logic 的指标
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-logic-metrics.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/logic-metrics/
- 主题分组:AIP Logic(十)
循序渐进 · AIP 教学 · AIP Logic(十)
# AIP Logic 的指标
Logic 资源底层由函数支撑。这篇讲怎么看到成功/失败次数与 P95 执行时长,判断一个 Logic 函数是否健康。
## 先记住这几条
① 指标来自底层函数 Logic 资源执行会映射到函数执行。
② 看三件事 成功次数、失败次数、P95 执行时长。
③ 窗口是 30 天 默认统计过去 30 天的表现。
## 写在前面
AIP Logic 资源由函数支撑,当一个 AIP Logic 资源执行时,会显示底层函数执行的指标,包括成功与失败次数,以及过去 30 天的 P95 执行时长。
你可以在 Ontology Manager 或 Workflow Lineage 中查看这些指标。在 Workflow Lineage 中,为给定执行选择 AIP Logic 节点。这可以让你了解:
- 成功/失败指标: 通过底层函数的成功与失败次数,监控你的 AIP Logic 执行的当前状态。

> 图:Workflow Lineage 中显示的 AIP Logic 执行指标。
- P95 时长指标: 跟踪第 95 百分位(P95)执行时长,帮助你发现性能瓶颈并优化工作流。

> 图:Workflow Lineage 中显示的 AIP Logic P95 时长指标。
你还可以访问运行历史,它提供了过去七天执行的完整视图。进一步了解 Ontology 和 AIP 可观测性。
所有指标都使用来自 Foundry Telemetry Service (FTS) 的最新数据近乎实时地更新。这确保你可以获取最新信息,用于监控、调试和维护你的 AIP Logic 资源的健康状况。
AIP Logic 执行的失败类型遵循与函数失败类型相同的分类。完整的失败类别列表请参阅函数指标文档。
## 权限
> 要点:看指标需要什么权限。
要查看 AIP Logic 指标,你必须是该 AIP Logic 资源的 viewer。
---
## AIP Logic 总览:无代码搭 AI 函数
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/overview/
- 主题分组:AIP Logic(一)
循序渐进 · AIP 教学 · AIP Logic(一)
# AIP Logic 总览:无代码搭 AI 函数
AIP Logic 是 AIP 的核心应用:在可视化环境里构建、测试、发布由 LLM 驱动的函数,无需写代码就能借助 Ontology 构建功能丰富的 AI 逻辑。想上手 AIP,从这组开始。
## 先记住这几条
① 无代码但不简单 拖拽式的 block 组合,能表达复杂业务逻辑。
② 站在 Ontology 上 直接读写对象、调用动作,不需要自己接 API。
③ 能用平台的 LLM 模型来自平台,共享限流与治理。
④ 可测试、可发布 内置调试器与发布流程。
## 写在前面
AIP Logic 是一个无代码开发环境,用于构建、测试和发布由 LLM 驱动的函数。AIP Logic 让你能够构建功能丰富的 AI 驱动函数,这些函数可以借助 Ontology,而无需承受开发环境和 API 调用通常带来的复杂性。借助 Logic 直观的界面,应用构建者可以编写 prompt、进行测试、评估与监控、设置自动化等等。
你可以使用 AIP Logic 来自动化并支撑你的关键任务,无论是将非结构化输入中的关键信息与你的 Ontology 连接起来、解决排期冲突、通过寻找最佳分配方案来优化资产性能,还是应对供应链中的中断等等。

> 图:AIP Logic 的引导界面,包含一个用于创建新 Logic 的按钮,以及一个列出你的 Logic 函数的空间。
Logic 函数也可以被自动化,从而自动应用 Ontology 编辑,或将其暂存以待人工审核。
使用 Foundry Branching 可以隔离地开发 Logic 函数。你还可以通过指标监控 Logic 函数的健康状况和性能,包括成功与失败次数以及执行时长。
AIP Logic 提供了一个直观的界面,可通过一个 Logic 函数来利用 Ontology 和 LLM;该函数接收输入(例如 Ontology 对象或文本字符串),并可以返回输出(对象和/或字符串),或对 Ontology 进行编辑。例如,下面这个由 LLM 驱动的函数接收来自某个 Ontology 对象的输入数据,将该数据与一封客户邮件进行交叉比对,并根据以往的解决方式来为某个特定问题推荐解决方案。
. Look only at the email body. Determine the best solution based on what has worked in the past. Return your one solution recommendation, do not list findings from every email.」该 block 的 Query objects 工具已针对「[Titan] Distribution Center Email」对象设置好,并被授予访问 email content 属性的权限。输出被设置为变量名「recommended solution」,类型为「primitive, string」。)
AIP Logic 构建在治理 Palantir 平台其余部分的同一套严格的安全模型之上,包括用户权限和函数权限。这些平台安全控制只会授予 LLM 完成某项任务所必需的访问权限。
仅在读取时强制执行 行级和列级访问控制(包括受限视图、对象安全策略和属性安全策略)会过滤模型代表用户所能读取的内容。模型永远无法看到用户无权读取的数据。这些控制不会延伸到模型的输出或它编写的任何 Ontology 编辑。为了让数据在向下游流转时持续受到保护,请将这些控制与标记(marking)或基于分类的访问控制搭配使用。完整的模型说明参见访问控制传播。
进一步了解 AIP Logic 的核心概念,或者开始使用并构建一个 Logic 函数。在评估函数时,AIP Evals 提供了一个结果分析器,可按根因对失败的测试用例进行分类,并就如何有针对性地修改 prompt 以改善结果给出建议。
---
## 暂存写入(Staged writes)
- 页面:https://www.hanzhongpin.xyz/ontology/aip-logic-staged-writes.html
- 官方原文:https://www.palantir.com/docs/foundry/logic/staged-writes/
- 主题分组:AIP Logic(五)
循序渐进 · AIP 教学 · AIP Logic(五)
# 暂存写入(Staged writes)
让 AI 直接改你的 Ontology 太危险怎么办?暂存写入让改动先停下来等人审,通过后才落库。
## 先记住这几条
① 写入可以暂存 不直接落库,先挂起等审核。
② 人工审核是安全阀 尤其适合高风险或高价值的写操作。
③ 与 Automate 配合 审核通过后自动流转。
## 写在前面
> Beta
暂存写入(staged writes)处于开发的 beta 阶段,可能在你的 enrollment 上不可用。功能在积极开发期间可能会发生变化。请联系 Palantir Support 申请访问权限。
暂存写入为那些会编辑 Ontology 中对象的 AIP Logic 函数提供了一种改进的执行模型。新建的 Logic 函数很快将默认启用暂存写入。
与旧版 Ontology 编辑行为相比,暂存写入的 Logic 函数:
- 支持嵌套函数和 action 调用中的 Ontology 编辑。 一个暂存写入的 Logic 函数可以调用其他暂存写入函数,或直接进行 Ontology 编辑的其他函数,也可以应用由其他会进行 Ontology 编辑的函数所支撑的 action。这在以前是不受支持的。
- 支持所有对象集过滤器。 现在支持所有对象集过滤器,包括 contain keywords 和 relative time range,而这两个在旧版模式下不受支持。
关于暂存写入语义的完整描述,请参阅暂存写入文档。
## 与旧行为的关键差异
> 要点:升级前必须知道的变化。
暂存写入的 Logic 函数与旧版 Ontology 编辑行为之间有几处显著差异。
### Ontology edits in nested function and action calls
启用暂存写入后,你的 Logic 函数可以调用其他暂存写入函数(例如其他 Logic 函数或 TypeScript v2 函数),或直接进行 Ontology 编辑的其他函数,也可以应用由其他会执行 Ontology 编辑的函数所支撑的 action。此前,在一个 Logic 函数内部调用由另一个同样会进行 Ontology 编辑的 Logic 函数所支撑的 action,是不受支持的。
嵌套调用所做的编辑,对同一 Logic 执行中的后续读取是可见的。所有编辑都会被暂存到临时存储中,并在执行完成时应用到 Ontology。
例如,一个处理支持邮件的 Logic 函数可以创建一个 Support Ticket 对象,然后应用一个由另一独立 Logic 函数支撑的分流(triage)action。该分流函数可以分配工单并编辑相关对象。所有编辑会被一起暂存,你 Logic 函数中靠后的 block 可以查询这两者的结果。
### Support for all object set filter boards
在旧版模式下,一旦你的 Logic 函数做了编辑,某些对象集过滤器 board 在本次执行的剩余过程中就不再受支持:
- Contain keywords
- Contain keywords (in order)
- Relative time range
启用暂存写入后,整个 AIP Logic 执行过程中都支持所有对象集过滤器。
### Function output is no longer a list of Ontology edits
会编辑 Ontology 的旧版 Logic 函数会返回一个 Ontology 编辑列表作为其输出。改用暂存写入的 Logic 函数则会把编辑暂存到临时存储中,并在执行完成时将其应用到 Ontology。因此,该函数不再返回 Ontology 编辑,而可以返回其他类型的值。
由于暂存写入的 Logic 函数不返回 Ontology 编辑,它们无法在 Automate 的 Logic effect 中被选中。要从 Automate 调用暂存写入的 Logic 函数,请用一个 action type 将其包装,并使用 action effect。参见下文自动化暂存写入的 Logic 函数。
## 启用或停用暂存写入
> 要点:开关在哪、怎么配。
新建的 Logic 函数很快将默认启用暂存写入。你可以使用 AIP Logic 中 Execution mode settings 下的 Enable staged write mode 开关,为某个 Logic 函数开启或关闭暂存写入。

> 图:AIP Logic 中的暂存写入开关。
禁用暂存写入会使函数回退到旧版行为,即函数返回一个 Ontology 编辑列表作为其输出。如果你的工作流依赖从 Automate 的 Logic effect 直接调用该 Logic 函数,你可能需要禁用暂存写入。
> 我们建议保持启用暂存写入,并通过 action type 来调用你的函数。旧版行为不支持嵌套 action 调用中的 Ontology 编辑,在函数做过编辑后不支持关键字过滤器和相对时间范围过滤器,并且将来会被弃用。
### Versioning when switching modes
切换暂存写入对版本的影响取决于该函数的输出类型:
- 输出类型是一个 Ontology 编辑列表: 启用或禁用暂存写入会发布一个新的函数主版本(major version),因为根据 Logic 配置的不同,输出类型会变为另一种类型。在 action 或 Automate 中配置的版本范围不会跨越主版本边界,因此现有使用方会继续针对先前发布的版本运行,不会自动升级。参见下文迁移现有自动化。
- 输出类型不是 Ontology 编辑列表: 切换暂存写入不会改变输出类型,因此不会发生主版本递增。如果现有使用方配置了自动升级,它们会自动采用新版本。
## 在 Automate 中使用暂存写入的 Logic 函数
> 要点:审核流程怎么流转。
暂存写入的 Logic 函数必须通过 action type 调用,才能在 Automate 中使用。该 action 提供了用于暂存和应用编辑的执行上下文。
### Create an action type from your Logic function
AIP Logic 为暂存写入的 Logic 函数提供了 Create action 按钮,用于生成一个调用你函数的 action type:
- 在你的 AIP Logic 文件中,导航到 Usage 标签页并选择 Create action。
- 检查生成的 action type。该 action 的参数由你 Logic 函数的输入映射而来。
- 保存该 action type。

> 图:AIP Logic 中的 Create action 按钮。
随后你可以在 Automate 的 action effect 中使用这个 action,也可以在任何其他支持 action 的地方(例如 Workshop)应用它。
> 创建 action type 并不会启用或禁用该函数上的暂存写入;执行模式仅由 Enable staged write mode 开关控制。
或者,你也可以在 Ontology Manager 中配置一个现有的 action type,使其由你的 Logic 函数支撑。使用 Create action 新建一个 action type 通常更为简单。
### Create an automation
对于暂存写入的 Logic 函数,在你创建好 action type 后,导航到 Automate 并创建一个 action effect。
在 Automate 中,像处理任何其他 action effect 一样,从触发该自动化的对象或值来配置 action 参数。action effect 可用的所有 Automate 能力——包括将 action 暂存为供人工审核的提案、重试策略和回退 effect——都适用于调用暂存写入 Logic 函数的 action。
## 迁移已有自动化
> 要点:老配置怎么过渡。
如果你为一个已在自动化中通过 Logic effect 直接使用的 Logic 函数启用了暂存写入:
- 该自动化会继续运行,针对先前发布的该函数旧版主版本。启用暂存写入不会破坏现有自动化。
- 如果你尝试将该自动化更新到该函数的暂存写入主版本,你将被阻止保存,因为 Logic effect 仅支持旧版 Logic 函数。
- Automate 中的 Auto upgrade to compatible versions 设置不会把自动化迁移到暂存写入版本,因为自动升级永远不会跨越主版本边界。
要将现有自动化迁移到暂存写入:
- 在你的 Logic 函数上启用暂存写入并发布。如果该函数的输出类型是一个 Ontology 编辑列表,这会创建一个新的主版本。
- 在 AIP Logic 的 Usage 标签页中选择 Create action,从该函数生成一个 action type。
- 在你的自动化中,将 Logic effect 替换为一个提交所生成 action 的 action effect。
- 保存该自动化。
### 常见问题速答 · FAQ
关于「暂存写入(Staged writes)」,读者最常问的几个问题。
与旧行为的关键差异是什么? 升级前必须知道的变化。暂存写入的 Logic 函数与旧版 Ontology 编辑行为之间有几处显著差异。
启用或停用暂存写入是什么? 开关在哪、怎么配。新建的 Logic 函数很快将默认启用暂存写入。你可以使用 AIP Logic 中 Execution mode settings 下的 Enable staged write mode 开关,为某个 Logic 函数开启或关闭暂存写入。
迁移已有自动化是什么? 老配置怎么过渡。如果你为一个已在自动化中通过 Logic effect 直接使用的 Logic 函数启用了暂存写入。
---
## 模型弃用与迁移
- 页面:https://www.hanzhongpin.xyz/ontology/aip-model-catalog-model-deprecation.html
- 官方原文:https://www.palantir.com/docs/foundry/model-catalog/model-deprecation/
- 主题分组:其他应用(三)
循序渐进 · AIP 教学 · 其他应用(三)
# 模型弃用与迁移
模型供应商经常弃用模型,依赖它的工作流就会被打断。这一篇讲 Palantir 如何通知、如何用 Upgrade Assistant 帮你迁移到替代模型。
## 先记住这几条
① 弃用是常态 供应商会定期下线旧模型。
② 影响面需要评估 哪些工作流依赖了它。
③ 有工具辅助迁移 Upgrade Assistant 会通知并引导。
④ 迁移要提前规划 别等到模型真的下线。
## 写在前面
模型供应商经常会弃用模型,这会影响依赖这些模型的工作流,并要求用户迁移到推荐的替代模型。当供应商宣布模型弃用时,Palantir 会通知受影响的用户,并通过 Upgrade Assistant 识别依赖受影响模型的资源。
收到通知后,我们鼓励用户提前规划,将任何使用即将弃用模型的现有工作流迁移到推荐的替代模型上。用户会收到迁移截止日期的通知,此后将对模型实施一系列 brownout(降级服务)访问限制,以推动剩余工作流完成迁移。
如果在 brownout 截止日期前未采取任何措施,使用已弃用模型的工作流将会失败,并在 brownout 期间输出以下错误消息:
json {
"errorCode": "NOT_FOUND",
"errorName": "LanguageModelService:LanguageModelNotAvailable",
"errorInstanceId": "",
"parameters": {
"safeParams": "{languageModelRid=, deprecationDate=, brownoutStart=, brownoutEnd=}",
"unsafeParams": "{}",
"message": "Unable to use model: language model is in planned deprecation and is currently under a brown-out"
}
}
同样,如果在供应商的模型弃用日期前未采取任何措施,使用已弃用模型的工作流将会失败,并输出下面的错误消息,直到该工作流迁移到替代模型为止:
json {
"errorCode": "NOT_FOUND",
"errorName": "LanguageModelService:LanguageModelNotAvailable",
"errorInstanceId": "",
"parameters": {
"safeParams": "{languageModelRid=, deprecationDate=}",
"unsafeParams": "{}",
"message": "Unable to use model: language model is deprecated"
}
}
## 降级期访问限制
> 要点:弃用前会先限流,别等到那时才发现。
模型 brownout 是一种引导用户远离正在被弃用模型的策略。Brownout 会引入刻意的、临时的不稳定性,以发出即将变化的信号,并避免突然中止向那些未对 Upgrade Assistant 中列出的受影响资源采取行动的用户提供服务。
每个模型都遵循特定的 brownout 时间表。要查看正在经历弃用的模型的 brownout 时间表,包括阶段数、开始日期和持续时间,请参阅该已弃用模型的 Upgrade Assistant 描述页面。
## 迁移模型
> 要点:怎么换到替代模型。
要成功从已弃用模型迁移出去并避免关键工作流中断,请执行以下步骤:
- 识别需要迁移的资源。
- 导航到受影响的资源。
- 替换已弃用的模型。
### Identify resources that require migration
导航到 Upgrade Assistant,并在 Active upgrades 小节中打开相关的模型弃用页面。在已弃用模型的描述页面上,向下滚动到 Resources 小节,即可看到受此次模型弃用影响的资源列表。

> 图:模型弃用受影响资源列表视图。
Resource identification criteria
资源会根据以下标准被标记为需要迁移:
- 如果某个资源调用了已弃用的模型,该资源将被标记为 PENDING。这表示该资源中使用的模型仍需迁移。
- 如果某个此前调用了已弃用模型的资源改而调用另一个模型,并且对已弃用模型的最后一次调用发生在 24 小时之前,该资源将被标记为 COMPLETED,因为使用不同的模型表明该资源已完成迁移。
在少数情况下,资源可能被标记为 COMPLETED,随后又回到 PENDING。如果某个资源对已弃用模型发起了新的调用,就可能出现这种情况。为防止这种情况,请确保 Workshop modules 等资源在相关函数保存并发布之后更新到该函数的最新版本。
配置为使用已弃用模型、但在迁移期内未被实际使用的资源不会出现在 Upgrade Assistant 的资源列表中。例如,如果某个 pipeline 配置为使用已弃用模型,但在迁移期内未被构建,它就不会出现在 Upgrade Assistant 的资源列表中,因为它并未主动调用已弃用模型。在这种情况下,我们建议盘点你的生产工作流,并使用下方小节中的工具来了解资源用量,评估是否有必要迁移。
### Navigate to the affected resources
在 Upgrade Assistant 描述页面中,选择一个资源以导航到该资源所在的应用。根据资源类型的不同,迁移到新模型的过程可能有所差异。对于每个受影响的资源,你必须确定已弃用模型的使用方式,例如 Pipeline Builder 和 AIP Logic 中的 Use LLM 节点,或 transforms 中的代码引用。你可能需要导航到额外的上游资源,才能为你的工作流选择新模型。
### Replace deprecated models
为防止已弃用模型对你工作流造成中断,需要选择一个新模型。Upgrade Assistant 中每个已弃用模型的描述页面都会包含潜在的替代模型,但我们强烈建议在 AIP Evals 中设置评估套件,以确保你为用例使用了最佳模型。
Upgrade Assistant 会识别使用即将弃用模型的资源,而每种资源类型都需要以不同方式解决。部分资源可以直接配置,使用模型选择器即可选择新模型。在其他资源类型中,例如 Workshop modules 或 pipelines,模型可能是从上游资源调用的,比如 AIP Logic functions 或 Code Repositories transforms。在这些情况下,模型选择需要在包含模型配置选项的上游资源中进行。关于资源类型的更多细节,请参阅下方小节。
用户必须对受影响的资源拥有查看和编辑权限。否则,将无法正确检查 pipelines 和 Workshop modules 等资源,以找到用于模型配置的根源上游资源。
### Model selector supported applications
如果已弃用模型是通过模型选择器选择的,则可以以相同方式选择新模型。在导航到 Logic functions 和 AIP Chatbots(原 AIP Agents)等资源时,打开资源配置设置并使用模型选择器选择新模型。
支持模型选择器的应用包括:
- Pipeline Builder
- AIP Chatbot Studio
- AIP Evals
- AIP Logic
- Workshop
- Quiver
- Marketplace
- Code Workspaces
资源配置设置会在受影响的模型旁显示一个警告,并将其标记为 Sunset。

> 图:一个已弃用的模型显示警告和推荐的替代模型。
要选择替代模型,请打开模型选择器并选择一个新模型。

> 图:模型选择器显示可用模型和模型描述。
### Model usage in Pipeline Builder
对于 Pipeline Builder 资源,Upgrade Assistant 会链接到整个 pipeline,而不是特定的受影响节点。为了在大型 pipeline 中高效地找到相关节点,请使用 Pipeline Builder 的搜索功能。
- 通过在 Upgrade Assistant 模型弃用页面的资源列表中选择相应项,导航到受影响的 pipeline。
- 选择 pipeline 图表右上角的搜索图标。
- 输入 “use LLM” 作为搜索词,查看该 pipeline 中所有 Use LLM 节点的列表。所有搜索结果还会以 pipeline 图表图例中所示的颜色高亮显示。

- 从列出的结果中,选择每个节点以在 pipeline 图表中将其高亮显示。右键点击所选节点,并从上下文菜单中选择 Edit。这将打开该节点的配置页面。
- 导航到 Model 小节,如果该模型正被弃用,模型名称旁会显示一个警告图标。如果存在此警告,请选择 Show configurations,并从 Model type 下拉菜单中选择一个新模型。
- 对该 pipeline 中所有 Use LLM 节点重复此过程。
- 保存、部署并重新构建你的 pipeline。
### Model usage in Workshop
Workshop 中的模型使用可能来源于 AIP widgets 或被引用的函数,例如 AIP Logic functions。取决于来源不同,模型可以从 widget 配置设置中更改,也可以从上游资源(例如 AIP Logic function 或 AIP Chatbot)的配置设置中更改。你可以通过在 Upgrade Assistant 模型弃用页面的资源列表中选择受影响的 Workshop modules,来导航到它们。进入编辑模式以查看 module 配置设置。
你需要对受影响的 Workshop modules 拥有编辑权限。请遵循以下说明来处理基于函数和基于 widget 的模型使用。
Function-based model usage
- 要识别某个 Workshop module 中使用的函数,请打开工作区左上角的 Overview 面板。在 Capabilities 小节下,选择 Functions。

- 在 Functions 面板中,选择每个函数以查看函数源代码。

- 选择函数源代码以导航到源应用,在本例中为 AIP Logic。在该源中,你可以配置模型设置,并在函数使用已弃用模型时选择新模型。
- 保存并发布该函数的新版本。
- 回到 Workshop,按步骤 1 所述导航到 Overview 面板中的 Functions 小节。选择已更新的函数,并使用 Bulk update version 小节下的函数版本下拉菜单,为所有变量或 widgets 选择该函数的最新版本。

- 对所有列出的函数重复此过程。
Widget-based model usage
基于 widget 的模型配置取决于所使用的 widget 类型。请审阅以下选项,并针对你的 Workshop module 中使用的 widgets 遵循相应说明:
- AIP chatbot: AIP Chatbot widget 使用 chatbots,因此模型配置必须在 AIP Chatbot Studio 的 chatbot 配置设置中进行。
- 在 widget 配置面板中,选择正在使用的 chatbot,以在 Chatbot Studio 中打开它。
- 通过在 chatbot 界面右上角选择 Edit 来编辑该 chatbot。
- 打开 chatbot 配置面板并从模型选择器中选择一个新模型。
- 保存并发布你的 chatbot。
- AIP generated content: 对于 AIP generated content widget,只有当该 widget 使用 Direct to LLM 或 LLM via prompt function 选项时,模型使用才能在 Workshop 中配置。否则,需要在被引用的 Logic function 中配置。

- Direct to LLM/LLM via prompt function: 可以使用 widget 配置设置中的模型选择器选择新模型。
- Logic: 如果该 widget 使用 Logic 选项,该 Logic function 将列在 Overview 面板中该 module 的函数下。更多细节请参阅基于函数的模型使用小节。
- Free-form analysis: free-form analysis widget 的模型使用可以直接在 Workshop 中配置。在 widget 配置设置中,打开 AIP options 并选择 Enabled 以配置模型设置。然后,从模型选择器中选择一个新模型。

- Logic - Chain of thought: 该 widget 使用 Logic functions,它们列在 Overview 面板中。更多细节请参阅基于函数的模型使用小节。
请确保在任何改动之后保存并发布你的 Workshop module。
### Code-based model usage
对于基于代码的模型使用,Upgrade Assistant 会列出包含该用法的 code repository、code workspace 或下游资源,而不是包含已弃用模型引用的确切代码文件或函数。对于下游资源被标记的情况,请查阅 Workshop 中的模型使用和附加工具小节。对于 code repository 或 workspace 被标记的情况,请打开 Upgrade Assistant 资源列表中列出的 repository 或 workspace。在 repository 或 workspace 中,你可以将已弃用模型的使用实例替换为新模型。
TypeScript v1 与 TypeScript v2 选择模型的方式不同,这改变了迁移所需的工作:
- TypeScript v1 在 import 语句中指明模型名称,因此已弃用模型必须在 import 处以及所有使用它的调用点进行替换。更多细节请查阅 TypeScript v1 语言模型文档;下面的示例使用的是旧版语言模型导入方式。
- TypeScript v2 通过代理端点调用模型,并使用模型别名来选择它。该别名解析为在 Resource imports 面板的 Platform SDK 标签页中配置的模型 RID,因此模型名称不会出现在函数体中。替换已弃用模型只需改动单个别名引用,而无需改动每个调用点。请求参数(例如 temperature 和 token 上限)遵循代理端点的格式,而不是 TypeScript v1 的 params 对象。
TypeScript v2 示例中使用的 openai 库并非预装。请从左侧面板的 Libraries 小节安装它。
模型的选择和使用方式如下方的 TypeScript v1、TypeScript v2 和 Python 示例所示:
TypeScript v1 TypeScript v2 Python import { Function } from "@foundry/functions-api"
// A deprecated model is imported
import { GPT_4_5 } from "@foundry/models-api/language-models"
/**
* Used to send a text completion request to the model based on user input
* @param {string} userInput - Text input to send to model
*/
export class MyFunctions {
@Function()
public async createChatCompletion(userInput: string): Promise {
// Deprecated model usage
const response = await GPT_4_5.createChatCompletion({
params: {
"temperature": 0,
"maxTokens": 1000,
},
messages: [{ role: "USER", contents: [{ text: userInput }], }],
});
return response.choices[0].message.content;
}
} import { PlatformClient } from "@osdk/client";
import OpenAI from "openai";
import { Aliases } from "@osdk/functions";
import { getFoundryToken, getOpenAiBaseUrl, createFetch } from "@osdk/language-models";
export default async function createChatCompletion(client: PlatformClient, userInput: string): Promise {
const oaiClient = new OpenAI({
apiKey: await getFoundryToken(client),
baseURL: getOpenAiBaseUrl(client),
fetch: createFetch(client),
});
const completion = await oaiClient.chat.completions.create({
// Deprecated model usage through its alias
model: Aliases.model("gpt45").rid,
messages: [
{ role: "user", content: userInput },
],
max_completion_tokens: 1000,
});
return completion.choices[0]?.message.content ?? "";
} from transforms.api import transform, Input, Output
from palantir_models.transforms import OpenAiGptChatLanguageModelInput
from palantir_models.models import OpenAiGptChatLanguageModel
from language_model_service_api.languagemodelservice_api_completion_v3 import GptChatCompletionRequest
from language_model_service_api.languagemodelservice_api import ChatMessage, ChatMessageRole
@transform(
reviews=Input("Input Dataset Rid"),
# Deprecated model usage
model=OpenAiGptChatLanguageModelInput("ri.language-model-service..language-model.gpt-4-5"),
output=Output("Output dataset rid or path"),
)
def compute_sentiment(ctx, reviews, model: OpenAiGptChatLanguageModel, output):
def get_completions(review_content: str) -> str:
system_prompt = "Take the following review determine the sentiment of the review"
request = GptChatCompletionRequest(
[ChatMessage(ChatMessageRole.SYSTEM, system_prompt), ChatMessage(ChatMessageRole.USER, review_content)]
)
resp = model.create_chat_completion(request)
return resp.choices[0].message.content
reviews_df = reviews.pandas()
reviews_df['sentiment'] = reviews_df['review_content'].apply(get_completions)
out_df = ctx.spark_session.createDataFrame(reviews_df)
return output.write_dataframe(out_df)
如果你不确定如何导入和使用新模型,请导航到 Model Catalog 应用查看 Palantir 提供的模型使用示例。在你的 code repository 或 workspace 中搜索已弃用模型的使用,并将所有实例替换为推荐的模型或你选择的模型。取决于你的工作流,这一过程可能涉及创建并向你的 repository 或 workspace 合并一个新分支,以便上游函数或 transform 的使用反映这些改动。
在上面的示例中,使用的是已弃用模型 GPT-4.5。升级到 GPT-4.1 在每种语言中需要不同的改动。
在 TypeScript v2 中,将 GPT-4.1 导入到 repository。导入对话框会为新模型创建一个别名。将传给 Aliases.model() 的别名名称更新为新别名。函数体中命名的是别名而不是模型。因此,这次更新只需要改动一行,而不是改动 import 语句和每个 TypeScript v1 调用点。
更新后的示例如下所示:
TypeScript v1 TypeScript v2 Python import { Function } from "@foundry/functions-api"
// Import a new model
import { GPT_4_1 } from "@foundry/models-api/language-models"
/**
* Used to send a text completion request to the model based on user input
* @param {string} userInput - Text input to send to model
*/
export class MyFunctions {
@Function()
public async createChatCompletion(userInput: string): Promise {
// Replace usage of the deprecated model with the new model.
const response = await GPT_4_1.createChatCompletion({
params: {
"temperature": 0,
"maxTokens": 1000,
},
messages: [{ role: "USER", contents: [{ text: userInput }], }],
});
return response.choices[0].message.content;
}
} import { PlatformClient } from "@osdk/client";
import OpenAI from "openai";
import { Aliases } from "@osdk/functions";
import { getFoundryToken, getOpenAiBaseUrl, createFetch } from "@osdk/language-models";
export default async function createChatCompletion(client: PlatformClient, userInput: string): Promise {
const oaiClient = new OpenAI({
apiKey: await getFoundryToken(client),
baseURL: getOpenAiBaseUrl(client),
fetch: createFetch(client),
});
const completion = await oaiClient.chat.completions.create({
// Reference the alias for the substitute model.
model: Aliases.model("gpt41").rid,
messages: [
{ role: "user", content: userInput },
],
max_completion_tokens: 1000,
});
return completion.choices[0]?.message.content ?? "";
} from transforms.api import transform, Input, Output
from palantir_models.transforms import OpenAiGptChatLanguageModelInput
from palantir_models.models import OpenAiGptChatLanguageModel
from language_model_service_api.languagemodelservice_api_completion_v3 import GptChatCompletionRequest
from language_model_service_api.languagemodelservice_api import ChatMessage, ChatMessageRole
@transform(
reviews=Input("Input Dataset Rid"),
# Replace usage of the deprecated model with the new model.
model=OpenAiGptChatLanguageModelInput("ri.language-model-service..language-model.gpt-4-1"),
output=Output("Output dataset rid or path"),
)
def compute_sentiment(ctx, reviews, model: OpenAiGptChatLanguageModel, output):
def get_completions(review_content: str) -> str:
system_prompt = "Take the following review determine the sentiment of the review"
request = GptChatCompletionRequest(
[ChatMessage(ChatMessageRole.SYSTEM, system_prompt), ChatMessage(ChatMessageRole.USER, review_content)]
)
resp = model.create_chat_completion(request)
return resp.choices[0].message.content
reviews_df = reviews.pandas()
reviews_df['sentiment'] = reviews_df['review_content'].apply(get_completions)
out_df = ctx.spark_session.createDataFrame(reviews_df)
return output.write_dataframe(out_df)
### Model usage in Quiver
Quiver 中的 LLM 使用可以在分析设置中配置。导航到受影响分析侧边栏中的设置标签页,并在 AIP Settings 小节下访问模型选择器。

> 图:Quiver 分析设置中的模型选择器。
### Additional tools
工作流可能会变得复杂且难以驾驭,导致很难直观地找到所有受影响的资源使用实例。请查阅下方小节,了解可用于帮助识别工作流中 LLM 使用的工具。
Workflow Lineage
为了更好地理解跨资源的模型使用情况,你可以使用 Workflow Lineage。使用键盘快捷键 Cmd + I(macOS)或 Ctrl + I(Windows)在 Workflow Lineage 中打开某个 Workshop 应用或函数 repository。在 Workflow Lineage 图表中,你将能够查看支撑某个应用的对象、actions 和函数。
- Workshop applications: 对于 Workshop 应用,Workflow Lineage 会显示上游资源(如 Logic functions)以及它们被配置使用的模型。Workflow Lineage 还允许用户查看消费某个给定函数的其他 Workshop 或 OSDK 应用,从而更容易地理解受影响资源的完整范围。如果某个资源使用了已弃用模型,Workflow Lineage 会显示一个警告图标和一条消息,提醒用户该模型已处于弃用状态。

Workflow Lineage 可以借助其批量更新功能,帮助完成 Workshop 的模型迁移操作。如基于函数的模型使用小节所示更新某个函数之后,你可以在 Workflow Lineage 中打开该 Workshop 应用,以批量更新一个或所有依赖该函数的 Workshop 应用所使用的函数版本。此外,Workflow Lineage 还让你能够通过一次操作,从 lineage 图表中批量替换语言模型,跨越多个 AIP Logic functions。
- Function repositories: Workflow Lineage 可以提供可视化表示,帮助用户理解函数 repository 中的模型使用情况。调用模型的函数会有一个相连的模型节点,让用户能够一眼看出这些函数是否在调用已弃用模型。

关于 Workflow Lineage 完整功能集的更多信息,请参阅 Workflow Lineage 的使用文档。
Ontology Manager
一旦你识别出包含已弃用模型的函数,就可以在 Ontology Manager 中打开它,以跟踪使用该函数的资源。然后你可以导航到这些资源并更新函数版本,以确保服务不中断。对于 Workshop 应用,你可以使用上一小节所述的 Workflow Lineage 来批量更新函数版本。
要查看函数使用情况,请导航到 Ontology Manager 并在侧边栏中选择 Functions。在 functions 页面上,你可以搜索函数名称,并从 Functions 表中选择它以打开其概览页面。
在函数概览页面中,向下滚动到 Usage history 小节,查看使用该函数的资源列表。你可以按版本筛选,找出可能正在使用该函数过时版本的资源。

> 图:函数概览页面中的 “Usage history” 小节。
然后你可以导航到使用该函数的资源,将其更新到最新版本。更多信息请参阅 Ontology Manager 的函数类型视图文档。
### 常见问题速答 · FAQ
关于「模型弃用与迁移」,读者最常问的几个问题。
降级期访问限制是什么? 弃用前会先限流,别等到那时才发现。模型 brownout 是一种引导用户远离正在被弃用模型的策略。Brownout 会引入刻意的、临时的不稳定性,以发出即将变化的信号,并避免突然中止向那些未对 Upgrade Assistant 中列出的受影响资源采取行动的用…
迁移模型是什么? 怎么换到替代模型。要成功从已弃用模型迁移出去并避免关键工作流中断,请执行以下步骤。
---
## AIP Model Catalog 总览
- 页面:https://www.hanzhongpin.xyz/ontology/aip-model-catalog-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/model-catalog/overview/
- 主题分组:其他应用(二)
循序渐进 · AIP 教学 · 其他应用(二)
# AIP Model Catalog 总览
Model Catalog 是平台里所有模型资源的总目录:统一查看有哪些模型、各自状态如何、被谁在用。选型与治理都从这里入手。
## 先记住这几条
① 模型的总目录 一处看清平台里有哪些模型。
② 关注模型状态 可用、弃用等状态一目了然。
③ 支撑选型与治理 谁在用哪个模型、影响范围多大。
## 写在前面
> 你可以在 Control Panel 中启用 Model Catalog。
Model Catalog 是 Foundry 中的一个 AIP 应用,旨在帮助发现和理解所有 Palantir 提供的模型。
Model Catalog 让构建者能够:
- 查看 AIP 中可用的模型并发现新模型。
- 为你的用例选择正确的模型。后续更新将提供更多用于比较和决策的工具与基准测试。
- 通过 Marketplace 使用基础模板以及完整的用例模板快速上手某个工作流。
- 使用沙箱/演练场(sandbox/playground)测试不同模型。
Model Catalog 目前不包含自定义 ML/AI 模型,只包含 LLM。你可以在 Modeling Objectives 中找到 ML/AI 模型。
Model Catalog 有两个主要视图:
- Model Catalog homepage
- Model entity page
## Model Catalog 首页
> 要点:总览视图能看什么。

> 图:Model Catalog 主页
Model Catalog 主页是一个发现与导航界面,展示用户在其 Foundry enrollment 中可用的所有大型语言模型。
> 查阅 AIP 中可用模型的完整列表。
在主页上有几种筛选模型的方式:
- Lifecycle status(生命周期状态)
- Experimental: 实验性模型可能被供应商或 Palantir 任一方视为实验性的,这意味着 API 可能变化、token 容量可能受限、在 AIP 应用中的行为可能不被完全支持,或出现其他不稳定行为。所有模型在首次于 AIP 中可用时都会以实验性状态开始。实验性模型通常用于探索和测试,对长期稳定性与支持的重视程度较低。当模型达到 Palantir 的性能与可用性标准后,会从实验性提升为稳定状态,这些标准包括但不限于:具备足够的吞吐量以在保持可用的同时处理生产工作负载的请求、在所有 AIP 应用中均可用,以及广泛的地域可用性。
> Enrollment administrators 可以在 Control Panel 的 AIP settings 小节中为其 enrollment 启用或禁用 Experimental 模型,从而让 Model Catalog 只显示处于 Stable 生命周期阶段的模型。
- Stable: 稳定(stable)或正式可用(generally available,GA)模型是同时获得模型供应商和 Palantir 认可的可靠模型。这些模型提供稳健的功能、有保障的支持,并面向长期生产使用而设计。模型的地域可用性因模型供应商的供给情况而异。你可以在受支持的 LLM 文档中查阅按地区划分的模型可用性完整列表,并在 Model Selector 中查看每个模型状态的信息。Palantir 会在收到模型供应商规定的下线日期后,将模型从稳定状态移至 sunset(即将下线)状态,并通过 Upgrade Assistant 通知用户这一变化。
- Sunset: sunset(即将下线)模型将在未来几个月内弃用,具体由模型供应商决定并公告。虽然 sunset 模型在其规定的弃用日期之后不能再支撑新的工作流,但该模型仍可能支持现有工作流。与其稳定状态的对应模型相比,sunset 模型将不会获得同等水平的技术支持。Palantir 会在收到模型供应商规定的弃用日期后,将模型从 sunset 状态移至 deprecated(已弃用)状态,并通过 Upgrade Assistant 通知用户这一变化。关于 sunset 模型的更多信息,请查阅模型弃用文档。
- Deprecated: 在其 sunset 期结束后,Palantir 会与模型供应商协同将模型从 Foundry 中移除,即弃用。已弃用模型无法支撑现有工作流(包括新的 API 调用),因此项目必须在模型被弃用之前迁移到稳定模型以保持功能正常。Foundry 会保留并允许访问已弃用模型的历史数据和日志。关于已弃用模型的更多信息,请查阅模型弃用文档。
- Type(类型)
- Completion model: 补全模型通过预测并补全输入文本来生成上下文相关的文本。这使其适用于内容生成、自动补全、翻译和问答等任务。
- Embedding model: 嵌入模型将词语和句子等离散数据转换为连续的向量表示。它最常用于语义搜索以及其他信息检索用例。
- Vision model: 视觉模型经过训练可以分析和解读视觉输入,使其能够识别物体、对图像进行分类,并支持针对图像和视频数据的各类计算机视觉任务。
- Model creator(模型创建方)
- 模型创建方是负责创建、开发和维护特定 LLM 的组织。例如 OpenAI、Anthropic、Google Gemini 和 Mistral AI。模型创建方可以直接提供其 LLM,也可以通过与其他组织合作提供,例如通过 Azure 提供的 OpenAI 以及通过 AWS 提供的 Anthropic。部分模型可能由 Palantir 提供并托管,例如 Llama 和 Mixtral。
如果某个模型不可用或呈灰色,意味着它未为你的 enrollment 启用。要启用某个模型,请联系你的平台管理员或 Palantir 代表。
了解关于 Model enablement 的更多信息。
## 模型实体页
> 要点:单个模型的详情。

> 图:Model catalog 模型视图
每个模型都有一个实体页面,包含三个主要小节:
- Playground: 供构建者试用不同模型的界面。
- How to use it: 通过创建一个资源来快速上手,该资源已预填充开始构建工作流所需的内容。Model Catalog 目前支持 Functions 和 Transforms。
- Model description: 包含基本描述、法律免责声明、模型的上下文窗口(如 token 上限)、训练数据截止时间等。
## 模型对比页
> 要点:横向比较选型。

> 图:Model catalog 比较视图
Model Catalog 的比较页面让构建者能够高效地比较和评估各种 LLM 的性能。该界面允许用户选择两个 LLM,并在相同的补全或视觉任务上对它们进行测试。这有助于做出有依据的决策,让构建者能够快速选出最适合其工作流的模型。
### 常见问题速答 · FAQ
关于「AIP Model Catalog 总览」,读者最常问的几个问题。
Model Catalog 首页是什么? 总览视图能看什么。Model Catalog 主页是一个发现与导航界面,展示用户在其 Foundry enrollment 中可用的所有大型语言模型。
模型实体页是什么? 单个模型的详情。每个模型都有一个实体页面,包含三个主要小节。
模型对比页是什么? 横向比较选型。Model Catalog 的比较页面让构建者能够高效地比较和评估各种 LLM 的性能。该界面允许用户选择两个 LLM,并在相同的补全或视觉任务上对它们进行测试。这有助于做出有依据的决策,让构建者能够快速选出最适合其工作流的模型。
---
## 构建支持语音的 OSDK 应用
- 页面:https://www.hanzhongpin.xyz/ontology/aip-realtime-audio-build-a-voice-enabled-osdk-application.html
- 官方原文:https://www.palantir.com/docs/foundry/realtime-audio/build-a-voice-enabled-osdk-application/
- 主题分组:其他应用(五)
循序渐进 · AIP 教学 · 其他应用(五)
# 构建支持语音的 OSDK 应用
这是一篇动手教程:用 OSDK 把实时语音能力接进你自己的应用。注意 —— 录音与知情同意由你负责。
## 先记住这几条
① 用 OSDK 集成 在自有应用里接入语音能力。
② 端到端流程要自己串 音频采集、实时传输、结果处理。
③ 合规责任在开发者 录音与知情同意必须自行处理。
## 写在前面
录音与知情同意由你负责 在部署任何录制或转录人类语音的应用之前,请确保已通知参与者,并在你所在司法管辖区要求的情况下备好同意流程。无论参与者是应用用户、通话中的第三方,还是任何其他语音被采集的人,这可能都适用。请参阅录音、转录与知情同意。
本教程将带你构建一个 OSDK 应用,它采集麦克风音频、将其流式传输到实时模型,并播放模型的语音回复。该应用以 Foundry 用户身份进行认证,因此每次交互都基于该用户的权限以及其可访问的 Ontology。关于 Foundry 上实时音频的高层概览,请参阅实时音频。
## 你将构建什么
> 要点:先明确目标产物。
到本教程结束时,你将拥有一个在浏览器中运行的 TypeScript 应用,它可以:
- 通过标准的 OSDK OAuth 流程对用户进行认证。
- 直接从浏览器打开一条到 Foundry 代理端点的 WebSocket 连接,该端点会转发到实时模型。
- 为智能体提供一个从 Ontology 读取数据的工具,并以用户的权限运行。
- 将麦克风音频流式传输到模型,并播放模型的语音回复。
## 前置条件
> 要点:动手前的准备。
在开始之前,请确保你具备以下条件:
- 一个通过 @osdk/create-app 搭建好的 OSDK 应用。生成的应用包含本教程所依赖的 OAuth 脚手架。关于 OSDK 本身的完整参考,请参阅 Ontology SDK。
- 在 Developer Console 中注册的一个不受限自定义应用。OSDK 前端针对该应用进行认证。需要“不受限”是为了让访问令牌能够包含步骤 1中使用的 language-model-service:use-model scope。
- 在你的 enrollment 中启用的一个实时模型。列表请参阅可用的音频模型。本教程使用 gpt-realtime-2。
- 在你的应用中安装的 @openai/agents 包:
bash npm install @openai/agents
## 第 1 步:获取 OAuth 访问令牌
> 要点:鉴权准备。
由 @osdk/create-app 生成的 OSDK 应用在 src/client.ts 中包含一个 OAuth client。该 client 使用来自 @osdk/oauth 的 createPublicOauthClient 创建,并暴露一个用于获取当前访问令牌的方法。clientId、foundryUrl 和 redirectUrl 的值在运行时从 @osdk/create-app 根据你的 .env 配置注入到 index.html 中的 osdk-* meta 标签读取。
为 OAuth client 配置 language-model-service:use-model scope,使生成的访问令牌被允许连接到实时端点。没有这个 scope,实时端点会在认证期间拒绝该 WebSocket 连接。该 scope 仅在不受限自定义应用上可用——在继续之前请确认你的应用是不受限的。
下面的代码片段展示了添加实时音频 scope 之后 src/client.ts 的完整形态。该文件的大部分由 @osdk/create-app 生成;本教程唯一需要的改动是在 scopes 数组中包含 language-model-service:use-model。这些导出在教程的其他地方会被使用:auth 用于下方获取令牌,foundryUrl 用于在步骤 2中构建 WebSocket URL,client 用于步骤 3中的 OSDK 查询。
typescript import { createClient, type Client } from "@osdk/client";
import { createPublicOauthClient, type PublicOauthClient } from "@osdk/oauth";
function getMetaTagContent(tagName: string): string {
const elements = document.querySelectorAll(`meta[name="${tagName}"]`);
const element = elements.item(elements.length - 1);
const value = element ? element.getAttribute("content") : null;
if (value == null || value === "") {
throw new Error(`Meta tag ${tagName} not found or empty`);
}
return value;
}
export const foundryUrl = getMetaTagContent("osdk-foundryUrl");
const clientId = getMetaTagContent("osdk-clientId");
const redirectUrl = getMetaTagContent("osdk-redirectUrl");
const ontologyRid = getMetaTagContent("osdk-ontologyRid");
const scopes = [
"language-model-service:use-model",
// Other scopes your application requires, for example:
// "api:read-data",
// "api:use-ontologies-read",
];
export const auth: PublicOauthClient = createPublicOauthClient(
clientId,
foundryUrl,
redirectUrl,
{ scopes }
);
export const client: Client = createClient(foundryUrl, ontologyRid, auth);
export default client;
要在运行时获取访问令牌,请调用 auth.getTokenOrUndefined()。如果用户尚未登录,请先调用 auth.signIn() 然后重试:
typescript import { auth } from "../client";
let token = await auth.getTokenOrUndefined();
if (!token) {
await auth.signIn();
token = await auth.getTokenOrUndefined();
}
if (!token) {
throw new Error("Unable to obtain access token. Please try again.");
}
## 第 2 步:连接实时端点
> 要点:建立长连接。
实时端点在以下 URL 接受 WebSocket 连接,其中 是你 Foundry 环境的主机名(与 src/client.ts 中用作 foundryUrl 的值相同),而 model 查询参数用于选择要使用的实时模型:
Code wss:///language-model-service/ws/v1/open-ai/realtime?model=gpt-realtime-2
这是一个 Foundry 代理端点,类似于 REST LLM 供应商兼容 API,但通过 WebSocket 暴露。该代理会将会话转发到底层供应商(根据你的 enrollment,为 OpenAI Direct 或 Azure OpenAI),并保留供应商的原生实时协议。因此,你可以不加修改地使用 OpenAI 实时 SDK(@openai/agents/realtime)。
访问令牌作为 WebSocket 子协议值传递,因为浏览器无法在 WebSocket 连接上设置自定义的 Authorization 头。请将该子协议值格式化为 Bearer-。
将子协议值视为凭据 访问令牌作为 WebSocket 子协议值的一部分,在浏览器的开发者工具网络面板中可见。请将其视为凭据:不要记录它,不要在面向用户的字符串中暴露它,也不要将其传输到除你的 Foundry 端点之外的任何系统。访问令牌是短时效的;WebSocket 会话使用其建立时的令牌,因此长时间运行的会话可能需要在令牌过期时重新连接。
使用 OpenAI 实时 SDK 打开连接,并提供一个自定义的 createWebSocket 函数,用该子协议值构造浏览器的 WebSocket。完整的连接流程封装在一个名为 startVoiceSession 的 async 函数中,它在会话就绪后返回。该函数由三个小型具名组成部分构成,下面分别定义,并在本节末尾进行组合。将结果保存为例如 src/voice/session.ts。
首先从导入和常量开始:
typescript import {
RealtimeAgent,
RealtimeSession,
OpenAIRealtimeWebSocket,
} from "@openai/agents/realtime";
import { foundryUrl } from "../client";
const PROXY_URL =
`wss://${new URL(foundryUrl).host}/language-model-service/ws/v1/open-ai/realtime` +
`?model=gpt-realtime-2`;
const CONNECT_TIMEOUT_MS = 10_000;
定义 createTransport 来构造传输层。createWebSocket 回调用 bearer token 子协议构造浏览器的 WebSocket,并附加记录诊断信息的 error 和 close 处理器。useInsecureApiKey: true 标志会禁用 SDK 中仅针对浏览器的一项防护,该防护禁止使用非临时(non-ephemeral)的 OpenAI key。它在这里不适用,因为认证由 WebSocket 子协议处理,而不是由 OpenAI key 处理。
typescript function createTransport(token: string): OpenAIRealtimeWebSocket {
return new OpenAIRealtimeWebSocket({
url: PROXY_URL,
useInsecureApiKey: true, // auth is via the subprotocol below, not OpenAI's apiKey
// eslint-disable-next-line @typescript-eslint/no-explicit-any
createWebSocket: async ({ url }: { url: string }): Promise => {
const ws = new WebSocket(url, [`Bearer-${token}`]);
ws.addEventListener("error", () => {
console.error("WebSocket connection failed (check network tab for details)");
});
ws.addEventListener("close", (ev) => {
// 1000 = normal close, do not surface as an error.
if (ev.code !== 1000) {
console.error(`WebSocket closed: ${ev.code}${ev.reason ? ` (${ev.reason})` : ""}`);
}
});
return ws;
},
});
}
定义 createSession 来构造会话,包含音频输入/输出格式、服务端语音活动检测(server-side voice activity detection),以及一个内联转录模型,以便在对话进行时对用户的语音进行转录:
typescript function createSession(
agent: RealtimeAgent,
transport: OpenAIRealtimeWebSocket,
): RealtimeSession {
return new RealtimeSession(agent, {
transport,
model: "gpt-realtime-2",
tracingDisabled: true,
config: {
outputModalities: ["audio"],
audio: {
input: {
format: "pcm16",
transcription: { model: "whisper-1" },
turnDetection: {
type: "server_vad",
threshold: 0.8,
silenceDurationMs: 500,
prefixPaddingMs: 300,
},
},
output: { format: "pcm16" },
},
},
});
}
定义 awaitSessionReady 来等待会话变得可用。调用 session.connect() 会在会话能够收发音频之前就返回,因此要等待 session.created,然后等待第一个 session.updated 事件。其后的 200 毫秒延迟给 SDK 留出稳定的时间;没有它,早期的音频分块可能会丢失。如果会话未在 CONNECT_TIMEOUT_MS 内达到该状态,promise 会以超时错误被拒绝。apiKey 字段未被使用,因为认证由 WebSocket 子协议处理;SDK 只是要求一个非空字符串:
typescript function awaitSessionReady(session: RealtimeSession): Promise {
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error("Connection timeout"));
}, CONNECT_TIMEOUT_MS);
let created = false;
let updatedCount = 0;
session.on("transport_event", (ev) => {
if (ev.type === "session.created") {
created = true;
}
if (ev.type === "session.updated" && created) {
updatedCount++;
if (updatedCount === 1) {
setTimeout(() => {
clearTimeout(timeout);
resolve(session);
}, 200);
}
}
});
session.connect({ apiKey: "unused" });
});
}
最后,将三个组成部分组合为 startVoiceSession:
typescript export async function startVoiceSession(
agent: RealtimeAgent,
token: string,
): Promise {
const transport = createTransport(token);
const session = createSession(agent, transport);
return awaitSessionReady(session);
}
一旦你从步骤 1 获得了访问令牌并有了智能体定义(见步骤 3),就调用 startVoiceSession(agent, token)。该函数会在会话准备好收发音频时返回。
## 第 3 步:给智能体一个读 Ontology 的工具
> 要点:让语音助手能查业务数据。
上面的示例搭建了一个通用助手。要让它有用,需要给智能体提供从 Ontology 读取和写入数据的工具。OpenAI 实时 SDK 支持工具调用:定义一个工具,将其注册到智能体上,当模型判断自己需要该信息时就会调用该工具的 execute 函数。
工具的 execute 函数在浏览器中运行,使用用户的 OAuth 令牌和 OSDK client。模型从不直接接触 Ontology——它只看到工具返回的内容。由你决定要暴露哪些数据、要应用哪些筛选条件,以及要写回什么。
下面的示例展示了一个工具桩(stub)。请将函数体替换为你针对自己 Ontology 的 OSDK 查询。关于 OSDK 查询语法和示例,请参阅 TypeScript OSDK。
typescript import { RealtimeAgent, tool } from "@openai/agents/realtime";
import { z } from "zod";
import { client } from "../client";
const lookupProduct = tool({
name: "lookup_product",
description: "Look up a product by name. Use this when the user asks about a specific product.",
parameters: z.object({
name: z.string().describe("The product name to look up"),
}),
execute: async ({ name }) => {
// TODO: replace this stub with an OSDK query against your Ontology.
// For example, if your Ontology has a Product object type:
//
// const page = await client(Product)
// .where({ name: { $startsWith: name } })
// .fetchPage({ $pageSize: 5 });
// return JSON.stringify(page.data.map((p) => ({
// id: p.id, name: p.name, price: p.price, stock: p.stock,
// })));
//
return JSON.stringify({
id: "stub-1",
name,
price: 0,
stock: 0,
note: "Replace the tool body with an OSDK query against your Ontology.",
});
},
});
const agent = new RealtimeAgent({
name: "Assistant",
instructions:
"You help users find products. When the user asks about a product, call the lookup_product tool.",
tools: [lookupProduct],
});
将这个智能体传入步骤 2 中的 startVoiceSession(agent, token)。当用户说话时,模型会决定是否调用该工具。工具的 execute 函数在浏览器中针对 OSDK client 运行,结果会被回传给模型以生成回复。
工具也可以写入 Ontology。要做到这一点,请在工具的 execute 函数中调用一个 action。Actions 会经过标准的 Foundry 权限和校验路径。
## 第 4 步:串流麦克风音频并播放回复
> 要点:打通双向音频。
给定 startVoiceSession 返回的 RealtimeSession,接下来连接麦克风采集和音频播放。使用浏览器的 MediaDevices API 采集麦克风音频,将其转换为 24 kHz 的 16 位 PCM,并在各分块到达时通过 session.sendAudio(chunk) 将每个分块转发给会话。应用会将从会话接收到的音频分块排队以进行播放。
麦克风采集和播放队列的实现不在本教程范围内。用于接收音频的会话级连接方式大致如下:
typescript const session = await startVoiceSession(agent, token);
// Surface mid-session errors from the SDK. WebSocket-level transport errors
// (such as a failure to establish the connection) are logged to the console
// from the handlers in `createTransport`; if the connection never establishes,
// `startVoiceSession` rejects after `CONNECT_TIMEOUT_MS`.
session.on("error", (event) => {
console.error("Realtime session error:", event.error);
});
// Play back audio from the model
session.on("audio", (event) => {
playbackQueue.enqueue(event.data); // your playback implementation
});
// Clear playback when the model is interrupted (for example, the user starts speaking)
session.on("audio_interrupted", () => {
playbackQueue.clear();
});
// Send mic audio to the model as 16-bit PCM chunks at 24 kHz arrive
startMicCapture((pcm16) => session.sendAudio(pcm16)); // your mic capture implementation
// Optional: prompt the agent to greet the user immediately rather than
// waiting for the user to speak first.
session.sendMessage("(Session started. Greet the user briefly.)");
## 下一步
> 要点:继续完善的方向。
- Build out your application. 将会话接入你的前端,添加你的应用所需的工具,并在工具的 execute 函数中调用 OSDK 查询和 actions 以与 Ontology 集成。
- Improve agent instructions. 关于为实时模型编写有效指令的指引,请参阅 OpenAI 实时提示词指南 ↗。
### 常见问题速答 · FAQ
关于「构建支持语音的 OSDK 应用」,读者最常问的几个问题。
你将构建什么? 先明确目标产物。到本教程结束时,你将拥有一个在浏览器中运行的 TypeScript 应用,它可以。
前置条件是什么? 动手前的准备。在开始之前,请确保你具备以下条件。
第 1 步:获取 OAuth 访问令牌是什么? 鉴权准备。由 @osdk/create-app 生成的 OSDK 应用在 src/client.ts 中包含一个 OAuth client。该 client 使用来自 @osdk/oauth 的 createPublicOauthClient 创建,并暴露一个…
第 2 步:连接实时端点是什么? 建立长连接。实时端点在以下 URL 接受 WebSocket 连接,其中 是你 Foundry 环境的主机名(与 src/client.ts 中用作 foundryUrl 的值相同),而 model 查询参数用于选择…
---
## Realtime audio 总览:语音交互
- 页面:https://www.hanzhongpin.xyz/ontology/aip-realtime-audio-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/realtime-audio/overview/
- 主题分组:其他应用(四)
循序渐进 · AIP 教学 · 其他应用(四)
# Realtime audio 总览:语音交互
音频是通过 Ontology 与平台交互的一种模态:对话前后从本体拉取上下文,实时模型边听边转写,可选地回话并触发工具调用,结果再写回本体。
## 先记住这几条
① 音频是一种交互模态 和文字、图形并列。
② 上下文来自 Ontology 对话前和对话中都会拉取。
③ 能听、能转写、能回话 还能发起工具调用。
④ 结果写回本体 形成闭环。
## 写在前面
音频是通过 Ontology 与平台其余部分交互的一种模态。上下文会在对话之前和对话期间从 Ontology 中拉取,实时模型能够基于该上下文进行聆听、转录,并可选地回话和发起工具调用。结果会被写回 Ontology,在那里 functions、pipelines、AIP Logic、Workshop、actions 以及其他 Foundry 能力均可使用。
用例包括:
- Dictation(听写)。 单一说话者口述决策、观察或笔记。系统转录音频、抽取实体,并以说话者的权限将它们写入 Ontology。
- Meetings(会议)。 系统实时对多说话者的音频进行转录、说话人分离(diarize)并结构化为 Ontology 对象。
- Live call assistance(实时通话辅助)。 一名人工正在与客户通话。某个 Foundry 应用进行聆听、转录对话、向通话中的 Foundry 用户呈现相关的 Ontology 上下文,并在通话结束时将结果写回。
- Voice-controlled interfaces(语音控制界面)。 Foundry 用户通过语音下达命令,而无需手动导航——查询 Ontology、触发 actions 并以免手操作的方式导航工作流。
## 录音、转写与知情同意
> 要点:合规红线,开发者自己负责。
录音与知情同意由你负责 使用实时音频构建的应用会采集、转录或以其他方式处理人类语音。许多司法管辖区要求在录音开始之前告知参与者其将被录音或转录,其中一些还要求获得明确同意。无论参与者是应用用户、通话另一端的第三方,还是任何其他语音被采集的人,这可能都适用。遵守这些要求是应用开发者以及部署该应用的组织的责任。
在部署实时音频工作流之前:
- 核实应用将在其中使用的每个司法管辖区所适用的法律和监管要求。
- 在音频采集开始之前,将适当的告知和同意流程构建到应用中。
- 随应用一同记录你的同意立场与数据保留实践。
- 遵守你组织的内部政策、合规要求和法律义务。
你有责任在部署之前核实这些要求并获得必要的同意。
## 开始使用
> 要点:入门路径。
要构建你的第一个语音启用应用,请遵循教程:构建一个语音启用的 OSDK 应用。
## 可用模型
> 要点:实时场景能用哪些模型。
关于受支持的实时语音到语音(speech-to-speech)和转录模型列表,请参阅可用的音频模型。
### 常见问题速答 · FAQ
关于「Realtime audio 总览:语音交互」,读者最常问的几个问题。
录音、转写与知情同意是什么? 合规红线,开发者自己负责。使用实时音频构建的应用会采集、转录或以其他方式处理人类语音。许多司法管辖区要求在录音开始之前告知参与者其将被录音或转录,其中一些还要求获得明确同意。无论参与者是应用用户、通话另一端的第三方,还是任何其他语音被采集的人,这可能都适用。
如何开始使用? 入门路径。要构建你的第一个语音启用应用,请遵循教程:构建一个语音启用的 OSDK 应用。
可用模型是什么? 实时场景能用哪些模型。关于受支持的实时语音到语音(speech-to-speech)和转录模型列表,请参阅可用的音频模型。
---
## AIP Threads 快速入门
- 页面:https://www.hanzhongpin.xyz/ontology/aip-threads-getting-started.html
- 官方原文:https://www.palantir.com/docs/foundry/threads/getting-started/
- 主题分组:其他应用(七)
循序渐进 · AIP 教学 · 其他应用(七)
# AIP Threads 快速入门
一个简单的工作流教程:上传文档 → 与文档交互 → 与 AIP Chatbot 交互。
## 先记住这几条
① 从上传文档开始 把材料放进线索里。
② 先跟文档对话 针对具体材料提问。
③ 再引入聊天机器人 结合更广的能力继续推进。
## 写在前面
本教程将引导你完成一个简单的工作流:上传文档、与文档交互,以及与 AIP Chatbot 交互。
## 进入 AIP Threads
> 要点:入口位置。
AIP Threads 可以从平台的工作区导航栏访问,也可以使用快速搜索快捷键 CMD + J(macOS)或 CTRL + J(Windows)访问。
## 应用界面
> 要点:界面构成。
AIP Threads 界面可以分为两个主要组件,在下方示意性截图中从左到右编号:
- Threads navigation
- Thread interaction interface

> 图:AIP Threads 用户界面,突出显示了 thread 导航和 thread 对话元素。
## 工作流概览
> 要点:整体流程。
在典型的 AIP Threads 工作流中,你可以先在左侧面板(1)上选择一个先前的对话或开始一个新对话,然后使用右侧面板(2)与文档或 AIP Chatbots 交互。要与 AIP Chatbot 对话,只需从 Thread 配置下拉菜单(A)中选择一个,即可开始交互(C)。要与文档交互,上传文档并在 Document card(B)中选择文档,然后开始交互(C)。
## 左侧面板
> 要点:资源与线索管理。
以下小节将讨论可在左侧面板中配置的功能。
### Basic navigation
你可以创建新 thread、从现有 thread 中选择,以及删除 thread。
### Dark mode
你可以使用 thread 历史记录下方的选项调整视觉设置。

> 图:AIP Threads 深色模式截图。
### Minimize left panel
你可以使用以下按钮最小化左侧面板。

> 图:AIP Threads 截图,指示如何最小化左侧面板。
### Download
你可以使用 Export 选项下载对话内容(以 JSON 或 PDF 格式)。

> 图:AIP Threads 截图,指示如何最小化左侧面板。
## 上传文档
> 要点:第一步操作。
AIP Threads 目前支持原生(非扫描)的 PDF 文档。
要上传文档,请按 Documents 卡片中的 Upload 选项操作。

> 图:AIP Threads 截图,突出显示了右上角的 'Upload documents' 选项以及文档卡片中的 'Upload documents to AIP Threads' 选项。
在为文档存储位置选择一个 media set 之后,拖放要处理的文档。

> 图:上传文档对话框,可选择位置、media set 名称、ontology 以及 PDF。
## 与文档交互
> 要点:围绕材料提问。
使用 Select documents 选项将文档添加到 thread 的上下文中,以打开文档选择对话框。

> 图:通过 'Selecting documents' 或添加最近上传的文档,将文档添加到 Thread 的上下文中。
你现在可以开始 thread,向文档提问。

> 图:一个带有引用的答案。
### Document modes
AIP Threads 有两种文档模式:full document text(完整文档文本)和 relevant document chunks(相关文档分块,beta)。完整文档文本会抽取文档的全部文本,而相关文档分块只抽取语义上最相关的分块。
完整文档文本适用于简短精炼的文档,或当你需要 LLM 审阅全部内容时。对于较大的文档,或当你需要聚焦于特定章节或细节时,相关文档分块模式更高效。请记住,使用完整文档文本可能会导致上下文窗口受限。为避免超出 LLM 的上下文容量,请切换到相关文档分块模式。
> 使用相关文档分块模式时,默认的分块策略为每块 4096 个字符(约 1024 个 token)、分块重叠 512 个字符(约 128 个 token),并使用 Text embedding ada-002 作为嵌入模型。无权访问 ada-002 模型的 enrollment 可以使用其他嵌入模型。

> 图:AIP Threads 中可用的两种文档模式
### Citations
模型已被指示在每个答案中提供对原始文档的引用,用户应核实 LLM 的回复。引用应指向 PDF 文档中信息出处的相应页码。

> 图:引用滚动到相关页面。
如果你想更改 thread 上下文中的文档,可以创建一个新 thread 并重新选择感兴趣的文档,或者选择 Start new thread with current configuration,该选项可从本页后面定义的模型下拉菜单访问。

> 图:创建一个新 thread 并重新选择感兴趣的文档,或选择 'Start new thread with current configuration'。
## 线索配置
> 要点:定制这条线索的行为。
以下小节概述了可用的各种配置选项。
### Model mode
用户可以选择用于与文档交互的 LLM。你可用的模型是你的 enrollment 中已启用的模型的一个子集。
用户可以修改 system prompt(系统提示词),它是用自然语言写给 LLM 的指令。如果你想修改 system prompt,请记住 LLM 只能访问你明确提供给它的数据。在默认的 AIP Threads 体验中,这仅是你添加到 thread 中的文档。这与 AIP Chatbot Mode 不同。
用户可以修改 model temperature,以确定更聚焦、更确定性的输出(默认值为 0)与更随机的输出(最大值为 1)之间的平衡。

> 图:如何更改模型详情。
Upgrade a Thread configuration to an AIP Chatbot
如果你发现某个特定文档、一组文档,或某种模型与提示词的配置足够有价值,值得再次使用或与其他用户分享,你可以使用模型配置下拉菜单中提供的选项,将该 thread 配置升级为一个 AIP Chatbot。

> 图:通过选择 'Upgrade to an AIP Chatbot' 将 thread 配置升级为 chatbot。
这将带你前往 AIP Chatbot Studio,在那里你可以完成 chatbot 的配置。在 AIP Chatbot Studio 中发布并刷新 AIP Threads 后,你将能够再次在 AIP Threads 中与它交互。
### AIP Chatbot Mode
要选择一个 AIP Chatbot 进行交互,请使用下拉菜单。

> 图:如何选择一个 chatbot。

> 图:已选择一个 chatbot。
要将某个 chatbot 设为你在开始新 thread 时的默认选项之一,请将该 chatbot 设为默认。

> 图:一个被固定为新 thread 默认项的 chatbot。
### 常见问题速答 · FAQ
关于「AIP Threads 快速入门」,读者最常问的几个问题。
进入 AIP Threads是什么? 入口位置。AIP Threads 可以从平台的工作区导航栏访问,也可以使用快速搜索快捷键 CMD + J(macOS)或 CTRL + J(Windows)访问。
应用界面是什么? 界面构成。AIP Threads 界面可以分为两个主要组件,在下方示意性截图中从左到右编号。
工作流概览是什么? 整体流程。在典型的 AIP Threads 工作流中,你可以先在左侧面板(1)上选择一个先前的对话或开始一个新对话,然后使用右侧面板(2)与文档或 AIP Chatbots 交互。
左侧面板是什么? 资源与线索管理。以下小节将讨论可在左侧面板中配置的功能。
---
## AIP Threads 总览
- 页面:https://www.hanzhongpin.xyz/ontology/aip-threads-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/threads/overview/
- 主题分组:其他应用(六)
循序渐进 · AIP 教学 · 其他应用(六)
# AIP Threads 总览
AIP Threads 让你与文档、数据"对话":把资料放进来,围绕它提问、追问、推进工作,形成一条可持续的线索。
## 先记住这几条
① 以"线索"组织工作 不是一次性问答,而是持续上下文。
② 可围绕多种材料 文档、数据都能成为对话对象。
③ 目的是推进工作 不只是问答,而是完成事情。
## 写在前面
AIP Threads 需要 启用 AIP 和 AIP custom workflows。
AIP Threads 是一款面向企业的通用生产力工具,借助 LLM 的强大能力,让用户能够完成各种任务和临时分析。只要你的 enrollment 已启用 AIP custom workflows,与文档(例如 PDF)和 AIP Chatbots(原 AIP Agents)(配备企业特定信息和工具的交互式助手)交互就无需任何额外配置或技术专长。要开始使用 AIP Threads,只需将你的文档拖放到界面中、从你有权访问的先前上传的文档中选取,或选择一个你和你组织创建的 AIP Chatbot。

> 图:AIP Threads 主界面,展示了若干包含文档和 AIP Chatbots 的对话。所选的对话提出了一个技术问题,答案中包含对原始文档的引用。
AIP Threads 的文档交互能力非常适合对 PDF 进行快速、迭代式和跨语言的分析,从而帮助用户获得具体的答案、摘要或比较:
- Technical manuals(技术手册): 通过引用设备手册和指南,对技术查询提供快速解答。
- Vendor communication(供应商沟通): 从供应商合同和协议中抽取并总结关键细节。
- Mission briefings(任务简报): 总结任务报告和作战计划。
- Intelligence reports(情报报告): 从情报简报中快速抽取并总结关键信息。
- Policy documents(政策文件): 总结并解读法律文本和政策文件。
- Grant applications(资助申请): 协助整理和理解资助申请所需材料及合规文件。
- Public records(公共记录): 快速检索并总结公共记录和监管文件。
- Regulatory guidelines(监管指南): 总结监管文件中的要点和变化。
- HR policy retrieval(HR 政策检索): 轻松搜索一组 HR PDF 以找到特定信息,例如育儿假政策的细节,确保快速获取相关的员工福利和指南。
对于更重复且更复杂的工作流,我们鼓励你探索其他可能更适合你工作流的 AIP 功能。
AIP Threads 使用第三方大型语言模型(LLMs)来处理查询,符合 Palantir 的安全标准。请注意按照你组织的政策使用此工具。
请查阅入门指南开始与你的文档交互。
---
## Palantir AI Platform (AIP),从零到能上手
- 页面:https://www.hanzhongpin.xyz/ontology/aip.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/overview/
- 主题分组:AI 平台
AI Platform (AIP) · 循序渐进教学
-
循序渐进 · 教学系列 · AI 平台
# Palantir AI Platform (AIP),从零到能上手
84 篇教学网页,全部来自 Palantir Foundry 官方文档,按学习顺序编排、全文中文讲解。
每篇都保留原文截图与官方链接,零基础也能顺着读完。
84 篇教学页面
10 个学习模块
283 张原文截图
## 建议的学习路径
AIP 内容多,别乱翻。按这个顺序走,先建立全局,再深入应用。
先看清全局(模块一):AIP 是什么、有哪些能力、怎么管起来、安全与计费怎么算。
- 再解决模型从哪来(模块二):平台自带模型不够用时的四条接入路径。
- 然后上手核心应用(模块三):AIP Logic —— 最值得精读的一组,学会用 block 搭 AI 逻辑。
- 接着学会验证(模块四):AIP Evals,给不确定的 LLM 输出建立可信度。
- 做对话机器人(模块五、六):Chatbot Studio 与平台内置的 AIP Assist。
- 按需深入专项(模块七~九):文档抽取、对话式分析、会动手的智能体。
- 最后按需查阅(模块十):模型目录、语音、Threads 等。
模块 1
## 核心平台(AIP 总览与治理)
先搞懂 AIP 是什么、能做什么、怎么管起来。这组是全局认知,建议从头顺读。
01
### AIP 总览:把 AI 接进你的数据与运营
AIP(Artificial Intelligence Platform)不是孤立的模型平台,它长在你的数据与 Ontology 之上,目标是把 AI 变成可运营、…
1 张图4 个要点
02
### AIP 能力清单:平台各处的 AI 特性
平台里几乎每个应用都配备了 AIP 驱动能力。这一篇把它们按应用分类列全,作为你的能力索引表。
5 张图3 个要点
03
### 开始使用 AIP:学习路径
这一篇很短,只回答一个问题:该按什么顺序学 AIP。
3 个要点
04
### 提示词工程最佳实践
写提示词(prompt)这件事,直接决定 LLM 输出的质量。这一篇讲怎么写出稳定可靠的提示词,是所有 AI 应用的基本功。
4 个要点
05
### 平台支持的 LLM 清单
AIP 支持来自 xAI、OpenAI、Anthropic、Meta、Google 等提供商的多种 LLM 与文本嵌入模型。这一篇是选型参照表。
4 个要点
06
### 兼容各提供商的原生 API 端点
Foundry 为主流 LLM 提供商提供代理端点,按各提供商原生 API 的格式接收请求 —— 你可以继续用熟悉的开源 SDK,同时白拿平台的限流、数据保护能力。…
3 个要点
07
### AI 伦理与治理
Palantir 把负责任 AI 当作构建方式本身,而不是事后补丁。这一篇讲他们的伦理原则与治理机制。
3 个要点
08
### AIP 的安全与隐私
把 AI 接进企业数据,安全是第一道门槛。这一篇讲 AIP 如何保护客户数据的隐私与安全。
3 个要点
09
### AIP 的计算用量与计费
LLM 按 token 计费:输入文本和输出文本都要算钱。这一篇讲清用量从哪来、怎么算、怎么控。
3 个要点
10
### Ontology 与 AIP 的可观测性
AI 跑出问题了,怎么查?这一篇讲 Workflow Lineage 里的一组能力,让你看清每条 AI 流程的来龙去脉。
3 个要点
11
### 管理员:开启 AIP 能力
AIP 能力默认可能并未全部开启。这一篇是管理员的操作指南:在哪些界面、按什么顺序把能力开出来。
8 张图3 个要点
12
### 管理员:LLM 容量管理
LLM 容量在行业层面是有限资源,所有提供商都会限制账户的最大可用容量。这一篇讲 AIP 如何在组织内分配这份稀缺资源。
9 张图3 个要点
13
### 管理员:LLM 注册速率限制
这一篇是纯数值参照表:各注册层级在商业环境与政府环境下的 TPM(每分钟 token 数)与 RPM(每分钟请求数)上限。
3 个要点
模块 2
## 接入自己的模型(Bring your own model)
平台自带模型不够用?这组讲怎么把外部模型、自建模型接进来。
01
### 自带模型(BYOM):把外部模型接进 AIP
平台自带模型不够用?自带模型(Bring-your-own-model,BYOM)让你把自己的 LLM 或账号接进 AIP,成为一等公民资源。这一篇是总览与选路指南…
2 张图3 个要点
02
### 用 REST API 来源支撑模型
当你的模型暴露标准供应商 API时,通过 Data Connection 里的 REST API 来源接入是最省事的路径。
2 张图3 个要点
03
### 用 compute module 支撑模型
把 LLM 服务跑在 compute module 里,再注册给 AIP —— 这条路径适合需要自定义推理逻辑或私有部署的场景。
5 张图3 个要点
04
### 自托管模型
在自己的基础设施上跑开源或私有模型,数据完全不出环境。这篇说明自托管的做法与代价。
3 个要点
05
### 构建代理层或联邦层
代理层夹在 AIP 与外部模型供应商之间,让你精确控制哪些数据会离开你的环境,以及请求怎么转发。
3 个要点
模块 3
## AIP Logic(用积木搭 AI 逻辑)
AIP 的核心应用:用块(Block)把 LLM 串成可靠的业务流程。想上手 AIP,这组最值得精读。
01
### AIP Logic 总览:无代码搭 AI 函数
AIP Logic 是 AIP 的核心应用:在可视化环境里构建、测试、发布由 LLM 驱动的函数,无需写代码就能借助 Ontology 构建功能丰富的 AI 逻辑。…
1 张图4 个要点
02
### AIP Logic 核心概念
读懂这一页,后面所有 Logic 文档都会顺畅很多。这里把 block、prompt、tool、output 等关键概念一次讲清。
4 个要点
03
### AIP Logic 快速入门
这一篇带你实际走一遍:进入 AIP Logic、认识界面、组合 LLM block、在调试器里看 LLM 的思维链(chain of thought)。
16 张图4 个要点
04
### AIP Logic 的 block 全清单
Block 是 AIP Logic 的积木,每块都有特定用途:读写 Ontology、做计算、聚合数据、调用函数、与 LLM 交互。这篇是积木图鉴。
11 张图4 个要点
05
### 暂存写入(Staged writes)
让 AI 直接改你的 Ontology 太危险怎么办?暂存写入让改动先停下来等人审,通过后才落库。
2 张图3 个要点
06
### 在分支上开发 AIP Logic
AIP Logic 与 Global Branching 集成,让你在隔离的分支上安全地改 Logic 函数,改完再合并。
6 张图4 个要点
07
### 执行模式设置:用户作用域 vs 项目作用域
Logic 函数有两种执行模式,决定了"以谁的身份运行、数据权限从哪来" —— 这是个容易踩坑但很关键的选择。
1 张图3 个要点
08
### 用 Automate 自动化 AIP Logic
Logic 函数可以被自动化触发,让 Ontology 编辑自动落地,或先暂存等人工审核 —— 触发源可以是已有对象,也可以是新建对象。
4 张图3 个要点
09
### AIP Logic 的计算用量
Logic 函数跑一次,钱花在哪?这一篇把用量拆开算给你看,帮你预测成本、优化设计。
3 个要点
10
### AIP Logic 的指标
Logic 资源底层由函数支撑。这篇讲怎么看到成功/失败次数与 P95 执行时长,判断一个 Logic 函数是否健康。
2 张图3 个要点
11
### AIP Logic 常见问题
按问题组织的一页,适合当速查手册用。遇到具体疑问时先来这里翻一翻。
3 张图3 个要点
模块 4
## AIP Evals(给 AI 做测试)
LLM 输出不确定,怎么知道它变好了还是变坏了?这组讲评测套件的搭建与运行。
01
### AIP Evals 总览:给 AI 函数做测试
LLM 的输出是不确定的(non-deterministic),传统单元测试不够用。AIP Evals 是专门为此设计的测试环境:建测试用例、定评估标准、跟历史版本…
1 张图4 个要点
02
### 为 Logic 函数建立评估套件
Logic 的 Preview 面板适合一次性试跑;但要建立真正的信心,必须拿大量输入去测。这篇是入门路径。
7 张图3 个要点
03
### 创建评估套件
评估套件 = 测试用例 + 目标函数 + 评估函数。这篇讲怎么把它搭起来,包括同时测多个目标函数的做法。
12 张图4 个要点
04
### 用中间参数评估 block 输出
LLM 函数往往包含多个步骤,只看最终结果可能看不出是哪一步出了问题。这篇讲怎么评测中间 block 的输出。
1 张图3 个要点
05
### 评估 Ontology 编辑
测一个会写 Ontology 的函数,难道每次都要真改数据?不用 —— 每个测试用例在 Ontology 模拟环境里跑,真实数据毫发无损。
3 个要点
06
### 运行评估套件
套件可以从多个地方运行:AIP Logic 的 Evals 侧边栏、AIP Evals 应用。可以整跑,也可以只跑单个用例 —— 后者是调试的利器。
4 张图3 个要点
07
### 运行实验:系统对比参数组合
想知道哪个模型性价比最高、哪版提示词效果最好?用实验系统性地跑多个参数组合,而不是靠猜。
15 张图3 个要点
08
### 把运行结果写入数据集
Evals 界面不是给所有人用的。把结果写进数据集,就能在 Workshop 等应用里跟其他信息一起展示,让领域专家也能看到。
1 张图3 个要点
09
### 分析运行结果
结果视图告诉你:函数在各测试用例与评估标准上的表现具体如何。可以在 Evals 应用里看,也能在 Logic / Chatbot Studio 的侧边栏里看。
7 张图3 个要点
10
### 在指标仪表盘查看结果
把多次运行的结果收拢到一处,用图表和统计呈现,还能比较聚合结果或单个测试用例的表现。
3 张图3 个要点
模块 5
## AIP Chatbot Studio(做对话机器人)
从零搭一个有上下文、能引用、能调工具的聊天机器人。
01
### AIP Chatbot Studio 总览
想做一个懂你业务、能引用出处、能调工具的对话机器人?AIP Chatbot Studio(原名 AIP Agent Studio)就是干这个的。
2 张图4 个要点
02
### Chatbot Studio 核心概念
这页把搭建聊天机器人要用到的关键概念一次讲全:应用状态、检索上下文、工具、引用等。
4 个要点
03
### Chatbot Studio 快速入门
这一篇带你从零搭一个基础聊天机器人:认识界面、配置信息与工具,然后部署到生产并监控。
9 张图3 个要点
04
### 应用状态(Application state)
聊天机器人要记住会话里的信息,才能做多轮推理。应用状态就是它的"工作记忆"。
8 张图3 个要点
05
### 检索上下文类型(Context types)
机器人回答得好不好,八成取决于喂给它的上下文。检索上下文针对每一条新消息确定性地运行,把相关内容塞进模型。
8 张图4 个要点
06
### 引用(Citations)
回答要可信,就得能指出来源。配置了文档或 Ontology 上下文的机器人会输出引用,点击可跳回原始材料。
7 张图4 个要点
07
### 工具(Tools)
工具是外部功能或 API,让 LLM 能执行操作或获取自身不具备的信息。有了工具,机器人从"能说"变成"能做"。
3 张图3 个要点
08
### 把命令用作工具
平台里的命令(command)可以直接挂成机器人的工具 —— 用户一句自然语言,就能触发应用里的具体操作。
6 张图3 个要点
09
### 把聊天机器人发布为函数
发布为函数(Function)后,你的聊天机器人就能在平台里任何可执行函数的地方被调用 —— 复用性大幅提升。
7 张图3 个要点
10
### 会话日志
每次聊天机器人的执行都会被结构化成事件记录下来,可导出到流式数据集,用于监控与分析。
4 个要点
11
### 用 Marketplace 分发聊天机器人
把聊天机器人打包成产品,分发给别的团队/环境安装使用 —— 这是从"自己用"到"组织内复用"的一步。
3 个要点
12
### 通过 Foundry API 使用聊天机器人
要在 Foundry 平台之上自建应用?这一篇讲用 Palantir API 调起会话、发消息、拿回复。
3 张图3 个要点
模块 6
## AIP Assist(平台里的 AI 助手)
内置问答助手,以及怎么把你的私有文档喂给它。
01
### AIP Assist 总览:平台里的 AI 助手
AIP Assist 是内建在平台里的 LLM 支持工具:用自然语言问它怎么用 Palantir,实时拿到答案。它同时是"产品文档的对话式入口"。
3 张图4 个要点
02
### AIP Assist 最佳实践
同样一个助手,会问的人和不会问的人拿到的答案质量差很多。这一篇讲怎么高效跟它打交道。
3 个要点
03
### 用自定义内容源驱动 AIP Assist
官方文档回答不了你公司内部的问题。这一组讲怎么把私有文档接进去,让助手也能回答运营与流程类问题。
3 个要点
04
### 注册自定义内容源
这一步是把内部文档登记进平台,让 AIP Assist 能检索到它。用它可以加速工作流、改善新人上手、自动回答支持类问题。
7 张图3 个要点
05
### 把自定义内容源投递给用户
注册完还不够,要在 Control Panel 里配置它对哪些用户可见,才能真正用上。
7 张图3 个要点
06
### 部署由自定义源驱动的 AIP Chatbot
自定义内容源还能进一步变成独立的对话机器人(通过 AIP Chatbot Studio),面向特定场景提供聚焦的协助。
10 张图3 个要点
07
### 自定义内容源最佳实践
要让答案好,先得懂原理:AIP Assist 底层用的是检索增强生成(RAG)。这一篇从 RAG 机制反推内容该怎么写。
3 个要点
08
### AIP Assist 的应用集成
AIP Assist 不只是个浮窗,它与平台各应用有多处集成点,让你在具体应用里就能拿到针对性帮助。
8 张图3 个要点
09
### AIP Assist 的建议动作
助手会主动推荐"下一步可以做什么",包括导航类和操作类建议 —— 对新人尤其友好。
3 张图3 个要点
模块 7
## AIP Document Intelligence(读懂文档)
从 PDF/扫描件里抽取结构化信息,并部署成可复用的策略。
01
### AIP Document Intelligence 总览
企业里大量信息锁在文档里。AIP Document Intelligence 是 Foundry 中文档抽取的统一入口:打开文档、试验抽取策略、验证效果、再部署成批…
6 张图3 个要点
02
### 文档智能核心概念
搞清传统抽取与 LLM 驱动抽取的本质区别,才能选对策略。这一篇把概念讲透。
2 张图4 个要点
03
### 把抽取策略部署到 Python transform
验证好的策略可以部署成 Python transform,对媒体集里所有文档的所有页面跑批量抽取 —— 这是从"试验"到"规模化"的关键一步。
3 个要点
04
### 把抽取策略部署到 Python 函数
如果需要按需、单次抽取(而不是批量跑),部署成函数更合适。这篇给出操作路径与生成的代码。
1 张图3 个要点
05
### 文档转文本(Document-to-text)变换
这是底层能力:把多种格式的文档转成文本,并且保留版面结构(段落、标题、表格)。抽取质量的上限由它决定。
4 个要点
模块 8
## AIP Analyst(对话式分析)
用自然语言问数据,自动生成分析并沉淀成资源。
01
### AIP Analyst 总览:对话式分析
AIP Analyst 是面向智能体工作流的界面:用自然语言在 Ontology 上做即席分析,不用写查询、不用搭看板。
3 张图4 个要点
02
### AIP Analyst 的能力(工具)
AIP Analyst 靠工具(tool)来搜索、分析并呈现答案。工具在 Tools 菜单里按类别分组,可整体或单独启用/禁用。
1 张图4 个要点
03
### 使用 AIP Analyst
这一篇逐个介绍构成一次分析会话的功能与概念,让你知道界面上每个部分在做什么。
6 张图3 个要点
04
### 分析资源(Analysis resources)
一次有价值的分析不该用完就丢。把分析保存为 Compass 资源,就能回头再看、共享给协作者、并纳入项目管理。
2 张图3 个要点
05
### AIP Analyst 的计算用量
AIP Analyst 是智能体式应用:一个问题可能引发大量模型调用与 Ontology 查询。理解用量来源,才能预测成本、选对模型、设计高效分析。
3 个要点
06
### AIP Analyst 的 Workshop 微件
把 AIP Analyst 作为 Workshop widget 嵌进业务应用,用户在自己的工作界面里就能用上 AI 分析,还能精细控制数据访问与工具范围。
2 张图3 个要点
07
### 嵌入 AIP Analyst
通过 iframe 把 AIP Analyst 嵌到 Workshop 或 OSDK 应用里,并用 URL 参数做定制化。这篇列出可用参数。
3 个要点
模块 9
## AI FDE(让 AI 帮你操作平台)
对话式操作 Foundry 的智能体:模式、能力、安全边界与最佳实践。
01
### AI FDE 总览:会动手的智能体
AI FDE(AI-powered forward deployed engineer)是一个交互式智能体:你用自然语言下指令,它直接在 Foundry 里替你操作…
1 张图4 个要点
02
### AI FDE 界面与导航
这一篇概览 AI FDE 的界面、导航与可用控件,动手前先认清每个部分在哪、干什么。
7 张图3 个要点
03
### AI FDE 的模式与能力
AI FDE 用模式(mode)界定当前在做什么大类任务,用能力(capability)表示跨模式的细粒度技能。理解这两层,才用得准。
1 张图4 个要点
04
### AI FDE 的安全与治理
安全与治理是内建在 AI FDE 里的,因为它完全以你的身份和权限运行 —— 它不是独立服务账号,只是"换了个交互方式的你"。
4 个要点
05
### AI FDE 最佳实践
让智能体替你操作平台,如何既高效又不失控?这一篇给出实操建议。
4 个要点
模块 10
## 其他 AIP 应用
Evolve、Model Catalog、Realtime audio、Threads —— 按需查阅。
01
### AIP Evolve 总览
AIP Evolve 负责编排成群的 AI FDE 智能体,用于持续改进 Foundry 里的 AI 系统 —— 从"一个智能体帮你做事"升级为"一群智能体协同优化…
3 张图3 个要点
02
### AIP Model Catalog 总览
Model Catalog 是平台里所有模型资源的总目录:统一查看有哪些模型、各自状态如何、被谁在用。选型与治理都从这里入手。
3 张图3 个要点
03
### 模型弃用与迁移
模型供应商经常弃用模型,依赖它的工作流就会被打断。这一篇讲 Palantir 如何通知、如何用 Upgrade Assistant 帮你迁移到替代模型。
14 张图4 个要点
04
### Realtime audio 总览:语音交互
音频是通过 Ontology 与平台交互的一种模态:对话前后从本体拉取上下文,实时模型边听边转写,可选地回话并触发工具调用,结果再写回本体。
4 个要点
05
### 构建支持语音的 OSDK 应用
这是一篇动手教程:用 OSDK 把实时语音能力接进你自己的应用。注意 —— 录音与知情同意由你负责。
3 个要点
06
### AIP Threads 总览
AIP Threads 让你与文档、数据"对话":把资料放进来,围绕它提问、追问、推进工作,形成一条可持续的线索。
1 张图3 个要点
07
### AIP Threads 快速入门
一个简单的工作流教程:上传文档 → 与文档交互 → 与 AIP Chatbot 交互。
16 张图3 个要点
---
## 避开这 8 个本体设计反模式
- 页面:https://www.hanzhongpin.xyz/ontology/anti-patterns.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/ontology-anti-patterns/
- 主题分组:反模式(Anti-patterns)
循序渐进 · 教学 · 反模式(Anti-patterns)
# 避开这 8 个本体设计反模式
建模时最容易踩的坑,往往不是语法错,而是"看似合理、后患无穷"的结构选择。这一篇逐个拆解官方列出的 8 个反模式(anti-pattern),并带你做病例诊断。
## 一句话速览
避开这 8 个本体设计反模式:建模时最容易踩的坑,往往不是语法错,而是"看似合理、后患无穷"的结构选择。这一篇逐个拆解官方列出的 8 个反模式(anti-pattern),并带你做病例诊断。
1 反模式(anti-pattern) 反模式(anti-pattern)指一种"表面上解决了一个问题、实际上带来更大麻烦"的常见做法
2 切分现实 基于数据来源系统(而非实体本身)为同一个现实世界实体创建不同的对象类型
3 噪声与歧义 对象类型包含了来自外部系统、在本体语境中毫无业务关联的不必要列("everything but the kitchen sink")…
4 用错锤子 过度依赖单一工具解决所有问题
## 什么是反模式(anti-pattern)
它能跑、能存,但会把你拖进长期维护泥潭。
反模式(anti-pattern)指一种"表面上解决了一个问题、实际上带来更大麻烦"的常见做法。在本体设计里,它通常不是一个会报错的硬错误,而是一个结构性选型错误:建模者用看似合理的捷径,换来了碎片化、难维护、难扩展的本体。
官方文档明确列出了 8 个反模式,覆盖三类问题:实体怎么分(System Silos、Department Silos、God Object、Time Machine)、属性与名字怎么取(Kitchen Sink、Misnomer)、工具与动作怎么用(Golden Hammer、Action Sprawl)。
> 为什么重要:躲开这些反模式,你得到的本体才能准确代表业务领域、减少维护开销,并支撑跨职能的工作流。下一节我们就逐个开刀。
## 实体建模反模式(一):怎么切分现实
这 4 个反模式都出在"一个实体该不该被拆/被合并"上。
1
### The System Silos
系统孤岛 · 按来源系统拆同一个实体
病症
基于数据来源系统(而非实体本身)为同一个现实世界实体创建不同的对象类型。例如 HR 系统、门禁系统、项目管理工具里都有"员工",于是分别建了 HR System Employee、Badge System Employee、Project Management Employee。
危害
现实视图碎片化、动作/链接/应用要重复建多份、同一实体信息互相冲突、业务逻辑改动要在所有类型里重做。
处方
创建代表现实实体的单一对象类型,用数据管道(pipelines)把多源系统合并到统一后备数据集;用主键(如员工 ID)跨系统唯一标识,并定义冲突值的优先规则(如 HR 对职位名有权威性)。
2
### The Department Silos
部门孤岛 · 各部门各建一份
病症
不同部门为同一对象类型创建自己的版本,让本体映射了组织结构而非业务现实。例如销售建 Sales Customer、支持建 Support Customer、财务建 Billing Customer、营销建 Marketing Contact。
危害
没有单一真相源、跨职能工作流做不了、重复开发、治理噩梦(一个类型里的修复不会传播到其他类型)。
处方
创建服务多部门的共享对象类型,需要时用属性和链接捕获部门特定信息(如 Customer → Support Ticket);用受限视图控制属性可见范围。
3
### The God Object
上帝对象 · 一个类型装下所有实体
病症
单一对象类型被过度加载,代表多个不同的现实实体。例如一个 Asset 想装下卡车、软件许可证、房产、金融工具,甚至"员工作为人力资产",结果 150+ 属性,大多数为 null。
危害
语义混淆、稀疏数据(大量 null)、无法强制业务规则、搜索结果混杂、动作类型需要大量条件逻辑。
处方
为不同实体创建不同的对象类型;当实体确实共享特征时,用接口(interfaces)建模共享属性与行为。
4
### The Time Machine
时光机 · 把历史版本建成对象
病症
把实体的历史版本建模成独立的对象或对象类型,而不是用时间序列/快照/版本策略。例如同对象类型里放 Contract v1/v2/v3,甚至每年一个 Contract 2023/2024/2025 类型。
危害
对象数量爆炸、当前状态模糊(哪个是权威?)、链接到底链哪版含糊、跨时段报告要去重。
处方
每个实体用单一对象反映当前状态;历史变更存到单独的链接对象类型(如 Contract Amendment),或启用编辑历史、用时间序列属性。
## 属性与命名反模式(二):噪声与歧义
这 2 个反模式让本体"看得到、读不懂"。
5
### The Kitchen Sink
洗碗池 · 把无关列全倒进来
病症
对象类型包含了来自外部系统、在本体语境中毫无业务关联的不必要列("everything but the kitchen sink")。例如从 CRM 建 Customer 时把 _crm_extracted_at、_crm_sequence、last_etl_update_timestamp 等技术产物也暴露成属性。
危害
用户困惑、性能下降(索引变大、搜索变慢)、重要业务属性被技术元数据淹没。
处方
有意地策划属性:只保留业务含义清晰、对工作流有用的列(业务标识、可读属性、业务日期、用于筛选/动作的状态);ETL 元数据留在后备数据集,不暴露为属性。
6
### The Misnomer
名不副实 · 模糊误导的命名
病症
对对象类型、属性、链接类型使用模糊、通用或误导性的名字。例如对象类型叫 Item,属性叫 value、type、date,链接叫 Related Item——没人知道到底指什么。
危害
用户误解、学习曲线陡、文档变成必需且易过时、跨团队各解释各的。
处方
用具体、自解释的名字:模糊属性加限定(monetaryValue)、链接按关系命名(Supervisor)、建立命名规范并加描述。
## 工具与动作反模式(三):用错锤子
这 2 个反模式出在"能力选错、动作切太碎"。
7
### The Golden Hammer
黄金锤 · 一把锤子敲所有钉子
病症
过度依赖单一工具解决所有问题。俗话说"If all you have is a hammer, everything looks like a nail"(手里只有锤子,看什么都像钉子)。例如用动作类型算本可管道预聚合的指标、用管道做本该事件驱动的自动化、用函数实现本可 concat 的简单派生。
危害
触及工具上限、不必要的复杂度、把本可自动化的步骤推给用户、性能差、调试难。
处方
按用例选工具:批量/流处理用 pipelines;人类决策用 action types;事件驱动反应用 automations;跨多对象的复杂实时逻辑用 functions;循环编排用 schedules。用 automations 填补"变了 → 该发生什么"之间的空白,无需用户点按钮。
8
### The Action Sprawl
动作蔓延 · 一堆单属性动作
病症
创建大量范围狭窄、各改一个属性的动作类型,而不是设计有意义业务操作的 cohesive 动作。例如 Update Employee First Name、Update Employee Email……二三十个单属性动作。
危害
用户面对冗长动作列表、一次业务更新要多次提交、动作不映射真实流程、审计轨迹碎片化。
处方
围绕业务操作设计动作:把相关改动打包成有意义工作流(如 Transfer Employee),用动作参数容纳可选字段,以业务操作命名并加规则校验。
## 怎么识别反模式:常见症状信号
建模中一旦看到这些信号,立刻警觉。
- God Object 信号:大量属性频繁为 null;属性含义随另一个属性的值而变;你忍不住问"这到底是个什么对象?";业务规则需要大量基于"类型"的条件逻辑。
- System / Department Silos 信号:同一概念在本体里出现多个版本;改一处逻辑要在多处重复;跨团队对"客户/员工"说法不一。
- Kitchen Sink 信号:属性里混着 _etl_*、_received_at 之类技术时间戳;用户问"这列是干嘛的?"。
- Misnomer 信号:value、type、date 等无限定名满天飞;不同团队对同名解释不同。
- Action Sprawl 信号:单对象类型动作超 10 个;动作名形如 Set [Property];用户抱怨步骤太多。
- Golden Hammer 信号:什么都用动作/管道/函数一种工具;本可预计算却实时算。
- Time Machine 信号:对象类型里含 version/isCurrent;对象数随"变更次数"而非"实体数"增长。
> 一个心法:每当你想"先都留着/都建一份/都用一个工具",先问一句"这代表业务现实吗?"——反模式往往就藏在"图省事"里。
## 病例诊断室:这段建模犯了哪个反模式?
读病例,点"点我诊断 →"翻出病名与处方。
病例诊断室 · 点击翻出病名与处方
病例 1
某组织 HR、门禁、项目系统里都有员工,团队没建统一的 Employee,而是建了 HR System Employee、Badge System Employee、Project Management Employee 三个对象类型。
点我诊断 →
病例 2
一个 Asset 对象类型想代表"任何有价值的东西",装进了卡车、软件许可证、房产、金融工具甚至员工,150+ 属性,大多数对任何给定对象都是 null。
点我诊断 →
病例 3
从 CRM 建 Customer 时,把 _crm_extracted_at、_crm_sequence、last_etl_update_timestamp 等技术产物也暴露成了属性。
点我诊断 →
病例 4
需要一个"按地区总销售额"的仪表板指标,团队却建了一个由用户手动触发的动作 Calculate Regional Sales Totals 写回对象,而不是用管道预计算。
点我诊断 →
病例 5
为 Employee 建了 Update Employee First Name、Update Employee Email、Update Employee Department 等二十多个动作,每次换部门要连续提交好几个。
点我诊断 →
病例 6
追踪合同变更时,团队在同对象类型里放了 Contract v1/v2/v3 作为独立对象,每年还另开 Contract 2023/2024/2025 对象类型。
点我诊断 →
## 一页带走
① 反模式是结构坑 它不报错,却让本体碎片化、难维护;8 个反模式分三类。
② 实体切分 按实体而非系统/部门建类型;一个类型别装多种实体;历史用链接对象而非版本对象。
③ 属性与命名 只留业务属性、剔除 ETL 噪声;名字要具体自解释,别用 value/type/date。
④ 工具与动作 按用例选工具别万能锤;动作围绕业务操作打包,别切成单属性碎片。
### 常见问题速答 · FAQ
关于「避开这 8 个本体设计反模式」,读者最常问的几个问题。
什么是反模式(anti-pattern)? 反模式(anti-pattern)指一种"表面上解决了一个问题、实际上带来更大麻烦"的常见做法。在本体设计里,它通常不是一个会报错的硬错误,而是一个结构性选型错误:建模者用看似合理的捷径,换来了碎片化、难维护、难扩展的本体。
实体建模反模式(一):怎么切分现实? 基于数据来源系统(而非实体本身)为同一个现实世界实体创建不同的对象类型。例如 HR 系统、门禁系统、项目管理工具里都有"员工",于是分别建了 HR System Employee、Badge System Employee、Project Management…
属性与命名反模式(二):噪声与歧义是什么? 对象类型包含了来自外部系统、在本体语境中毫无业务关联的不必要列("everything but the kitchen sink")。例如从 CRM 建 Customer 时把 _crm_extracted_at、_crm_sequence、last_etl_…
工具与动作反模式(三):用错锤子是什么? 过度依赖单一工具解决所有问题。俗话说"If all you have is a hammer, everything looks like a nail"(手里只有锤子,看什么都像钉子)。
---
## 用本体驱动的应用把数据变成生产力
- 页面:https://www.hanzhongpin.xyz/ontology/applications.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/applications/
- 主题分组:应用(Applications)
循序渐进 · 教学 · 应用(Applications)
# 用本体驱动的应用把数据变成生产力
本体(Ontology)建好之后,靠哪些"开箱即用"的应用让它真正被人、被 AI 代理用起来?这一篇带你逐个认识 Foundry 里的对象感知应用,并学会为需求选对工具。
## 一句话速览
用本体驱动的应用把数据变成生产力:本体(Ontology)建好之后,靠哪些"开箱即用"的应用让它真正被人、被 AI 代理用起来?这一篇带你逐个认识 Foundry 里的对象感知应用,并学会为需求选对工具。
1 "对象感知应用"(object-aware applications) Foundry 里有一批应用是原生运行在本体层(Ontology layer)之上的
2 工作流风格与配置模型 探索式应用不需要构建者预配置,终端用户在数据进入本体后即可开箱即用;它们通常自带搜索、可视化、变换能力,让用户自己回答各种未预设的问…
## 什么是"对象感知应用"(object-aware applications)
先建立一句话心智模型:应用是长在本体之上的"界面层"。
Foundry 里有一批应用是原生运行在本体层(Ontology layer)之上的。它们不把数据当成一张张孤立的表,而是把每个"对象"(object)当成一等公民:你能搜索它、顺着链接走到相关对象、对对象做分析、还能把决策写回对象。
这些应用合起来构成一套"分析 + 运营"的平台,能服务从业务分析师到一线操作员的不同角色。换句话讲,本体是"企业如何被理解"的接口,应用是人和代理使用这个接口的入口。
> 记牢:应用本身不存业务数据,数据在本体(及其后备数据集)里。应用只是让人/代理方便地去发现、分析、操作这些数据。
"An Ontology is not simply a raw write-through of source systems. It is the interface through which people and agents understand the enterprise, investigate changing conditions, and make decisions."本体不只是源系统的直写镜像,而是人和代理理解企业、调查变化、做出决策的接口。
## 应用全景:8 个对象感知应用
先混个脸熟,下一节再用三个维度拆解它们的差别。
- Object Views:围绕某个对象的"个人主页",集中展示它的资料、关联对象、关键指标和相关应用/工作流。
- Object Explorer:即开即用的搜索与分析工具,用可视化方式探索本体里的任何对象。
- Quiver:用拖拽界面做高级分析与图表,支持时间序列,可发布为只读看板。
- Workshop:无代码搭出来的交互式应用/看板,贴合特定用户的固定工作流。
- Slate:更灵活、需要更多代码的复杂应用构建器,可直接读 Foundry 数据集。
- Carbon:把多个资源/应用拼成给运营人员的一站式工作区(workspace)。
- Map:在地理空间语境里把对象和其他数据叠加分析。
- Contour / Insight:通用分析应用(在"验证演练"里会再提到它们)。
应用 主要用途 工作流风格 配置模型
Object Views 发现(Discovery) 工作流专用 开箱即用
Object Explorer 发现 & 分析 探索式 开箱即用
Quiver 分析 & 看板 探索式 / 看板专用 开箱即用 / 可定制
Workshop 应用 & 看板 工作流专用 可定制
Slate 应用 & 看板(复杂) 工作流专用 可定制
Carbon 运营工作区 工作流专用 可定制
Map 地理空间 探索式 / 工作流专用 开箱即用
上表可对照原文的三维对比表阅读:每个应用都落在"用途 / 工作流风格 / 配置模型"三个轴线上。
## 三个维度看懂差异
选工具时,先问自己这三个问题。点开每层看说明。
维度一用途(Primary use case)
这个应用最擅长解决哪类问题?
用途决定了"它该出现在用户的哪段旅程里":是帮人找到信息(Discovery)、帮人回答问题(Analysis)、把分析变成只读看板(Dashboards),还是做成固定流程的运营应用(Applications)。
维度二工作流风格(Workflow style)
用户是自己探索,还是要人先搭好?
探索式(Exploratory):无需构建者预配置,数据进入本体后终端用户开箱即用、自己定义分析路径(如 Object Explorer、Quiver)。工作流专用(Workflow-specific):必须先由"构建者"在编辑模式里搭好,下游用户才能用(如 Workshop、Slate)。
维度三配置模型(Configuration model)
上线前要不要先投入搭建成本?
开箱即用(Walk-up usable):几乎零配置、立即可用、维护负担低(如 Object Explorer)。可定制(Customizable):需要构建者前期投入打造贴合特定流程的界面,代价是更高的持续维护成本,但换来"恰好解决问题"的体验(如 Workshop、Slate)。
> 窍门:当你拿不准用哪个,先定用途,再看"要不要先搭"(工作流风格)和"能不能接受搭建成本"(配置模型),三个维度一卡就清楚了。
## 四种主要用途(use cases)
把"用途"这一维展开,看清每个词背后的用户场景。
Discovery(发现) 帮用户找到对的信息或工作流。靠两类能力:策展式内容中心(落地页 / "360 视图")和搜索(关键词 + 顺着链接下钻)。
Analysis(分析) 帮用户回答从简单到极复杂的问题。路径是探索式的——用户自己定义,且高度迭代:一个问题引出下一个问题。
Dashboards(看板) 一组预配置、以只读为主的可视化,供更广人群做周期汇报或运营监控。图表多,但不如 Applications 那样可定制、可交互。
Applications(应用) 为特定用户群、解决特定问题的交互式运营界面。比看板复杂,常带工作流元素并捕获用户输入(如写回 writeback)。
易混:看板(Dashboards)和应用(Applications)都"可视化",但看板偏只读汇报,应用偏"带流程、收输入、写回"的运营操作。
## 工作流风格与配置模型
这一节把另两个维度讲透,正好对应"谁来搭、搭多少"。
探索式应用不需要构建者预配置,终端用户在数据进入本体后即可开箱即用;它们通常自带搜索、可视化、变换能力,让用户自己回答各种未预设的问题。Object Explorer 与 Quiver 主要属于这一类。Quiver 较特别:分析模式是探索式,但产出可发布为预配置的 Quiver 看板,变成工作流专用制品。
工作流专用应用必须先由"构建者"在编辑模式里搭好,下游用户才能用。Workshop 与 Slate 模块都如此——它们有两个用户群:搭界面的人和用界面的人。
配置模型描述"界面上线前必须配多少"。开箱即用(如 Object Explorer)几乎零配置、零维护;可定制(Workshop、Slate)需要构建者前期投入,换取恰好贴合需求的界面,但也带来更高维护成本。
"The drill measures how much work the Ontology performs on the participant's behalf."(设计验证里的一句话,同样适用于选应用:好的应用让本体替用户多干活,而不是让用户自己拼。)
## 场景匹配演练:这个需求该用哪个应用?
读题,凭直觉选,点选项立刻看解析。
## 一页带走
① 应用长在本体上 对象感知应用不存数据,只是人和代理使用本体接口的入口。
② 三维度选工具 用途、工作流风格、配置模型——先定用途,再看要不要先搭、肯不肯投入成本。
③ 探索式 vs 专用 Object Explorer/Quiver 开箱探索;Workshop/Slate/Carbon 要先由构建者搭好。
④ 看板 ≠ 应用 看板偏只读汇报,应用偏带流程、收输入、能写回的运营操作。
### 常见问题速答 · FAQ
关于「用本体驱动的应用把数据变成生产力」,读者最常问的几个问题。
一句话速览是什么? 用本体驱动的应用把数据变成生产力:本体(Ontology)建好之后,靠哪些"开箱即用"的应用让它真正被人、被 AI 代理用起来?这一篇带你逐个认识 Foundry 里的对象感知应用,并学会为需求选对工具。
工作流风格与配置模型是什么? 探索式应用不需要构建者预配置,终端用户在数据进入本体后即可开箱即用;它们通常自带搜索、可视化、变换能力,让用户自己回答各种未预设的问题。Object Explorer 与 Quiver 主要属于这一类。
---
## 不止 RAG:把「本体对象」喂给大模型
- 页面:https://www.hanzhongpin.xyz/ontology/augmented-generation.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/ontology-augmented-generation/
- 主题分组:本体增强生成 Ontology-Augmented Generation
循序渐进 · 教学 · 本体增强生成 Ontology-Augmented Generation
# 不止 RAG:把「本体对象」喂给大模型
本体增强生成(Ontology-Augmented Generation, OAG)讲的不是怎么调 LLM,而是怎么把最相关的业务上下文找出来、
再喂给它。这一篇梳理从基础语义搜索到进阶检索(HyDE、关键词排名、混合搜索)的整套打法。
## 一句话速览
不止 RAG:把「本体对象」喂给大模型:本体增强生成(Ontology-Augmented Generation, OAG)讲的不是怎么调 LLM,而是怎么把最相关的业务上下文找出来、再喂给它。
1 这一篇在讲什么 大语言模型(LLM)一旦配上业务专属上下文,威力巨大
2 真的还需要检索吗 原文给了一个常被忽略的提醒:随着新一代模型上下文长度变长,你可能根本不需要语义搜索,而是直接把完整上下文塞进 prompt
3 四步走 原文给出的「基础语义搜索」落地步骤很朴素
4 四种提效手段 原文观察到:如果你的 AIP 工具答不出本该在语料里找到的问题,多半是「检索」这步没把最相关上下文捞上来
## 这一篇在讲什么?
OAG 的核心难题不是「生成」,而是「找到对的上下文」。
大语言模型(LLM)一旦配上业务专属上下文,威力巨大。但原文一开篇就指出:面对一个任务,
第一步几乎总是找到该交给 LLM 的相关上下文——而这一步,往往是设计检索增强生成(Retrieval-Augmented Generation, RAG)系统里最难的部分。
Finding the relevant context is often the most challenging part of designing a retrieval augmented generation system.
找到相关的上下文,往往是设计检索增强生成系统里最具挑战性的一步。
这一篇给出若干「上下文检索」的常见思路。原文特别强调:没有唯一的最优解,
最佳方案高度依赖你的数据特点;但下面这些主题是个不错的起点,可以按需组合、裁剪。
>
为什么放在「本体」系列里:OAG 的「对象」指的就是本体(Ontology)里的对象类型(object type)与属性——
把检索结果挂到对象上,工作流才能直接用。这正是前面几篇铺垫的闭环。
## 先问一句:真的还需要检索吗?
上下文够短,直接整段塞进 prompt 反而更简单。
原文给了一个常被忽略的提醒:随着新一代模型上下文长度变长,你可能根本不需要语义搜索,
而是直接把完整上下文塞进 prompt。
With new model generations' increased context lengths, you may not need to use semantic search at all and can instead pass the full context in the prompt. For example, GPT-4o's 128k context window corresponds to 300+ pages of text.
随着新一代模型上下文长度增加,你可能完全不需要语义搜索,而可以直接把完整上下文放进 prompt。例如 GPT-4o 的 128k 上下文窗口相当于 300 多页文本。
所以原文的实用建议是:如果你的应用的完整上下文落在窗口上限之内,优先从「不搜索」开始。
只有当内容多到放不下、或需要精准定位某段时,才引入语义搜索与下面的进阶技巧。
## 基础语义搜索:四步走
分块 → 建带媒体引用的对象 → 做语义搜索 → Workshop 里看 PDF。
原文给出的「基础语义搜索」落地步骤很朴素:
步骤 1定一个分块(chunking)策略
把长文档切成合适的块
块太长会超出模型 token 限制;块太碎又会丢上下文。分块策略直接决定下游检索质量(呼应文档处理那一篇)。
步骤 2建 chunk 对象,带 media reference 属性
每个块对应一个本体对象,并挂上媒体引用
用 media reference(媒体引用)属性,让 chunk 能回溯到原始 PDF 的对应位置——方便后面在 PDF Viewer 里高亮。
步骤 3作为语义搜索工作流的一部分去检索 chunk
把 chunk 接入语义搜索
具体怎么生成嵌入、怎么写检索函数,留给本系列后面的「用官方模型 / 自定义模型做语义搜索」两篇展开。
步骤 4:在 Workshop 里使用 PDF Viewer 组件,并配置好相应选项,让检索结果能直接定位到原文。
## 进阶检索:四种提效手段
当基础方案答不上来时,从这四个里挑着加。
原文观察到:如果你的 AIP 工具答不出本该在语料里找到的问题,多半是「检索」这步没把最相关上下文捞上来。可选手段有四种:
手段 解决什么
HyDE
假设文档嵌入
不直嵌查询,而是先让 LLM 生成一段「假设答案」,再嵌入它——结构上更接近真答案,检索更准。
关键词排名搜索
Ranked keyword
领域语料上通用嵌入模型常水土不服;用 Object Storage v2 自带的「相关性」做排名搜索更稳。
查询增强
Query augmentation
把用户问题交给 LLM 预处理:去掉停用词、补同义词(enriching),或抽取核心诉求(extraction)。
混合搜索
Hybrid search
用 RRF(倒数排名融合)把「向量搜索」与「关键词搜索」的结果融合成一张列表。
### HyDE 长什么样?
原文举例:用户问「如何处理动物碰撞(animal collisions)理赔?」先让 LLM 产出一段假设章节,例如:
Animal Claims Management: General Terms:
Animal collision is commonly insured in fully comprehensive packages...
因为这段「假设答案」在结构上已经离真答案很近,它的嵌入也就更接近真正包含答案的那个 chunk——
于是语义搜索命中率更高。代码上,就是「先 GPT_4o.createChatCompletion 生成假设段,
再 TextEmbeddingAda_002.createEmbeddings 嵌入,最后做 nearestNeighbors」。
### RRF 怎么融合两个列表?
RRFscore(d) = Σ 1 / (k + r(d))
k 是正则项:k 越大,文档「出现在列表里」比「排第几」更重要。
r(d) 是文档在某列表中的排名。把多列得分相加即为总得分。
## 动手演示:一次提问背后检索了哪些对象
选一个问题,逐步展开 OAG 的检索流水线。
下面把「一次提问 → 拿到答案」拆成几步。点一个问题,再点「下一步」,看每一步背后到底在动哪些对象、做什么事。
这正对应原文说的——难点在检索,不在生成。
动手试试 · 提问背后的检索流水线
提问:如何处理鹿撞车理赔?
提问:德语质检表格的规则?
下一步 ▶
选一个问题,看 OAG 背后分几步检索并组装上下文。
说明:这是教学化的流水线示意(真实代码见原文 HyDE / 混合搜索示例)。重点是体会「检索相关对象 → 组装上下文 → 生成」这条主线。
## 该从哪开始?原文的建议
先跑通基础版,缺什么补什么,别一上来就全上。
面对这么多手段,原文的态度很务实:
Our recommendation would be to start with the basic implementation, and then add features as it becomes necessary.
我们的建议是先做基础版本,然后在确有必要时再加功能。
- 先从基础四步跑通一个能用的搜索。
- 如果发现答不出本该能答的问题,先排查「检索」是否漏掉了相关上下文。
- 再按需叠加:比如只加 HyDE + 语义分块就够,其余先不动。
- 领域语料水土不服时,先用关键词排名搜索(简单、开箱即用),再考虑微调自定义模型。
>
对应到本系列:基础四步用到的「生成嵌入 / 写检索函数」会在下两篇(官方模型、自定义模型做语义搜索)具体落地;
这里你只需先建立「检索是难点、按需叠加」的大局观。
## 一页带走
① 难点在检索 OAG 的核心是把最相关上下文找出来,再喂给 LLM。
② 够短就不搜 上下文放得进窗口(如 128k≈300+页),优先直塞 prompt。
③ 四步打底 分块→带媒体引用的对象→语义检索→PDF Viewer。
④ 按需叠加 HyDE/关键词排名/查询增强/混合搜索,缺啥补啥。
### 常见问题速答 · FAQ
关于「不止 RAG:把「本体对象」喂给大模型」,读者最常问的几个问题。
这一篇在讲什么? 大语言模型(LLM)一旦配上业务专属上下文,威力巨大。但原文一开篇就指出:面对一个任务,第一步几乎总是找到该交给 LLM 的相关上下文——而这一步,往往是设计检索增强生成(Retrieval-Augmented Generation, RAG)系统里最难的部分…
先问一句:真的还需要检索吗? 原文给了一个常被忽略的提醒:随着新一代模型上下文长度变长,你可能根本不需要语义搜索,而是直接把完整上下文塞进 prompt。
基础语义搜索:四步走是什么? 原文给出的「基础语义搜索」落地步骤很朴素。
进阶检索:四种提效手段是什么? 原文观察到:如果你的 AIP 工具答不出本该在语料里找到的问题,多半是「检索」这步没把最相关上下文捞上来。可选手段有四种。
---
## 分支动作(Branching action types)
- 页面:https://www.hanzhongpin.xyz/ontology/branching-action-types.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/branching-action-types/
- 主题分组:动作类型详解
动作类型详解
# 分支动作(Branching action types)
想试跑一个动作又怕改坏生产数据?分支(branching)让动作在隔离环境里运行与验证,合入 main 前绝不污染生产。这一篇讲清怎么用。
## 什么是分支动作(branching action)
本体动作与 Global Branching 集成,让你在分支上"安全地试"。
本体(Ontology)动作与全局分支(Global Branching)集成,让你能在分支(branch)上测试动作类型,而不影响生产环境。你可以在合入 main 之前,先在隔离的分支上下文里运行动作、校验配置、观察编辑结果。
"Ontology actions integrate with Global Branching, enabling you to test action types on a branch without affecting your production environment."本体动作与全局分支集成,使你能够在分支上测试动作类型,而不影响生产环境。
铁律:分支上的动作编辑仅供测试,不会被合并回 main 。分支上产生的编辑不会随合并进入生产。
## 在分支上运行动作
要跑得起来,有一个前置条件:相关对象类型必须先"建索引"。
前置相关对象类型必须已建索引
动作修改的所有对象类型,都要在该分支上完成索引(index)。
可以在单个对象类型页面,或在 Ontology Manager 的动作类型页面为相关对象类型建立索引。若动作修改了尚未建索引的对象类型,编辑动作类型时会出现警告。
未就绪索引未完成就运行 → 编辑不被应用
动作有效,但写不进去,只弹提示。
如果对象类型尚未建索引就运行动作,动作不会应用其编辑。提示(toast)会说明:动作有效,但它编辑的某些对象类型在分支上是只读的,并链接到 Ontology Manager 让你先建索引再重跑。
> 提示:在分支的 Workshop 模块里试跑动作,是验证配置是否正确的最常用方式。但请始终记住:分支上的编辑不会合并回 main。
## 函数后端动作与"分支感知"
函数后端(function-backed)动作在分支上的行为,取决于它是否"分支感知"。
BRANCH-AWARE · 分支感知
分支感知函数
可在分支上被修改。
从分支读取 schema。
仍在分支上执行,不写回 main。
vs
NON-BRANCH-AWARE
非分支感知函数
不能在分支上被修改。
只从 main 读取 schema。
同样只在分支执行,不写回 main。
> 提示:无论是否分支感知,所有函数后端动作都只在分支上执行,不会把改动写回 main。支持的函数类型见 Global Branching 文档。
## 管理分支上的副作用(side effects)
默认情况下,分支上"什么外部动作都不发生"——这是安全设计。来亲手感受一下。
互动实验:分支上跑动作,外部系统会被碰到吗?
> 你在分支上执行一个带 webhook 的动作。默认分支上 webhook 不执行。
在分支启用 webhook 执行
在分支运行动作
重置
>
三类副作用在分支上的默认行为(点击每行右侧匹配):
注意:一旦在分支上"开启"这些副作用,它们会完全像在 main 上一样执行 ——如果 webhook 配置打向生产外部环境,即使在分支运行也会打到生产。开启前务必想清楚。
## 要点小结
确认你真正理解了分支动作的边界。
点击揭晓:在分支上开启 webhook 后,如果它本就指向生产外部系统,会发生什么?
点击这里揭晓 →
## 一页带走
① 分支 = 安全沙盒 在分支测试动作,不影响生产,编辑不合并回 main。
② 前置:建索引 动作修改的对象类型都需在分支上建索引,否则编辑不应用。
③ 函数分支感知 分支感知函数可在分支改、读分支 schema;都只在分支执行。
④ 副作用默认关闭 webhook / 外部调用 / 通知默认不执行;开启则照打生产。
---
## Management & enablement(管理与赋能)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-administration.html
- 官方原文:https://www.palantir.com/docs/foundry/administration/overview/
- 主题分组:平台模块(十一)
循序渐进 · 教学 · 平台模块(十一)
# Management & enablement(管理与赋能)总览
平台提供完整的治理与管理能力,集中在 Control Panel 这个统一入口:注册管理、认证、资源管理、平台体验配置。
## 先记住这几条
① Control Panel 是统一入口 治理与管理的集中界面。
② 管理注册与认证 enrollment 与 authentication 是管理员的核心职责。
③ 资源与体验也要管 资源配额、平台体验配置同属管理范畴。
## 写在前面

> 图:admin overview
Palantir 平台提供了一套完整的治理与管理能力,集中在一个名为 Control Panel(控制面板) 的统一界面中。平台将安全、资源管理、用例生命周期和审计能力整合到一个可以跨不同实施一致套用的共享基础之上。除核心治理外,这也使得企业级数据架构(包括「数据网格 data mesh」和「数据织体 data fabric」范式)能够规模化落地。无论在集中式还是联邦式模型下,Palantir 在管理、运营与赋能上的做法都能消除「安全」与「丰富协作」之间长久以来的取舍矛盾。
## Control Panel
Control Panel
> 要点:统一的管理控制台。
所有管理工作流都可以在 Control Panel 中完成——这是 Palantir 用于管理平台的统一界面。你可以从 Workspace 侧边栏中选择 Open other workspaces(打开其他工作区) 来访问 Control Panel。
## 配置与管理注册
配置与管理注册
> 要点:环境/注册的开通与管理。
Palantir 的「enrollment(租户/注册实例)」被定义为由平台管理员管理的一个或多个「Organizations(组织)」。每一项管理职能都可以映射到既有的治理实现(例如 Active Directory),并在既有用户组与具体角色之间建立细粒度映射。完整的管理任务范围都可以通过 Control Panel 进行定义、联邦化与实施。
进一步了解如何管理 enrollment。
## 认证
认证
> 要点:身份认证体系的配置。
对 Palantir 平台的访问通过已注册的identity provider(身份提供方)管理,它既负责用户校验,也提供驱动平台各处安全控制所需的任意属性。Palantir 采用 SAML 2.0 开放标准,并提供了直观的机制,将元数据属性映射到平台内管理的用户属性。随着组织对 Palantir 平台的使用范围扩大、甚至可能扩展到外部合作伙伴的 Organization,可以持续接入并管理更多的身份提供方。
进一步了解身份认证。
## 资源管理
资源管理
> 要点:资源配额与分配。
Palantir 为管理员提供全面的资源管理工具,使他们能够理解并管理平台资源的使用情况。这套能力确保可执行的、细粒度的指标可以回溯到具有语义含义的账户、项目甚至单个资源。用量可见性工作流提供了以项目为视角的资源开销透镜;而资源分配工作流则允许管理员定义项目如何消费共享资源——并可在需要时对该消费设置上限。
进一步了解资源管理。
## 平台体验
平台体验
> 要点:面向使用者的体验配置。
Palantir 提供了一系列配置选项,用于在用户体验层面实现组织一致性与聚焦。这包括可配置的工作区,它能把平台全部应用筛选为一个子集,以贴合特定团队或用户类型的需求。用户的落地页、平台 Logo 及其他资源也可以被定制,确保 Palantir 平台原生融入更广义组织的视觉风格与品牌。
进一步了解如何定制平台体验:
- 配置平台体验设置
- 配置工作区
### 常见问题速答 · FAQ
关于「Management & enablement(管理与赋能)总览」,读者最常问的几个问题。
Control Panel是什么? 统一的管理控制台。所有管理工作流都可以在 Control Panel 中完成——这是 Palantir 用于管理平台的统一界面。你可以从 Workspace 侧边栏中选择 Open other workspaces(打开其他工作区)来访问 Control Pa…
配置与管理注册是什么? 环境/注册的开通与管理。Palantir 的「enrollment(租户/注册实例)」被定义为由平台管理员管理的一个或多个「Organizations(组织)」。
认证是什么? 身份认证体系的配置。对 Palantir 平台的访问通过已注册的identity provider(身份提供方)管理,它既负责用户校验,也提供驱动平台各处安全控制所需的任意属性。
如何资源管理? 资源配额与分配。Palantir 为管理员提供全面的资源管理工具,使他们能够理解并管理平台资源的使用情况。这套能力确保可执行的、细粒度的指标可以回溯到具有语义含义的账户、项目甚至单个资源。
---
## AIP(人工智能平台)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-aip.html
- 官方原文:https://www.palantir.com/docs/foundry/aip/overview/
- 主题分组:平台模块(一)
循序渐进 · 教学 · 平台模块(一)
# AIP(人工智能平台)总览
AIP 把 AI 与你的数据和运营连接起来,用于驱动业务流程自动化。这一篇讲它的六个特性:无缝集成、安全治理、模型管理、可扩展性、可解释性。
## 先记住这几条
① AIP 连接 AI 与运营数据 不是孤立的模型平台,而是长在本体之上。
② 安全与治理内建 AI 的使用受平台既有权限与治理体系约束。
③ 模型统一管理 模型的接入、版本、使用集中管理。
④ 强调可解释 AI 的决策要能追溯、能解释。
## 写在前面

> 图:AIP header image.
Palantir 的人工智能平台(AIP)将 AI 与你的数据和运营连接起来。AIP 旨在驱动运营流程的自动化,提供一套完整的工具,供组织内所有人使用——从开发者到一线用户。
AIP 的构建工具,如 AIP Logic、AIP Chatbot Studio(前身是 AIP Agent Studio)和 AIP Evals,让你能够基于 Ontology 与开发者工具链,开发出可用于生产的 AI 工作流、智能体和函数。此外,AIP 通过让受沙箱保护、自动扩缩容的应用在既有的安全、审计和资源管理框架内无缝集成生成式 AI,从而改造了应用环境。
AIP 与 Foundry(Palantir 的数据运营平台)以及 Apollo(Palantir 用于自主软件部署的「任务控制台」)一起,构成了一个操作系统,可以交付从 LLM 驱动的 Web 应用到使用视觉-语言模型的移动应用、再到嵌入本地化 AI 的边缘应用等全方位的 AI 驱动产品。
本页其余部分简要概述 AIP 的关键优势。关于 AIP 能力的更多细节,建议查阅 AIP 文档,包括 AIP 应用参考。想动手练习,可在 learn.palantir.com ↗ 上学习课程「Speedrun:你的第一个 AIP 工作流」↗。
## 无缝集成
无缝集成
> 要点:与本体、应用、工作流的集成方式。
Palantir AIP 可以与你组织在 Foundry 租户上的既有数据无缝集成。这让你能够构建并交互由 LLM 驱动的智能体和工作流,它们可以利用来自各种数据源和格式的数据。
## 安全与治理
安全与治理
> 要点:AI 场景下权限与合规如何保证。
AIP 纳入了 Palantir 所有先进的安全措施,以在符合行业法规的前提下保护敏感数据。AIP 提供强大的访问控制、加密与审计能力,以维护数据的完整性与透明度。此外,内置的治理工具帮助组织在使用 AI 的过程中保持问责制与历史血缘。
想进一步了解平台内 LLM 如何安全地处理用户提示,可通过选择 Palantir AIP FAQs 查阅 《常见问题:Palantir AIP 利用第三方托管的 LLM 的安全与隐私》↗。
## 模型管理
模型管理
> 要点:模型生命周期管理。
AIP 提供了一套完整的工具,用于构建、训练和部署大语言模型。支持多种不同的大语言模型,让数据科学家和工程师能够使用自己偏好的工具,并为每个用例挑选最合适的模型。此外,AIP 提供版本控制与协作功能,使团队能在模型全生命周期内高效管理模型。
## 可扩展性与性能
可扩展性与性能
> 要点:规模化的能力支撑。
AIP 专为处理大规模数据操作而设计,确保 AI 模型能够根据组织需求部署和扩展。平台的架构支持分布式计算,从而实现高性能处理和实时分析——这对关键任务型应用至关重要。AIP 还提供对资源使用和限额设置的细粒度控制。
想进一步了解帮助开发者监控并优化所构建智能体与应用性能的工具,请查阅 Ontology 与 AIP 可观测性文档。
## 可解释性与透明度
可解释性与透明度
> 要点:AI 结果要能解释,这是企业落地的关键。
在构建面向生产部署的 AI 工作流时,信任至关重要;而对 LLM 而言,信任来自可解释性与透明度,也来自严格的评估。AIP 提供生成详细审计轨迹、模型决策解释与评估的工具,帮助用户理解并信任结果。这种信任对组织安全地在现实场景中部署 AI、并基于 AI 洞察做出知情且符合伦理的决策,至关重要。
***
注意:AIP 功能的可用性可能发生变化,不同客户之间也可能存在差异。
### 常见问题速答 · FAQ
关于「AIP(人工智能平台)总览」,读者最常问的几个问题。
无缝集成是什么? 与本体、应用、工作流的集成方式。Palantir AIP 可以与你组织在 Foundry 租户上的既有数据无缝集成。这让你能够构建并交互由 LLM 驱动的智能体和工作流,它们可以利用来自各种数据源和格式的数据。
安全与治理是什么? AI 场景下权限与合规如何保证。AIP 纳入了 Palantir 所有先进的安全措施,以在符合行业法规的前提下保护敏感数据。AIP 提供强大的访问控制、加密与审计能力,以维护数据的完整性与透明度。
如何模型管理? 模型生命周期管理。AIP 提供了一套完整的工具,用于构建、训练和部署大语言模型。支持多种不同的大语言模型,让数据科学家和工程师能够使用自己偏好的工具,并为每个用例挑选最合适的模型。此外,AIP 提供版本控制与协作功能,使团队能在模型全生命周期内高效管理模型。
可扩展性与性能是什么? 规模化的能力支撑。AIP 专为处理大规模数据操作而设计,确保 AI 模型能够根据组织需求部署和扩展。平台的架构支持分布式计算,从而实现高性能处理和实时分析——这对关键任务型应用至关重要。AIP 还提供对资源使用和限额设置的细粒度控制。
---
## Analytics(分析)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-analytics.html
- 官方原文:https://www.palantir.com/docs/foundry/analytics/overview
- 主题分组:平台模块(八)
循序渐进 · 教学 · 平台模块(八)
# Analytics(分析)总览
Foundry 为组织中每种角色的用户提供分析能力,并且与本体深度集成:既有点选式也有代码式的分析工具。
## 先记住这几条
① 面向所有角色 从业务人员到数据科学家都有对应工具。
② 与本体集成 分析直接建立在本体之上,不用另建一套语义。
③ 点选与代码两种路径 低门槛与高自由度并存。
## 写在前面

> 图:分析能力概览
Foundry 为组织里每种类型的用户都提供分析能力,并且与 Foundry 本体深度集成。开箱即用的既有点选式工具,也有代码式工具,可以做表格式分析、自上而下的可视化分析、地理空间分析、时序分析等等。Foundry 里的分析不止于传统的"只读"范式 —— 它还能把数据写回本体,从而在统一的安全、血缘和治理模型之下产出有价值的新洞察。
## 核心应用
核心应用
> 要点:平台提供的主要分析应用。
Foundry 的核心分析应用包括:
- Contour —— 自上而下的分析应用,用于快速大规模探索表格数据、通过可视化变换派生新数据集、制作图表。
- Quiver —— 多模态图表应用,支持对象驱动分析、时序驱动分析、点选式机器学习,以及搭建仪表盘。
- Code Workbook —— 融合数据工程与数据科学范式的应用,可以用 Python、R 或 SQL 快速构建数据变换、训练机器学习模型等等。
- Notepad —— 一体化方案,把 Foundry 里各种动态的分析、可视化和运营产物,和排版文本、媒体嵌在一起。
- Fusion —— 电子表格形态的应用,把表格计算与 Foundry 本体及对象驱动查询系统的能力结合起来。
## 分析连接
分析连接
> 要点:与外部分析工具(如 BI)的连接能力。
Foundry 还设计成能与你现有的分析工具深度集成。组织可以通过标准 API 和接口,把自己的商业智能、可视化及其他分析应用接到 Foundry 上。集成方式包括:
- 常见工具的开箱连接器,比如 Power BI® 和 Tableau 。
- 用于临时取数的 REST API 。
- 用于通用连接的 ODBC 与 JDBC 驱动 。
- 面向数据科学工具的 Python ↗ 和 R ↗ SDK。
- 面向 Microsoft Report Builder、Excel 这类工具的引导式集成,基于标准接口实现。
进一步了解在 Foundry 里可以做的分析类型。
Power BI® 及 Power BI® 标识是微软集团公司的商标。
---
## Use case development(业务应用开发)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-app-building.html
- 官方原文:https://www.palantir.com/docs/foundry/app-building/overview/
- 主题分组:平台模块(六)
循序渐进 · 教学 · 平台模块(六)
# Use case development(业务应用开发)总览
平台为各类构建者提供应用搭建与工作流管理能力:Workshop、OSDK React、自定义组件、Slate,以及 Automate、Carbon 等工作流工具。
## 先记住这几条
① 两条主线 应用搭建(Application building)与工作流搭建管理。
② Workshop 是主力 低代码应用搭建的主要工具。
③ 也能写原生代码 OSDK React 与自定义组件满足定制需求。
④ 工作流有专门工具 Automate、Carbon、Workflow Lineage 覆盖自动化与编排。
## 写在前面

> 图:Application building header image.
Palantir 平台旨在用一套强大的用例开发工具,赋能多元化的构建者群体,这些工具包括应用构建工具、工作流构建工具、集成的分析工具,以及开发者工具。它们各自利用 Foundry 核心的安全、血缘、数据与计算原语,让团队专注于交付运营能力,而非管理基础设施。Palantir 平台中的每种工具都被设计成持续、安全地丰富 Ontology 内一致的数据与逻辑资产集合。这让知识能够随着运营工作流在企业内规模化而不断累积。关于在构建之前如何选择与界定用例的范围,请在 Palantir Learning 门户上查阅 为 Foundry 与 AIP 界定用例范围 ↗。
## 应用搭建
应用搭建
> 要点:Workshop、OSDK React 应用、自定义组件、Slate、Code Workspaces 应用。
Palantir 平台提供多种方式构建应用,以适应不同需求:
- Workshop 是一个无代码、面向对象的运营应用构建器,是将对象、链接与动作转化为交互式工作流最快的方式。
- OSDK React 应用 让你用 React 构建完全自定义的用户界面,由 Ontology SDK (OSDK) 驱动,适用于内置工具之外所需的体验。Pilot 提供了一种流畅的、由 AI 驱动的方式,从自然语言提示构建这些 OSDK 应用。
- 自定义组件(Custom widgets) 让技术构建者用自定义前端代码扩展 Workshop,无需从零构建独立应用即可添加定制功能。
- Slate 是一个低代码、拖拽式的构建器,用于运营应用、交互式仪表盘与自定义落地页,可使用 HTML、CSS 与 JavaScript 进行可选定制。
- Code Workspaces 应用 让你从第三方 IDE 构建并发布交互式的 Streamlit、Dash 与 Shiny® 应用,由 Foundry 数据与治理支撑。
### Workshop
Workshop 是一个灵活、面向对象的的应用构建工具。Workshop 利用 Ontology 中的语义原语(如对象与链接)与动能原语(如动作与函数),实现交互式 Web 与移动应用的快速交付。Workshop 中的应用构建体验让用户能够用无代码、低代码与基于代码的组件创建强大的应用。开始用组件构建、并将对象、链接与动作编织进用户驱动的工作流,无需任何技术专长,这些工作流远不止仪表盘或被动可视化。与此同时,基于代码的、借助函数的丰富能力,可以无缝嵌入 Workshop 组件,以实现复杂的交互、级联流程与复杂的数据采集。当工作流需要内置组件之外的功能时,你可以用自定义组件扩展一个 Workshop 应用,在不离开 Workshop 的情况下添加定制的、基于代码的组件。
进一步了解 Workshop。
### OSDK React applications
OSDK React 应用让你用 React ↗ 构建完全可定制用户界面,由 Ontology SDK (OSDK) 驱动,并通过 Developer Console 创建。通过将 Foundry 视为你的后端,你可以将 React 生态与 Ontology 的大规模查询、编辑及细粒度治理控制结合起来,安全地交付定制应用。要在不从代码开始的情况下构建 OSDK React 应用,Pilot 提供了一种流畅、由 AI 驱动的经历,它从自然语言提示生成 Ontology 实体、设计与前端,并引导你完成部署。
进一步了解 OSDK React 应用。
### Custom widgets
自定义组件(Custom widgets) 让技术构建者用自定义前端代码安全地扩展 Workshop 应用。你无需从零构建独立应用,就可以实现开箱即不支持的功能(例如定制可视化或针对特定领域的 Ontology 对象视图),并将它们直接嵌入 Workshop 模块中。你也可以在 Workshop 内嵌入一个完整的、全页面的自定义组件,将自定义代码的灵活性带入 Workshop 框架。
进一步了解自定义组件。
### Slate
Slate 为构建者提供一套灵活的工具,用于快速创建运营应用与交互式仪表盘。Slate 让应用开发者用拖拽界面构建动态、响应式的应用,减少开发时间与成本。Slate 包含与 Foundry Ontology 无缝集成的能力,但也让开发者用 HTML、CSS 与 JavaScript 完全定制应用。
进一步了解 Slate。
### Code Workspaces applications
Code Workspaces 应用让你从 Code Workspaces 中的第三方 IDE,使用 Python 的 Streamlit ↗ 或 Dash ↗,以及 R 的 Shiny® ↗,构建并发布交互式 Web 应用。数据科学家与开发者可以将分析转化为基于 Foundry 数据的运营应用,托管在 Foundry 容器中,并内置平台的版本控制、分支与数据治理。
进一步了解 Code Workspaces。
## 工作流搭建与管理
工作流搭建与管理
> 要点:Workflow Lineage、Automate、Carbon、Solution Designer、Use Cases。
Palantir 平台中主要的工作流构建与管理工具是 Workflow Lineage、Automate、Solution Designer 与 Use Cases。
### Workflow Lineage
Workflow Lineage 提供一个交互式工作区,用于理解并管理应用及其底层流程。借助 Workflow Lineage,你可以探索工作流并查看对象、动作、函数、大语言模型与应用的细节。Workflow Lineage 对正在创建、调试或维护工作流的应用构建者特别有用。血缘图、更深的属性与 Workshop 组件/变量血缘,以及升级工具,在修改或扩展工作流时都很有帮助。
### Automate
Automate 为你提供单一入口,用于设置并执行平台中所有业务自动化。Automate 应用让用户定义条件与效果;条件被持续检查,当指定条件满足时效果被自动执行。
进一步了解 Automate。
### Carbon
Carbon 支持为特定用户组配置定制的平台体验,即所谓的工作区(workspaces)。Carbon 可以为需要执行关键运营工作流、但技术较薄弱的用户提供聚焦的体验。每个 Carbon 工作区都是应用与资源的精选集合,可被配置为优化一组给定的、面向终端用户的运营工作流。例如,一个飞机零部件维护工作区可能包含一个 Workshop 应用,其中带有一个动态更新的、需要维护的零部件清单,以及用于分诊每个零部件的、由 Ontology 驱动的动作;另一个用于调查每个零部件维护问题的应用;以及一个展示随时间变化的维护趋势的 Quiver 分析。Carbon 让 Foundry 应用与分析能力的丰富画卷,能够被整合进聚焦的、运营化的体验中。
进一步了解 Carbon。
### Solution Designer
Solution Designer 是一个交互式工具,用于创建用 Palantir 平台构建的解决方案的架构表示,包括第一方与第三方集成点、到平台资源的链接、按需访问文档与最佳实践等。
进一步了解 Solution Designer。
### Use Cases
Use Cases 应用让构建者能够在单一运营界面中组织他们的工作。通过将文件系统视图与 Ontology 管理视图结合,开发者可以访问一个聚焦的、关于他们所负责工作的精选视图。
进一步了解 Use Cases 应用。
## 开发工具链
开发工具链
> 要点:与开发者工具链的衔接。
Palantir 的开发者工具链让你使用自己的工具,在 Palantir 平台之上构建你自己的应用。
Palantir 开发者工具链的核心是 Developer Console 中生成的 Ontology SDK (OSDK)。Ontology SDK 被创建为 TypeScript 的 npm 包,或 Python 的 pip / Conda 包,它只包含你 Ontology 的一个预选子集。该 SDK 让你能够访问对象类型、应用动作来更新 Ontology 中的数据、调用函数,并为启用 AIP 的租户运行 AIP Logic 函数。Developer Console 还包含为你应用所选实体提供的、与 Ontology 相关的文档。应用使用 OAuth 流程作为公开或机密客户端来访问数据。
进一步了解 Ontology SDK。
你也可以直接使用 Foundry 的 REST API,从任何语言或运行时查询对象、应用动作并调用函数,用于完全在 Foundry 之外构建的应用。
### 常见问题速答 · FAQ
关于「Use case development(业务应用开发)总览」,读者最常问的几个问题。
应用搭建是什么? Workshop、OSDK React 应用、自定义组件、Slate、Code Workspaces 应用。
工作流搭建与管理是什么? Workflow Lineage、Automate、Carbon、Solution Designer、Use Cases。
开发工具链是什么? 与开发者工具链的衔接。Palantir 的开发者工具链让你使用自己的工具,在 Palantir 平台之上构建你自己的应用。
---
## Data connectivity & integration(数据连接与集成)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-data-integration.html
- 官方原文:https://www.palantir.com/docs/foundry/data-integration/overview
- 主题分组:平台模块(二)
循序渐进 · 教学 · 平台模块(二)
# Data connectivity & integration(数据连接与集成)总览
Foundry 提供远超常规 ETL/ELT 的数据连接与集成能力:连接数据源、做数据转换、管理管道。这是本体之下的数据底座。
## 先记住这几条
① 不止是 ETL 连接、转换、编排是一整套工程化能力。
② 三个环节 连接数据 → 数据转换 → 管道管理。
③ 它是本体的上游 本体对象的数据来源最终都靠这一层供给。
## 写在前面

> 图:数据集成概览
Foundry 提供一套高度可配置的数据连接与集成工具,能力远超常见的 ETL(抽取-转换-加载)或 ELT(抽取-加载-转换)方案。Foundry 的设计目标是让数据集成的成本随时间下降 —— 通过一整套丰富的能力,成为数据团队的"力量倍增器"。通用云服务只为基础管道和实验提供存储与计算,而要管理、交付和校验支撑关键运营的数据集,还需要许多额外的能力层。Foundry 的定位,就是为世界上最复杂的环境充当数据集成的骨干。
## 连接数据
连接数据
> 要点:把外部系统的数据接入平台。
这一切始于一个可扩展的数据连接框架,它能与所有类型的源系统建立连接 —— 结构化的、非结构化的、半结构化的 —— 并支持所有关键的数据传输方式,比如批量、微批量或流式。这套能力与平台的数据转换和数据管理功能打通,涵盖数据版本的完整血缘、用于协同管理数据抽取的细粒度安全控制,以及数据同步配置的分支管理。
进一步了解如何在 Foundry 中连接数据。
## 数据转换
数据转换
> 要点:把原始数据加工成可用形态。
在数据转换方面,Foundry 提供了一个可扩展、可伸缩的"数据构建系统",利用多模态计算产出输出数据集。Foundry 与计算引擎解耦的 "Build" 框架提供了完全集成的安全与数据血缘,并且允许混用第三方计算运行时。此外,Foundry 还内置了一整套数据转换编写、变更管理、数据质量、管道调度与元数据探查能力,它们协同工作,为数据工程师提供一个"任务控制台"。
进一步了解如何用 Foundry 做数据转换。
## 管道管理
管道管理
> 要点:编排、调度与监控数据管道。
Foundry 的管道管理能力把变更管理、数据质量和数据加载功能组合在一起。
Pipeline Builder 应用让数据管道又快又灵活地交付,同时保证健壮性与安全性。进一步了解 Pipeline Builder。
数据工程师可以为生产管道定义严格的发布流程,包括健康检查 —— 确保只有完全合规的数据才会被部署到生产环境。一旦发现问题,平台会给出针对所发现差异的诊断信息。
诊断信息既可以在 Foundry 内置的分析和建模工具里查看,任何通过 REST API 或其他接口访问输出结果的第三方工具也能获取。
进一步了解如何在 Foundry 中维护和管理管道。
### 常见问题速答 · FAQ
关于「Data connectivity & integration(数据连接与集成)总览」,读者最常问的几个问题。
连接数据是什么? 把外部系统的数据接入平台。这一切始于一个可扩展的数据连接框架,它能与所有类型的源系统建立连接 —— 结构化的、非结构化的、半结构化的 —— 并支持所有关键的数据传输方式,比如批量、微批量或流式。
数据转换是什么? 把原始数据加工成可用形态。在数据转换方面,Foundry 提供了一个可扩展、可伸缩的"数据构建系统",利用多模态计算产出输出数据集。Foundry 与计算引擎解耦的 "Build" 框架提供了完全集成的安全与数据血缘,并且允许混用第三方计算运行时。
如何管道管理? 编排、调度与监控数据管道。Foundry 的管道管理能力把变更管理、数据质量和数据加载功能组合在一起。
---
## Developer toolchain(开发工具链)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-dev-toolchain.html
- 官方原文:https://www.palantir.com/docs/foundry/dev-toolchain/overview/
- 主题分组:平台模块(五)
循序渐进 · 教学 · 平台模块(五)
# Developer toolchain(开发工具链)总览
平台提供一整套构建于本体之上的开发工具:OSDK、各类 API、平台 SDK、开发环境、MCP、计算模块与自定义端点。
## 先记住这几条
① OSDK 是核心 Ontology SDK 让外部代码直接操作本体对象。
② API 与平台 SDK 并存 本体 API 操作本体,平台 SDK 操作平台资源。
③ MCP 是新入口 Palantir MCP 与 Ontology MCP 让 AI 工具能接入平台。
④ 还有计算与自定义端点 Compute Modules 与自定义端点扩展能力边界。
## 写在前面

> 图:developer toolchain overview
Palantir 平台附带一套开发者工具,让你能够在 Ontology 之上进行构建,并通过新的工作流、应用与功能释放价值。借助 Palantir 的开发者工具链,你可以直接从开发环境访问 Ontology 的全部能力。
除了别处介绍的数据连接与应用构建工具之外,Palantir 开发者工具链还提供:
- 向你的应用开放的 核心 API 与 SDK。
- 用于加速工作流的开发环境与面向开发者的功能。
- Palantir MCP,让 AI IDE 与 AI 智能体能够利用 Palantir 上下文并在 Foundry 各处采取行动。
- Ontology MCP,将 Ontology 资源作为 MCP 工具暴露给外部 AI 智能体。
- 计算模块,用于容器化你的代码并扩展部署。
## 核心 API 与 SDK
核心 API 与 SDK
> 要点:OSDK、APIs、Platform SDKs 三者分工。
Palantir 开发者产品线的核心,是那些开放平台、让你能够构建与 Palantir 平台及你的 Ontology 数据直接集成的应用的 API 与 SDK。
### Ontology SDK (OSDK)
Ontology SDK (OSDK) 让开发者可以用 Python、Java 和 TypeScript 从自己的 Ontology 生成 SDK。OSDK 让你能够访问对象类型、应用动作来更新 Ontology 中的数据、调用函数,以及为启用 AIP 的租户运行 AIP Logic 函数。平台内的 Developer Console 包含为你所选应用实体提供的、与 Ontology 相关的文档。应用使用 OAuth 流程作为公开或机密客户端来访问数据。
### APIs
Palantir 的 API 支持用户在 Palantir 平台上构建,能够程序化管理平台访问权限以及支撑你 Ontology 的数据。API 参考也可通过 Developer Console 在平台内获取。
可用的 Palantir API 包括:
- 数据集: 读取、写入和管理数据集,包括分支、事务、文件与视图。
- 文件系统: 管理空间、项目、文件夹与资源角色。
- 管理: 管理用户、用户组、组织、主机与标记(markings)。
- 编排: 触发构建、检查任务并配置调度。
- 连接: 管理连接、虚拟表,以及来自外部源的文件或表导入。
- SQL 查询: 对数据集执行 SQL。
- 媒体集: 上传、检索并管理媒体集及其条目。
查看完整的 API 文档,获取端点的完整列表,包括模型、审计日志、数据健康检查、流、检查点与记事本。
### Platform SDKs
Palantir 的平台 SDK 已公开发布,适用于 Python ↗ 与 TypeScript ↗,并会随着新 API 的推出而不断扩展。这些 SDK 可以与 Ontology SDK 一同使用,共享相同的 Palantir 平台客户端。
## 开发环境与功能
开发环境与功能
> 要点:在哪写代码、怎么调试。
除了专注于数据连接的开发工具(如 Pipeline Builder 与 Code Repositories)之外,Code Workspaces 让你在构建 Palantir 平台应用时,使用 VS Code 等熟悉的 IDE。VS Code 工作区 与 Developer Console 集成,让你可以快速构建 React 应用。你可以从平台内的 Developer Console 创建一个 VS Code 工作区。
Palantir 面向开发者的功能旨在加速在平台上构建的过程。Global Branching 等特性帮助为端到端工作流的开发创造一个安全、流畅的环境。
## Palantir MCP
Palantir MCP
> 要点:让 AI 客户端接入 Foundry 的协议入口。
Palantir MCP 是 Model Context Protocol ↗ 的一种实现,让 AI IDE 与 AI 智能体能够在 Palantir 平台中自主构建端到端应用——从数据集成、Ontology 配置到应用开发。此外,你可以使用 Palantir MCP 让外部 AI 系统查询文档、元数据与数据,并在平台上执行高层任务。开发者可以在专注于自己正在构建的系统时,使用 Palantir MCP 自动化辅助性任务。
## Ontology MCP
Ontology MCP
> 要点:面向本体的 MCP 能力。
Ontology MCP (OMCP) 是 Developer Console 的一项特性,将你的应用的 Ontology 资源作为 Model Context Protocol(MCP)工具暴露出来,使外部 AI 智能体能够与你的 Ontology 交互。Palantir MCP 面向 Ontology 构建者与开发工作流,而 Ontology MCP 面向 Ontology 消费者:那些需要安全读写生产 Ontology 数据的外部 AI 智能体。
Ontology MCP 将对象类型、动作类型与查询函数作为 MCP 工具暴露,并与桌面智能体与无头(headless)智能体框架集成。
## 计算模块
计算模块
> 要点:运行自定义计算负载。
计算模块(Compute Modules)特性让你能够在 Palantir 平台上部署交互式容器,从而带入你已有的代码库(无论何种语言)并在平台内运行。例如,借助计算模块,你可以将一个第三方机器学习模型带入平台,并集成进你的工作流。
关于计算模块的更多信息,你可以观看这段官方 Build with AIP:Compute Modules ↗ 视频,并参考文档。
## 自定义端点
自定义端点
> 要点:对外暴露自定义服务。
自定义端点 让开发者能够配置并部署用户自定义的 API 端点,拥有自己的 URL 模式、请求与响应形态以及规范,同时利用 Foundry 的后端能力。这些端点通过动作与函数由 Ontology 支撑。
### 常见问题速答 · FAQ
关于「Developer toolchain(开发工具链)总览」,读者最常问的几个问题。
核心 API 与 SDK是什么? OSDK、APIs、Platform SDKs 三者分工。Palantir 开发者产品线的核心,是那些开放平台、让你能够构建与 Palantir 平台及你的 Ontology 数据直接集成的应用的 API 与 SDK。
开发环境与功能是什么? 在哪写代码、怎么调试。除了专注于数据连接的开发工具(如 Pipeline Builder 与 Code Repositories)之外,Code Workspaces 让你在构建 Palantir 平台应用时,使用 VS Code 等熟悉的 IDE。
Palantir MCP是什么? 让 AI 客户端接入 Foundry 的协议入口。Palantir MCP 是 Model Context Protocol ↗ 的一种实现,让 AI IDE 与 AI 智能体能够在 Palantir 平台中自主构建端到端应用——从数据集成、Ontology…
Ontology MCP是什么? 面向本体的 MCP 能力。Ontology MCP (OMCP) 是 Developer Console 的一项特性,将你的应用的 Ontology 资源作为 Model Context Protocol(MCP)工具暴露出来,使外部 AI 智能体能够与你的…
---
## Product delivery(产品交付)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-devops.html
- 官方原文:https://www.palantir.com/docs/foundry/devops/overview/
- 主题分组:平台模块(九)
循序渐进 · 教学 · 平台模块(九)
# Product delivery(产品交付)总览
Foundry DevOps 让你把在 Foundry 里构建的数据驱动工作流打包、快速开发并部署,配合 Marketplace 分发给他人复用。
## 先记住这几条
① 打包成产品 把本体、模型、管道、应用打包成一个可交付单元。
② Marketplace 负责分发 产品发布到 Marketplace,供他人安装复用。
③ 交付要跨环境 从开发到生产的环境迁移是核心场景。
## 写在前面
## Foundry DevOps
Foundry DevOps
> 要点:打包、版本、部署的能力。
Foundry DevOps 让你快速开发并部署在 Foundry 里构建好的、数据驱动的工作流包,这些包可以利用你组织的本体、AI 模型、管道、数据连接,甚至是端到端的完整用例。
Foundry DevOps 的主要能力:
- 灵活的打包方式 —— 把任意组合的 Foundry 资源打成一个产品。
- 自动化的版本与依赖管理 —— 产品规模变大时,各个模块化组件仍能无缝同步。
- 用发布通道给新产品版本打标签,确保它只触达符合条件的安装实例。
- 管理一批安装实例。
Foundry DevOps 适合下面这些场景:
- 产品分发: 把你的产品发布到 Foundry Marketplace,供组织内其他安装者或更广的 Foundry 社区使用。
- 构建生态: 为每个生态参与者(客户、子公司、部门等)装上你的产品,并配上他们自己的输入数据。
- 发布管理: 创建对应各个开发环境的安装实例,并为升级和发布通道定制维护窗口。
- 快速启动新用例: 装一次你的产品,作为最新定制用例的起点。
了解如何创建产品和管理产品。
## Marketplace
Marketplace
> 要点:产品的发布与安装分发。
Marketplace 商店让已发布的数据产品更容易被发现和安装。

> 图:Marketplace 商店前台
Marketplace 的主要能力:
- 引导式产品安装,包括为满足产品输入项而推荐的相关产品。
- 可以为安装实例开启自动升级,无需人工干预就能接受新产品版本,并支持维护窗口和发布通道。
了解如何浏览和安装 Marketplace 产品。
### 常见问题速答 · FAQ
关于「Product delivery(产品交付)总览」,读者最常问的几个问题。
Foundry DevOps是什么? 打包、版本、部署的能力。Foundry DevOps 让你快速开发并部署在 Foundry 里构建好的、数据驱动的工作流包,这些包可以利用你组织的本体、AI 模型、管道、数据连接,甚至是端到端的完整用例。
Marketplace是什么? 产品的发布与安装分发。Marketplace 商店让已发布的数据产品更容易被发现和安装。
---
## Model connectivity & development(模型接入与开发)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-model-integration.html
- 官方原文:https://www.palantir.com/docs/foundry/model-integration/overview/
- 主题分组:平台模块(三)
循序渐进 · 教学 · 平台模块(三)
# Model connectivity & development(模型接入与开发)总览
在平台里,模型(model)是封装任意机器学习逻辑的制品,可以在数据管道、本体、应用层被复用。这篇讲模型来源、建模目标与本体中的模型。
## 先记住这几条
① 模型 = 封装的 ML 逻辑 任何机器学习逻辑都能封装成模型制品。
② 跨层复用 同一个模型可在管道、本体、应用里使用。
③ 模型可进入本体 模型可以挂到本体上,成为对象的一种能力。
## 写在前面

> 图:model integration overview
在 Palantir 平台中,模型(models)是封装任意机器学习逻辑的产物。模型可以在数据流水线、Ontology、应用层等各层工作流中被使用,从而支撑各种各样的用例。
Palantir 采用开放的方式支持模型集成。模型既可以在平台内基于已集成的数据进行开发,也可以在外部开发后作为库、产物、容器或 API 导入平台。
一旦集成,模型即可配合平台的工具用于推理、部署、治理、ML Ops 和运营化。模型创建与使用的每一步都受到平台在血缘、安全、版本管理、可复现性和审计方面的保障约束。
## 模型来源
模型来源
> 要点:模型从哪里来:外部训练、平台内训练等。
任何形态的模型都可以在平台内开发(例如通过 scikit-learn、TensorFlow、OR-tools 等开源工具,或自定义库),从外部环境导入(例如 Notebook、第三方数据科学产品或容器镜像仓库),或配置为外部托管的 API。
进一步了解平台内的模型开发以及外部模型的集成。
## 建模目标
建模目标
> 要点:建模任务的管理与组织方式。
Modeling Objectives 充当「指挥中心」,用于精简某一问题下的模型管理、评估、评审、发布与部署。除了一套便捷的用户界面之外,Modeling Objectives 还提供治理与权限层、自动化层(例如对模型候选者的统一评估)以及 CI/CD 层,支持模型持续、无停机的部署。
Objectives 支持面向任何建模问题的完整模型生命周期,包括那些传统上不被 ML Ops 工具覆盖的问题,例如仿真与优化。
借助 Objectives,组织可以超越「建一条数据流水线」本身,将模型安全地以运营形态部署给做决策的用户和系统。一旦投入运营,Foundry 能够从生产数据、结果、应用和用户操作中形成 ML 反馈回路。这些反馈回路为建模团队提供了强大的数据资产,用于监控、理解和改进生产表现,并适应新情况。
进一步了解 Modeling Objectives。
## 本体中的模型
本体中的模型
> 要点:模型如何与本体结合,成为业务能力。
Ontology 是 Palantir 平台的运营层。Ontology 将数字资产与其现实世界中的对应物连接起来,以支撑各类不同的用例。
模型一旦集成进平台,即可通过 Modeling Objectives 部署,并注册为可在 Ontology 层中使用。这让运营型交互工作流能够由高可信的模型支撑,从而驱动快速、关键的业务决策。
进一步了解 Ontology以及如何将模型与其集成。
### 常见问题速答 · FAQ
关于「Model connectivity & development(模型接入与开发)总览」,读者最常问的几个问题。
模型来源是什么? 模型从哪里来:外部训练、平台内训练等。任何形态的模型都可以在平台内开发(例如通过 scikit-learn、TensorFlow、OR-tools 等开源工具,或自定义库),从外部环境导入(例如 Notebook、第三方数据科学产品或容器镜像仓库),或配置为外…
建模目标是什么? 建模任务的管理与组织方式。Modeling Objectives 充当「指挥中心」,用于精简某一问题下的模型管理、评估、评审、发布与部署。除了一套便捷的用户界面之外,Modeling Objectives 还提供治理与权限层、自动化层(例如对模型候选者的统一评…
本体中的模型是什么? 模型如何与本体结合,成为业务能力。Ontology 是 Palantir 平台的运营层。Ontology 将数字资产与其现实世界中的对应物连接起来,以支撑各类不同的用例。
---
## Observability(可观测性)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-observability.html
- 官方原文:https://www.palantir.com/docs/foundry/observability/overview/
- 主题分组:平台模块(七)
循序渐进 · 教学 · 平台模块(七)
# Observability(可观测性)总览
平台内建工具用于监控资源健康、排查开发/生产问题、跨服务追踪执行、分析遥测。这一篇讲监控、调试与日志导出三块。
## 先记住这几条
① 三件事:监控、调试、追踪 看健康度、查问题、跟调用链。
② 本体与 AIP 也有观测能力 不只是基础设施,业务层同样可观测。
③ 日志可导出 遥测数据能导出去做进一步分析。
## 写在前面
Palantir 平台提供内置工具,用于监控资源健康、调试开发与生产中的问题、跨服务追踪执行,以及大规模分析遥测(telemetry)数据。

> 图:在 Workflow Lineage 中跨日志搜索。
监控: 你可以使用 Data Health 工具监控平台。借助 Data Health,你可以为失败、延迟等指标设置规则和阈值;可以按资源或跨项目大规模配置监控器;可以通过 PagerDuty、Slack、webhook 或 Foundry 通知接收告警;并可以查看过去 30 天的执行次数与 P95 延迟指标。
调试: Workflow Lineage 工具让你可以探索和调查平台历史与日志。你可以查看 7 天的执行历史,按状态、用户、时长或版本筛选,并精确定位需要关注的具体执行。Workflow Lineage 还允许你跨日志搜索,从某个源执行器的所有执行中查找特定的日志消息、错误或模式。
追踪: 要可视化跨越函数、动作与 LLM 调用的完整请求旅程,你可以使用追踪视图。追踪视图让你可以深入任意操作,查看其时长、输入、输出与错误。
分析: 要对日志数据做进一步分析,你可以将 Foundry 的日志、指标与追踪导出到一个流式数据集,以驱动你自己的仪表盘、流水线或自定义可观测性工作流。
## 监控
监控
> 要点:指标(Metrics)与健康度监控。
监控工具帮助你随时间追踪资源的健康与稳定性,主动发现问题,并在问题发生时收到告警。
Data Health 是监控平台资源健康的主要应用。Data Health 提供两套功能:
- 监控视图: 你可以使用基于范围的监控规则,跨项目、文件夹、应用或单个资源大规模监控 Foundry 资源。
- 健康检查: 可以在单个资源上配置详细的健康检查,包括对数据集、调度与表的内容和 schema 校验。
监控视图与健康检查在发现问题时会生成告警。告警可以通过 Foundry 通知,或通过 PagerDuty、Slack 等外部系统 送达。
### Metrics
Foundry 提供跨多种资源类型的指标,帮助你随时间监控健康与性能。
- 函数、动作与 AIP Logic: 通过 Ontology Manager 或 Workflow Lineage,查看过去 30 天近乎实时的成功/失败次数与 P95 执行时长。你也可以借助 Workshop 中的 Observability Chart 组件,将这些指标直接嵌入运营应用,在流程其余部分旁边监控资源健康。
- 流与计算模块: 在 Metrics(指标) 标签页访问指标,以监控长时运行计算任务的健康与稳定性。

> 图:Metrics 标签页。
## 调试
调试
> 要点:本体与 AIP 的可观测能力,以及日志。
调试工具通过提供对执行细节、日志与追踪的可见性,帮助你在开发与生产环境中调查问题。
### Ontology and AIP observability
Workflow Lineage 中的 Ontology 与 AIP 可观测性 特性,让你对 AIP 与 Ontology 工作流的执行获得全面的洞察。使用这些特性来了解你的智能体、函数、语言模型、自动化、动作与 Ontology 的性能。
这些特性可用于获取指标、执行历史、分布式追踪、日志与日志搜索的可见性。
### Logs
你可以查看用于运行你代码的第三方库(如流所使用的 Kafka)产生的日志,以及你的代码所输出的日志。日志在多种任务类型上可用:
- 批处理与流式转换: 可在转换的任务报告中查看实时日志。
- 计算模块: 可在计算模块概览页查看日志。
- 函数: 可在 Workflow Lineage 中查看日志。
你还可以跨日志搜索,从某个源执行器的所有执行中查找特定的日志消息、错误或模式。源执行器是调用链中的第一个可执行资源,例如函数、动作、自动化、AIP Logic、AIP 智能体或模型实时部署。
## 日志导出
日志导出
> 要点:把日志导出到外部系统。
> 日志导出在你的租户中可能不可用。如需了解更多信息,请联系 Palantir 支持。
为了支持平台内工具当前能力之外的任意处理,你可以创建一个位于指定文件夹中的流,其中包含某个组织的全部遥测数据。这包括日志、指标与追踪。该流中的数据可以使用 Foundry 的数据分析工具套件进行分析,或导出到第三方系统。

> 图:通过 Control Panel 导出日志。
在「配置日志」页面进一步了解如何将日志导出到流。
### 常见问题速答 · FAQ
关于「Observability(可观测性)总览」,读者最常问的几个问题。
如何监控? 指标(Metrics)与健康度监控。监控工具帮助你随时间追踪资源的健康与稳定性,主动发现问题,并在问题发生时收到告警。
调试是什么? 本体与 AIP 的可观测能力,以及日志。调试工具通过提供对执行细节、日志与追踪的可见性,帮助你在开发与生产环境中调查问题。
日志导出是什么? 把日志导出到外部系统。日志导出在你的租户中可能不可用。如需了解更多信息,请联系 Palantir 支持。
---
## Ontology building(本体构建)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-ontology.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/overview/
- 主题分组:平台模块(四)
循序渐进 · 教学 · 平台模块(四)
# Ontology building(本体构建)总览
本体(Ontology)是组织的运营层,坐落在接入平台的数据资产之上。这一篇是本体模块的地图:对象与链接、动作与函数、接口,以及如何驱动决策。
## 先记住这几条
① 本体 = 运营层 它不是数据库,而是业务语义层,把数据变成"业务对象"。
② 三块核心内容 对象与链接类型、动作类型与函数、接口。
③ 本体驱动决策 最终目的是让决策有依据、能落地、能回写。
## 写在前面

> 图:Ontology overview header image.
Palantir Ontology 是面向组织的运营层。它架设于集成进 Palantir 平台的数字资产之上(数据集、虚拟表与模型),并将它们与现实世界中的对应物相连——从工厂、设备、产品等物理资产,到客户订单、金融交易等概念。在许多场景下,Ontology 充当了组织的数字孪生,既包含语义要素(对象、属性、链接),也包含动能要素(动作、函数、动态安全),从而支撑各类用例。
## 对象类型与链接类型
对象类型与链接类型
> 要点:本体的骨架:业务实体以及实体之间的关系。
定义组织的语义,就是把现有数据源映射为 Ontology 中的对象、属性与链接。Ontology 远不止数据编目或 schema 设计,它让你为终端用户工作流打下健壮的基础:为所有字段提供丰富元数据,并为所有变更配备细粒度的安全与治理。
了解如何创建 Ontology 的语义要素:对象类型与链接类型。
## 动作类型与函数
动作类型与函数
> 要点:让本体"动起来"的两种机制:写操作与计算逻辑。
组织的动能——在符合组织管控与治理的前提下推动变更——由 Ontology 中的动作类型与函数定义。动作类型让你能够从组织内的操作员处采集数据,或编排连接到现有系统的决策流程;而函数则提供了一种编写和演进任意复杂业务逻辑的方式。
了解如何创建 Ontology 的动能要素:动作类型与函数。
## 接口
接口
> 要点:抽象契约,让不同对象类型被一致对待。
接口(interface)是一种描述对象类型形态及其能力的 Ontology 类型。接口提供对象类型的多态性,使得对共享相同形态的对象类型能够进行一致的建模与交互。
进一步了解接口。
## 驱动决策
驱动决策
> 要点:本体最终要服务于业务决策,而不只是建模。
投资建设 Ontology 的目标,是支撑组织规模化地做出更好的决策。为此,Ontology 深度集成进 Palantir 面向用户的分析与运营工具:用户可以创建可复用的 Object Views、在 Object Explorer 中搜索感兴趣的对象、在 Quiver 中执行复杂分析、在 Workshop 中构建高质量应用,等等。
进一步了解如何在面向用户的应用中利用 Ontology。 既然已经了解了原理,现在就通过 Palantir Learning 门户上的课程 ↗开始动手构建你的第一个 Ontology。
### 常见问题速答 · FAQ
关于「Ontology building(本体构建)总览」,读者最常问的几个问题。
对象类型与链接类型是什么? 本体的骨架:业务实体以及实体之间的关系。定义组织的语义,就是把现有数据源映射为 Ontology 中的对象、属性与链接。Ontology 远不止数据编目或 schema 设计,它让你为终端用户工作流打下健壮的基础:为所有字段提供丰富元数据,并为所有变更配备细粒…
动作类型与函数是什么? 让本体"动起来"的两种机制:写操作与计算逻辑。组织的动能——在符合组织管控与治理的前提下推动变更——由 Ontology 中的动作类型与函数定义。
接口是什么? 抽象契约,让不同对象类型被一致对待。接口(interface)是一种描述对象类型形态及其能力的 Ontology 类型。接口提供对象类型的多态性,使得对共享相同形态的对象类型能够进行一致的建模与交互。
驱动决策是什么? 本体最终要服务于业务决策,而不只是建模。投资建设 Ontology 的目标,是支撑组织规模化地做出更好的决策。为此,Ontology 深度集成进 Palantir 面向用户的分析与运营工具:用户可以创建可复用的 Object Views、在 Object Ex…
---
## Security & governance(安全与治理)总览
- 页面:https://www.hanzhongpin.xyz/ontology/cat-security.html
- 官方原文:https://www.palantir.com/docs/foundry/security/overview/
- 主题分组:平台模块(十)
循序渐进 · 教学 · 平台模块(十)
# Security & governance(安全与治理)总览
Palantir 为最高安全要求与强监管行业提供软件平台。这一篇从平台安全、企业安全、基础设施安全三个层面讲清安全模型。
## 先记住这几条
① 三个层面 平台安全、企业安全、基础设施安全。
② 面向强监管行业 十余年在高度监管行业的实践经验沉淀。
③ 治理与安全并重 不只是防攻击,还包括合规与审计。
## 写在前面

> 图:Security Overview
Palantir 帮助组织用强大、安全的软件平台解决现实世界的问题。十多年来,我们与最安全、监管最严格的行业的客户合作,为他们最敏感的数据构建软件。如今,安全与隐私仍然是产品开发、公司文化与内部运营的基石。
Palantir 平台被全球的医疗提供商、金融机构、公用事业公司、制造商、电信运营商、航空公司与制药企业用于支撑他们最敏感的工作流。Palantir 平台是为注重安全的客户而构建的——他们需要以安全、合规的方式处理金融数据、个人可识别信息(PII)、受保护健康信息(PHI)、受控非密信息(CUI),乃至机密政府数据。Palantir 的安全基础设施通过对齐 HIPAA、GDPR、ITAR 等框架,满足跨行业、跨洲的监管要求。
随着我们的软件支撑起大型企业与政府的关键任务运营,我们的威胁模型专注于挫败资源充足、技术高超且持久的对手。为了击败这些对手,我们采取高度明确的态度,并对所有客户强制执行高标准的安全下限。例如,多年来多因素认证(MFA)一直是我们所管理的所有软件即服务(SaaS)平台客户的强制要求。想动手练习平台的数据保护工具,可在 learn.palantir.com 上学习 Foundry 中的数据保护工具课程 ↗。
## 平台安全
平台安全
> 要点:平台层面的安全机制。
Palantir 平台将安全作为核心开发理念。Palantir 的安全模型在透明且可用的前提下严格强制细粒度访问控制,以构建一个协作且可信的生态系统:
- 严格强制: 确保用户只能访问被授权交互的数据。
- 细粒度控制: 强大到足以实现灵活的访问控制粒度。
- 透明: 让用户能够推断谁可以访问哪些资源,以及为什么。
- 可用性: 让用户能够自信地推断并管理访问控制。
Palantir 安全模型同时涵盖认证(authentication)与授权(authorization)。认证验证用户身份,而授权基于用户的属性与权限授予访问。
Palantir 平台中的数据安全通过强制(mandatory)与自主(discretionary)两类控制的组合来提供,二者在传播方式上有所不同。强制控制(标记(markings)、基于分类的访问控制与组织)通过 Palantir 的溯源与血缘能力,在派生过程中随每个数据单元传播。自主控制被授予单个资源上的用户。这包括资源级角色授予(Owner、Editor、Viewer、Discoverer),以及通过受限视图、对象安全策略与属性安全标记上的细粒度策略所做的行或列过滤。自主的行、列控制过滤用户能读取的内容;它们不会延伸到下游输出或导出。完整模型见访问控制传播。
Palantir 平台中的数据与资源组织在 Projects(项目)中。用户属于 Organizations(组织),并被组织在平台内或通过外部身份提供方管理的用户组中。组织是一种施加在 Projects 上的强制控制形式,在不同用户组与资源组之间强制严格的隔离。因此,除非显式配置了共享协议,否则一个组织的用户无法访问另一个组织的资源。
对于高度敏感的数据,标记是另一种可施加于需要特殊保护的数据或资源(例如 PII 或财务敏感数据)的强制控制形式。除组织成员资格外,用户还必须具备特殊权限才能发现或访问此类数据。
## 企业安全
企业安全
> 要点:面向企业组织的安全能力。
我们拒绝以付费墙、加价或捆绑销售来限制审计日志、单点登录、多因素认证等核心安全控制。无论你是小型企业还是联邦机构,都能在标准 Palantir 产品中用上每一项核心企业安全特性:
- 对所有数据(传输中与会话静止时)的强制加密,采用强健、现代的密码学标准。
- 强认证与身份保护控制,包括单点登录与多因素认证。
- 强授权控制,包括强制与自主访问控制。
- 用于检测与调查潜在滥用的强健安全审计日志。
- 高度可扩展的信息治理、管理与隐私控制,以满足任何用例的需求。
## 基础设施安全
基础设施安全
> 要点:底层基础设施的安全保障。
如果你使用的是我们托管的 SaaS 平台,Palantir 所托管的基础设施还有额外的安全控制层来帮助保护你的数据:
- 围绕零信任、最小权限与纵深防御原则构建的强健安全架构。
- 强制执行安全基线配置,配合严格的变更管理与安全监控流程。
- 强网络安全加固与分段。
- 基于主机与基于网络的入侵检测系统,用于检测并挫败异常活动。
- 激进的基础设施与应用漏洞管理与补丁,拥有业界领先的 SLA。
- 对传入 Web 请求进行 Web 应用防火墙(WAF) 检测,以识别并阻断攻击。
- 在环境每一层(包括用户、主机、网络与应用)的安全监控。
## 更多安全资源
更多安全资源
> 要点:进一步阅读的官方资源。
Palantir 设有 SafeBase Trust Center 页面 ↗,集中存放所有安全文档与信息。你可以使用 SafeBase 来解答与我们安全标准和流程相关的问题。SafeBase 包含安全白皮书、策略、渗透测试报告、合规信息、认证(如 SOC 与 ISO)等。
处于保密协议(NDA)下的现有与潜在客户,可申请访问额外的非公开材料。
## 小结
小结
> 要点:整体结论。
Palantir 高度重视客户的安全成效,并致力于在安全实践与项目上保持透明。我们坚定地持续改进安全、数据保护与隐私控制,为你提供保护数据最有效的手段。
### 常见问题速答 · FAQ
关于「Security & governance(安全与治理)总览」,读者最常问的几个问题。
平台安全是什么? 平台层面的安全机制。Palantir 平台将安全作为核心开发理念。Palantir 的安全模型在透明且可用的前提下严格强制细粒度访问控制,以构建一个协作且可信的生态系统。
企业安全是什么? 面向企业组织的安全能力。我们拒绝以付费墙、加价或捆绑销售来限制审计日志、单点登录、多因素认证等核心安全控制。无论你是小型企业还是联邦机构,都能在标准 Palantir 产品中用上每一项核心企业安全特性。
基础设施安全是什么? 底层基础设施的安全保障。如果你使用的是我们托管的 SaaS 平台,Palantir 所托管的基础设施还有额外的安全控制层来帮助保护你的数据。
还有哪些安全资源? 进一步阅读的官方资源。Palantir 设有 SafeBase Trust Center 页面 ↗,集中存放所有安全文档与信息。你可以使用 SafeBase 来解答与我们安全标准和流程相关的问题。
---
## 配置分组(Section):把动作表单整理得井井有条
- 页面:https://www.hanzhongpin.xyz/ontology/configure-sections.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/configure-sections/
- 主题分组:动作类型详解
动作类型详解
# 配置分组(Section):把动作表单整理得井井有条
当动作的参数越来越多,表单就会又长又乱。配置分组(section)能按逻辑把参数归组、分栏、加说明,还能折叠与按条件显示,让表单只在恰当的时刻露出恰当的字段。
## 一句话速览
配置分组(Section):把动作表单整理得井井有条:当动作的参数越来越多,表单就会又长又乱。配置分组(section)能按逻辑把参数归组、分栏、加说明,还能折叠与按条件显示,让表单只在恰当的时刻露出恰当的字段。
1 配置分组(section) 动作表单(action form)可以用 sections(配置分组)来定制
2 添加一个分组 在 Form 标签页,点击 Add section(添加分组)
3 用列布局(columns)节省空间 你可以把参数组织在列里,更好地利用表单空间,或把相关参数靠得更近
4 把参数放进分组 有两种办法把参数加进 section:从分组配置视图(section configuration view)里加,或从 Form 标…
## 什么是配置分组(section)
先建立一个整体印象:分组是表单的"收纳盒"。
动作表单(action form)可以用 sections(配置分组)来定制。一个 section 提供对参数的逻辑归组(logical grouping),把相关的字段摆在一起,让填写的人一眼看懂该填什么。
除此之外,section 还支持三件有用的事:分栏(columns)、说明(descriptions)、以及条件覆盖(conditional overrides)。也就是说,分组不只是"圈一块地",它还能控制内部字段怎么排、说什么、以及什么时候出现。
> 提示:分组里的这些能力(折叠、隐藏、条件覆盖)会一并作用在它包含的每个参数上——组合起来,就能做出"聪明"的表单:只在合适的情境下才展示需要的字段。
## 如何添加一个分组
在 Form(表单)标签页里开启一个分组。
在 Form 标签页,点击 Add section(添加分组)。这会打开一个详细的配置弹窗,你可以在其中:
- 填写分组的标题(title);
- 选择列布局(column layout,单列或双列);
- (可选)写一段面向用户的说明(description)。
这里有个容易记混的细节:分组的说明不做任何样式修饰,而且与"参数说明"不同——它会始终显示在分组内部,而不是藏在 tooltip(悬停提示)里。
"The description is not stylized and, unlike parameter descriptions, will always be shown in the section itself, not in a tooltip."说明不做样式修饰,且始终显示在分组内部,而非 tooltip。
## 用列布局(columns)节省空间
单列太长?用双列把紧凑的字段并排摆。
你可以把参数组织在列里,更好地利用表单空间,或把相关参数靠得更近。一个 section 最多能被分成 一列或两列(one or two columns)。
当某些参数本身占用空间不大时,把它们分到独立的列里特别有用——既省纵向空间,阅读也更顺。
动手试:切换 section 的列数
单列布局
两列布局
参数 A 占用空间小的字段适合并入同一列。
参数 B 并排摆放,纵向更紧凑。
参数 C 两列布局让表单更短。
参数 D 相关字段靠得更近。
## 把参数放进分组
两种加入方式:在分组里新建/移入,或在 Form 里拖拽。
有两种办法把参数加进 section:从分组配置视图(section configuration view)里加,或从 Form 标签页里加。
方式一在分组配置视图里操作
在分组配置视图点击 Add new parameter(添加新参数)来配置;或点击 Add existing parameter(添加已有参数)把现有参数移入。
适合从零规划一个分组的字段构成,能直接在该视图内完成新参数的配置。
方式二在 Form 标签页里拖拽
Form 标签页把各分组及其参数列在一个总览里;按住参数左侧的"八点"手柄拖入已有分组即可。
参数和分组的显示顺序,取决于它们在 Form Content(表单内容)里的排序——拖到哪,就显示到哪。
点击此处,回顾两种加入方式。
## 折叠、隐藏与条件显示
让表单"该藏就藏、该现就现"。
分组可以折叠(collapsible),也可以整体隐藏(hidden),还能使用条件覆盖(conditional overrides),给你更多定制表单行为的方式。所有这些特性同样会作用到分组内部的参数上。
组合使用这些能力,就能做出更聪明的表单:例如一个分组可以先藏起来,只有当用户先填了某个前置参数后,才把它显示出来。这样表单不会一次把所有字段砸到用户脸上。
注意:分组内部参数的顺序、是否必填等,都会受到分组特性的影响;调整分组时,记得一并检查里面的参数表现。
一个 section 最多可以分成几列?点击揭晓。
## 一页带走
① 分组即"收纳盒" section 对参数做逻辑归组,支持分栏、说明与条件覆盖。
② 说明常驻组内 section 说明不做样式修饰、始终显示在内部,而非 tooltip。
③ 两种加参方式 分组配置视图里 Add existing parameter,或在 Form 中拖拽八点手柄。
④ 该藏就藏 分组可折叠、隐藏,并基于前置参数条件显示,做更聪明的表单。
### 常见问题速答 · FAQ
关于「配置分组(Section):把动作表单整理得井井有条」,读者最常问的几个问题。
什么是配置分组(section)? 动作表单(action form)可以用 sections(配置分组)来定制。一个 section 提供对参数的逻辑归组(logical grouping),把相关的字段摆在一起,让填写的人一眼看懂该填什么。
如何添加一个分组? 在 Form 标签页,点击 Add section(添加分组)。这会打开一个详细的配置弹窗,你可以在其中。
用列布局(columns)节省空间是什么? 你可以把参数组织在列里,更好地利用表单空间,或把相关参数靠得更近。一个 section 最多能被分成 一列或两列(one or two columns)。
把参数放进分组是什么? 有两种办法把参数加进 section:从分组配置视图(section configuration view)里加,或从 Form 标签页里加。
---
## 一致性保证(Consistency guarantees)
- 页面:https://www.hanzhongpin.xyz/ontology/consistency-guarantees.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/consistency-guarantees/
- 主题分组:动作类型详解
动作类型详解
# 一致性保证(Consistency guarantees)
当多个用户同时运行动作(action)修改同一个本体(Ontology)时,Foundry 如何保证数据不乱、不丢、不串?这一篇讲清事务、写模式与隔离级别。
## 一句话速览
一致性保证(Consistency guarantees):当多个用户同时运行动作(action)修改同一个本体(Ontology)时,Foundry 如何保证数据不乱、不丢、不串?这一篇讲清事务、写模式与隔离级别。
1 一个动作就是一笔事务(transaction) 在 Foundry 里,一个动作(action)通过单一事务对本体(Ontology)进行读取、应用你定义的逻辑、并把编辑写入一个或…
2 批量写 vs 暂存写 区别在于:同一个动作在写之后再读,能不能看到自己刚写的内容
3 对象级的写-写冲突 当两个动作并发写入同一个对象时(即使是不同的属性),其中一个会失败
4 写偏斜(Write skew)陷阱 设想一个值班(on-call)场景:动作 A 和动作 B 都读取了"当前谁在值班"这一重叠数据,然后各自写入不同的对象
## 一个动作就是一笔事务(transaction)
先建立直觉:动作不是零散的几次修改,而是一笔"全有或全无"的账。
在 Foundry 里,一个动作(action)通过单一事务对本体(Ontology)进行读取、应用你定义的逻辑、并把编辑写入一个或多个对象(object)和链接(link)。简单来说,它像数据库的一笔事务,提供标准的 ACID 属性。
"An action applies edits to the Ontology through a single transaction that can read from the Ontology, apply user-defined logic, and write edits to one or more objects and links."动作通过单一事务对本体进行编辑:它可以读取本体、应用用户定义的逻辑,并将编辑写入一个或多个对象和链接。
- 原子性(Atomicity):编辑作为单一、全有或全无的批次应用;但它不扩展到通知、webhook、函数外部调用这类"副作用(side effects)"。
- 一致性(Consistency):只有当本体约束(如属性类型、是否可空)被满足时才提交。
- 隔离性(Isolation):控制在并发执行时,动作之间如何互相影响(见下文隔离级别)。
- 持久性(Durability):提交之后,编辑被永久持久化。
> 提示:提交完成后,之后启动的动作或查询能看到这次编辑;但同一个动作执行期间自身的读,是否"看到自己的写入",取决于写模式。
## 两种写模式:批量写 vs 暂存写
两种模式都会把编辑收集起来,最后作为"单一原子批次"一次性提交,中途不会被别人看到半截结果。
区别在于:同一个动作在写之后再读,能不能看到自己刚写的内容。
BATCHED WRITES · 默认
批量写(Batched)
自身后续读 "看不到" 已收集到的编辑。
例:更新 status 后再读,返回的是原值。
→
STAGED WRITES
暂存写(Staged)
自身后续读 "能看到" 自己的编辑(含搜索/聚合)。
当前支持 TypeScript v2、Python、AIP Logic 的函数后端动作。
互动实验:读你自己的写入
模拟:批量写 Batched
模拟:暂存写 Staged
> 点击上方按钮,模拟"先写入 status = Closed,再读取该对象"。
## 三种隔离级别(Isolation levels)
隔离级别决定两件事:你读到的是哪个版本的数据,以及哪些并发变更会让你这个动作失败。点击展开看区别。
默认快照隔离(Snapshot isolation)
新批量写动作默认采用,提供单时间点的稳定读视图。
读:所有直接对本体的读,都观察"动作开始时"的一个单时间点快照;同一对象或搜索重复查询都返回相同结果。
写:批量写,自身后续读不含早前的编辑。
冲突检查:若另一个动作改了你正写入的对象,则本动作失败;仅读取的对象不会导致冲突。
注意:函数调用的 source 在时间点视图之外,可能读到不同时间的数据,不受原子/冲突检查覆盖。
旧版Legacy
为早期动作类型保留;新批量写默认已改为快照隔离。
读:通常来自单时间点,但不保证;可能因存储刷新导致不同对象看到不同状态。
写:两种写模式都支持(批量不含自身编辑、暂存含)。
冲突检查:若在对象加载到提交之间,有其他动作改了你写入的对象,则失败;但读的不一致可能让你基于"多时间点"做决定。
慎用读已提交(Read committed)
即将提供;每读返回读时的最新提交值,无固定快照。
读:每次读都返回读那一刻的最新提交值,没有固定快照。
写:批量写。
冲突检查:无;"最后提交者赢",早提交者的编辑会被丢弃(并发改同对象时要特别小心)。
> 提示:隔离级别在 Ontology Manager 的 Capabilities 标签中设置,创建后仍可更改。默认新批量写动作是快照隔离;暂存写动作目前仅支持 Legacy。
## 冲突检测:对象级的写-写冲突
在支持冲突检查的隔离级别下,本体会在"对象级"检测写-写冲突。
当两个动作并发写入同一个对象时(即使是不同的属性),其中一个会失败。失败时,该动作的全部编辑被丢弃。此外,底层数据集(backing dataset)重建也可能引发更广泛的、瞬时的冲突——重建完成后重试通常就能成功。
写-写冲突(Write-write conflict)
两个动作同时改同一对象
→ 其中一个失败,全部编辑被丢弃。
例:A、B 同时改 Alert #7 的不同属性,仍会冲突。
≠
瞬时冲突(Transient conflict)
底层数据集重建引发
→ 重试通常成功。
由平台自动重试机制兜底(见下一步)。
注意:冲突检查只在"写入的对象"上做,只读的对象不会引发冲突——这正是下一步"写偏斜"的根因。
## 写偏斜(Write skew)陷阱
快照隔离只检查"写"的对象,不检查"读"的对象,于是可能破坏你本想守护的业务不变式。
设想一个值班(on-call)场景:动作 A 和动作 B 都读取了"当前谁在值班"这一重叠数据,然后各自写入不同的对象。两个动作都能提交,结果导致一段时间内无人值班——这正是快照隔离无法捕捉的"写偏斜"。
"Snapshot isolation cannot catch this because the violated invariant lives on data the actions read [...] not on any single object either action wrote."快照隔离抓不到它,因为被破坏的不变式存在于动作"读取"的数据上,而不在任何一个动作"写入"的单一对象上。
点击揭晓:当发现这种隐患,该怎么重新设计?
点击这里揭晓解法 →
## 瞬时错误重试与隔离级别选型
平台能自动重试,但前提是你的动作没有"不可重复的副作用"。
当动作遇到瞬时错误(含冲突、对象加载失败)时,平台最多自动重试 5 次,并按配置的隔离级别重新执行。默认只在没有外部调用(如 webhook)时重试;若动作含外部调用,默认不重试,以免重复触发副作用。
把场景匹配到合适的隔离级别(点击每行右侧选项):
## 一页带走
① 动作即事务 一个动作是单事务、ACID;原子性不覆盖通知/webhook 等副作用。
② 两种写模式 批量写看不到自己的写入;暂存写能看到(read-your-own-writes)。
③ 三种隔离级别 默认快照隔离;Legacy 向后兼容;读已提交无冲突检查。
④ 冲突与重试 写-写冲突对象级检测;瞬时错误最多自动重试 5 次(无外部调用时)。
### 常见问题速答 · FAQ
关于「一致性保证(Consistency guarantees)」,读者最常问的几个问题。
两种写模式:批量写 vs 暂存写是什么? 区别在于:同一个动作在写之后再读,能不能看到自己刚写的内容。
冲突检测:对象级的写-写冲突是什么? 当两个动作并发写入同一个对象时(即使是不同的属性),其中一个会失败。失败时,该动作的全部编辑被丢弃。此外,底层数据集(backing dataset)重建也可能引发更广泛的、瞬时的冲突——重建完成后重试通常就能成功。
写偏斜(Write skew)陷阱是什么? 设想一个值班(on-call)场景:动作 A 和动作 B 都读取了"当前谁在值班"这一重叠数据,然后各自写入不同的对象。两个动作都能提交,结果导致一段时间内无人值班——这正是快照隔离无法捕捉的"写偏斜"。
瞬时错误重试与隔离级别选型是什么? 当动作遇到瞬时错误(含冲突、对象加载失败)时,平台最多自动重试 5 次,并按配置的隔离级别重新执行。默认只在没有外部调用(如 webhook)时重试;若动作含外部调用,默认不重试,以免重复触发副作用。
---
## 核心概念(Core concepts)
- 页面:https://www.hanzhongpin.xyz/ontology/core-concepts.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/core-concepts/
- 主题分组:概念篇
循序渐进 · 教学 · 概念篇
# 核心概念(Core concepts)
上一篇讲了"为什么",这一篇讲"是什么"。本体由几个最基本的概念拼成:
对象类型、属性、链接类型、动作类型。它们和你在数据表里见过的东西,其实是一一对应的。
## 一句话速览
核心概念(Core concepts):上一篇讲了"为什么",这一篇讲"是什么"。本体由几个最基本的概念拼成:对象类型、属性、链接类型、动作类型。它们和你在数据表里见过的东西,其实是一一对应的。
1 本体 = 对世界的"分类" 原文给本体的定义一句话就说清:本体是对世界的分类(a categorization of the world)
2 一张对照表 本体的概念和数据表的结构是平行的,原文直接给了这张对照表
3 对象类型、对象、对象集 继续用表格类比:对象类型 ≈ 一张数据集(一类事物的定义);对象 ≈ 表里的一行(一个具体实例)
4 属性(Property)与共享属性 属性是对象类型上"某个特征"的 schema 定义;属性值则是某个对象在该特征上的具体取值 (类比:列 ≈ 属性,单元格 ≈ 属性值…
## 本体 = 对世界的"分类"
在 Foundry 里,本体就是组织的数字孪生。
原文给本体的定义一句话就说清:本体是对世界的分类(a categorization of the world)。
在 Foundry 中,本体就是组织的数字孪生(digital twin)——它把组织的数字资产(数据集、模型)整合成一个连贯的整体。
具体怎么做?本体把数据集和模型映射成四种东西:对象类型(object type)、属性(property)、
链接类型(link type)、动作类型(action type)。下面这几步,我们逐个拆开。
The Foundry Ontology creates a complete picture of an organization's world by mapping datasets and models to object types, properties, link types, and action types.
Foundry 本体通过把数据集和模型映射成对象类型、属性、链接类型、动作类型,勾勒出组织的完整世界。
## 数据集 vs 本体:一张对照表
如果你会用表格,就已经懂一半本体了。
本体的概念和数据表的结构是平行的,原文直接给了这张对照表:
数据集 Dataset 本体 Ontology
整张数据集 对象类型 Object type
一行 Row 对象 Object
一列 Column 属性 Property
一个单元格 Field 属性值 Property value
两表连接 Join 链接类型 Link type
### 动手对照:点左边的"数据集零件",看它在本体里是什么
这是本篇专属的小实验室——点一下,左右两侧就会填上对应的概念。
数据集零件 → 本体对应物
整张数据集
一行记录
一列字段
一个单元格
两表连接
数据集侧 ? 点上面的按钮开始
本体侧对应物 ? 点击左侧开始对照
>
关键直觉:数据集是"扁平的格子",本体是"有结构、有关系、能行动"的世界模型。映射过去之后,
AI 和人都不再是"查表",而是"和真实世界里的对象打交道"。
## 对象类型、对象、对象集
"一类事物"和它的"一个个实例"。
对象类型 Object type
现实世界某类实体或事件的 schema 定义。例如 Customer、Order。
对象 Object
某个对象类型的单个实例,对应现实里一个具体实体/事件。例如"客户张伟"。
对象集 Object set
多个对象实例的集合,代表一组现实实体/事件。例如"所有逾期未付的订单"。
继续用表格类比:对象类型 ≈ 一张数据集(一类事物的定义);对象 ≈ 表里的一行(一个具体实例)。
区别在于,对象不是孤单的一行——它通过链接和别的对象连成网(下一步讲)。
## 属性(Property)与共享属性
对象的"特征",以及跨类型复用的"共享"特征。
属性是对象类型上"某个特征"的 schema 定义;属性值则是某个对象在该特征上的具体取值
(类比:列 ≈ 属性,单元格 ≈ 属性值)。
原文还特别提到 共享属性(shared property):一个可以在多个对象类型上复用的属性。
它的价值在于——跨类型保持一致的建模,并把属性的元数据集中管理。比如"最后更新时间"这种通用字段,
与其在每个类型各写一遍,不如定义成共享属性统一治理。
>
初学者记住:属性是描述对象的"形容词"。一个对象类型由若干属性组成,但对象是"谁"、属性是"它长什么样"。
## 链接类型(Link type):对象之间的关系
本体真正的威力,在"关系"而不在"单元格"。
链接类型是两个对象类型之间"关系"的 schema 定义;链接(link)则是两个具体对象之间那段关系的一个实例。
类比:就像数据集之间可以用各种方式 join,对象之间也能基于属性值建立链接。
An object type defines an entity or event; a property defines its characteristics; a link type defines the relationship between two object types; an action type defines how an object type can be modified.
对象类型定义实体/事件;属性定义其特征;链接类型定义两类对象间的关系;动作类型定义对象如何被修改。
例子:Order → Customer 的"归属"关系,就是一个链接类型;某一行具体订单指向张伟,就是一条链接。
正是这些关系,让"顺着链接导航"成为可能——这也是为什么本体比一张扁平表更有用。
## 动作类型(Action type):世界怎么被改变
把"一次可以做的改动"定义清楚,业务人员才能动手。
动作类型是"一组改动"的 schema 定义:它可以一次性修改对象、属性值、链接,
并且包含动作提交时会触发的副作用行为(side effect)。配置好之后,终端用户就能通过"执行动作"来改动对象。
>
串起来看:对象类型 + 属性 + 链接类型 = 世界"是什么"(语义侧);动作类型 = 世界"怎么变"(动力侧,呼应理念篇的四件套)。
函数(下一篇会深入)则是驱动这些判断与改动的"逻辑"。
## 还有几个重要概念:函数 / 接口 / 角色 / Object Views
先混个脸熟,后面每篇会单独展开。
函数 Function
一段带输入、返回输出的代码逻辑,原生集成进本体:能接收对象/对象集、读属性值,并被动作类型和应用复用。
接口 Interface
描述"对象类型长什么样、能干什么"的本体类型,提供多态——让共享同一形状的类型能被一致地建模与交互。
角色 Roles
本体的核心权限模型。类似文件系统里的角色,可在本体级或单个资源级授予,控制对对象类型/链接类型/动作类型的访问。
Object Views
围绕某个对象的信息与实践中枢:关键信息、链接对象、相关指标,以及分析、看板、应用都汇集于此。
### 练一练:它到底属于哪一类?
点选项,系统自动判分(判分逻辑由共享引擎接管)。
## 一页带走
① 本体 = 世界的分类 把数据集/模型映射成四类概念,构成组织的数字孪生。
② 对象类型/对象/对象集 类 ≈ 表、实例 ≈ 行、集合 ≈ 一组行。
③ 属性 + 链接类型 属性是特征(列),链接类型是关系(join)。
④ 动作类型 定义"世界怎么变"的一组改动(含副作用)。
### 常见问题速答 · FAQ
关于「核心概念(Core concepts)」,读者最常问的几个问题。
本体 = 对世界的"分类"是什么? 原文给本体的定义一句话就说清:本体是对世界的分类(a categorization of the world)。在 Foundry 中,本体就是组织的数字孪生(digital twin)——它把组织的数字资产(数据集、模型)整合成一个连贯的整体。
数据集 vs 本体:一张对照表是什么? 本体的概念和数据表的结构是平行的,原文直接给了这张对照表。
对象类型、对象、对象集是什么? 继续用表格类比:对象类型 ≈ 一张数据集(一类事物的定义);对象 ≈ 表里的一行(一个具体实例)。区别在于,对象不是孤单的一行——它通过链接和别的对象连成网(下一步讲)。
属性(Property)与共享属性是什么? 属性是对象类型上"某个特征"的 schema 定义;属性值则是某个对象在该特征上的具体取值 (类比:列 ≈ 属性,单元格 ≈ 属性值)。
---
## 在 Ontology Manager 里创建接口
- 页面:https://www.hanzhongpin.xyz/ontology/create-interface.html
- 官方原文:https://www.palantir.com/docs/foundry/interfaces/create-interface/
- 主题分组:接口(二)
循序渐进 · 教学 · 接口(二)
# 在 Ontology Manager 里创建接口
跟着步骤在 Ontology Manager 里新建一个接口,并可选地为它添加链接类型和动作类型约束。
## 先记住这几条
① 创建入口是 Ontology Manager 接口在本体管理器里创建。
② 属性映射是核心动作 接口定义哪些属性,后面由对象类型映射过去。
③ 链接类型约束是可选的 接口可以约束链接,但不是必须。
④ 动作类型约束也是可选的 可以声明实现该接口的对象要支持哪些动作。
## 写在前面
按照以下步骤,在 Ontology Manager 中创建一个新的接口。
- 首先,通过左侧面板上方的 Ontologies(本体) 下拉菜单,确认你正在处理所选择的 Ontology。
- 创建新接口,可以任选以下任一方式:
- 在页面右上角,选择 New > Interface(新建 > 接口)。
- 在左侧面板 Resources(资源) 分区下,选择 Interfaces > + New interface(接口 > + 新建接口)。然后在 Interfaces 页面中,从屏幕右上角选择 New interface(新建接口)。
- 创建向导的第一页提供关于接口的说明。选择 Next(下一步)。

- 输入接口的显示名称和 API 名称。你也可以选择性地填写接口描述,并选择一个合适的图标。

- 为接口添加属性。你可以在接口本地定义属性(推荐),也可以使用共享属性。对于每个属性,选择它是必填(required)还是可选(optional)。

对于必填属性,任何实现该接口的对象类型都必须提供从本地属性到接口属性的映射。对于可选属性,实现时可以不提供映射。可选属性在构建 Marketplace 包时很有用——你可以在不引入难以解决的升级阻碍的前提下,对接口进行迭代。
- 选择一个项目用于保存该接口,然后选择 Create(创建)。

- 回到 Ontology Manager,在右上角选择 Save(保存) 以将改动应用到你的 Ontology。
## 创建接口链接类型(可选)
创建接口链接类型(可选)
> 要点:给接口加上链接约束,让实现它的对象类型也满足链接要求。
如果你想让该接口链接到另一个接口或对象类型,可以可选地为其添加接口链接类型。

> 图:添加链接类型约束。
- 在左侧面板选择 Link type constraints(链接类型约束)。
- 然后在右上角选择 Create new link type constraint(新建链接类型约束)。

> 图:创建链接类型约束。
如果某个建模场景要求接口链接类型,那么任何实现该接口的对象类型都必须新增或复用一条满足该接口链接类型约束的链接类型。
## 创建接口动作类型约束(可选)
创建接口动作类型约束(可选)
> 要点:约束实现接口的对象类型必须支持哪些动作。
如果你想让接口定义跨实现对象类型的预期动作能力,可以可选地为其添加接口动作类型约束。

> 图:接口动作类型约束标签页。
- 在左侧面板选择 Action type constraints(动作类型约束)。
- 选择 Create new(新建)。
- 添加约束元数据,选择是否要求实现,并配置参数约束。

> 图:动作类型约束配置对话框。
如果某个建模场景要求接口动作类型约束,那么任何实现该接口的对象类型都必须将该约束映射到一条满足约束的具体动作类型。
### 常见问题速答 · FAQ
关于「在 Ontology Manager 里创建接口」,读者最常问的几个问题。
创建接口链接类型(可选)是什么? 给接口加上链接约束,让实现它的对象类型也满足链接要求。如果你想让该接口链接到另一个接口或对象类型,可以可选地为其添加接口链接类型。
创建接口动作类型约束(可选)是什么? 约束实现接口的对象类型必须支持哪些动作。如果你想让接口定义跨实现对象类型的预期动作能力,可以可选地为其添加接口动作类型约束。
---
## 派生属性(Derived Properties)入门
- 页面:https://www.hanzhongpin.xyz/ontology/derived-properties.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/derived-properties/
- 主题分组:派生属性
循序渐进 · 教学 · 派生属性
# 派生属性(Derived Properties)入门
有些值不必手动维护——比如"这个客户名下有多少笔订单"。派生属性让你在运行时自动算出来。这一篇讲清它是什么、能算什么、为什么安全,并用一个实验室让你亲手感受它的价值。
## 一句话速览
派生属性(Derived Properties)入门:有些值不必手动维护——比如"这个客户名下有多少笔订单"。派生属性让你在运行时自动算出来。这一篇讲清它是什么、能算什么、为什么安全,并用一个实验室让你亲手感受它的价值。
1 运行时现算的值 派生属性(derived property)是在运行时(runtime)根据其他属性或链接(links)计算出来的属性
2 少了一样东西 简言之:存储属性是"记账本上写死的数字",派生属性是"每次打开都重新数一遍的结果"
3 查表与聚合 派生属性的核心,是"顺着链接去算"
4 不会"算"出越权数据 派生属性在计算时,会沿用参与计算的所有对象的安全策略(security)
## 什么是派生属性:运行时现算的值
它不存数据,而是"根据别的东西算出来"。
派生属性(derived property)是在运行时(runtime)根据其他属性或链接(links)计算出来的属性。它不单独存储,而是在被需要时现算——比如"聚合某个链接对象上的属性",或"从被链接的对象上挑选一个属性值"。
Derived properties are properties that are calculated at runtime based on the values of other properties or links on objects.派生属性是在运行时,根据对象上其他属性或链接的值计算出来的属性。
Beta 提示:派生属性目前处于 Beta 阶段,可能不在你的环境可用,且功能在持续演进。本文以官方文档已公开的内容为准。
## 和"存储属性"的区别:少了一样东西
普通属性要靠人/动作去填;派生属性自己会算。
普通(存储)属性
totalOrders = 42
这个值要由数据源导入,或由动作(action)在每次增删时去更新;忘了更新就会失真。
⇄
派生属性
ordersCount = 现算
根据"该客户链接的订单对象"实时算出,永远跟着底层数据走,无需手动维护。
简言之:存储属性是"记账本上写死的数字",派生属性是"每次打开都重新数一遍的结果"。
## 它能算什么:查表与聚合
根据链接是一对一还是一对多,玩法不同。
派生属性的核心,是"顺着链接去算"。链接的形态决定了能做什么:
单链接:查表(select) 顺着"多对一"链接,从被链接的那单个对象上取一个属性值。例如从"订单"指向的"客户",取客户的姓名作为订单上的派生属性。
多链接:聚合(aggregate) 顺着"一对多"链接,对那一组链接对象做统计。常见运算包括计数(count)、求和(sum)、平均(average)、最大(max)、最小(min)等。
> 关键点:算出来的派生属性还能在本请求内继续被过滤、排序、再聚合,形成一条计算链。
## 安全特性:不会"算"出越权数据
它沿用参与计算的所有对象的安全策略。
派生属性在计算时,会沿用参与计算的所有对象的安全策略(security)。换句话说,如果一个用户本来看不到某个链接对象,那么在派生属性里也不会因为"聚合/查表"而意外看到它。
Derived properties use the security of all objects involved in the calculation, so they do not expose information a user would otherwise be unable to see.派生属性沿用计算所涉所有对象的安全策略,因此不会暴露用户本无权查看的信息。
> 提示:这让派生属性能安全地替代很多"预先算好再存储"的方案,又不破坏权限边界。
## 实验室:手动计数器 vs 派生属性
亲手点几下,感受"自动"和"手动"的差距。
实验室:手动维护的计数器 vs 派生属性
+ 新增一笔订单
- 移除一笔订单
手动同步计数器
手动维护的计数器 totalOrders
0
每次增删都要记得点"同步"去更新;忘了就和实际对不上。
尚未同步
派生属性 ordersCount(实时计算)
0
运行时根据链接的订单对象自动算,永远等于真实数量。
始终准确
先点几次"新增订单":左边手动计数器不会自己变,右边派生属性立刻跟上。记得再点"同步"让手动值对齐。
> 对照结论:手动计数器依赖人的纪律,派生属性依赖系统计算——后者在订单频繁变动时几乎不会出错。
## 在哪用、有哪些限制
知道边界,才不会在错误的地方依赖它。
在哪用:在 Ontology Manager 中为一个对象类型配置派生属性(选择基于哪个链接、做查表还是聚合);在代码侧,TypeScript OSDK 通过 withProperties 操作使用它(需 @osdk/client 的 2.2.0-beta.x 及以上版本),用于返回或在后续过滤、聚合、排序中使用。
当前已知限制(Beta):文档列出了这些边界——
- OSv1:含派生属性的查询不能包含仍用 OSv1 索引的对象类型。
- 文本搜索:派生属性不能用于文本搜索或关键词过滤。
- Structs:在 TypeScript OSDK 中,含派生属性的查询暂不能包含 struct 类型属性(可用 $select 排除)。
- Marketplace:使用派生属性的函数暂不支持 Marketplace。
> 记忆点:派生属性擅长"算",但不擅长"被搜索"。为什么文本搜索用不了 →
## 一页带走
① 运行时现算 派生属性不存储,按其他属性或链接在运行时计算,免去手动维护。
② 查表与聚合 单链接查表取值,多链接做 count/sum/average/max/min 等聚合。
③ 安全不越权 沿用参与计算对象的安全策略,不会算出用户本看不到的数据。
④ 边界要记牢 Beta 阶段:不能文本搜索、暂不支持 OSv1/Struct/Marketplace 相关用法。
### 常见问题速答 · FAQ
关于「派生属性(Derived Properties)入门」,读者最常问的几个问题。
什么是派生属性:运行时现算的值? 派生属性(derived property)是在运行时(runtime)根据其他属性或链接(links)计算出来的属性。它不单独存储,而是在被需要时现算——比如"聚合某个链接对象上的属性",或"从被链接的对象上挑选一个属性值"。
和"存储属性"的区别:少了一样东西是什么? 简言之:存储属性是"记账本上写死的数字",派生属性是"每次打开都重新数一遍的结果"。
它能算什么:查表与聚合? 派生属性的核心,是"顺着链接去算"。链接的形态决定了能做什么。
安全特性:不会"算"出越权数据是什么? 派生属性在计算时,会沿用参与计算的所有对象的安全策略(security)。换句话说,如果一个用户本来看不到某个链接对象,那么在派生属性里也不会因为"聚合/查表"而意外看到它。
---
## 用"基于任务的验证"检验本体真的好用
- 页面:https://www.hanzhongpin.xyz/ontology/design-validation.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/ontology-design-validation/
- 主题分组:设计验证(Validation)
循序渐进 · 教学 · 设计验证(Validation)
# 用"基于任务的验证"检验本体真的好用
结构审查只能证明本体"在技术上正确",证明不了"真的被人用好用"。这一篇教你用真实业务问题做演练,让人和 AI 代理都跑一遍,把可用性缺口暴露出来。
## 一句话速览
用"基于任务的验证"检验本体真的好用:结构审查只能证明本体"在技术上正确",证明不了"真的被人用好用"。这一篇教你用真实业务问题做演练,让人和 AI 代理都跑一遍,把可用性缺口暴露出来。
1 结构审查的局限(limits of structural review) 结构审查(structural review)回答的是"本体在语义上连贯、技术上正确吗":对象类型是否代表连贯实体、链接有没有意义的…
2 基于任务的验证(task-based validation) 基于任务的验证补上"能否被使用"的缺口:你用组织的真实业务问题,让未参与构建的人和AI 代理在通用分析工具里独立完成调查,从而验证本…
3 去哪找真实业务问题(sourcing real business questions) 问题要从组织的运营节奏派生:领导反复在问什么?
4 观察 → 该审查什么 对每个问题,记录:是否正确回答、耗时、犹豫点、搜索词、试过的对象类型/链接、是否求助
## 结构审查的局限(limits of structural review)
结构对 ≠ 能用。这是验证要补的缺口。
结构审查(structural review)回答的是"本体在语义上连贯、技术上正确吗":对象类型是否代表连贯实体、链接有没有意义的基数(cardinality)、多个类型是否该共享接口。它能防止不可逆的设计错误,但它评估的是模型内部完整性,确认不了实际可用性。
"Structural correctness does not guarantee operational usability."结构正确,并不保证运维可用性。
关键区别:结构审查是"模型自己对自己"的检查;验证是"让人和代理拿真实问题来用"的演习。前者挡住硬错,后者暴露软坑。
## 什么是基于任务的验证(task-based validation)
用真实问题,让依赖本体的人与代理实跑一遍。
基于任务的验证补上"能否被使用"的缺口:你用组织的真实业务问题,让未参与构建的人和AI 代理在通用分析工具里独立完成调查,从而验证本体的可发现性(discoverability)、表达性(expressiveness)与运维可用性(operational usability)。
"you test the model against the decisions and investigations it must support, with the people and agents who will depend on it."你用模型必须支撑的决策与调查,去测试它——和那些将依赖它的人与代理一起。
"A builder can often navigate these weaknesses from memory, but a builder alone cannot validate the design."构建者常凭记忆绕开弱点,但光靠构建者无法验证设计。
> 为什么非要"未参与构建的人":构建者脑子里装着模型,会本能绕开弱点;只有新手/领域专家的真实路径,才能暴露普通用户会不会卡住。
## 去哪找真实业务问题(sourcing real business questions)
问题别编,从运营节奏里挖。
问题要从组织的运营节奏派生:领导反复在问什么?团队做决策前需要什么信息?哪些报告因为底层难整合而一直补不齐?保留那些"本体表达起来很别扭"的问题——它的失败本身就是设计缺失的信号。
把问题排成三层序列:① 确立情况(哪个客户 / 设施 / 资产)→ ② 追踪贡献因素(订单 / 事件 / 物料)→ ③ 评估影响(风险 / 干预点)。一层层追问,最容易暴露链接与聚合上的断点。
> 窍门:优先选"高后果、常发生"的问题。一个问题牵动多步调查,验证收益最大。
## 设计演练(drill design decisions)
工具、参与者、形式,三个决定先定好。
工具 人员演练只用通用分析应用:Insight、Contour、Quiver。禁用 purpose-built 的 Workshop 应用,也禁用 AI 助手(AIP Analyst / AI FDE)——我们要测的是"本体本身好不好用",不是"定制界面替你铺好了路"。
参与者 优先选未构建本体的领域专家或新用户。团队形式可先无协助尝试,再由教练介入,区分"模型问题"和"知识问题"。
单人 vs 团队 单人隔离测可用性(一个人能否独立跑到答案);团队测共享流利度(大家用本体的说法是否一致)。
练习格式 Quiz-style game:问题开局隐藏、高分给多步难题、指定最不熟悉者操作、必须展示分析路径。Timed drill-down:构建从组织级到颗粒细节的连贯依赖问题链,测总完成时间。
## 读懂结果:观察 → 该审查什么
记录分析路径比记录答案更有信息量;点开看每个观察对应哪条规则。
对每个问题,记录:是否正确回答、耗时、犹豫点、搜索词、试过的对象类型/链接、是否求助。特别注意手动导出 / 自建连接行为——它强烈暗示"业务里有关联,但本体没表示出来"。单次失败可能是边缘案例,重复出现的困惑才是系统问题。
观察到的现象 应审查的规则 / 反模式
无法识别起始对象类型 The Misnomer
同一概念选了不同对象类型 Department Silos
无法在相关概念间移动 / 手动导出或自建连接 Link design
合理路径得到不同答案 Naming conventions
仅构建者或技术用户成功 System Silos
合理路径持续缓慢 Normalization and derived properties
根本找不到合理路径 数据缺失 / 覆盖缺口
下面用点击方式复习一遍映射——读观察,点"点我看该审查什么":
观察:用户盯着本体,却说不出该从哪个对象类型入手
点我看该审查什么 →
观察:同一概念,不同人挑了不同的对象类型
点我看该审查什么 →
观察:用户把数据导出到表格,自己手动 VLOOKUP 关联
点我看该审查什么 →
观察:走通了合理路径,但特别慢
点我看该审查什么 →
## 对比人与代理 · 把验证变成日常
人和代理各跑一遍,缺口在哪一目了然。
对比人与代理(comparing people and agents):用 AIP Analyst / AI FDE 跑同样的问题,只给问题和本体访问权限、不提供人类路径。得到的矩阵很有用:
- 人和代理都成功 → 路径可发现,设计基本稳。
- 代理成、人败 → 检查人机界面、别名、视觉层次(人没找着的,代理靠语义找着了)。
- 人成、代理败 → 识别那些藏在人心里的隐式业务逻辑,考虑补进本体或文档。
- 人和代理都败 → 缺数据 / 缺链接 / 语义缺失,是本体层面的真缺口。
"People and agents must repeatedly move from a consequential question to a trustworthy answer through a path that reflects how the organization actually operates."人和代理必须反复地、沿着反映组织真实运作的路径,从要紧问题走到可信答案。
把验证变成日常(ongoing practice):初始只需少量关键问题、代表参与者、通用应用即可。优先改"影响多道题"的高价值变更,重跑旧题测改进、引入新题测泛化。最终可把问题集发展为对本体的 evaluation suite(评测套件)。
## 互动:跑一遍验证演练(清单)
勾选你已完成哪几步,看看离一次完整验证还差什么。
验证演练清单 · 勾选已完成步骤
- 从运营节奏收集 3–5 个真实业务问题(高后果、常发生)
- 选未参与构建的领域专家 / 新用户作为参与者
- 只用通用分析应用(Insight / Contour / Quiver),禁用 Workshop 与 AI 助手
- 让参与者独立把问题跑到可信答案,记录搜索词与试过的对象类型/链接
- 特别标记"手动导出 / 自建连接"行为作为缺口信号
- 用"观察 → 审查"映射表定位设计缺口
- 用 AIP Analyst / AI FDE 重跑同一问题,对比人与代理
- 把问题集沉淀为本体的 evaluation suite,作为持续实践
> 已勾选 0 / 8 步。完成前 6 步即可跑通第一次验证;7–8 步把它变成长期机制。
## 一页带走
① 结构对 ≠ 能用 结构审查挡硬错;基于任务的验证补"可用性"缺口。
② 用真实问题跑 让未构建的人与代理在通用分析应用里独立调查,记录路径而非只看答案。
③ 观察映射规则 手动连接→Link design;慢→派生属性;同概念多类型→Department Silos。
④ 持续化 人和代理对比找缺口;把问题集做成 evaluation suite,验证变日常。
### 常见问题速答 · FAQ
关于「用"基于任务的验证"检验本体真的好用」,读者最常问的几个问题。
读懂结果:观察 → 该审查什么? 对每个问题,记录:是否正确回答、耗时、犹豫点、搜索词、试过的对象类型/链接、是否求助。特别注意手动导出 / 自建连接行为——它强烈暗示"业务里有关联,但本体没表示出来"。单次失败可能是边缘案例,重复出现的困惑才是系统问题。
对比人与代理 · 把验证变成日常是什么? 对比人与代理(comparing people and agents):用 AIP Analyst / AI FDE 跑同样的问题,只给问题和本体访问权限、不提供人类路径。得到的矩阵很有用。
---
## 把 PDF 变成可检索的知识
- 页面:https://www.hanzhongpin.xyz/ontology/document-processing.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/document-processing/
- 主题分组:文档处理 Document processing
循序渐进 · 教学 · 文档处理 Document processing
# 把 PDF 变成可检索的知识
海量非结构化知识藏在 PDF 和图片里。这一篇讲怎样用 Pipeline Builder 把文档提取成文本、切成小块、嵌入成向量,
最终让语义搜索能精准命中原文——还能把原 PDF 渲染在侧边供核对。
## 一句话速览
把 PDF 变成可检索的知识:海量非结构化知识藏在 PDF 和图片里。这一篇讲怎样用 Pipeline Builder 把文档提取成文本、切成小块、嵌入成向量,最终让语义搜索能精准命中原文——还能把原 PDF…
1 这一篇在讲什么 本篇给出一份基础指南:用 Pipeline Builder 解析 PDF,做语义搜索;
2 数据提取流水线(概览) 要把 PDF 接入语义搜索,原文给出的导入与提取步骤是
3 为什么要"分块(chunking)" 分块,就是把大段文本切成更小的文本段
4 Chunk string 板卡的四个参数 分块由 Pipeline Builder 里的 Chunk string 板完成
## 这一篇在讲什么?
从 PDF / 图片里提取数据,喂给语义搜索。
本篇给出一份基础指南:用 Pipeline Builder 解析 PDF,做语义搜索;并建议在只要纯文本时,
如何在 Workshop 应用里把信息呈现出来。
Semantic search is a powerful tool to use with PDFs, particularly if the content is broken down into smaller "chunks" that are embedded separately, helping users and workflows find important information that might otherwise be hard to access.
语义搜索与 PDF 配合非常强大,尤其是当内容被拆成更小的"块"分别嵌入时——能帮助用户和工作流找到原本难以获取的重要信息。
核心思路一句话:上传 PDF → 提取文本 → 把文本分块 → 对每块做嵌入 → 把结果变成可检索的本体对象,
搜索命中后,把对应的原 PDF 渲染在侧边,供用户"回到源头"核对。
## 数据提取流水线(概览)
用 Pipeline Builder 解析 PDF 的四步。
要把 PDF 接入语义搜索,原文给出的导入与提取步骤是:
步骤 1把 PDF 导入为媒体集
Import the PDFs as a media set
先在 Foundry 里把 PDF 注册成一个"媒体集(media set)",作为后续处理的统一来源。
步骤 2加入 Pipeline Builder
Add the media set to Pipeline Builder
把媒体集作为数据源加进 Pipeline Builder,开始搭建转换流程。
步骤 3Get Media References 板
展开媒体引用
用 Get Media References 板,把媒体集引用展开成可逐条处理的行。
步骤 4Text Extraction 板
抽取纯文本
用 Text Extraction 板,从 PDF / 图片里抽取出纯文本,准备进入分块与嵌入。
点开每一层看细节。这四步产出的是一份"每行一个文档、带 object_text 文本列"的数据集,后面分块就在这上面做。
## 为什么要"分块(chunking)"?
长文本切成小块,再分别嵌入,检索才准。
分块,就是把大段文本切成更小的文本段。原文强调它有两个关键好处:
① 嵌入模型有最大输入长度 超出长度模型装不下;切块保证每段都在上限内。
② 小块语义更清晰 更短的文本在搜索时"语义更独特",更容易被精准命中。
>
关键约束:目标是把长文本切成更小的 chunk,每个 chunk 都关联(link)回原始对象。
这样搜到某个 chunk,就能顺藤摸瓜找到它来自哪份文档的哪一段。
## Chunk string 板卡的四个参数
在 Pipeline Builder 里用 Chunk string 板配置分块;把下面的参数拖到正确解释。
分块由 Pipeline Builder 里的 Chunk string 板完成。加好板后,要配置这几个参数:
点每个参数右边的按钮选解释,答完自动给反馈。
## 分块示例拆解(无代码)
用 Pipeline Builder 把一行文档变成多行 chunk。
原文用一个最简例子演示:一个两行数据集,列是 object_id 和 object_text。
object_id object_text
abc gold ring lost
xyz fast cars zoom
### 逐步发生了什么
① Chunk String 板 新增一列 chunks,是 object_text 被切出的数组。例:["gold","ring","lost"]。文档建议每块约 256 字符、overlap 约 20 字符。
② Explode Array with Position 板 把数组展开成多行,每行带一个 struct:{position, element}。
③ 拉出 position / element 把 struct 里的位置与文本拆成独立列。
④ 造唯一 chunk_id 把数组下标转成字符串拼到原 object_id 上(如 abc_0),并删掉多余列。
最终得到的表里,每行是一个 chunk,带 object_id(用于关联)、新主键 chunk_id、以及要嵌入的 chunk 文本:
object_id chunk chunk_id embedding
abc gold abc_0 [-0.7, …, 0.4]
abc ring abc_1 [0.6, …, -0.2]
abc lost abc_2 [-0.8, …, 0.9]
xyz fast xyz_0 [0.3, …, -0.5]
>
进阶:更复杂的分块策略,原文建议用代码仓库(code repository)写进 pipeline,而非完全无代码。
## 动手演示:一份文档从上传到可检索
点"运行下一步",看 pipeline 如何一步步把 PDF 变成可语义检索的对象。
动手试试 · 文档处理流水线
从"上传 PDF"到"可检索",共 8 步。点"运行下一步"逐步推进。
运行下一步 →
重置
## 一页带走
① 先提文本 PDF → 媒体集 → Pipeline Builder → 提取文本。
② 再分块 chunk size / overlap / separators;每块关联回原对象。
③ 后嵌入 每块调嵌入模型得到向量。
④ 建对象索引 chunk 变对象、可检索,原 PDF 侧边供核对。
### 常见问题速答 · FAQ
关于「把 PDF 变成可检索的知识」,读者最常问的几个问题。
这一篇在讲什么? 本篇给出一份基础指南:用 Pipeline Builder 解析 PDF,做语义搜索;并建议在只要纯文本时,如何在 Workshop 应用里把信息呈现出来。
数据提取流水线(概览)是什么? 要把 PDF 接入语义搜索,原文给出的导入与提取步骤是。
为什么要"分块(chunking)"? 分块,就是把大段文本切成更小的文本段。原文强调它有两个关键好处。
Chunk string 板卡的四个参数是什么? 分块由 Pipeline Builder 里的 Chunk string 板完成。加好板后,要配置这几个参数。
---
## 下拉安全(dropdown security)
- 页面:https://www.hanzhongpin.xyz/ontology/dropdown-security.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/dropdown-security/
- 主题分组:动作类型详解
动作类型详解
# 下拉安全(dropdown security)
对象下拉里的"静态值过滤"可能把敏感信息泄露给看不了对象的人。这一篇讲风险怎么产生、后端如何脱敏,以及该用什么来替代静态值。
## 一句话速览
下拉安全(dropdown security):对象下拉里的"静态值过滤"可能把敏感信息泄露给看不了对象的人。这一篇讲风险怎么产生、后端如何脱敏,以及该用什么来替代静态值。
1 风险从哪来 文档开宗明义地给出了警告:对象下拉校验里的静态值过滤(static value filters),会暴露给所有能查看该动作类型的人
2 Area 51 Investigation 文档举了个例子:有一个 Document 对象,带 Investigation Name 属性
3 技术细节 文档解释了后端通常怎么做:在大多数情况下,动作后端会对动作类型定义里的敏感信息脱敏(redact)
4 防范 把上面的内容收成可执行的建议
## 风险从哪来
一句话:写死的过滤值,会被所有能看动作类型的人看到。
文档开宗明义地给出了警告:对象下拉校验里的静态值过滤(static value filters),会暴露给所有能查看该动作类型的人。使用这类过滤,可能把"属性值的组合"泄露给无权查看被过滤对象的用户。
Static value filters in object dropdown validations are exposed to all users who can view the action type.对象下拉校验中的静态值过滤,会暴露给所有能查看该动作类型的用户。
缓解办法(mitigation)是:改用对象属性或参数来过滤对象集——因为这些值不会直接显示在界面里。
记住这条分界线:只有"静态写死的值"有泄露风险;用参数或对象属性作过滤值,则安全。
## 例子:Area 51 Investigation
一个具体的"过度暴露"场景。
文档举了个例子:有一个 Document 对象,带 Investigation Name 属性。动作里给对象引用参数加过滤,只显示 Investigation Name = "Area 51 Investigation" 的文档。
问题来了:那些根本看不了这些文档的用户,通过这条过滤,反而知道了"存在一些 Document 对象,其 Investigation Name 是 Area 51 Investigation"。这就是把底层数据的存在性泄露了出去。
而且文档强调:这只适用于静态值过滤。如果过滤改成"按参数过滤"或"按另一个对象的属性过滤",就不会有这个问题:
- 按参数过滤:参数值由用户提供,不暴露任何底层数据。
- 按对象属性过滤:会尊重该用户对对象的可见性限制。
> 结论:这两种查询方式都不构成隐私顾虑。下面用"点开看答案"验证几条判断:
- 过滤写死 "Area 51 Investigation" → 点此揭晓
- 过滤值来自用户填的 Name 参数 → 点此揭晓
- 过滤值取另一个对象参数的属性 → 点此揭晓
## 技术细节
后端会脱敏,但"表单网络请求"是个例外。
文档解释了后端通常怎么做:在大多数情况下,动作后端会对动作类型定义里的敏感信息脱敏(redact)。例如提交条件(submission criteria)对不能编辑动作类型的用户是隐藏的;同样地,用户既不会在界面里、也不会在后端响应里看到新的对象下拉过滤。
但有一个关键例外:当用户查看动作表单时,下拉校验会被转换成一个对象集(object set)。这意味着用户可以审查包含该对象集的网络请求。在前面的例子里,用户会收到一个带有 Investigation Name = 'Area 51 Investigation' 过滤的对象集 RID——即便他看不了任何对应对象,也暴露了这个属性值的存在。
these values will not be visible in the interface for any users.这些值对任何用户都不会显示在界面里。
文档还补了一句:如果"可见性"比"安全性"更让你在意,这条警告可以忽略。下面用一个小实验体会"动作定义"和"表单网络请求"的差异:
脱敏检查小实验
分别点两个按钮,看后端对"动作定义"和"表单网络请求"的处理有何不同。
查看动作类型定义
查看表单网络请求
你能看到 — —
> 点击上面按钮。
## 怎么防范
一句话:别用静态值过滤敏感字段,改用参数或对象属性。
把上面的内容收成可执行的建议:
- 用参数或对象属性过滤替代写死的静态值,值不会直接暴露在界面里。
- 敏感字段不要写进过滤值尤其是不希望被人知道"存在与否"的属性。
- 理解"界面不可见 ≠ 网络请求不可见"表单渲染时校验会变成对象集,可能被审查请求的人看到。
- 按风险权衡若可见性优先于安全,文档说该警告可忽略——但默认应保守。
> 回顾:这一页接在"参数过滤"之后。过滤本身好用,但"值从哪来"决定了安不安全。
## 一页带走
① 静态值有风险 写死过滤值会暴露给所有看动作类型的人。
② 参数/属性安全 用它们过滤,值不直接显示且尊重可见性。
③ 界面≠请求 表单网络请求可能带出对象集过滤。
④ 用参数替代 敏感字段别写死,改用参数或对象属性。
### 常见问题速答 · FAQ
关于「下拉安全(dropdown security)」,读者最常问的几个问题。
风险从哪来是什么? 文档开宗明义地给出了警告:对象下拉校验里的静态值过滤(static value filters),会暴露给所有能查看该动作类型的人。使用这类过滤,可能把"属性值的组合"泄露给无权查看被过滤对象的用户。
Area 51 Investigation是什么? 文档举了个例子:有一个 Document 对象,带 Investigation Name 属性。动作里给对象引用参数加过滤,只显示 Investigation Name = "Area 51 Investigation" 的文档。
技术细节是什么? 文档解释了后端通常怎么做:在大多数情况下,动作后端会对动作类型定义里的敏感信息脱敏(redact)。例如提交条件(submission criteria)对不能编辑动作类型的用户是隐藏的;同样地,用户既不会在界面里、也不会在后端响应里看到新的对象下拉过滤。
---
## 不止改字段:动作类型还能做哪些事
- 页面:https://www.hanzhongpin.xyz/ontology/explore-action-types.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/explore-action-types/
- 主题分组:动作类型详解
动作类型详解
# 不止改字段:动作类型还能做哪些事
快速开始只做了"改一个属性",而动作类型(action type)的配置面能表达远不止属性编辑——这一篇逐一认识可用的规则。
## 一句话速览
不止改字段:动作类型还能做哪些事:快速开始只做了"改一个属性",而动作类型(action type)的配置面能表达远不止属性编辑——这一篇逐一认识可用的规则。
1 从"改一个属性"到"改变本体" 快速开始里建的那个动作类型(action type),本质是一条"修改单个对象某个属性"的规则(rule)
2 向导 vs 详情页 新建向导会配置一个新动作类型的第一条规则:在 Action type 步打开 Object 标签、选对象类型,再在 Object a…
3 创建、修改、删除对象 快速开始改的是"用户选中的对象"
4 管理与对象之间的链接 该用哪条规则,取决于链接类型(link type)的基数(cardinality)
## 从"改一个属性"到"改变本体"
动作类型能表达的能力,远超一次属性编辑。
快速开始里建的那个动作类型(action type),本质是一条"修改单个对象某个属性"的规则(rule)。但同一个配置面还能让你:创建和删除对象、管理对象之间的链接(link)、用函数(function)跑自定义逻辑、调用外部系统、通知用户、触发构建(build),以及合并场景(scenario)里的暂存编辑。
这一篇用快速开始里的 Demo Ticket 对象类型当例子,方便你接着同一个本体(Ontology)往下做。下面这张表把"想达成的目标"和"该加哪条规则"对应起来。
想做的事 该加的规则
创建一个新对象 Create object
用户没提供对象时也能建 Create or modify object
删除已有对象 Delete object
关联 / 解除两个对象 Create link / Delete link
规则描述不清的逻辑 Run function
通知有变动的用户 Notification
应用后重算数据集 Schedule
下面动手练:把左边的"目标"点选到右边正确的规则上。
## 规则加在哪里:向导 vs 详情页
规则(rules)可以从两个地方添加。
新建向导会配置一个新动作类型的第一条规则:在 Action type 步打开 Object 标签、选对象类型,再在 Object actions 下选这个动作要做的改动,并在 Mapping 步挑选包含的属性。
对于一个已经存在的动作类型,则在 Ontology Manager 里打开它,切到 Rules 标签,点 Add new rule 选择需要的规则。本页讲到的每条规则都能在这里加。
重要:单个动作类型可以组合多条规则;但 Run function 规则是例外——它不能和其他 Ontology 规则组合,因为函数代码本身就能表达其他规则能做的全部事情。
## 创建、修改、删除对象
这几条规则直接增删改本体里的对象。
快速开始改的是"用户选中的对象"。若想改成新建一张工单,就加一条 Create object 规则并选 Demo Ticket 对象类型。对象类型的主键(本例是 Ticket ID)是必填属性,必须填上;再用 Add property 把 Title、Status、Priority 等其它属性加进来。
每加一个属性,系统会自动创建一个同名参数(parameter)并把它映射到该属性。你也可以把属性映射到"对象引用参数的某个属性"、一个用户改不了的静态值(static value),或"当前用户 / 提交时间"。
另两条相关规则:
- Create or modify object:改对象引用参数提供的对象;若没提供,则新建一个(自动生成唯一 ID,或用用户提交的主键)。
- Delete object:删除对象引用参数提供的对象;它不能引用同一个动作里新建的对象。
> 注意组合顺序:当动作含多条规则时,Foundry 会把它们编译成"每个对象一次编辑",规则顺序会影响结果,且有些组合不被支持(见《动作·规则》)。
## 管理与对象之间的链接
动作既能改属性,也能维护对象间的关系。
该用哪条规则,取决于链接类型(link type)的基数(cardinality):
- 多对多(many-to-many):加 Create link 规则关联两个由对象引用参数提供的对象,或加 Delete link 规则解除关系。
- 一对一 / 一对多:关系存在对象的外键(foreign key)属性上,要用 Modify object 规则去设置或清空那个外键属性,而不是用链接规则。
你还可以在同一个动作里既创建对象又建好它的多对多链接:先配置 Create object 规则(对象类型要带多对多链接类型),再在 Add property 下方点 Add link 选择链接类型并配置。
## 函数、外部系统与其它能力
当声明式映射不够用时,还有这些规则可用。
Run function(跑自定义逻辑)
规则用"声明式映射"描述编辑,但有时不够——比如要改"用户选中的对象所关联的所有对象"、要从读多个对象的业务逻辑里算出某属性、或要建多种类型的对象并互相链接。这时就加一条 Run function 规则,选已发布的 Ontology edit function(本体编辑函数)及其版本。函数的每个输入都会变成一个参数,可像其它参数一样加约束。注意:它不能和其他 Ontology 规则组合。默认动作停留在你选的版本上,也可开启 auto upgrades 在运行时解析版本区间。
Webhook(调用外部系统)
当某个外部系统才是流程的"真相源"时,webhook 规则会在应用动作时向该系统发请求,并可以把动作参数作为输入传过去。两条规则时机不同:
- Webhook:在对象编辑应用之后发送(Side Effects 组);可有多个;失败不展示给终端用户。
- Writeback Webhook:在任何其它规则评估之前发送(External Request 组);失败则编辑不应用、用户可见失败;只能有一个,其输出参数可供后续规则使用。
Notification / Schedule / Apply scenario / Interface 规则
Notification 规则在动作应用后通知用户(内容用动作前本体状态生成);Schedule 规则(Advanced 组)在动作应用后触发一次构建;Apply scenario 把场景里的暂存编辑作为单笔事务提交(需要持有场景 RID 的 Scenario 参数);实现某个接口(interface)的对象类型,则有专门的 Interface 规则族(Create/Modify/Delete object of interface 等)。
Action types can express much more than a property edit.动作类型能表达的,远不止一次属性编辑。
## 一页带走
① 规则是能力的入口 Create/Delete object、link、function、webhook、notification、schedule 都在 Rules 里加。
② 两条添加路径 新建向导配第一条规则;已有动作在 Ontology Manager 的 Rules 标签追加。
③ 链接看基数 多对多用 link 规则,一对一/多对多用 Modify object 改外键。
④ function 是例外 Run function 不能与其它 Ontology 规则组合,它 alone 表达一切。
### 常见问题速答 · FAQ
关于「不止改字段:动作类型还能做哪些事」,读者最常问的几个问题。
从"改一个属性"到"改变本体"是什么? 快速开始里建的那个动作类型(action type),本质是一条"修改单个对象某个属性"的规则(rule)。但同一个配置面还能让你:创建和删除对象、管理对象之间的链接(link)、用函数(function)跑自定义逻辑、调用外部系统、通知用户、触发构建(bui…
规则加在哪里:向导 vs 详情页是什么? 新建向导会配置一个新动作类型的第一条规则:在 Action type 步打开 Object 标签、选对象类型,再在 Object actions 下选这个动作要做的改动,并在 Mapping 步挑选包含的属性。
创建、修改、删除对象是什么? 快速开始改的是"用户选中的对象"。若想改成新建一张工单,就加一条 Create object 规则并选 Demo Ticket 对象类型。对象类型的主键(本例是 Ticket ID)是必填属性,必须填上。
管理与对象之间的链接是什么? 该用哪条规则,取决于链接类型(link type)的基数(cardinality)。
---
## 从函数里调用外部 API
- 页面:https://www.hanzhongpin.xyz/ontology/fn-api-calls.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/api-calls/
- 主题分组:函数(十六)
循序渐进 · 教学 · 函数(十六)
# 从函数里调用外部 API
函数可以调外部系统,但必须先在平台上配置数据源和凭据。这篇讲配置外部 API 访问、在函数里使用、OAuth 2.0,以及常见报错排查。
## 先记住这几条
① 必须先配置外部源 不能直接在代码里写死地址和密码,要先在平台登记 source。
② 凭据由平台托管 函数里拿到的是预配置好的 client,不接触明文密钥。
③ OAuth 2.0 有专门流程 需要 outbound application 配合,有几种用法可选。
④ 常见报错是代理认证 HTTP 407 是最高频的报错,原因通常是出口代理没配好。
## 写在前面
可以从 TypeScript v1、TypeScript v2 与 Python 函数向外部源发起 API 调用,但这需要额外的配置。下面的内容与外部源的使用一起详细说明了这些配置。
:::callout{theme="neutral" title="Source aliases"}
对于 TypeScript v2 与 Python 函数,我们建议通过源别名(source aliases)引用源。源别名是一个可移植的、具名的引用,你可以将它作为源标识符,替代具体的源。当你的函数通过 Marketplace 产品 分发时,别名可以按环境重新映射到不同的源,从而保持你的函数代码可移植。TypeScript v1 函数使用生成的源符号,不支持别名。
## 配置外部 API 访问
配置外部 API 访问
> 要点:第一步永远是配置,代码之前先把通路打通。
默认情况下,函数不允许调用外部 API。要启用从函数调用外部系统,你必须在 Data Connection 中配置一个源,以允许 Foundry 与该外部系统连接。
为了让函数安全地连接到你源的外部系统,你的源必须配置为启用导出,并允许将源导入 Code Repositories。这两项都可以通过在 Data Connection 中导航到该源并打开 Connection settings(连接设置) 部分来配置。
对于 TypeScript v1 函数,源的 API 名称(在 Connection settings 下的 Code import configuration 标签页配置)是你在代码中引用的标识符。
请务必在你的源中完整配置证书链。
Webhook 与函数的运行时环境并不完全相同。
有时,webhook 能正常工作,而从函数发起的 API 调用却可能遇到 UNABLE_TO_GET_ISSUER_CERT 错误。
请参阅我们关于源终端中 openssl 命令的文档来验证证书。
## 在函数里使用外部源
在函数里使用外部源
> 要点:配置好之后,代码里如何引用。
要从函数发起 API 调用,你必须首先使用资源导入侧边栏将你的源导入一个函数仓库。对于 TypeScript v2 与 Python 函数,我们随后建议创建一个源别名,并使用其别名键作为源标识符。TypeScript v1 函数直接引用导入的源。然后你必须声明你的函数使用了该源,如下面示例所示。
示例如下:
TypeScript v1 TypeScript v2 Python import { ExternalSystems } from "@foundry/functions-api";
import { MySource } from "@foundry/external-systems/sources";
export class MyExternalFunctions {
@ExternalSystems({ sources: [MySource] })
@Function()
public async myExternalFunction(): Promise {
const { url } = MySource.getHttpsConnection();
const response = await MySource.fetch(url);
return response.text();
}
} import { getSource, getHttpsConnection, getFetch } from "@palantir/functions-sources";
export const config = {
sources: ["mySourceAlias"]
}
async function MyExternalFunction(): Promise {
const source = await getSource("mySourceAlias");
const { url } = getHttpsConnection(source);
const fetch = await getFetch(source);
const response = await fetch(url);
return response.text();
} from functions.api import function
from functions.sources import get_source
@function(sources=["mySourceAlias"])
def my_external_function() -> str:
source = get_source("mySourceAlias")
url = source.get_https_connection().url
client = source.get_https_connection().get_client()
response = client.get(url)
return response.text
你可以在实时预览中测试你的函数,并在发布后使用它发起外部调用。
在 serverless 执行或实时预览中,尚不支持使用第三方客户端,除非覆写 fetch 函数或 HTTP agent。为确保你的 API 调用在所有环境中都能正常工作,你必须使用相关的库方法来发起带正确配置的请求。对外部源或内部 Foundry URL 的直接 API 调用,不能保证在所有环境中都有效。
## 访问源属性与凭据
访问源属性与凭据
> 要点:怎么拿到地址和凭据(注意:不写死在代码里)。
你可以访问每种函数类型对应库所提供的源属性。
下面的示例展示了如何获取上面例子中源的 base URL。
TypeScript v1 TypeScript v2 Python const { url } = MySource.getHttpsConnection(); const { url } = getHttpsConnection(source); url = get_source("mySourceAlias").get_https_connection().url
你也可以使用以下语法访问源上存储的额外密钥或凭证:
TypeScript v1 TypeScript v2 Python const secret = MySource.getSecret("MySecret"); const secret = source.secrets["MySecret"]; secret = get_source("mySourceAlias").get_secret("MySecret")
## 使用预配置客户端
使用预配置客户端
> 要点:直接用平台准备好的 client,省去认证细节。
对于提供 REST API 的源,源对象允许你获取一个客户端。该客户端会预配置源上指定的服务端证书与客户端证书。它还会包含额外的代理配置,允许从函数执行所在环境向外出口(egress)。如果可能,你应当始终使用这个客户端,以保证你的函数能从所有环境出口到该源。
TypeScript v1 TypeScript v2 Python const fetch = MySource.fetch; const fetch = await getFetch(source); client = source.get_https_connection().get_client()
另外,你也可以使用自己的客户端或发起外部请求的第三方库,并用源对象获取属性与凭证。
TypeScript v2 函数提供了一个预配置的 HTTP agent,作为接受自定义 HTTP agent 的第三方库的额外集成点。
下面的示例演示了获取该 agent 并将其用于 axios ↗。
TypeScript v2 import { getHttpAgent, getHttpsConnection } from "@palantir/functions-sources";
import axios from 'axios';
const agent = await getHttpAgent(source);
const { url } = getHttpsConnection(source);
const response = await axios.get(url, {
httpsAgent: agent,
});
> 目前,除非源提供 HTTPS 客户端,否则无法访问非凭证类的源属性。例如,你将无法访问 PostgreSQL 源 上的 hostname 或其他非密钥属性。
## 用 OAuth 2.0 出向应用
用 OAuth 2.0 出向应用
> 要点:三种用法:预配置 client、原生 HTTP 手动注入 token、在动作里使用。
如果你的外部 API 需要 OAuth 2.0 授权,你可以在 Control Panel 中配置一个出站应用(outbound application),并将其用作 REST API 源的认证方法。当你的函数运行时,源会将调用用户的 OAuth 访问令牌作为会话凭证暴露出来。你的函数随后可以使用该令牌,代表用户调用外部 API。
这种模式在 Python 与 TypeScript v2 函数中受支持。代码示例如下,见使用源预配置的客户端。
### Limitations
- TypeScript v1: TypeScript v1 函数无法直接从容中获取 OAuth 令牌。要从 TypeScript v1 函数认证一个 OAuth 2.0 API,请将调用包装在配置了出站应用的 REST API 源上的一个 webhook 中。如需直接获取令牌,请考虑迁移到 TypeScript v2。
- 部署模式: 当函数在部署模式下运行时,OAuth 令牌刷新不可用。如果调用用户的访问令牌在执行期间过期,函数无法自动刷新它。请在 serverless 模式 下运行函数,以使用 OAuth 支撑的出站应用。
- 在 Workshop 中直接使用函数: 直接在 Workshop 模块中使用的函数,例如函数支撑的变量或填充组件内容的函数,无法触发 OAuth 2.0 的交互式授权提示。如果用户尚未授权该出站应用,函数会失败,而非显示提示。要从 Workshop 使用 OAuth 支撑的函数,请将其包装在一个函数支撑的动作中。或者,确保在函数于 Workshop 中被直接调用之前,用户已从另一个交互式界面(例如针对同一出站应用的函数支撑动作)完成授权流程。
### Use the source's pre-configured client
最简单的方法是使用源提供的 HTTP 客户端。Authorization 头会被自动注入。
Python TypeScript v2 from functions.api import function
from functions.sources import get_source
@function(sources=["myOAuthSourceAlias"])
def call_external_api() -> str:
source = get_source("myOAuthSourceAlias")
url = source.get_https_connection().url
client = source.get_https_connection().get_client()
response = client.get(url + "/api/v1/resource", timeout=10)
return response.text import { getSource, getHttpsConnection, getFetch } from "@palantir/functions-sources";
export const config = {
sources: ["myOAuthSourceAlias"]
};
export default async function callExternalApi(): Promise {
const source = await getSource("myOAuthSourceAlias");
const { url } = getHttpsConnection(source);
const fetch = await getFetch(source);
const response = await fetch(url + "/api/v1/resource");
return response.text();
}
### Use a native HTTP client with manual token injection
如果你需要使用自己的 HTTP 客户端而非源提供的那个,请从会话凭证中获取 OAuth 令牌,并手动设置 Authorization 头。
Python TypeScript v2 import requests
from functions.api import function
from functions.sources import get_source
from external_systems.sources import OauthCredentials, Refreshable, SourceCredentials
@function(sources=["myOAuthSourceAlias"])
def call_external_api() -> str:
source = get_source("myOAuthSourceAlias")
url = source.get_https_connection().url
refreshable_credentials: Refreshable[SourceCredentials] = source.get_session_credentials()
session_credentials: SourceCredentials = refreshable_credentials.get()
if not isinstance(session_credentials, OauthCredentials):
raise ValueError("Expected OAuth credentials")
access_token: str = session_credentials.access_token
response = requests.get(
url + "/api/v1/resource",
headers={"Authorization": f"Bearer {access_token}"},
timeout=10,
)
return response.text import { getSource, getHttpsConnection } from "@palantir/functions-sources";
export const config = {
sources: ["myOAuthSourceAlias"]
};
export default async function callExternalApi(): Promise {
const source = await getSource("myOAuthSourceAlias");
const credentials = await source.sessionCredentials?.get();
if (!credentials || credentials.type !== "oauth") {
throw new Error("Expected OAuth credentials");
}
const accessToken: string = credentials.accessToken;
const { url } = getHttpsConnection(source);
const response = await fetch(url + "/api/v1/resource", {
headers: { Authorization: `Bearer ${accessToken}` },
});
return response.text();
}
### Use OAuth-backed functions in actions
一个常见模式是调用一个 OAuth 支撑的外部 API,并将结果喂给一个 Ontology 编辑。随后你可以通过一个函数支撑的动作暴露该函数。当用户从 Workshop 或 AIP Studio 运行该动作时,他们的 OAuth 令牌被用于发起 API 调用,所产生的对象编辑也归属于他们。
例如,下面的函数使用 OAuth 令牌从第三方身份服务获取调用用户的资料,然后使用该信息创建一个新的 Ontology 对象:
Python TypeScript v2 from functions.api import function, OntologyEdit
from functions.sources import get_source
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import UserProfile
@function(sources=["myOAuthSourceAlias"], edits=[UserProfile])
def link_user_profile() -> list[OntologyEdit]:
source = get_source("myOAuthSourceAlias")
url = source.get_https_connection().url
client = source.get_https_connection().get_client()
response = client.get(url + "/v1/me", timeout=10)
response.raise_for_status()
profile = response.json()
ontology_edits = FoundryClient().ontology.edits()
ontology_edits.objects.UserProfile.create(
profile["id"],
display_name=profile["display_name"],
)
return ontology_edits.get_edits() import { getSource, getHttpsConnection, getFetch } from "@palantir/functions-sources";
import { UserProfile } from "@ontology/sdk";
import { Client } from "@osdk/client";
import { createEditBatch, Edits } from "@osdk/functions";
type OntologyEdit = Edits.Object;
export const config = {
sources: ["myOAuthSourceAlias"],
edits: [UserProfile],
};
export default async function linkUserProfile(client: Client): Promise {
const source = await getSource("myOAuthSourceAlias");
const { url } = getHttpsConnection(source);
const fetch = await getFetch(source);
const response = await fetch(url + "/v1/me");
if (!response.ok) {
throw new Error(`Failed to fetch profile: ${response.status}`);
}
const profile = await response.json();
const batch = createEditBatch(client);
batch.create(UserProfile, {
userProfileId: profile.id,
displayName: profile.display_name,
});
return batch.getEdits();
}
## 常见错误排查
常见错误排查
> 要点:HTTP 407 代理认证等高频问题的处理。
对于 OAuth 授权错误,例如 HTTP 401: Unauthorized、Credentials expired and no refresh handler provided,或 Resolved source credentials are not present on the Source,请参阅 Data Connection 故障排查参考中的 OAuth 与出站应用。
### HTTP 407: Proxy authentication required
函数的网络请求必须被你的源的出口策略(egress policies)覆盖。如果目标主机名与允许的策略不匹配,请求可能返回 HTTP 407: Proxy Authentication Required。
如果你的出口策略看起来正确,请检查请求 URL 是如何构建的。getHttpsConnection() 返回的 URL 没有尾部斜杠,因此附加的路径如果省略了前导 /,会被拼接到主机名上:
text "https://example.com" + "api/v1"
→ "https://example.comapi/v1"
结果的主机名(example.comapi)不被任何出口策略覆盖,因此请求被拒绝。请在路径前加上 /(例如 url + "/api/v1")。
### 常见问题速答 · FAQ
关于「从函数里调用外部 API」,读者最常问的几个问题。
配置外部 API 访问是什么? 第一步永远是配置,代码之前先把通路打通。默认情况下,函数不允许调用外部 API。要启用从函数调用外部系统,你必须在 Data Connection 中配置一个源,以允许 Foundry 与该外部系统连接。
在函数里使用外部源是什么? 配置好之后,代码里如何引用。要从函数发起 API 调用,你必须首先使用资源导入侧边栏将你的源导入一个函数仓库。对于 TypeScript v2 与 Python 函数,我们随后建议创建一个源别名,并使用其别名键作为源标识符。
访问源属性与凭据是什么? 怎么拿到地址和凭据(注意:不写死在代码里)。你可以访问每种函数类型对应库所提供的源属性。
使用预配置客户端是什么? 直接用平台准备好的 client,省去认证细节。对于提供 REST API 的源,源对象允许你获取一个客户端。该客户端会预配置源上指定的服务端证书与客户端证书。它还会包含额外的代理配置,允许从函数执行所在环境向外出口(egress)。
---
## 分支上的函数开发
- 页面:https://www.hanzhongpin.xyz/ontology/fn-branching-functions.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/branching-functions/
- 主题分组:函数(八)
循序渐进 · 教学 · 函数(八)
# 分支上的函数开发
函数可以在分支(branch)上开发、发布和消费,这样改动不会直接影响主线。这一篇讲分支开发流程、冲突解决与合并。
## 先记住这几条
① 分支隔离改动 在分支上开发和发布函数,主线不受影响。
② 支持 v1 / v2 / AIP Logic TypeScript v1、v2 与 AIP Logic 函数支持分支。
③ 冲突要 rebase 解决 分支落后于主线时,用 rebase 处理冲突。
④ 合并回主线才生效 分支上的函数最终要合并,才能进入正式使用。
## 写在前面
你可以在全局分支(global branch)上开发、发布并使用函数。目前 TypeScript v1、TypeScript v2 和 AIP Logic 函数支持此特性。
你不能修改分支上的 Python 函数。若要在合并进 main 之前测试,可引用分支上的特定函数版本。函数代码只能使用存在于 main 上的 schema。
## 在分支上开发
在分支上开发
> 要点:分支上的开发、发布、消费流程与主线一致,但作用域隔离。
在全局分支上开发 TypeScript 函数之前,请确保你的仓库满足以下要求。要使用 TypeScript v1 的 Global Branching,请将 functions-typescript 子模板升级到 0.903.0 或更高版本;具体步骤参见仓库升级文档。要使用 TypeScript v2 的 Global Branching,请将 typescript-functions 父模板升级到 0.1299.0 或更高版本,并启用本地 Ontology SDK。
你可以开发一个依赖全局分支上资源改动的函数,例如新建或修改过的 Ontology 实体。

> 图:在分支上开发新函数。
就绪后,用一个版本目标(version target)发布你的函数——即在全局分支合并时发布到 main 的稳定版本。在分支开发期间,函数以不稳定的预览版本形式发布。

> 图:在分支上发布函数。
成功在分支上发布函数后,你就可以在 Workshop、AIP Logic 和函数支撑的动作中使用分支上的新函数版本。该版本会打上 Branched pre-release(分支预发布) 标签。分支上发布的函数在其他分支(包括 main)上不可访问。

> 图:在 Workshop 中使用分支函数。

> 图:在动作中使用分支函数。
目前在 TypeScript v1 仓库中,无法依赖查询函数的分支版本。
在分支上持续开发时,你可以不断地往同一个版本目标发布函数版本。只要版本目标保持不变,任何使用你函数的资源都会自动拉取最新发布的版本。这让你无需在每次发布后手动更新函数引用,即可快速迭代。
如果分支上的版本目标发生变化,你必须把所有在分支上使用了旧版本的函数依赖方更新到新版本目标。这也会以检查项的形式显示出来。
## 冲突解决与 rebase
冲突解决与 rebase
> 要点:主线有更新时,把分支 rebase 上去解决冲突。
在分支上开发时,你不会自动收到发布到 main 的更新函数版本。这能防止 main 的开发干扰你的分支工作。如果 main 上有更新的版本可用,你会在函数版本选择器和 Ontology Manager 中看到通知。随后你可以对函数版本执行 rebase(变基),以拉取 main 上的所有更新版本。

> 图:变基函数对话框。
如果你的版本目标在开发期间被发布到 main,你必须在合并前选择一个新的版本目标。一旦选定,更新所有依赖方以使用新的版本目标。
## 合并回主线
合并回主线
> 要点:验证通过后合并,函数才算正式进入主线。
合并全局分支时,被修改的函数会以稳定版本目标发布到 main。使用分支上所发布版本的资源,会自动开始使用合并时发布到 main 的新稳定版本。
Foundry 只会把你的版本目标合并进 main,不会合并在分支上发布的其他版本。这些版本在分支合并后不会存在于 main 上。
### 常见问题速答 · FAQ
关于「分支上的函数开发」,读者最常问的几个问题。
在分支上开发是什么? 分支上的开发、发布、消费流程与主线一致,但作用域隔离。在全局分支上开发 TypeScript 函数之前,请确保你的仓库满足以下要求。要使用 TypeScript v1 的 Global Branching,请将 functions-typescript 子模板…
冲突解决与 rebase是什么? 主线有更新时,把分支 rebase 上去解决冲突。在分支上开发时,你不会自动收到发布到 main 的更新函数版本。这能防止 main 的开发干扰你的分支工作。
合并回主线是什么? 验证通过后合并,函数才算正式进入主线。合并全局分支时,被修改的函数会以稳定版本目标发布到 main。使用分支上所发布版本的资源,会自动开始使用合并时发布到 main 的新稳定版本。
---
## 部署型函数:常驻执行模式
- 页面:https://www.hanzhongpin.xyz/ontology/fn-deployed.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/functions-deployed/
- 主题分组:函数(十八)
循序渐进 · 教学 · 函数(十八)
# 部署型函数:常驻执行模式
函数默认是无服务器(serverless)的,但也可以部署成常驻服务。这篇讲两种执行模式怎么选、部署架构长什么样。
## 先记住这几条
① 两种模式:serverless 与 deployed serverless 按需启动省事,deployed 常驻省冷启动。
② 选型的取舍 冷启动敏感、需要长连接的场景更适合 deployed。
③ 部署有前置条件 不是所有语言/场景都能直接部署。
④ 架构上有额外组件 部署模式会引入常驻实例,运维责任更重。
## 写在前面
## 前置条件
前置条件
> 要点:部署前必须满足的条件,先核对再动手。
本指南要求你已编写并发布了一个 Python 或 TypeScript v2 函数。关于教程,请查阅 Python 函数上手或 TypeScript v2 函数上手文档。
## 两种执行模式怎么选
两种执行模式怎么选
> 要点:对比维度与选型建议。
如果你的租户启用了 serverless 函数,新仓库默认会使用它。对于大多数场景,我们通常建议使用 serverless 函数。虽然部署式(deployed)函数在某些情形下有用,但 serverless 执行模式需要更少的维护,且能避免与长期运行的部署相关的开销。
部署式函数拥有一些 serverless 函数不具备的能力:
- 部署式函数长期运行的性质意味着,如果函数能够容忍重启,则可能实现本地缓存。
- Serverless 函数支持使用所提供的源对象上的客户端调用外部源,但不支持第三方客户端。你必须部署你的函数,才能用第三方客户端发起外部 API 调用。
- 部署式函数支持 GPU 分配,通过并行处理加速计算密集的模型训练与推理工作流,而 serverless 函数不支持。
- 部署式函数可以访问完整的服务发现(service discovery)API,而 serverless 函数只能访问有限的服务发现 API 子集,例如 api_gateway 和 telemetry。
部署式函数也有一些不适用于 serverless 执行的限制:
- Serverless 函数支持按需执行同一函数的不同版本,使升级更安全。而部署式函数同一时刻只能运行一个函数版本。
- Serverless 函数仅在执行时产生费用,而部署式函数只要部署在运行就会产生费用。
- Serverless 函数需要更少的前期搭建与长期维护,因为基础设施是自动管理的。
要为你的租户启用 serverless 函数,请联系你的 Palantir 管理员。
## 部署架构
部署架构
> 要点:部署后的整体结构,理解它才能排查问题。
函数可以以 serverless 模式运行(利用按需资源),也可以被部署到一个长期运行的容器中。
> 如果你的租户已启用,我们建议使用 serverless 函数而非部署式函数。尽管某些情况下部署式函数很有用,但 serverless 执行器通常更灵活。
当你的函数被部署时,会创建一个长时运行的环境来处理进入的执行请求。该环境会根据请求量自动扩缩容,并偶尔被自动化进程重启。来自同一仓库的所有函数都由同一个部署托管。
函数的执行模式与部署配置,在函数通过 Marketplace 分发时会被打包并复现。详情与限制见部署式函数在 Marketplace 中。
:::callout{theme="warning" title="计算成本"}
部署式函数会就运行中的部署产生计算成本。Serverless 函数仅在执行时产生成本。
## Deploy a function
Deploy a function
按照以下步骤配置并部署一个函数:
- 打开你的函数仓库,导航到 Branches(分支) 标签页,然后选择 Tags and releases(标签与发布)。
- 悬停在你想要部署的函数上,然后选择 Open in Ontology Manager(在 Ontology Manager 中打开)。

> 图:在 Ontology Manager 中打开所选函数。
- 从左侧的版本选择器中选择你想使用的函数版本。
- 选择 Configure execution(配置执行)。

> 图:配置函数的执行。
- 如果你的环境中启用了 serverless 函数,你会看到在 serverless 与 deployed 之间切换的选项。如果未选择且不存在部署,默认使用 serverless。

> 图:函数在 serverless 模式下的设置。
- 选择 Deployed(部署式) 执行模式选项。
- 如果函数还没有部署,选择 Create deployment(创建部署)。

> 图:函数在 deployed 模式下、尚无已有部署时的设置。
- 部署首次创建时,会应用默认配置。你可以滚动到页面底部查看完整配置。

> 图:函数在 deployed 模式下的设置。
- 按需修改部署配置。你可以配置以下内容:
- 分配给部署的计算资源,包括 CPU、GPU 和内存。
- 基于请求负载的自动扩缩容最小值与最大值。
- 部署启动时将设置的环境变量。
- 函数在返回超时错误之前被允许运行的总时长。与其他部署设置不同,超时是针对每个函数版本单独配置的。

> 图:修改函数在 deployed 模式下的内存分配。
- 选择 Save and start deployment(保存并启动部署),保存任何改动并启动部署。你也可以选择 Save without starting deployment(保存但不启动部署),仅保存配置而不启动部署。

> 图:保存并启动函数在 deployed 模式下的部署。
- 如果你选择了 Save and start deployment,需要等待托管该函数的部署启动完成。这可能需要几分钟。
- 要验证部署是否运行,导航到包含该函数的代码仓库并运行该函数。函数应当成功执行并返回预期结果。

> 图:在 deployed 模式下运行一个函数。
### 常见问题速答 · FAQ
关于「部署型函数:常驻执行模式」,读者最常问的几个问题。
前置条件是什么? 部署前必须满足的条件,先核对再动手。本指南要求你已编写并发布了一个 Python 或 TypeScript v2 函数。关于教程,请查阅 Python 函数上手或 TypeScript v2 函数上手文档。
两种执行模式怎么选? 对比维度与选型建议。如果你的租户启用了 serverless 函数,新仓库默认会使用它。对于大多数场景,我们通常建议使用 serverless 函数。
部署架构是什么? 部署后的整体结构,理解它才能排查问题。函数可以以 serverless 模式运行(利用按需资源),也可以被部署到一个长期运行的容器中。
---
## 本体编辑(Ontology edits)总览
- 页面:https://www.hanzhongpin.xyz/ontology/fn-edits-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/edits-overview/
- 主题分组:函数(十三)
循序渐进 · 教学 · 函数(十三)
# 本体编辑(Ontology edits)总览
函数不只读取数据,还能返回「本体编辑」来创建、修改、删除对象。这篇讲编辑什么时候生效,以及几个容易踩的坑。
## 先记住这几条
① 编辑 = 增删改对象 Ontology edit 是对对象的创建、修改、删除操作。
② 函数返回编辑,平台来执行 函数不直接改库,而是把编辑「交回去」由平台应用。
③ 生效时机有讲究 编辑不是立刻可见,理解何时应用很关键。
④ 有若干已知限制 与对象搜索、Automate、可选数组的交互都有注意事项。
## 写在前面
Ontology 编辑(Ontology edit)是指创建、修改或删除对象的操作。函数支持返回 Ontology 编辑,供函数支撑的动作使用。
- TypeScript v1 函数使用 @OntologyEditFunction 装饰器编写,它提供简化的特殊语义。TypeScript v1 函数还会使用 @Edits 装饰器为动作提供溯源(provenance)信息,动作可利用这些信息执行权限控制。你可以使用验证 Ontology 编辑提供的 API,为 TypeScript v1 的 Ontology 编辑函数编写单元测试。
- TypeScript v2 函数使用从 @osdk/functions 包导出的 createEditBatch 函数编写。这些函数依赖 Edits 类型为动作提供溯源信息。
- Python 函数通过在 Ontology SDK 中导出的 FoundryClient 创建一个编辑容器来编写。这些函数依赖 @function 装饰器的 edits 参数为动作提供溯源信息。
本文档的其余部分将描述 Ontology 编辑函数在底层是如何运作的,帮助你更好地理解其基础设施。
## 编辑何时生效
编辑何时生效
> 要点:提交后何时真正应用到本体,这决定了你能否立即读到结果。
关于 Ontology 编辑函数,一个常见的误解是:运行它们会不会更新 Ontology 中的对象。当你在 Authoring(创作) 环境的函数助手中运行 Ontology 编辑函数时,编辑不会应用到实际对象上。使用函数更新对象的唯一方式,是按照函数支撑的动作文档所述,将动作配置为使用该函数的形式。
这意味着你可以放心地在函数助手中运行 Ontology 编辑函数,用各种输入验证结果,而不必担心对象本身会被更新。
!Results pane
## 注意事项
注意事项
> 要点:与对象搜索的配合、在 Automate 里应用、函数动作里的可选数组问题。
Edits and object search
对象与链接的变更,会在你的函数执行完毕后才传播到对象集(object set)API。这意味着,任何依赖于被编辑值的 Objects.search() 查询——例如基于你编辑的属性或链接做的过滤、邻近搜索或聚合——都会使用旧的对象、属性和链接,从而可能不反映对 Ontology 的编辑(包括创建与删除)。你的函数需要手动处理这种情况。
这与「检索一个你已编辑过的特定对象(例如通过主键)」不同。后一种情况下,函数基础设施会在对象被物化(materialize)时应用你的待定编辑,因此会返回编辑后的属性和链接值。示例见 The @Edits decorator。
对于下面的示例,假设存在一个 ID 为 1 的 Employee。
TypeScript v1 TypeScript v2 Python import { OntologyEditFunction, Edits } from "@foundry/functions-api";
import { Employee, Objects } from "@foundry/ontology-api";
export class CaveatEditFunctions {
@Edits(Employee)
@OntologyEditFunction()
public async editAndSearch(): Promise {
const employeeOne = Objects.search().employee().filter(e => e.id.exactMatch(1)).all()[0];
employeeOne.name = "Bob";
const count = await Objects.search().employee().filter(e => e.name.exactMatch("Bob")).count() ?? -1;
console.log(count);
// 期望:1,实际:0
}
} import { Client } from "@osdk/client";
import { Employee } from "@ontology/sdk";
import { Edits, createEditBatch } from "@osdk/functions";
type OntologyEdit = Edits.Object;
async function editAndSearch(client: Client): Promise {
const batch = createEditBatch(client);
const employeeOne = await client(Employee).fetchOne(1);
batch.update(employeeOne, { name: "Bob" });
const count = await client(Employee)
.where({
name: {
$eq: "Bob"
}
})
.aggregate({
$select: {
$count: "unordered"
}
})
.then(response => response.$count);
console.log(count);
// 期望:1,实际:0
return batch.getEdits();
}
export default editAndSearch; from functions.api import function, OntologyEdit
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Employee
@function(edits=[Employee])
def edit_and_search() -> list[OntologyEdit]:
client = FoundryClient()
ontology_edits = client.ontology.edits()
employee = client.ontology.objects.Employee.get(1)
editable_employee = ontology_edits.objects.Employee.edit(employee)
editable_employee.name = "Bob"
count = client.ontology.objects.Employee.where(Employee.object_type.name == "Bob").count().compute()
print(count)
# 期望:1,实际:0
return ontology_edits.get_edits()
Apply Ontology edits in Automate
Automate 不会应用由「作为 effect 使用的函数」所返回的编辑。要通过自动化应用 Ontology 编辑,请改用配置函数支撑的动作。更多信息见 Function effects。
Optional arrays in function-backed actions
在代码仓库中运行 @OntologyEditFunction 时,被省略的可选数组会被当作 undefined 处理;而通过动作执行该函数时,它们会被作为空数组传入。
### 常见问题速答 · FAQ
关于「本体编辑(Ontology edits)总览」,读者最常问的几个问题。
编辑何时生效? 提交后何时真正应用到本体,这决定了你能否立即读到结果。关于 Ontology 编辑函数,一个常见的误解是:运行它们会不会更新 Ontology 中的对象。
注意事项是什么? 与对象搜索的配合、在 Automate 里应用、函数动作里的可选数组问题。
---
## 函数上手:从建仓库到跑通第一个函数
- 页面:https://www.hanzhongpin.xyz/ontology/fn-getting-started.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/getting-started/
- 主题分组:函数(三)
循序渐进 · 教学 · 函数(三)
# 函数上手:从建仓库到跑通第一个函数
不管你选 TypeScript v1、v2 还是 Python,建仓库 → 开发 → 试跑 → 发布 → 调用这五步是通用的。这一篇讲这条主流程。
## 先记住这几条
① 先建仓库,再写函数 函数必须活在一个「函数仓库」里,仓库在创建时就绑定语言。
② live preview 免发布试跑 实时预览让你在发布之前就跑通函数,是开发期最常用的一步。
③ 发布 = 打版本标签 发布函数实质是给仓库打一个 tag,版本一旦创建不可更改。
④ 三种语言流程相同 具体写法不同,但建仓库、试跑、发布、运行这套平台流程是共用的。
## 写在前面
> 你可以使用 VS Code 工作区,以相同的界面与工具编写函数仓库。VS Code 工作区支持实时预览、资源导入、SDK 生成与发布管理。
在 Foundry 中开始使用函数有三种语言选择:TypeScript v1、TypeScript v2 和 Python。关于每种语言支持的特性,请查阅语言特性支持规范。
尽管每种语言所支持的特性各不相同,但无论使用哪种语言,你都能访问相同的基础平台功能,包括运行、测试和发布函数。本页概述这些功能,帮助你理解如何使用函数仓库,而不论你将使用哪种语言。
关于特定语言的详细上手说明,请参考以下教程:
- TypeScript v1 函数上手
- TypeScript v2 函数上手
- Python 函数上手
阅读下面各节,了解关于函数仓库创建与使用的通用信息。
## 第 1 步 · 创建函数仓库
第 1 步 · 创建函数仓库
> 要点:从项目或 Code Repositories 应用里新建仓库,此时就要选定语言。
创建函数仓库时,你可以选择最适合你需求的语言。你可以从所选项目的 + New > Repository(+ 新建 > 仓库) 直接初始化函数仓库,也可以在 Code Repositories 应用中点击右上角的 + New repository(+ 新建仓库)。仓库初始化完成后,你就可以添加并运行函数。

> 图:创建一个函数代码仓库。
关于如何为特定语言创建函数仓库的详细说明,请参考以下教程章节:
- 创建 TypeScript v1 函数仓库
- 创建 TypeScript v2 函数仓库
- 创建 Python 函数仓库
## 第 2 步 · 选开发环境
第 2 步 · 选开发环境
> 要点:可以用 VS Code 工作区,也可以用平台内置编辑器 —— 界面和工具链一致。
你可以在 Code Repositories 或 VS Code 工作区中开发函数仓库:
- VS Code 工作区(推荐): 通过 Palantir 的 Visual Studio Code 扩展,使用实时预览、资源导入、SDK 生成、分支管理、集成终端以及函数发布管理。要在 VS Code 工作区中打开一个函数仓库,请在仓库头部选择 Edit in VS Code(在 VS Code 中编辑)。
- Code Repositories: 使用下面各节描述的、基于 Web 的开发环境来开发和管理函数。
了解如何在 VS Code 中导航函数开发。
## 第 3 步 · 实时预览里试跑
第 3 步 · 实时预览里试跑
> 要点:不用发布就能运行函数并看结果,是排查逻辑错误最省事的方式。
函数实时预览让你能够在把函数提交到仓库之前先进行测试。在函数加入仓库后,你可以在实时预览中运行它。方法是:打开底部工具栏的 Functions(函数),选择 Live Preview(实时预览)。选择一个函数,输入参数值,然后点击 Run(运行) 执行函数。

> 图:在函数实时预览中运行你的新函数。
实时预览运行在与已发布函数不同的运行时环境中。差异包括 CPU 资源、可用内存,以及函数在超时前能运行的时长。
管理已发布函数的运行时环境。
选择右上角的 Commit(提交),将改动提交到仓库的 master 分支。
## 第 4 步 · 发布(打版本)
第 4 步 · 发布(打版本)
> 要点:发布即打 tag,之后这个版本就固化下来了。
提交工作后,你会看到 Tag version(打标签版本) 选项。这会将仓库中的所有函数发布到 function registry,使它们能在平台各处被访问。

> 图:“Tag version” 选项。
选择 Tag version,基于 master 分支打一个发布标签。根据改动的范围设置标签名称,然后选择 Tag and release(打标签并发布)。

> 图:为新的发布选择要打的版本类型。
要查看函数打标签与发布时的进度,请选择 View(查看) 弹窗,或导航到 Tags(标签) 标签页。一旦 Step 2: Release(第 2 步:发布) 完成,选择已发布的函数即可在 function registry 中查看它们。
在函数发布后,权限传播期间,Workshop 或 function registry 中可能无法立即按名称搜索到这些函数。

> 图:标签与发布检查均已通过,新函数已发布。
## 第 5 步 · 真正调用它
第 5 步 · 真正调用它
> 要点:发布后的函数才能在 Workshop、动作类型等地方被真正调用。
当你所打标签的检查项通过后,导航回 Code Repositories 中的 Code(代码) 标签页,从底部工具栏选择 Functions(函数)。你应该能在 Published(已发布) 分区下看到你的新函数。选择它,试着运行这个新函数:

> 图:在函数助手中运行新函数。
进一步了解如何在平台各处利用函数。
### 常见问题速答 · FAQ
关于「函数上手:从建仓库到跑通第一个函数」,读者最常问的几个问题。
第 1 步 · 创建函数仓库是什么? 从项目或 Code Repositories 应用里新建仓库,此时就要选定语言。
第 2 步 · 选开发环境是什么? 可以用 VS Code 工作区,也可以用平台内置编辑器 —— 界面和工具链一致。
第 3 步 · 实时预览里试跑是什么? 不用发布就能运行函数并看结果,是排查逻辑错误最省事的方式。函数实时预览让你能够在把函数提交到仓库之前先进行测试。在函数加入仓库后,你可以在实时预览中运行它。方法是:打开底部工具栏的 Functions(函数),选择 Live Preview(实时预览)。
第 4 步 · 发布(打版本)是什么? 发布即打 tag,之后这个版本就固化下来了。提交工作后,你会看到 Tag version(打标签版本)选项。这会将仓库中的所有函数发布到 function registry,使它们能在平台各处被访问。
---
## 函数语言特性对照:TS v1 / TS v2 / Python
- 页面:https://www.hanzhongpin.xyz/ontology/fn-language-feature-support.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/language-feature-support/
- 主题分组:函数(二)
循序渐进 · 教学 · 函数(二)
# 函数语言特性对照:TS v1 / TS v2 / Python
Foundry 函数有三种语言可选,但不是所有功能三种语言都支持。这一篇用对照表说清:什么场景该选哪种语言,以及各自的硬边界在哪。
## 先记住这几条
① 三种语言,能力不等价 TypeScript v1 / TypeScript v2 / Python 的功能覆盖有差异,选语言前先看这张表。
② OSDK 支持是关键差异 TypeScript v2 用新的 Ontology SDK(OSDK),v1 用的是旧的一代 SDK。
③ Serverless 只覆盖部分 免服务器(serverless)执行模式并非所有语言都支持,这是选型的硬约束。
④ 先定语言,再写函数 语言在创建仓库时就要选定,中途更换需要迁移,所以先看清楚再动手。
## 写在前面
并非所有特性都被所有语言支持。各语言的功能支持情况请参考下表。
Functions capability by language AIP Logic TypeScript v1 TypeScript v2 Python Description Ontology 对象支持 是 是 是 是 在函数中访问 Ontology 对象的能力。 Ontology 接口支持 否 否 是 否 在函数中访问并编辑 Ontology 接口的能力。 Ontology 编辑支持 是 是 是 是 在函数中编辑 Ontology 对象的能力。 媒体处理能力 否 是 部分 部分 与媒体项交互的能力。TypeScript v1 支持完整的媒体操作,包括文档 OCR 和音频转写。TypeScript v2 和 Python 支持通过 Ontology 编辑上传媒体,以及对媒体属性做基础操作,但不支持文档类或音频类的专用操作。 可在 Workshop 中查询 是 是 是 是 从 Workshop 应用调用函数。 可用于 Pipeline Builder 否 否 否 是 从 Pipeline Builder 流水线调用函数。 函数调用模型支持 是 是 是 是 从函数执行实时部署的模型。TypeScript v2 和 Python 需要使用绑定到 Ontology 的模型函数。 语言模型集成 否 否 是 是 使用模型别名和 Platform SDK 导入,通过代理端点调用语言模型。 语义搜索支持 是 是 是 是 使用函数为语义搜索生成向量。 Webhook 支持 否 是 部分 部分 从函数调用 webhook的能力。TypeScript v1 可直接调用 webhook;TypeScript v2 和 Python 需要把 webhook 发布为webhook 函数,该功能目前处于 Beta 阶段。 外部 API 调用支持 否 是 是 是 从函数内部查询外部服务。 Serverless 执行支持 是 是 是 是 Serverless 函数会在被调用时按需启动。更多说明见下文的 serverless functions。 部署式执行支持 否 否 是 是 部署式函数会分配专用资源,随时准备响应请求。 暂存写入支持 \[Beta] 否 否 是 是 在 TypeScript v2和 Python中使用暂存写入,从而在编辑函数中获得「写后可读」保障与原子化执行。 从 API 网关调用函数 是 是 是 是 从 API 网关访问查询函数的能力。 Marketplace 支持 是 是 是 是 在 Marketplace中打包并发布函数的能力。 自带模型(Bring-your-own-model) 是 是 否 否 将函数注册为模型的能力。函数接口方法是一种旧方案,仅适用于 TypeScript v1。
## Ontology SDK 支持情况
Ontology SDK 支持情况
> 要点:v1 与 v2 访问本体的 SDK 完全不同,这直接影响代码写法和可用 API。
Python 与 TypeScript v2 函数支持 Ontology SDK(OSDK)。OSDK 让你能够直接在开发环境中使用 Ontology,并提供诸多好处,例如与 Developer Console 兼容、支持 OSDK 版本管理。建议在函数仓库中使用 Python 或 TypeScript v2,以享受这些能力。
## TS v1 与 TS v2 逐项对比
TS v1 与 TS v2 逐项对比
> 要点:逐项列出两代 TypeScript 的差异,是从 v1 迁移到 v2 的决策依据。
TypeScript v1 与 TypeScript v2 都允许你使用 TypeScript 的核心语言特性,但在受支持的平台特性上存在差异(见上表)。我们建议使用 TypeScript v2 构建工作流,以充分利用相比 v1 的多项关键改进:
- 在完整 Node.js 运行时中执行 Serverless: TypeScript v2 函数运行在 Node.js 环境中,支持 fs、child_process、crypto 等核心模块。这使得与文件系统交互、并行执行 CPU 密集任务,或需要其他系统级操作的 NPM 库具有更好的兼容性。
- 一流的 OSDK 支持: OSDK 现在可以在 TypeScript v2 函数中无缝使用,便于在平台内外复用代码。同时,它还提供了更高效的大规模 Ontology 数据操作 API。
- 可配置的资源请求: TypeScript v2 函数允许你最多请求 8 个 vCPU 和 5GB 内存,对性能与可扩展性有更强的控制力。
- 暂存写入 \[Beta]: TypeScript v2 支持暂存写入,作为一种替代性的 Ontology 编辑函数执行模型——它提供函数内的「写后可读」保障,并允许嵌套调用其他暂存写入函数。
## Serverless(免服务器)函数
Serverless(免服务器)函数
> 要点:serverless 省去部署环节,但只在部分语言可用 —— 这是最容易踩的坑。
如果你的租户启用了 serverless 函数,新建的仓库默认会使用 serverless 函数。对于大多数场景,我们建议使用 serverless 函数而非部署式函数。借助 serverless 函数,你可以按需提供同一函数的多个版本,使升级更安全。
使用 Python 或 TypeScript v2 函数时,也存在一些场景更偏好部署式函数,或必须使用部署式而非 serverless,但这些情况并不常见。在可用的情况下,serverless 函数因以下原因被优先推荐:
- Serverless 函数支持按需执行同一函数的不同版本,使升级更安全。而部署式函数同一时刻只能运行一个版本。
- Serverless 函数仅在执行时产生费用,而部署式函数只要部署在运行就会产生费用。
- Serverless 函数需要更少的前期搭建与长期维护,因为基础设施是自动管理的。
### 常见问题速答 · FAQ
关于「函数语言特性对照:TS v1 / TS v2 / Python」,读者最常问的几个问题。
Ontology SDK 支持情况是什么? v1 与 v2 访问本体的 SDK 完全不同,这直接影响代码写法和可用 API。
TS v1 与 TS v2 逐项对比是什么? 逐项列出两代 TypeScript 的差异,是从 v1 迁移到 v2 的决策依据。
Serverless(免服务器)函数是什么? serverless 省去部署环节,但只在部分语言可用 —— 这是最容易踩的坑。
---
## 本地本体 SDK(Local OSDK)
- 页面:https://www.hanzhongpin.xyz/ontology/fn-local-sdks.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/local-sdks/
- 主题分组:TypeScript v2(二)
循序渐进 · 教学 · TypeScript v2(二)
# 本地本体 SDK(Local OSDK)
TypeScript v2 的本体 SDK 由资源导入自动生成,不用再手工安装和版本化一个独立包。这篇讲新建、命令行生成、以及旧仓库迁移。
## 先记住这几条
① SDK 自动生成 根据你导入的资源自动生成,不再手工维护版本。
② 与资源导入绑定 导入什么资源,SDK 里就有什么类型。
③ 命令行也能生成 不只在 UI 里,CLI 同样可以生成 SDK。
④ 老仓库可迁移 已有仓库可以改成用本地 SDK。
## 写在前面
TypeScript v2 函数支持本地本体 SDK:OSDK 会根据你导入的资源自动生成,而不用手工做版本管理、也不用作一个单独的包来安装。这意味着 SDK 里的类型永远和你最新导入的资源保持一致。想要完整支持全局分支,本地 SDK 是必需的。
## 新建本地 SDK
新建本地 SDK
> 要点:新仓库如何一开始就使用本地 SDK。
如果你是第一次为仓库创建本地 SDK,按下面的步骤来:
- 在 Code Repositories 或 VS Code 里打开 Resources 侧边面板。
- 点面板右下角的 Select。代码编辑器里会打开一个 Modify Import Resources 标签页。
- 从下拉菜单里选择一个可用的本体。
- 在侧边面板里勾选要导入的对象类型、链接类型、接口类型以及其他实体。

> 图:Resources 侧边面板,显示本体选择包名选择
随着你从本体里不断添加实体,SDK 会自动更新到新版本,仓库里也会生成对应的代码绑定。之后你就可以从 SDK 包(比如 @ontology/sdk)里导入本体实体,用在函数签名里。当你给函数打版本标签时,SDK 会在 CI 里生成,并和你的函数版本打包在一起,反映的是打标签那一刻的本体的状态。
## 命令行生成 SDK
命令行生成 SDK
> 要点:用 CLI 生成,适合自动化流程。
如果你不用 VS Code,可以用 ./rune 命令行工具来生成和重新生成本地 SDK。先准备好开发环境:
bash ./rune env prepare
第一次生成 SDK 时要提供一个包名:
bash ./rune sdk generate --sdk-package-name ontology
这个包名决定了你代码里本体实体的导入路径(例如 import { MyObjectType } from "@ontology/sdk")。包名可以随便取,但约定俗成用 ontology。
改完资源导入之后要重新生成 SDK:
bash ./rune sdk generate
如果仓库里没有 ./rune,跑一下 .palantir-scripts/install-rune 来安装它。
## 迁移已有仓库
迁移已有仓库
> 要点:把旧的手工版本化 SDK 换成自动生成的本地 SDK。
要把一个仓库从独立 SDK 迁移到本地 SDK:
- 找到仓库里的 functions.json 文件,把 useSdkSidebar 设为 false。
- 打开 Resources 侧边面板。点顶部的 Migrate 生成本地 SDK,并把自动生成的改动提交到仓库的 package.json 和 package-lock.json 文件。

> 图:Resources 侧边面板,显示迁移到本地 SDK 的按钮
### 常见问题速答 · FAQ
关于「本地本体 SDK(Local OSDK)」,读者最常问的几个问题。
新建本地 SDK是什么? 新仓库如何一开始就使用本地 SDK。如果你是第一次为仓库创建本地 SDK,按下面的步骤来。
命令行生成 SDK是什么? 用 CLI 生成,适合自动化流程。如果你不用 VS Code,可以用 ./rune 命令行工具来生成和重新生成本地 SDK。先准备好开发环境。
迁移已有仓库是什么? 把旧的手工版本化 SDK 换成自动生成的本地 SDK。要把一个仓库从独立 SDK 迁移到本地 SDK。
---
## 管理已发布的函数
- 页面:https://www.hanzhongpin.xyz/ontology/fn-manage.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/manage-functions/
- 主题分组:函数(七)
循序渐进 · 教学 · 函数(七)
# 管理已发布的函数
函数发布之后,在 Ontology Manager 里统一查看和管理。这一篇讲搜索、概览页、配置继承、快照,以及时间/内存等强制上限。
## 先记住这几条
① 统一入口是 Ontology Manager 所有类型的函数发布后都在这里查看和管理。
② 有强制资源上限 执行时间与内存都有硬限制,超限会被终止 —— 这是最常见的线上故障原因。
③ 配置可继承 函数配置支持继承机制,改一处影响一片。
④ 快照保证一致性 consistent snapshots 确保函数看到的本体状态是一致的。
## 写在前面
发布后,所有类型的函数都可以通过 Ontology Manager 查看和管理。
## 搜索函数
搜索函数
> 要点:函数多了之后,先学会怎么快速找到它。
要搜索函数,导航到 Ontology Manager 并选择 Functions(函数) 标签页。你可以按函数上的大多数元数据进行搜索,包括但不限于函数名、描述、API 名称与 RID。

> 图:在 Ontology Manager 中搜索函数
## 函数概览页
函数概览页
> 要点:单看一个函数的基本信息与健康状态。
在 Ontology Manager 中,选择一个函数即可查看其输入、输出、使用历史与函数指标,包括成功与失败次数以及 P95 执行时长。

> 图:在 Ontology Manager 中查看函数概览
## 函数配置页
函数配置页
> 要点:配置执行相关参数,注意配置是可以继承的。
某些类型的函数允许你配置超时、内存上限等资源。如果你的函数支持任何配置选项,你可以在 Configuration(配置) 标签页查看并编辑它们。如果该标签页不存在,说明函数不支持任何配置选项。
> 配置覆盖是按函数版本生效的。取决于你发布函数所用的应用,新版本可能采用默认配置,你可能需要重新应用之前的配置覆盖。
例如,你可以配置 TypeScript 函数的超时,如下图所示。

> 图:在 Ontology Manager 中管理函数运行时配置
### Configuration inheritance
函数在发布新版本时,开箱即用地支持继承配置覆盖。配置根据语义化版本规范,从上一个稳定版本继承。如果发布的是非稳定版本,配置将从上一个版本继承,无论它是否为稳定发布。
配置继承要求你的仓库包含更新的模板配置。你可以检查隐藏的 templateConfiguration.json 文件,确认仓库所基于的版本。
- 对于 TypeScript v1 函数仓库,必须满足 parentTemplateVersion >= 3.512.0
- 对于 Python 函数仓库,必须满足 parentTemplateVersion >= 0.423.0
## 一致性快照
一致性快照
> 要点:保证函数执行期间读到的是同一份本体快照,避免读到半截状态。
函数支撑的动作会自动在单次运行中的所有读请求上使用同一个 Ontology 快照。
一致性快照提供以下特性:
- 数据一致性: 没有快照时,函数内连续的 Ontology 查询可能因底层数据在两次请求之间发生变化而返回不同版本的数据。有了快照,你的函数运行在一个一致的 Ontology 视图上,类似于数据库事务中的快照隔离。
- 性能提升: 在所有 Ontology 请求间复用同一个快照,显著提升了 Ontology 读性能。单个函数支撑的动作,以及其中的任何查询,都能享受到这一好处。
### Snapshot configuration
如果你需要为高级用例显式管理快照,可以在函数配置页使用以下选项配置快照行为:
- 默认(推荐): 除非遇到与快照相关的错误,否则保持该选项选中。
- 禁用快照: 当你需要在一次运行中获取每次查询的最新数据,或因长时运行的工作负载而遇到快照错误时使用。
- 启用快照: 当你需要在所有读之间获得一致的时点视图、并希望获得更好的读性能,且你的函数能够容忍数据在运行中不更新时使用。对大多数用例不推荐。
默认情况下,带有源(sources)的函数针对实时数据运行,不使用快照。不建议强制启用快照,因为函数可能执行写入或调用外部系统。
## 强制上限
强制上限
> 要点:时间限制、内存限制、多线程、对象集上限 —— 踩线就失败,务必先看清楚。
平台设置了若干限制,以防止函数在执行时消耗过多资源。
### Time limit
函数默认限制运行时间为 60 秒。这些限制可以在函数配置页修改。
在实时预览中运行函数时,允许运行长达 280 秒,即使已在函数配置页修改过。
通过 Automate 执行的函数异步运行,最长可达 4 小时,超出标准执行限制。
TypeScript v1 函数还额外限制 30 秒 CPU 时间,且不可配置。当函数超过这一阈值时,原因通常是低效的数据加载逻辑。请参阅优化性能一节,了解如何避免 CPU 超时。
### Memory limit
内存限制因 TypeScript v1、TypeScript v2 与 Python 函数而异。
TypeScript v1
函数执行限制内存使用为 128 MB(兆字节)。这个限制很少达到;通常函数会先遇到时间限制或对象加载限制,而非内存限制。
Deployed Python functions
部署式 Python 函数默认内存使用为 2 GB(吉字节)。目前,部署式 Python 函数无法在函数配置页配置内存使用。
Serverless Python and TypeScript v2 functions
Serverless 函数默认内存使用为 1024 MiB(兆比字节)。这可以在函数配置页从 512 MiB 配置到 5120 MiB。
### Multithreading
对于 TypeScript v1,函数执行在单线程上,任意时刻只允许一个计算。但你可以并行化对象集或链接的加载。更多信息请参阅优化性能。
对于 TypeScript v2 与 Python 函数,你可以使用内置的 Node.js worker_threads 与 Python threading 库进行多线程处理。
### Object set limits with TypeScript v1
使用对象集时,调用 .all() 或 .allAsync() 会在以下情况抛出错误:
- 一次性从对象集加载超过 100,000 个对象。一般而言,即便加载数万个对象也会遇到时间或内存限制。若你遇到此限制,请考虑使用聚合获取汇总数据,或使用排序与限制获取对象子集。
- 一次性使用超过 3 个 邻近搜索(search arounds) 。
某些聚合与分桶操作存在限制。详见聚合一节。
### 常见问题速答 · FAQ
关于「管理已发布的函数」,读者最常问的几个问题。
搜索函数是什么? 函数多了之后,先学会怎么快速找到它。要搜索函数,导航到 Ontology Manager 并选择 Functions(函数)标签页。你可以按函数上的大多数元数据进行搜索,包括但不限于函数名、描述、API 名称与 RID。
函数概览页是什么? 单看一个函数的基本信息与健康状态。在 Ontology Manager 中,选择一个函数即可查看其输入、输出、使用历史与函数指标,包括成功与失败次数以及 P95 执行时长。
函数配置页是什么? 配置执行相关参数,注意配置是可以继承的。某些类型的函数允许你配置超时、内存上限等资源。如果你的函数支持任何配置选项,你可以在 Configuration(配置)标签页查看并编辑它们。如果该标签页不存在,说明函数不支持任何配置选项。
一致性快照是什么? 保证函数执行期间读到的是同一份本体快照,避免读到半截状态。函数支撑的动作会自动在单次运行中的所有读请求上使用同一个 Ontology 快照。
---
## 把函数打包进 Marketplace
- 页面:https://www.hanzhongpin.xyz/ontology/fn-marketplace-functions.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/marketplace-functions/
- 主题分组:函数(九)
循序渐进 · 教学 · 函数(九)
# 把函数打包进 Marketplace
用 Foundry DevOps 可以把函数打进 Marketplace 产品,让别人安装复用。这一篇讲打包方式、版本与 API 名解析、部署函数的特殊限制。
## 先记住这几条
① 函数可随产品分发 函数和产品一起打包,安装方直接可用。
② 版本与 API 名要解析 安装时怎么决定用哪个版本、API 名冲突怎么办,有 dedup / stable 两种模式。
③ 部署函数有特殊限制 同一时间只能部署一个版本,升级时会重启。
④ 静态输入与别名 静态函数输入、自定义别名、模型别名让包更灵活。
## 写在前面
你可以使用 Foundry DevOps 将你的函数包含进 Marketplace 产品 中,供其他用户安装与复用。
## 把函数加入产品
把函数加入产品
> 要点:打包时可以连源码一起带上,注意扩展函数执行的额外要求。
要将一个函数加入产品,请创建一个产品。然后,如下面所示添加一个函数输出。

> 图:添加一个函数输出。
系统会提示你选择一个函数及其版本。

> 图:搜索一个函数。
### Including source code for code repositories
打包一个在代码仓库中创作的函数时,其底层仓库会自动作为产品中的一个附加输出被包含进来。虽然你可以选择将代码仓库与其源代码一起打包,但我们通常不鼓励为不打算以引导模式(bootstrap mode)安装的产品包含源代码。这是因为一个通过 Marketplace 安装的函数,并不需要其底层源代码就能成功执行。此外,代码仓库并不能保证开箱即可编译或构建。
如果你希望在安装后修改一个函数(例如修复 bug 或增强功能),我们建议直接修改原始函数、发布一个新版本的 Marketplace 产品,然后升级该安装。如果你不拥有所安装的产品,应向其维护者提交 bug 报告或功能请求。
### Extended function execution requirements
使用扩展执行能力的函数有额外的 Marketplace 安装要求。这些能力包括从函数内部调用动作,以及获取存活时间(TTL)更长的认证令牌。在安装之前,管理员必须将目标项目添加到 Control Panel 中 Functions settings(函数设置) 下的 Extended function execution(扩展函数执行) 允许列表中。
关于允许列表的配置说明,请参阅 Functions settings。
## 版本与 API 名解析
版本与 API 名解析
> 要点:deduplication 与 stable 两种模式,决定装到目标环境后指向哪个版本。
当一个函数通过 Marketplace 安装时,其版本与 API 名称有两种解析方式:去重模式(deduplication mode)与稳定模式(stable mode)。
### Deduplication mode
这是通过 Marketplace 安装时解析函数版本与 API 名称的历史默认行为。
在去重模式下,函数的版本解析如下:
- 当函数最初由一次安装创建时,其第一个版本发布在 0.1.0。
- 在后续安装(如升级)时,函数以其最新版本递增一个次版本号发布。例如,如果已安装函数的最新版本是 1.1.0,下一次安装将发布在 1.2.0。
> 函数版本是不可变的。换句话说,一旦某个函数版本被发布,它就不能被修改或覆盖。
函数的 API 名称解析方式如下:
- 如果 API 名称已经被安装所用 Ontology 中的另一个函数占用,将通过追加递增的整数后缀来去重。例如,如果 API 名称 myFunction 已被占用,该函数将以 API 名称 myFunction1 安装。如果该名称也被占用,它将以 myFunction2 安装,依此类推。
- 一旦已安装函数上存在某个 API 名称,该函数在后续安装(如升级)中保持该 API 名称。
> 函数 API 名称 在每个 Ontology 内是唯一的。准确地说,如果一个 Ontology 中已存在 API 名称为 myFunction 的函数,则同一 Ontology 中不能存在另一个具有相同 API 名称的函数。
### Stable mode
:::callout{theme="neutral" title="Beta"}
稳定模式处于测试(beta)开发阶段,在你的租户中可能不可用。功能在积极开发期间可能发生变化。请联系 Palantir 支持在你的租户上启用此功能。
版本与 API 名称是你函数 API 的组成部分。因此在许多情况下,通过 Marketplace 打包与安装时保留它们是可取的。当与静态引用函数依赖的上游应用一起安装函数时,这一点尤其重要,例如 Developer Console 应用。
稳定模式不支持计算模块函数,因为这些函数在 Foundry 中有自己的版本管理行为。
在稳定模式下,函数的版本解析如下:
- 已安装的函数总是以其打包时的版本发布。
- 如果该版本对已安装函数已存在,将创建一个全新的函数;旧函数会被隐藏,其 API 名称会被移除。
创建新函数来解决版本冲突会影响上游应用。如果上游应用是同一安装的一部分,它会自动更新以引用新函数。否则,你需要手动更新它。
函数的 API 名称解析如下:
- 已安装的函数总是以它打包时所用的 API 名称发布。
- 如果该 API 名称已被另一个函数占用,将发生安装错误。要解决此冲突,你必须删除现有函数或更改其 API 名称。
## 部署型函数的处理
部署型函数的处理
> 要点:Marketplace 如何打包执行模式、安装时如何应用配置,以及三条硬限制。
函数要么运行在 serverless 执行模式,要么被部署到一个长期运行的容器中。Marketplace 将函数仓库的执行模式与函数本身一起打包,因此已安装的函数会以它在被打包环境中相同的方式运行。
### How Marketplace packages function execution mode
函数执行模式是按仓库配置的,Marketplace 为同一部署支撑的所有函数打包一次。
对于处于部署模式的仓库,Marketplace 会捕获环境变量、资源请求与限制、扩缩容限制,以及其他关键部署配置细节。
Marketplace 不会将容器镜像作为固定值打包。相反,容器镜像在安装时根据被安装函数的版本解析,因此已安装的部署总是运行被安装函数的镜像。
要打包一个仓库处于部署模式的函数,该仓库必须存在一个部署,且它必须运行着你正在打包的函数版本。否则,打包会失败。要解决此问题,请启动或更新该部署,使其运行你想要打包的版本,或将仓库切换到 serverless 执行。
### How Marketplace applies configuration during installation
当你安装或升级一个产品时,Marketplace 将打包好的执行模式与部署配置应用到目标环境。这等同于解锁安装,并手动配置执行以匹配产品被打包的环境。
如果打包的模式是部署式,Marketplace 会为已安装的仓库创建一个部署(如果尚不存在),将打包的部署配置应用到它,并启动该部署。
如果打包的模式是serverless,Marketplace 将已安装仓库设置为 serverless 执行。如果为该仓库已存在部署,Marketplace 会停止该安装。
Serverless 函数并非在每个租户上都可用。如果一个产品将某个函数以 serverless 模式打包,但目标环境不支持 serverless 执行,该函数会改为以部署模式安装。发生这种情况时,Marketplace 会以默认配置创建并启动一个部署。这保证了已安装函数可作为部署式函数运行。
:::callout{theme="warning" title="计算成本"}
部署式函数在其部署运行期间会产生计算成本,而 serverless 函数仅在执行时产生成本。因此,一个因目标环境不支持 serverless 执行而以部署模式安装的 serverless 函数,会产生长期运行部署的计算成本。
### Limitations of deployed functions in Marketplace
Marketplace 中的部署式函数有以下限制。
Only one version of a function can be deployed at a time
一个部署运行函数的单一版本。当你升级一个包含部署式函数的 Marketplace 产品时,该函数以新版本重新发布,且该新版本会自动部署以取代之前部署的版本。
正在升级的安装之外的产品不会因该升级而更新。如果某个外部产品,或既不包含在 Marketplace 产品中也不属于关联产品(linked product)的产品,引用了部署式函数的某个特定版本,它的引用会继续指向旧版本。由于同一时刻只能部署一个函数版本,任何指向该函数旧版本的引用都会返回错误。
为避免此问题,你必须:
- 将部署式函数的消费者打包在同一个产品或关联产品中,使它们与函数一起升级。
- 尽可能使用 serverless 执行。Serverless 函数可以按需执行函数的不同版本,因此升级不会使对早期版本的引用失效。
Deployments restart during upgrades
对支撑部署式函数的长期运行容器的一些更改(例如更新它所配置的源),无法在该容器运行时应用。因此,作为 Marketplace 产品升级的一部分,每次升级时该部署可能被停止并重新启动,意味着函数可能经历停机。
## 静态函数输入
静态函数输入
> 要点:安装时固定的输入值,减少安装后的手工配置。
此特性仅支持 TypeScript v1。
通过在安装时提供一个本地定义的函数,覆写随 Marketplace 产品附带的「静态」函数输入,可以修改函数行为的一部分。为此,你可以使用 @Static 装饰器指定某个函数可被覆写。
Code import { Function, Static, Double } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public async modifyNumberByStaticFoo(
n: Double,
@Static() staticFunctionInput: (num: Double) => Promise = this.defaultFoo
): Promise {
return await staticFunctionInput(n);
}
private async defaultFoo(n: number) {
return -n;
}
}
打包函数时,任何静态输入都会作为函数输入出现在安装过程中。安装者随后可以提供他们自己的函数逻辑,覆写默认行为。
在被覆写的静态函数内部调用查询或发起 API 调用不受支持。
## 自定义别名
自定义别名
> 要点:给函数起别名,便于跨环境引用。
自定义别名(custom aliases) 存储字符串值,例如配置参数、特性开关或环境特定设置。当你向 Marketplace 产品添加一个带自定义别名函数时,这些别名会自动作为 Inputs(输入) 下的可配置参数出现。安装者可以在不修改函数源代码的情况下,设置环境特定的值。
自定义别名在 TypeScript v2 与 Python 函数中受支持。与静态函数输入不同,自定义别名:
- 同时适用于 TypeScript v2 与 Python
- 允许安装者配置字符串值,而非函数逻辑
- 在 Marketplace 安装体验中支持描述与预设值
关于在函数中定义与使用自定义别名的细节,请参阅 Custom aliases。
## 模型别名
模型别名
> 要点:函数依赖的模型也能用别名绑定。
你可以将那些通过模型别名(model aliases)引用语言模型的函数添加到 Marketplace 产品中。Marketplace 对这些别名施加了特定限制。
模型别名不能在安装期间重新映射。如果别名所引用的模型在目标环境中不可用,函数会在运行时无法解析该别名。
与自定义别名(在安装过程中作为可配置参数出现)不同,Marketplace 在运行时使用源仓库中配置的确切模型 RID 来解析模型别名。请确保别名所引用的模型,在将安装该产品的每个目标环境中都可用。
## 已知问题
已知问题
> 要点:接口类型输入在 Marketplace 函数里目前有已知限制。
### Interface inputs in Marketplace functions
接受接口作为输入参数的函数,可能在目标环境中抛出 MarketplaceSdkObjectMappingNotFound 错误。Marketplace 要求 SDK 绑定包含具体的对象类型,而不仅仅是接口。
如果函数声明了一个接口输入,而目标环境包含实现该接口的具体类型的对象,SDK 无法找到具体类型的映射。函数随后在运行时失败。
规避方法: 确保目标环境中使用的具体对象类型也存在于源环境中,然后将其显式包含在 Marketplace 打包的 SDK 中。这会生成所需的映射,使函数能够解析并使用该对象类型。
### 常见问题速答 · FAQ
关于「把函数打包进 Marketplace」,读者最常问的几个问题。
把函数加入产品是什么? 打包时可以连源码一起带上,注意扩展函数执行的额外要求。要将一个函数加入产品,请创建一个产品。然后,如下面所示添加一个函数输出。
版本与 API 名解析是什么? deduplication 与 stable 两种模式,决定装到目标环境后指向哪个版本。
部署型函数的处理是什么? Marketplace 如何打包执行模式、安装时如何应用配置,以及三条硬限制。
静态函数输入是什么? 安装时固定的输入值,减少安装后的手工配置。此特性仅支持 TypeScript v1。
---
## 函数监控
- 页面:https://www.hanzhongpin.xyz/ontology/fn-monitoring.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/monitoring/
- 主题分组:函数(十)
循序渐进 · 教学 · 函数(十)
# 函数监控
函数上线后要盯住性能和可靠性。监控规则可以设动态作用域,这篇讲有哪些规则可用、怎么配。
## 先记住这几条
① 监控盯性能与可靠性 两类关注点:跑得慢不慢、会不会失败。
② 规则可配动态作用域 监控范围可以按条件动态圈定,不用逐个函数硬编码。
③ 与动作监控是两套 注意这是函数(functions)的监控,不要和动作类型的监控混淆。
## 写在前面
Foundry 里的函数可以被监控,用来跟踪性能与可靠性。本页说明函数有哪些可用的监控能力。
你也可以在 Ontology Manager 里查看函数指标的实时数据,包括每种函数类型的成功与失败次数,以及 P95 耗时。
## 可用的监控规则
可用的监控规则
> 要点:先看平台提供了哪些现成规则,再决定要不要自定义。
Foundry 的函数监控支持下面几种规则类型:
- 函数耗时 P95: 当执行时间的 95 分位数超过阈值时告警。
- 时间窗口内的函数失败次数: 当一段时间内的总失败数超过阈值时告警。这条规则统计所有类型的失败。
- 时间窗口内面向用户的函数失败次数: 当一段时间内面向用户的失败数超过阈值时告警。这条规则只统计函数代码抛出的面向用户错误。
- 时间窗口内非面向用户的函数失败次数: 当一段时间内非面向用户的失败数超过阈值时告警。这条规则排除面向用户的错误,因此适合用来监控基础设施和系统级的故障。
每种规则的详细配置选项与参数,参见监控规则参考文档。
## 配置函数监控
配置函数监控
> 要点:配置步骤,以及动态作用域(dynamic scopes)的用法。
要为函数配置监控,按创建监控视图与规则的标准流程走即可:
- 创建一个监控视图,参见监控视图总览文档。
- 为函数添加一条监控规则,参见添加监控规则一节。
- 配置合适的阈值和告警级别。
- 按告警订阅指南设置告警通知。

> 图:监控告警配置示例
### Dynamic scopes
函数监控支持把 Workflow Lineage、Workshop 和 OSDK 应用作为动态作用域。选中其中某个作用域后,监控会自动跟踪该作用域内资源所调用的全部函数,并随着函数的增删自动调整,不需要你再手工维护。

> 图:选择作用域的弹窗,显示函数监控可用的动态作用域选项
## 相关文档
相关文档
> 要点:延伸出去的官方文档入口。
- 监控规则参考
- 监控视图总览
- 告警的外部系统集成
### 常见问题速答 · FAQ
关于「函数监控」,读者最常问的几个问题。
可用的监控规则是什么? 先看平台提供了哪些现成规则,再决定要不要自定义。Foundry 的函数监控支持下面几种规则类型。
配置函数监控是什么? 配置步骤,以及动态作用域(dynamic scopes)的用法。
---
## 在 VS Code 里开发函数
- 页面:https://www.hanzhongpin.xyz/ontology/fn-navigating-vscode.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/navigating-vscode/
- 主题分组:函数(四)
循序渐进 · 教学 · 函数(四)
# 在 VS Code 里开发函数
装了 Palantir 扩展的 VS Code 工作区,就是完整的函数开发环境:导入资源、切分支、预览、提交、打标签,全在编辑器里完成。
## 先记住这几条
① 扩展 = 平台能力搬进编辑器 Palantir 扩展把分支、预览、提交、发布等操作直接做成 VS Code 里的按钮。
② 先导入资源,再写代码 函数要用本体对象,得先把资源导入仓库,SDK 才会生成对应类型。
③ 分支开发也是标准流程 在 VS Code 里就能创建/切换分支,不用回网页端操作。
④ 保存即格式化等小技巧很值 几个编辑器配置能显著提升日常开发效率。
## 写在前面
你可以使用 VS Code 工作区配合 Palantir 的 Visual Studio Code 扩展,在编辑器内导入资源、预览函数、管理分支、提交并发布改动、升级仓库,以及使用本地开发工具。
## 导入资源到函数仓库
导入资源到函数仓库
> 要点:把本体对象、数据集等资源导入仓库,代码里才能引用到它们。
在函数中使用 Foundry 资源之前,先将它们导入你的仓库:
- 选择 VS Code 活动栏(Activity Bar)中代表向下箭头的 Resource imports(资源导入) 图标。
- 在 Resources(资源) 面板中,根据你想要导入的资源,选择 Ontology SDK 或 Platform 标签页。
- 选择 Add(添加),然后选择一种资源类型,例如对象类型、接口、动作、查询函数或数据源。
- 找到并选择你想使用的资源,然后确认选择。
- 在你的代码中引用该资源之前,等待代码生成与依赖安装完成。

> 图:VS Code 中已选中 Resource imports 图标,Resources 面板显示可用的 Ontology SDK 资源类型。
要获取最新的可用资源类型,请确保你的仓库通过仓库升级保持最新。进一步了解导入 Ontology 类型。
## 用 Palantir 扩展开发与发布
用 Palantir 扩展开发与发布
> 要点:扩展把「切分支 / 预览 / 提交 / 打标签 / 升级仓库」都搬进了 VS Code。
选择活动栏中的 Palantir 图标,打开 Palantir 面板——该面板提供分支、预览、提交、发布和仓库管理操作。

> 图:Palantir 扩展面板显示分支控件,以及用于预览函数、提交和提议改动、打标签版本、升级仓库的操作。
### Create or switch branches
在开始编辑前,使用 Branch(分支) 分区创建或切换分支:
- 选择 Code 或 Global 标签页。
- Code 分支是代码仓库内变更底层的 Git 分支。
- Global 分支可以包含跨多个受支持的 Foundry 应用与资源的相关变更。
- 选择创建分支图标(一个带加号的分支)。
- 输入新分支的名称,然后确认以创建它。
全局分支的支持取决于函数语言和仓库配置。进一步了解 VS Code 中的分支、Code Repositories 中的分支选项,以及在全局分支上开发与发布函数。
### Preview a function
- 在 Palantir 面板中,选择 Function preview(函数预览)。
- 选择一个函数,提供其输入,点击运行以使用所提供的输入值执行你的代码。
- 在你的代码执行时,查看输出、日志、编辑等。这将帮助你调试并测试函数。
如果你在全局分支上开发,预览会针对 Palantir 面板中当前选中的分支运行。进一步了解在实时预览中测试函数。
### Commit, propose, and tag changes
当你的预览和测试成功后:
- 在 Changes(变更) 分区选择 Commit(提交),查看改动的文件,并输入一段描述性的提交信息。
- 如果你的工作需要经过代码评审才能合并,选择 Propose changes(提议改动)。
- 选择 Tag version(打标签版本),选择版本并发布来自所选分支的函数。
打标签会发布仓库中的所有函数,而不仅仅是你最近编辑的那个函数。
进一步了解发布函数与函数版本管理。
### Upgrade the repository
在 Changes(变更) 分区选择 Upgrade(升级) 以启动一次仓库升级。查看生成的改动,再次运行你的测试与函数预览,然后提交升级。进一步了解自动与手动仓库升级。
## VS Code 实用技巧
VS Code 实用技巧
> 要点:跑 npm、保存时格式化、用 AI 工具、快捷键 —— 都是日常高频操作。
以下各节介绍可选的 VS Code 特性与快捷键,它们能加速函数开发。
### Run npm commands from the functions project
打开集成终端,切换到包含函数项目 package.json 文件的 functions-typescript 目录。TypeScript v1 与 TypeScript v2 函数仓库使用相同的路径:
bash cd functions-typescript
npm test
运行 npm run 以列出当前项目可用的脚本。关于所包含的测试框架的更多信息,请参阅单元测试函数。
### Format when you save
打开 Settings(设置),搜索 format on save(保存时格式化),并启用 Editor: Format On Save(编辑器:保存时格式化)。按 Cmd+S(macOS)或 Ctrl+S(Windows/Linux)保存当前文件并运行所配置的格式化器。你也可以从命令面板运行 Format Document(格式化文档)。
进一步了解 VS Code 中的格式化 ↗。
### Use AI development tools
Palantir MCP 默认集成进 VS Code 工作区,并为 TypeScript 函数仓库提供上下文工具,因此 Continue 扩展可以引用你的函数代码、已导入的 Ontology 资源以及 Foundry 上下文。
进一步了解 VS Code 工作区中的 AI 开发工具与 Palantir MCP。
### Use built-in navigation and editing shortcuts
VS Code 内置的快捷键可以减少上下文切换:
Action macOS Windows/Linux 打开命令面板 Cmd+Shift+P Ctrl+Shift+P 快速打开文件 Cmd+P Ctrl+P 在仓库中搜索 Cmd+Shift+F Ctrl+Shift+F 跳转到当前文件中的符号 Cmd+Shift+O Ctrl+Shift+O 跳转到符号定义 F12 F12 查找符号的引用 Shift+F12 Shift+F12 重命名符号并更新其引用 F2 F2 显示可用的快速修复 Cmd+. Ctrl+.
在 Quick Open 中,在文件名后加冒号和行号(例如 myFunction.ts:42),即可直接跳转到该行。你也可以在选中位置时按住 Option(macOS)或 Alt(Windows/Linux),以添加多个光标,同时编辑重复的代码。完整的列表请查阅 VS Code 默认键盘快捷键 ↗。
### 常见问题速答 · FAQ
关于「在 VS Code 里开发函数」,读者最常问的几个问题。
导入资源到函数仓库是什么? 把本体对象、数据集等资源导入仓库,代码里才能引用到它们。在函数中使用 Foundry 资源之前,先将它们导入你的仓库。
用 Palantir 扩展开发与发布是什么? 扩展把「切分支 / 预览 / 提交 / 打标签 / 升级仓库」都搬进了 VS Code。
VS Code 实用技巧是什么? 跑 npm、保存时格式化、用 AI 工具、快捷键 —— 都是日常高频操作。
---
## 用函数配置通知
- 页面:https://www.hanzhongpin.xyz/ontology/fn-notifications.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/configure-notifications/
- 主题分组:函数(十四)
循序渐进 · 教学 · 函数(十四)
# 用函数配置通知
函数可以灵活决定通知发给谁、发什么内容,甚至发到用户外部邮箱。这篇讲自定义通知、获取用户与组、以及返回收件人。
## 先记住这几条
① 函数决定通知内容与收件人 比静态配置的通知更灵活,可以运行时算出来。
② 可以发到外部邮箱 通知不只站内,还能发到用户邮箱地址。
③ 收件人要从本体里取 通常需要先查到 User / Group 对象,再作为收件人返回。
## 写在前面
函数可以用来灵活地配置平台里要发出的通知,包括发到用户外部邮箱的通知。
在函数里配置通知会用到 Principal(代表一个 User 或 Group)和 notification 类型。读这一节时,下面两个参考可能会有用:
- Principal、User 与 Group 类型参考
- notification 类型参考
## 定义自定义通知
定义自定义通知
> 要点:通知的内容结构怎么定义。
假设本体里有一个 Issue 对象,可以指派给某个 User。你可以写一个函数,定义要发给这个 User 的通知,内容带上该 Issue 的详细信息。
TypeScript v1 TypeScript v2 Python import { EmailNotificationContent, Function, Notification, ShortNotification, User } from "@foundry/functions-api";
import { Issue } from "@foundry/ontology-api";
export class NotificationFunctions {
@Function()
public createIssueNotification(issue: Issue, user: User): Notification {
// 创建一条站内展示的短通知
const shortNotification = ShortNotification.builder()
.heading("New issue")
.content("A new issue has been assigned to you.")
// 链到平台里的 Issue 对象
.addObjectLink("Issue", issue)
.build();
// 定义邮件正文。邮件正文可以包含无样式的 HTML,比如数据表格
// 注意:正文里可以同时取用 user 和 issue 的属性
const emailBody = `Hello, ${user.firstName},
A new issue has been assigned to you: ${issue.description}.`;
const emailNotificationContent = EmailNotificationContent.builder()
.subject("New issue")
.body(emailBody)
.addObjectLink("Issue", issue)
.build();
return Notification.builder()
.shortNotification(shortNotification)
.emailNotificationContent(emailNotificationContent)
.build();
}
} import { NotificationLink, Notification } from "@osdk/functions";
import { Issue } from "@ontology/sdk";
import type { Osdk } from "@osdk/api";
export default function createIssueNotification(issue: Osdk.Instance): Notification {
// 链到平台里的 Issue 对象
const links: NotificationLink[] = [
{
label: "Issue",
linkTarget: {
type: "object",
object: issue
}
}
]
const platformNotification = {
heading: "New issue",
content: "A new issue has been assigned to you.",
links: links
}
// 定义邮件正文。邮件正文可以包含无样式的 HTML,比如数据表格
const emailBody = `Hello,
A new issue has been assigned to you: ${issue.description}.`;
const emailNotification = {
subject: "New issue",
body: emailBody,
links: links
}
return {
platformNotification: platformNotification,
emailNotification: emailNotification
}
} from functions.api import function, Notification, PlatformNotification, NotificationObjectLink, EmailNotification
from ontology_sdk.ontology.objects import Issue
@function()
def createIssueNotification(issue: Issue) -> Notification[Issue]:
# 如果要配置带对象链接的通知,必须在返回类型里声明对象类型
# 链到平台里的 Issue 对象
links = [
NotificationObjectLink(label="Issue", objectTarget=issue)
]
#创建一条站内展示的短通知
platform_notification = PlatformNotification(
heading="New issue",
content="A new issue has been assigned to you.",
links=links
)
# 定义邮件正文。邮件正文可以包含无样式的 HTML,比如数据表格
emailBody = f"Hello, \n A new issue has been assigned to you: {issue.description}."
email_notification = EmailNotification(
subject="New issue",
body=emailBody,
links=links
)
return Notification(platform_notification, email_notification)
## 获取用户与组
获取用户与组
> 要点:从本体里查出要通知的对象。
除了把 User 作为参数传进函数,你也可以按需去查一个 User 或 Group。假设 Issue 对象有一个 assignee 字段,里面存的是用户 ID。下面这个例子中,函数返回一条提醒用户关注该 issue 的通知:
TypeScript v1 TypeScript v2 Python import { EmailNotificationContent, Function, Notification, ShortNotification, User, UserFacingError, Users } from "@foundry/functions-api";
import { Issue } from "@foundry/ontology-api";
export class NotificationFunctions {
@Function()
public async createIssueReminderNotification(issue: Issue): Promise {
if (!issue.assignee) {
throw new UserFacingError("Cannot create notification for issue without an assignee.");
}
const user = await Users.getUserByIdAsync(issue.assignee);
const emailBody = `Hello, ${user.firstName},
This is a reminder to investigate the following issue: ${issue.description}`;
// 也可以用这种结构把整条通知一次内联构造出来
return Notification.builder()
.shortNotification(ShortNotification.builder()
.heading("Issue reminder")
.content("Investigate this issue.")
.addObjectLink("Issue", issue)
.build())
.emailNotificationContent(EmailNotificationContent.builder()
.subject("New issue")
.body(emailBody)
.addObjectLink("Issue", issue)
.build())
.build();
}
} import { NotificationLink, Notification } from "@osdk/functions";
import { Users } from "@osdk/foundry.admin";
import { Issue } from "@ontology/sdk";
import { Client } from "@osdk/client";
import type { Osdk } from "@osdk/api";
export default async function createIssueReminderNotification(client: Client, issue: Osdk.Instance): Promise {
const user = await Users.get(client, issue.assignee);
const emailBody = `Hello, ${user.firstName},
This is a reminder to investigate the following issue: ${issue.description}`;
// 也可以用这种结构把整条通知一次内联构造出来
const links: NotificationLink[] = [
{
label: "Issue",
linkTarget: {
type: "object",
object: issue
}
}
]
// 也可以用这种结构把整条通知一次内联构造出来
return {
platformNotification: {
heading: "Issue reminder",
content: "Investigate this issue.",
links: links
},
emailNotification: {
subject: "New issue",
body: emailBody,
links: links
}
}
} from functions.api import function, Notification, PlatformNotification, NotificationObjectLink, EmailNotification
from ontology_sdk.ontology.objects import Issue
from foundry_sdk import FoundryClient
import foundry_sdk
@function()
def createIssueReminderNotification(issue: Issue) -> Notification[Issue]:
client = FoundryClient(auth=foundry_sdk.UserTokenAuth(...), hostname="example.palantirfoundry.com")
user = client.admin.User.get(issue.assignee)
# 链到平台里的 Issue 对象
links = [
NotificationObjectLink(label="Issue", objectTarget=issue)
]
#创建一条站内展示的短通知
platform_notification = PlatformNotification(
heading="Issue reminder",
content="Investigate this issue.",
links=links
)
# 定义邮件正文。邮件正文可以包含无样式的 HTML,比如数据表格
# 注意:正文里可以同时取用 user 和 issue 的属性
emailBody = f"Hello, {user.firstName}, \n A new issue has been assigned to you: {issue.description}."
email_notification = EmailNotification(
subject="Issue reminder",
body=emailBody,
links=links
)
return Notification(platform_notification, email_notification)
## 返回收件人
返回收件人
> 要点:把查到的用户/组作为收件人返回给平台。
上面介绍的 Notification API 让你返回自定义的通知内容。用函数配置通知还有另一种方式:返回通知的收件人列表。做法很简单 —— 写一个函数,返回一个或多个 Principal 对象,比如 User 或 Group 对象。
下面这个例子中,函数同时返回了报告该 issue 的用户和当前负责该 issue 的用户:
TypeScript v1 TypeScript v2 Python import { Function, User, UserFacingError, Users } from "@foundry/functions-api";
import { Issue } from "@foundry/ontology-api";
export class NotificationFunctions {
/**
* 给定一个 Issue,返回代表该 Issue 当前负责人和最初报告人的用户。
*/
@Function()
public async getIssueAssigneeAndReporter(issue: Issue): Promise {
if (!issue.assignee || !issue.reporter) {
throw new UserFacingError("Cannot create notification for issue without an assignee or reporter.");
}
const user = await Users.getUserByIdAsync(issue.assignee);
const issueReporter = await Users.getUserByIdAsync(issue.reporter);
return [user, issueReporter];
}
} import { UserId, Principal } from "@osdk/functions";
import { Users, Groups } from "@osdk/foundry.admin";
import { Issue } from "@ontology/sdk";
import { Client } from "@osdk/client";
import type { Osdk } from "@osdk/api";
/**
* 给定一个 Issue,返回代表该 Issue 当前负责人和最初报告人的用户。
*/
async function getIssueAssigneeAndReporter(client: Client, issue: Osdk.Instance): Promise {
const user = await Users.get(client, issue.assignee);
const issueReporter = await Users.get(client, issue.reporter);
return [user.id, issueReporter.id];
}
/**
* 给定一个 Issue,返回该 issue 当前的负责人用户,以及该 issue 所属的组。
*/
async function getIssueAssigneeAndGroups(client: Client, issue: Osdk.Instance): Promise {
// 要同时返回组和用户,就用 Principal 类型。
const user = await Users.get(client, issue.assignee);
const group = await Groups.get(client, issue.group);
return [{type: "user", id: user.id}, {type: "group", id: group.id}];
} from functions.api import Array, function, Principal, UserId
from ontology_sdk.ontology.objects import Issue
from foundry_sdk import FoundryClient
import foundry_sdk
# 给定一个 Issue,返回代表该 Issue 当前负责人和最初报告人的用户。
@function()
def getIssueAssigneeAndReporter(issue: Issue) -> Array[UserId]:
client = FoundryClient(auth=foundry_sdk.UserTokenAuth(...), hostname="example.palantirfoundry.com")
user = client.admin.User.get(issue.assignee)
issueReporter = client.admin.User.get(issue.reporter)
return [user.id, issueReporter.id]
# 给定一个 Issue,返回该 issue 当前的负责人用户,以及该 issue 所属的组。
@function()
def getIssueAssigneeAndGroup(issue: Issue) -> Array[Principal]:
# 要同时返回组和用户,就用 Principal 类型。
client = FoundryClient(auth=foundry_sdk.UserTokenAuth(...), hostname="example.palantirfoundry.com")
user = client.admin.User.get(issue.assignee)
group = client.admin.Group.get(issue.group)
return [Principal.user(user.id), Principal.group(group.id)]
### 常见问题速答 · FAQ
关于「用函数配置通知」,读者最常问的几个问题。
定义自定义通知是什么? 通知的内容结构怎么定义。假设本体里有一个 Issue 对象,可以指派给某个 User。你可以写一个函数,定义要发给这个 User 的通知,内容带上该 Issue 的详细信息。
获取用户与组是什么? 从本体里查出要通知的对象。除了把 User 作为参数传进函数,你也可以按需去查一个 User 或 Group。假设 Issue 对象有一个 assignee 字段,里面存的是用户 ID。下面这个例子中,函数返回一条提醒用户关注该 issue 的通知。
返回收件人是什么? 把查到的用户/组作为收件人返回给平台。上面介绍的 Notification API 让你返回自定义的通知内容。用函数配置通知还有另一种方式:返回通知的收件人列表。
---
## 函数权限:编写与执行分别受什么约束
- 页面:https://www.hanzhongpin.xyz/ontology/fn-permissions.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/permissions/
- 主题分组:函数(十二)
循序渐进 · 教学 · 函数(十二)
# 函数权限:编写与执行分别受什么约束
函数的编写和执行受不同权限检查。这篇分三层讲清:谁能在仓库里写代码、谁执行函数时要有本体权限、扩展执行又多一道关。
## 先记住这几条
① 写函数 ≠ 能执行函数 编写权限和执行权限是两套检查,别混为一谈。
② 执行时受本体权限约束 函数加载对象时,仍然受本体实体权限与对象加载权限限制。
③ 扩展执行要多授权 extended function execution 能突破部分限制,但需要额外批准。
④ 常见坑:权限不足导致空结果 很多「函数返回空」的问题,根因是执行权限而不是代码。
## 写在前面
在平台中创作与执行函数,要经过多种权限检查。本节概述你应当了解的不同类型权限,以及你可能遇到的常见问题。
## 编写函数的权限
编写函数的权限
> 要点:需要本体实体权限与对象加载权限,才能在仓库里开发和调试。
函数仓库必须被授予适当的权限,以便:
- 访问 Ontology,从而能够生成正确的代码绑定。
- 加载对象,以便运行函数执行的实时预览。
仓库权限必须被显式授予,且与授予你用户账户的权限不同。因此,你必须采取具体步骤,将对象类型、链接类型与底层数据源导入包含你仓库的 Project(项目)中。
关于这些步骤的教程,请参阅本节。下面我们解释所导入的具体资源,以及为这些资源授予的权限。
### Ontology entity permissions
在仓库中,每当检查运行或 Code Assist 启动时,函数插件都会基于仓库的权限加载最新的 Ontology,并为每个已加载的对象与链接类型生成代码绑定。所加载的对象与链接类型的集合,取决于以下资源类型的导入:
- Ontologies
- Ontology 分支
- 对象类型
- 链接类型
在函数仓库中,你可以通过导航到 Settings > Ontology 导入所需的 Ontology 资源。该界面允许你选择要导入到项目中的对象与链接类型。

> 图:ontology-settings
如果你的用户账户可以访问多个 Ontology,你也可以选择想要使用哪一个。目前,尚不支持将多个 Ontology 导入到单个 Project。

> 图:ontology-picker
:::callout{theme="warning" title="Ontology 导入作用于整个 Project,而非单个仓库"}
尽管上述界面出现在函数仓库内,但你导入的任何 Ontology、对象类型与链接类型都是在 Project 级别添加的。这意味着,在一个仓库中更改导入,可能会影响同一 Project 中的其他仓库。如果你希望有两个依赖不同 Ontology 实体的仓库,应将它们分到不同的 Project 中。
### Object loading permissions
仓库中的 functions helper(函数助手) 允许用户以两种方式执行函数:执行一个已发布的函数,或在实时预览中执行代码。当在实时预览中执行时,函数代码在 Code Assist 中编译并运行——Code Assist 是专为代码作者快速迭代而设计的基础设施。
因为它与仓库绑定,Code Assist 受到与代码生成相同的权限要求约束,如上所述。这意味着,在实时预览中运行函数时,你希望使用的每个对象类型的底层数据源都必须导入到 Project 中。
在 functions helper 中,如果有已导入到 Project 但相应数据源未导入的对象类型,实时预览中会显示一条警告,提示你更新导入:

> 图:preview-backing-datasources
对于大多数对象类型,Import backing datasources(导入底层数据源) 对话框会提示你导入一个 Foundry 数据集。对于启用了行级安全的对象类型,会提示你导入一个 Restricted View(受限视图)。
## 已发布函数的执行权限
已发布函数的执行权限
> 要点:函数本身的执行权限 + 运行时加载对象的权限,两层都要有。
一旦函数发布,它就准备好被更广泛的用户群体使用,并可以被配置为在 Workshop 与 Actions 等应用中执行。对于执行已发布函数的权限,仍有几点需要注意。
### Function permissions
要执行一个函数,用户必须对发布该函数的仓库拥有 Viewer(查看者) 角色。通常,最好将函数仓库放在依赖该仓库中函数的终端用户应用所在的同一个 Project 中,无论这些应用是用 Workshop、Slate 还是其他工具创建的。如果用户遇到指示他们缺少读取函数权限的错误(ReadFunctionsPermissionDenied),请检查他们是否具有对仓库的读取访问。进一步了解如何移动与共享资源。
相比之下,代码为 FunctionRegistry:ReadOntologyFunctionPermissionDenied 的 PERMISSION_DENIED 错误,通常意味着该函数在 Developer Console 中未注册或不可用,而非表示文件夹级别的权限问题。请在 Developer Console 中添加并注册该函数,因为仅有的文件夹与仓库权限不足以让函数可执行。
要更广泛地审查访问,请使用侧边栏中的 Check access(检查访问) 面板,检查某人对 Workshop 或 Slate 应用的访问情况,包括对其依赖函数的访问。更多信息参见检查权限。
函数支撑的动作 是一个特殊情况:终端用户不一定需要对该函数有读取访问,就能应用使用它的动作。管理员在配置动作以使用某个函数时,必须对该函数有读取访问。之后,用户将能够基于动作级权限来应用该动作,而无论他们对函数的访问如何。
### Object loading permissions
当函数加载对象数据时,无论是作为参数还是通过对象搜索,运行该函数的终端用户的权限决定了哪些对象被加载。对于使用行级权限保护的对象类型,这意味着执行同一函数的不同用户可能收到不同的结果。这一行为是预期的——用户只应看到他们有权访问的对象,并且该行为使得单个函数可以为对各对象访问权限不同的用户工作。
:::callout{theme="warning" title="仅在读取时强制执行"}
行与列的访问控制(包括受限视图、对象安全策略与属性安全标记)过滤函数运行时用户能读取的内容。这些控制不会延伸到函数的输出。为了让数据在向下游流动时保持受保护,请将这些控制与标记(marking)或基于分类的访问控制搭配使用。完整模型见访问控制传播。
## 扩展执行
扩展执行
> 要点:需要额外授权才能以扩展能力运行,是权限模型里最敏感的一档。
管理员通过 Control Panel 中的 Functions settings(函数设置) 控制扩展执行能力。这些能力授予提升的访问,例如从函数内部调用动作,或获取存活时间(TTL)最长四小时的认证令牌。
要发布、执行或安装具备扩展能力的函数,管理员必须配置相应的允许列表(allowlist):
- 允许发布扩展函数的仓库: 只有该允许列表中的仓库才能发布具备扩展能力的函数。
- 允许以扩展能力执行的函数: 只有该允许列表中的函数才能以扩展能力执行。Foundry 在执行时检查该允许列表。
- 允许通过 Marketplace 安装扩展函数的项目: 只有该允许列表中的项目才能成功从 Marketplace 安装具备扩展能力的函数。
如果发布、执行或 Marketplace 安装对具备扩展能力的函数返回权限错误,请让你的管理员核实相关的允许列表。
### 常见问题速答 · FAQ
关于「函数权限:编写与执行分别受什么约束」,读者最常问的几个问题。
编写函数的权限是什么? 需要本体实体权限与对象加载权限,才能在仓库里开发和调试。函数仓库必须被授予适当的权限,以便。
已发布函数的执行权限是什么? 函数本身的执行权限 + 运行时加载对象的权限,两层都要有。一旦函数发布,它就准备好被更广泛的用户群体使用,并可以被配置为在 Workshop 与 Actions 等应用中执行。对于执行已发布函数的权限,仍有几点需要注意。
扩展执行是什么? 需要额外授权才能以扩展能力运行,是权限模型里最敏感的一档。管理员通过 Control Panel 中的 Functions settings(函数设置)控制扩展执行能力。
---
## 用 Platform SDK 调用平台 API
- 页面:https://www.hanzhongpin.xyz/ontology/fn-platform-sdk.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/platform-sdk/
- 主题分组:函数(十七)
循序渐进 · 教学 · 函数(十七)
# 用 Platform SDK 调用平台 API
除了操作本体,函数还能反向调用 Foundry 平台自身的 API(读写数据集、管资源等)。这篇讲安装、初始化客户端、以及客户端权限。
## 先记住这几条
① 平台 SDK ≠ 本体 SDK OSDK 操作本体对象,Platform SDK 操作平台资源(数据集、服务等)。
② 先初始化 client 凭据与端点由环境提供,初始化后才能调用。
③ 客户端本身有权限边界 SDK 能做什么,取决于运行它的主体有什么权限。
④ Python 版本要核对 Python SDK 对解释器版本有兼容要求。
## 写在前面
Foundry 的 API 暴露了丰富的功能,你可以通过函数搭配 Foundry platform SDK 库来使用。借助 platform SDK,你可以构建用于管理或治理工作流的函数、与调度和构建交互、访问媒体集,等等。
TypeScript v1 函数不支持一等身份认证。对于这类工作流,我们建议使用 Python 函数与 TypeScript v2 函数。
## 安装 SDK
安装 SDK
> 要点:安装步骤,注意 Python 版本兼容性要求。
要安装 Foundry platform SDK,请在代码仓库中打开 Libraries 侧边栏,搜索 SDK 名称:Python 对应 foundry-platform-sdk,TypeScript 对应 @osdk/foundry。

> 图:Libraries 搜索面板,正在搜索 Python 版 platform SDK。

> 图:Libraries 搜索面板,正在搜索 TypeScript 版 platform SDK。
### Python version compatibility
Python 版 foundry-platform-sdk 需要 Python 3.9 或更高版本。对 Python 3.14 的支持从 foundry-platform-sdk 1.93.0 版本开始。更早的 SDK 版本在 Python 3.14 下可能返回 typing 模块错误。要解决这些错误,请升级到 1.93.0 或更高版本;或者改用 Python 3.11、3.12 或 3.13。
## 初始化客户端
初始化客户端
> 要点:拿到可用的 client 实例。
你的函数需要身份认证才能与 Foundry API 交互。这一过程需要实例化一个经过认证的「客户端(client)」,通过它你可以用 SDK 向 Foundry API 发起请求。在 TypeScript v2 仓库中,这需要 @osdk/client 库,它应当已预先安装。你可以查找绿色图钉来确认:

> 图:TypeScript 用的身份认证库。
## 调用平台 API
调用平台 API
> 要点:用 client 发起调用,以及客户端权限的边界。
函数完成认证后,你就可以开始使用 Foundry API。下面的示例展示了如何在 Python 和 TypeScript 中调用语言模型或查询媒体集:
TypeScript v2 Python import {
Client, // 若你的函数与 Ontology 交互则使用 Client
PlatformClient // 若你的函数不与 Ontology 交互则使用 PlatformClient
} from "@osdk/client";
import { Functions } from "@osdk/foundry";
export default async function useLlm(
client: PlatformClient, // 该参数由 Foundry 在运行时填充
prompt: string
): Promise {
const promptMessage = [
{
role: "USER",
content: prompt
}
];
const result = await Functions.Queries.execute(
client,
"com.foundry.languagemodelservice.models.gpt41.CreateChatCompletion",
{
parameters: {
messages: promptMessage
}
},
{
preview: true, // 仅对不稳定端点需要,详见 API 参考
}
);
return result.value["completion"] as string;
} from foundry_sdk import FoundryClient
@function
def media_item_to_base64(media_item_rid: str, media_set_rid: str) -> str:
foundry_client = FoundryClient()
result = foundry_client.media_sets.MediaSet.read(
media_set_rid=media_set_rid,
media_item_rid=media_item_rid,
preview=True # 仅对不稳定端点需要,详见 API 参考
)
# 将二进制流转换为 base64 编码字符串
base64_encoded = base64.b64encode(result).decode('utf-8')
return base64_encoded
### Client permissions
在运行时由 Foundry 传入的 TypeScript v2 客户端,以及在代码中初始化的 Python 客户端,拥有以下权限范围:
- api:admin-read
- api:functions-read
- api:ontologies-read
- api:orchestration-read
- api:usage:mediasets-read
- api:usage:ontologies-write
每个平台 API 端点都需要特定的权限范围才能访问。这些范围的说明可在 API 参考中查阅。
Foundry 函数不支持通过 api:usage:datasets-read 范围直接读取数据集。数据集读取会返回权限错误。代码在 Code Workspaces 实时预览中可能成功,因为它以你的用户上下文和完整权限范围运行;但作为已部署函数运行时则会失败,因为已部署函数使用的是受限权限。
### 常见问题速答 · FAQ
关于「用 Platform SDK 调用平台 API」,读者最常问的几个问题。
安装 SDK是什么? 安装步骤,注意 Python 版本兼容性要求。要安装 Foundry platform SDK,请在代码仓库中打开 Libraries 侧边栏,搜索 SDK 名称:Python 对应 foundry-platform-sdk,TypeScript 对应 @os…
初始化客户端是什么? 拿到可用的 client 实例。你的函数需要身份认证才能与 Foundry API 交互。这一过程需要实例化一个经过认证的「客户端(client)」,通过它你可以用 SDK 向 Foundry API 发起请求。
调用平台 API是什么? 用 client 发起调用,以及客户端权限的边界。函数完成认证后,你就可以开始使用 Foundry API。下面的示例展示了如何在 Python 和 TypeScript 中调用语言模型或查询媒体集。
---
## 查询函数:通过 API 网关对外提供只读能力
- 页面:https://www.hanzhongpin.xyz/ontology/fn-query.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/query-functions/
- 主题分组:函数(十五)
循序渐进 · 教学 · 函数(十五)
# 查询函数:通过 API 网关对外提供只读能力
Query 是函数的只读子集,可以通过 API 网关对外暴露,且不允许有副作用。这篇讲装饰器、API 名校验、版本管理与调用方式。
## 先记住这几条
① Query 必须是只读的 不能有副作用,这是它与普通函数的核心区别。
② 通过 API 网关暴露 外部系统可以直接调用,是函数对外的主要出口。
③ API 名有校验规则 命名不规范会发布失败。
④ 版本化更新 改 query 要走版本更新流程。
## 写在前面
查询(Queries)是函数的只读子集,可以选择性通过 API 网关暴露。它们不能有任何副作用,例如修改 Ontology 或改动外部系统。如果你需要通过 API 网关获得这些额外的编辑能力,应使用 Action。
## Query 装饰器
Query 装饰器
> 要点:用装饰器把一个函数标记为 query,并可指定 API 名。
使用以下语法定义一个查询函数。
TypeScript v1 TypeScript v2 Python import { Query } from "@foundry/functions-api";
@Query({ apiName: "myTypeScriptV1Function" }) // 在包含该函数的文件中导出一个带有 apiName 参数的配置对象
export const config = {
apiName: "myTypeScriptV2Function"
}; from functions.api import function
@function(api_name="myPythonFunction")
对于 Python 和 TypeScript v1 函数,装饰器接受一个 string 类型的 API 名称参数,该参数用于定义 API 名称,是必需的。使用 TypeScript v1 时,如果未定义 apiName 参数,该查询的行为将与既有的 @Function 装饰器类似。对应的 Python 语法是 api_name。
### Example: API-named query
下面的示例演示如何通过 API 网关暴露一个查询:
TypeScript v1 TypeScript v2 Python import { Query, Double } from "@foundry/functions-api";
import { Objects, Aircraft } from "@foundry/ontology-api";
export class PublishedQueries {
@Query({ apiName: "getReschedulableAircraftCount" })
public async countAircraftTakingOffAfter(minimumTimeInMinutes: Double): Promise {
const aircraftCount = await Objects.search().aircraft()
.filter(aircraft => aircraft.timeUntilNextFlight.range().gt(minimumTimeInMinutes))
.count();
return aircraftCount!;
}
} import { Client } from "@osdk/client";
import { Double } from "@osdk/functions";
import { Aircraft } from "@ontology/sdk";
export const config = {
apiName: "getReschedulableAircraftCount"
};
async function countAircraftTakingOffAfter(client: Client, minimumTimeInMinutes: Double): Promise {
const { $count } = await client(Aircraft).where({
timeUntilNextFlight: {
$gt: minimumTimeInMinutes
}
}).aggregate({ $select: { $count: "unordered" } })
return $count;
}
export default countAircraftTakingOffAfter;
from functions.api import Double, function
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Aircraft
@function(api_name="getReschedulableAircraftCount")
def count_aircraft_taking_off_after(minimum_time_in_minutes: Double) -> Double:
client = FoundryClient()
aircraft_count = client.ontology.objects.Aircraft.where(
Aircraft.object_type.time_until_next_flight > minimum_time_in_minutes
).count().compute()
return aircraft_count
## API 名校验
API 名校验
> 要点:命名规则与校验,避免发布时才发现不合规。
查询的 apiName 必须是一个满足以下要求的字符串:
- 采用 lowerCamelCase(小驼峰)形式。
- 长度小于 100 个字符。
- 不能以数字开头。
- 在导入到仓库的所有 Ontology 之间保持唯一。
- 如果 apiName 不唯一,打标签过程会失败,需要你更改名称。
此外,包含 API 命名查询的仓库必须从至少一个 Ontology 导入实体。
## 版本与更新
版本与更新
> 要点:带 API 名的 query 如何升级版本。
API 命名的查询始终使用已发布查询的最新标签版本,并不遵循与其他 Foundry 函数相同的语义化版本(semantic versioning)范式。
要将 API 名称与查询解除关联、并在 API 网关中使其失效,必须从查询装饰器中移除 API 名称,并从仓库发布一个新的标签。
在装饰器中更改 API 名称并发布新标签,会使调用方失效。仅支持该查询最新发布的版本。
为了让调用方能够在不产生破坏性变更的情况下按需升级,你可以支持同一 API 名称的多个版本。为此,你必须在仓库中复制一份查询代码,并赋予一个不同的 API 名称,例如 getReschedulableAircraftCountV2。
## 搜索与查看
搜索与查看
> 要点:发布后在哪里找到它们。
与其他函数一样,你可以在 Ontology Manager 中搜索和管理你的查询。你可以按查询名称或 API 名称搜索。在上面的示例中,API 名称对应 getReschedulableAircraftCount,查询名称对应 countAircraftTakingOffAfter。

> 图:在 Ontology Manager 中搜索查询
> 使用 TypeScript v1 函数时,你可能需要更新仓库中的 functions.json 文件,将 enableQueries 属性设为 true 以启用查询:
TypeScript v1
{
"enableQueries": true
}
## 调用 query 函数
调用 query 函数
> 要点:外部怎么真正发起调用。
发布你的 TypeScript 或 Python 查询函数后,导航到你想消费该函数的代码仓库,并使用 Resource imports(资源导入) 侧边栏导入它。
你的函数将可以从消费方仓库中被调用。例如:
TypeScript v1 TypeScript v2 Python import { Queries } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public callQueryFunction(): Promise {
return Queries.getReschedulableAircraftCount(10);
}
} import { Client } from "@osdk/client";
import { Double } from "@osdk/functions";
import { getReschedulableAircraftCount } from "@ontology/sdk";
async function callQueryFunction(client: Client): Promise {
return client(getReschedulableAircraftCount).executeFunction({ timeUntilNextFlight: 10 });
}
export default callQueryFunction; from functions.api import Double, function
from ontology_sdk import FoundryClient
@function
def call_query_function() -> Double:
return FoundryClient().ontology.queries.get_reschedulable_aircraft_count(
time_until_next_flight=Double(10)
)
对于 TypeScript v1 函数,Foundry 必须知道你从已发布函数中调用了哪些查询函数和语言模型方法。我们自动提供静态分析,尝试检测出被调用的查询。但这一静态分析偶尔可能漏掉某些调用,从而导致运行时错误,提示你添加 @Uses 装饰器。该装饰器用于补全自动检测出的查询使用情况。语言模型方法也列在同一个 queries 数组中。
以下示例演示了 @Uses 装饰器的用法:
TypeScript v1 import { Uses } from "@foundry/functions-api";
import { Queries } from "@foundry/ontology-api";
export class MyFunctions {
@Uses({ queries: [Queries.getReschedulableAircraftCount] })
@Function()
public callQueryFunction(): Promise {
return Queries.getReschedulableAircraftCount(10);
}
}
### 常见问题速答 · FAQ
关于「查询函数:通过 API 网关对外提供只读能力」,读者最常问的几个问题。
Query 装饰器是什么? 用装饰器把一个函数标记为 query,并可指定 API 名。
API 名校验是什么? 命名规则与校验,避免发布时才发现不合规。查询的 apiName 必须是一个满足以下要求的字符串。
版本与更新是什么? 带 API 名的 query 如何升级版本。API 命名的查询始终使用已发布查询的最新标签版本,并不遵循与其他 Foundry 函数相同的语义化版本(semantic versioning)范式。
搜索与查看是什么? 发布后在哪里找到它们。与其他函数一样,你可以在 Ontology Manager 中搜索和管理你的查询。你可以按查询名称或 API 名称搜索。在上面的示例中,API 名称对应 getReschedulableAircraftCount,查询名称对应 count…
---
## Functions settings:管理员全局设置
- 页面:https://www.hanzhongpin.xyz/ontology/fn-settings.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/functions-settings/
- 主题分组:函数(二十一)
循序渐进 · 教学 · 函数(二十一)
# Functions settings:管理员全局设置
Control Panel 里的 Functions settings 页面,让管理员管控「扩展执行」这类高危能力:哪些仓库能发布、哪些函数能跑、哪些项目能装。
## 先记住这几条
① 这是管理员视角 面向平台管理员,不是开发者日常操作。
② 管的是扩展执行 extended function execution 绕过部分常规限制,需要白名单。
③ 三层白名单 允许的仓库、允许的函数、允许安装的项目,层层收紧。
## 写在前面
Control Panel 里的 Functions settings 页面,让管理员管理一组决定函数在某个 space 内行为的设置;下面各节会说明每项设置分别控制哪种能力是否启用。进入方式是:找到你要配置的 space,进入 Control Panel > Functions settings。
## 扩展函数执行
扩展函数执行
> 要点:三层白名单:仓库、函数、Marketplace 安装项目。
Extended function execution(扩展函数执行) 弹窗允许指定的函数以某些扩展能力运行:
- 在函数内部调用动作。
- 获取一个有效期(TTL)最长可达四小时的认证令牌。

> 图:Control Panel 中的扩展函数执行设置,显示控制函数扩展能力的三张白名单
由于这些能力相当于给函数提升了权限,扩展函数执行的开关提供了细粒度控制:通过弹窗里可折叠区域配置的一组白名单,决定它能在哪些地方启用。一个函数必须先满足相关的白名单,才能以这些扩展能力去发布、执行或被安装。配置下面这几张白名单,就能控制哪些仓库、函数和项目可以使用扩展函数执行。
### Repositories allowed to publish extended functions
这张白名单里的仓库,是该 space 中唯一能发布带扩展执行能力函数的仓库。要添加仓库,点 Add 然后搜索你要放行的仓库。
### Functions allowed to execute with extended capabilities
这张白名单里的函数,是唯一会以扩展能力执行的函数。这个列表在执行时检查,所以函数必须一直留在白名单里,才能继续以扩展能力执行。从已放行仓库发布的新函数会自动同步到函数白名单。要添加函数,点 Add 然后搜索你要放行的函数。
### Projects allowed for installing extended functions via Marketplace
这张白名单里的项目,是唯一能通过 Marketplace 成功安装带扩展执行能力函数的项目。要添加项目,点 Add 然后搜索你要放行的项目。
---
## 流式函数:分块返回结果
- 页面:https://www.hanzhongpin.xyz/ontology/fn-streaming.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/streaming-functions/
- 主题分组:函数(二十)
循序渐进 · 教学 · 函数(二十)
# 流式函数:分块返回结果
Python 与 TypeScript v2 函数可以把结果分块流式返回,数据边生成边处理,不用等全部算完。
## 先记住这几条
① 流式 = 边算边给 结果是分块(chunk)返回的,调用方可以立即开始处理。
② 适合耗时生成场景 数据随时间产生时(如大模型逐字输出)最有用。
③ 只有部分语言支持 Python 与 TypeScript v2 支持,TypeScript v1 不支持。
④ 通过 OSDK 调用 消费端要用支持流式的方式接收。
## 写在前面
Python 和 TypeScript v2 函数可以把一次执行的结果分块流式返回。当数据是随时间陆续产生的时候,这个能力很有用 —— 调用方不必等结果全部生成完,就能开始处理。
## 写流式函数
写流式函数
> 要点:函数侧怎么写才能分块产出结果。
要流式返回,Python 函数必须把返回类型标注为 Iterable[T],并用 yield 关键字在数据可用时逐个产出。在 TypeScript 里,你需要在 function 关键字后加一个 * 来声明异步生成器函数,返回类型写 AsyncIterable,同样用 yield 逐个产出。
下面的例子演示了一个函数如何返回整数流,每个整数之间间隔一秒:
Python TypeScript v2 from functions.api import function
from typing import Iterable
import time
@function
def my_lazy_number_generator(n: int) -> Iterable[int]:
for i in range(n):
time.sleep(1)
yield i import { Integer } from "@osdk/functions";
export default async function* myLazyNumberGenerator(n: Integer): AsyncIterable {
for (let i = 0; i < n; i++) {
await new Promise(resolve => setTimeout(resolve, 1_000));
yield i;
}
}
流式返回在处理语言模型时特别有用 —— 模型生成完整输出往往要花不少时间。通过把模型产出的每一块内容立刻 yield 出去,你就能提供实时体验,而不必阻塞等待整个响应完成。关于在函数里调用语言模型,参见TypeScript v2 与 Python 函数中的语言模型。
下面的例子用 openai SDK 调用语言模型,并通过在请求里打开 stream 开关把响应流式传回来:
Python TypeScript v2 from openai import OpenAI
from functions.api import function
from functions.aliases import model
from foundry_sdk.v2.language_models import (
get_openai_base_url,
get_foundry_token,
get_http_client,
)
from typing import Iterable
@function
def create_chat_completion(prompt: str) -> Iterable[str]:
client = OpenAI(
api_key=get_foundry_token(preview=True),
base_url=get_openai_base_url(preview=True),
http_client=get_http_client(preview=True),
)
stream = client.chat.completions.create(
model=model("gpt55").rid,
messages=[
{
"role": "user",
"content": prompt,
},
],
stream=True
)
for event in stream:
if event.choices:
content = event.choices[0].delta.content
if content:
yield content import { PlatformClient } from "@osdk/client";
import OpenAI from "openai";
import { Aliases } from "@osdk/functions";
import { getFoundryToken, getOpenAiBaseUrl, createFetch } from "@osdk/language-models";
export default async function* createChatCompletion(client: PlatformClient, prompt: string): AsyncIterable {
const oaiClient = new OpenAI({
apiKey: await getFoundryToken(client),
baseURL: getOpenAiBaseUrl(client),
fetch: createFetch(client),
});
const stream = await oaiClient.chat.completions.create({
model: Aliases.model("gpt55").rid,
messages: [
{ role: 'user', content: prompt },
],
stream: true
});
for await (const event of stream) {
const content = event.choices[0]?.delta?.content;
if (content) {
yield content;
}
}
}
## 通过 OSDK 调用流式函数
通过 OSDK 调用流式函数
> 要点:消费端如何逐块接收并处理。
流式函数打好标签并发布之后,就可以通过本体 SDK来调用它 —— 在 React 应用里、在 Workshop 的自定义组件里,或者在另一个函数里。
:::callout{theme="neutral" title="Beta"}
通过本体 SDK 执行带流式响应的函数目前处于 beta 阶段,开发过程中功能可能发生变化。
Python TypeScript from foundry_sdk_runtime import AllowBetaFeatures
with AllowBetaFeatures():
with client.ontology.queries.create_chat_completion_streaming(prompt="珠穆朗玛峰在哪里?") as stream:
for text in stream:
# ... import { __EXPERIMENTAL__NOT_SUPPORTED_YET__executeStreamingFunction } from "@osdk/api/unstable";
const stream = client(__EXPERIMENTAL__NOT_SUPPORTED_YET__executeStreamingFunction).executeStreamingFunction(
createChatCompletion,
{
prompt: "珠穆朗玛峰在哪里?",
}
);
for await (const text of stream) {
// ...
}
### 常见问题速答 · FAQ
关于「流式函数:分块返回结果」,读者最常问的几个问题。
写流式函数是什么? 函数侧怎么写才能分块产出结果。要流式返回,Python 函数必须把返回类型标注为 Iterable[T],并用 yield 关键字在数据可用时逐个产出。
通过 OSDK 调用流式函数是什么? 消费端如何逐块接收并处理。流式函数打好标签并发布之后,就可以通过本体 SDK来调用它 —— 在 React 应用里、在 Workshop 的自定义组件里,或者在另一个函数里。
---
## 函数里的日志与埋点
- 页面:https://www.hanzhongpin.xyz/ontology/fn-telemetry.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/instrumentation-telemetry/
- 主题分组:函数(十一)
循序渐进 · 教学 · 函数(十一)
# 函数里的日志与埋点
从函数里主动发出日志和 span,才能在生产环境监控和排查。这篇讲支持哪些遥测类型、怎么写、以及日志的最佳实践。
## 先记住这几条
① 两类遥测:日志与 span 日志记事件,span 记录一段执行的耗时与调用关系。
② 目的是生产排障 没有埋点,线上出问题只能盲猜。
③ 日志有最佳实践 乱打日志会产生噪音甚至性能问题,要讲方法。
## 写在前面
你可以从函数里主动发出某些类型的遥测数据,用来监控和排查生产环境的工作流。
想了解如何查看函数发出的遥测数据,参见本体与 AIP 可观测性文档。
## 支持的遥测类型
支持的遥测类型
> 要点:Logs 与 Spans 两类,先看各自适用场景。
下表概览了每种函数语言支持的遥测类型。无论哪种函数,平台都会自动创建一个覆盖函数整个执行时长的 span,以及一条请求日志。
语言 日志 Span 指标 TypeScript v1 支持 仅平台预定义的 span[1] 仅平台预定义的指标[2] TypeScript v2 支持 支持[3] 仅平台预定义的指标[2] Python 支持 支持[3] 仅平台预定义的指标[2]
[1] TypeScript v1 函数里平台预定义的 span 包括对象加载、查询执行这类操作。
[2] Foundry 会为所有类型的函数记录总执行时长。
[3] TypeScript v2 与 Python 函数会自动为所有出向网络请求打点,此外你也可以自己添加自定义 span。
### Logs
你可以从函数里发出自定义日志,并在事后回看。下面的例子演示了 TypeScript v1、TypeScript v2 和 Python 函数分别怎么打日志。
在 TypeScript v2 函数里,Foundry 会帮你初始化 OpenTelemetry SDK 的全局 logger provider,你可以从它那里取到一个 logger。如果你想用第三方日志库,必须把它们配置成通过从全局 logger provider 取到的 logger 来输出日志。
TypeScript v1 TypeScript v2 Python export class MyFunctions {
@Function()
public myFunction(name: string): string {
console.log(`This is a custom log line, ${name}.`);
return `Hello, ${name}!`;
}
} import { logs } from "@opentelemetry/api-logs";
const logger = logs.getLogger("my-function");
export default function myFunction(name: string): string {
logger.emit({
body: "This is a custom log line.",
attributes: {
name
},
});
// 也可以直接用全局的 console 对象
console.log(`This is a custom log line, ${name}.`);
return `Hello, ${name}!`;
} import logging
from functions.api import function
logger = logging.getLogger(__name__)
@function
def my_function(name: str) -> str:
logger.info("This is a custom log line.")
return f"Hello, {name}!"
Logging best practices
打日志请遵循下面这些做法:
- 选对日志级别: 正常操作用 INFO,可恢复的问题用 WARN,失败用 ERROR,详细诊断信息用 DEBUG。
- 带上相关上下文: 加上标识符、数量、操作细节,便于理解执行过程。
- 不要打敏感数据: 不要记录凭据、可能含敏感信息的完整 API 响应,或其他涉密内容。
关于如何写好日志、查看服务日志、按级别过滤,参见服务日志与调试。
### Spans
你也可以在 TypeScript v2 和 Python 函数里创建自定义 span,用来跟踪某个具体操作耗时多久。下面的例子演示了如何创建自定义 span。
在 TypeScript v2 和 Python 函数里,Foundry 会帮你初始化 OpenTelemetry SDK 的全局 tracer provider,你可以从它那里取到一个 tracer。如果你想用第三方链路追踪库,必须把它们配置成通过从全局 tracer provider 取到的 tracer 来输出追踪数据。
TypeScript v2 Python import { trace } from "@opentelemetry/api";
import { Integer } from "@osdk/functions";
const tracer = trace.getTracer("my-function");
export default function sqrt(n: Integer): Integer {
const sqrt = tracer.startActiveSpan("my-custom-span", (span) => {
try {
return Math.sqrt(n);
} finally {
span.end();
}
});
return sqrt;
} import math
from functions.api import function
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
@function
def sqrt(n: int) -> int:
with tracer.start_as_current_span("my-custom-span"):
return math.sqrt(n)
---
## TypeScript v2 的本体编辑
- 页面:https://www.hanzhongpin.xyz/ontology/fn-ts-v2-edits.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/typescript-v2-ontology-edits/
- 主题分组:TypeScript v2(四)
循序渐进 · 教学 · TypeScript v2(四)
# TypeScript v2 的本体编辑
v2 函数不只读取,还能构造一批本体编辑:改属性、改链接、创建对象、删除对象,甚至编辑结构体属性。
## 先记住这几条
① 编辑要打包成 batch 多个编辑操作组装成一个批次返回。
② 增删改全覆盖 更新属性、更新链接、创建对象、删除对象四类。
③ 接口也能作为编辑目标 除了对象,接口上的属性和对象同样可编辑。
④ 结构体属性单独处理 struct 属性的编辑有专门写法。
## 写在前面
除了编写从 Ontology 读取数据的函数之外,你还可以编写用于创建对象、编辑对象属性与对象间链接的函数。本页介绍函数中可用的对象编辑 API。关于编辑函数如何工作的更多细节,请参阅概览页。
要使函数中创建的编辑真正被应用,Ontology 编辑函数必须被配置为一个 函数支撑的动作(function-backed Action) 。以这种方式配置动作,让你可以提供额外的元数据、配置权限,并在各种运营界面中访问该动作。正如文档所述,在动作之外运行编辑函数并不会真正修改任何对象数据。
标准的 Ontology 编辑使用一个编辑批次(edit batch)。TypeScript v2 还支持暂存写入(staged writes),它在函数内提供「写后可读」保障:编辑对同一次执行中后续的查询立即可见,且嵌套的暂存写入函数调用共享这些编辑。当函数必须读取它刚刚写入的数据时,请使用暂存写入。暂存写入目前处于测试(beta)开发阶段,在你的租户中可能不可用。
:::callout{theme="warning" title="意外的搜索结果影响的是编辑批次,而非暂存写入"}
当你使用编辑批次时,在编辑对象后立即搜索它们可能返回意外结果。这一注意事项不适用于暂存写入。详见 Caveats 一节。
## 定义编辑函数
定义编辑函数
> 要点:什么样的函数才能返回编辑。
编辑 Ontology 的函数必须显式声明将要被编辑的实体,使用从 @osdk/functions 包导出的 Edits 类型。下面的例子声明了一个新类型,表示对 Employee 与 Ticket 对象类型以及 Employee 与 Ticket 之间链接类型的编辑。多个实体的编辑需要用 | 运算符连接。
TypeScript v2 import { Employee, Person, Ticket } from "@ontology/sdk";
import { Edits } from "@osdk/functions";
type OntologyEdit = Edits.Object | Edits.Interface | Edits.Object | Edits.Link;
然后你必须声明该函数返回新类型的编辑数组。
TypeScript v2 export default function createNewTicketAndAssignToEmployee(): OntologyEdit[] {
// ...
}
## 构造编辑批次
构造编辑批次
> 要点:把多个编辑组装成一个 batch。
要在 TypeScript v2 函数中执行 Ontology 编辑,首先使用从 @osdk/functions 导出的 createEditBatch 函数构造一个 Ontology 编辑批次,将之前声明的类型作为类型参数传入:
TypeScript v2 import { Employee, Ticket } from "@ontology/sdk";
import { Client } from "@osdk/client";
import { createEditBatch, Edits } from "@osdk/functions";
type OntologyEdit = Edits.Object | Edits.Object | Edits.Link;
export default function createNewTicketAndAssignToEmployee(client: Client): OntologyEdit[] {
const batch = createEditBatch(client);
// ...
}
该批次用于跟踪函数中所做的所有编辑。
## 更新属性
更新属性
> 要点:对象属性与接口属性的更新写法。
### Object properties
使用所创建批次上的 update 方法修改一个或多个对象属性:
TypeScript v2 batch.update(employee, { lastName: newName });
如果你尚未将 employee 对象实例加载到内存,也可以通过引用对象的 API 名称与主键来更新它:
TypeScript v2 batch.update({ $apiName: "Employee", $primaryKey: 23 }, { lastName: newName });
在同一函数执行的后半段,再次访问 employee 的 lastName 属性值,将不会反映你在编辑批次上调用 update 时所做的更改。
有时,将一个对象类型某个实例的所有属性值复制到另一个实例是很有用的。下面的例子将 employee2 的属性值赋给 employee1:
TypeScript v2 batch.update(employee1, employee2);
已有对象的主键属性值无法被更新。
### Interface properties
你可以使用 update 方法通过一个 Ontology 接口修改对象的接口属性。在下面的例子中,person 的类型是一个 Ontology 接口,但其底层实例是一个实现 Person 接口的对象。
update 方法对于对象类型和接口都接受两个参数。对于接口,它接受将被修改的接口以及将被修改的接口属性。
TypeScript v2 batch.update(person, { firstName: newFirstName });
由底层对象的主键属性实现的接口属性无法被更新。
## 更新链接
更新链接
> 要点:修改对象之间的链接关系。
对于多对多链接,所创建批次上提供了 link 与 unlink 方法,用于在对象之间添加或移除链接。
TypeScript v2 // 将一名员工分配到一个办公室。
batch.link(employee, "office", office);
// 解除员工与办公室的分配。
batch.unlink(employee, "office", office);
对于一对一与一对多链接,使用所创建批次上的 update 方法修改源对象的外键属性。下面的例子展示了一对多链接。一名员工可以有多个工单,但每个工单只能有一名员工。
TypeScript v2 // 将工单分配给员工。
batch.update({ $apiName: "Ticket", $primaryKey: 13 }, { assignedEmployeeId: 52 });
// 解除工单的分配。
batch.update({ $apiName: "Ticket", $primaryKey: 13 }, { assignedEmployeeId: undefined });
与更新属性类似,如果你之前没有加载过对象类型的具体实例,也可以用 API 名称与主键引用链接的任意一侧。
TypeScript v2 // 将工单分配给员工。
batch.link({ $apiName: "Employee", $primaryKey: 23 }, "assignedTickets", { $apiName: "Ticket", $primaryKey: 12 });
// 解除员工与工单的分配。
batch.unlink({ $apiName: "Employee", $primaryKey: 23 }, "assignedTickets", { $apiName: "Ticket", $primaryKey: 12 });
## 创建对象
创建对象
> 要点:创建对象与接口实例。
### Objects
你可以使用编辑批次上的 create 方法创建新对象。创建新对象时,必须为它的主键指定一个值,并可以可选地初始化任何其他属性。
在这个例子中,我们用给定的 ID 创建一个新 Ticket 对象,设置其 dueDate 属性,并通过修改 assignedTickets 链接将它分配给给定的 Employee。为了简化 dueDate 新值的计算,我们使用了 luxon 库。
TypeScript v2 import { Employee, Ticket } from "@ontology/sdk";
import { Client, Osdk } from "@osdk/client";
import { createEditBatch, Edits, Integer } from "@osdk/functions";
import { DateTime } from "luxon";
type OntologyEdit = Edits.Object | Edits.Object | Edits.Link;
export default function createNewTicketAndAssignToEmployee(
client: Client,
employee: Osdk.Instance,
ticketId: Integer,
): OntologyEdit[] {
const batch = createEditBatch(client);
batch.create(Ticket, {
ticketId,
dueDate: DateTime.now().plus({ days: 7 }).toFormat('yyyy-MM-dd'),
});
// 新工单在 Ontology 中还不是一个具体实例,但我们可以通过引用它的 API 名称和主键来链接它
batch.link(employee, "assignedTickets", { $apiName: "Ticket", $primaryKey: ticketId });
return batch.getEdits();
}
### Interfaces
你可以通过调用 create 方法并指定一个接口、底层对象类型以及一组接口属性,来通过接口创建新的对象实例。所提供的接口属性中,必须有一个由底层对象类型的主键属性实现。
TypeScript v2 editBatch.create(Person, {
$objectType: "Employee",
firstName: "John",
lastName: "Doe",
});
## 删除对象
删除对象
> 要点:删除对象与接口实例。
### Objects
你可以通过调用编辑批次上的 delete 方法删除一个对象。
在这个例子中,我们删除分配给给定员工的所有工单:
TypeScript v2 for await (const ticket of employee.$link.assignedTickets.asyncIter()) {
batch.delete(ticket);
}
也可以使用主键而非实例来删除对象:
TypeScript v2 batch.delete({ $apiName: "Ticket", $primaryKey: 12 });
### Interfaces
你可以通过调用 delete 方法通过一个接口删除一个对象。
TypeScript v2 batch.delete(person);
## 结构体属性上的编辑
结构体属性上的编辑
> 要点:struct 类型属性的特殊处理。
对象类型与接口类型的 Ontology struct(结构体)属性都可以用 TypeScript v2 函数编辑。TypeScript v2 中的 Struct 类型 使用 TypeScript 接口定义。函数中的 Struct 类型可用于编辑 Ontology struct 属性,只要它们包含与 struct 属性相同的字段,且字段名与 Ontology struct 属性字段的 API 名称匹配。
TypeScript v2 interface Address {
street: string,
city: string,
state: string,
country: string,
zipcode: string,
}
export default function updateEmployeeAddress(
client: Client,
employee: Osdk.Instance,
newAddress: Address
): OntologyEdit[] {
const batch = createEditBatch(client);
batch.update(employee, { address: newAddress });
return batch.getEdits();
}
### 常见问题速答 · FAQ
关于「TypeScript v2 的本体编辑」,读者最常问的几个问题。
定义编辑函数是什么? 什么样的函数才能返回编辑。编辑 Ontology 的函数必须显式声明将要被编辑的实体,使用从 @osdk/functions 包导出的 Edits 类型。
构造编辑批次是什么? 把多个编辑组装成一个 batch。要在 TypeScript v2 函数中执行 Ontology 编辑,首先使用从 @osdk/functions 导出的 createEditBatch 函数构造一个 Ontology 编辑批次,将之前声明的类型作为类型参数传…
更新属性是什么? 对象属性与接口属性的更新写法。使用所创建批次上的 update 方法修改一个或多个对象属性。
更新链接是什么? 修改对象之间的链接关系。对于多对多链接,所创建批次上提供了 link 与 unlink 方法,用于在对象之间添加或移除链接。
---
## 从 TypeScript v1 迁移到 v2
- 页面:https://www.hanzhongpin.xyz/ontology/fn-ts-v2-migration.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/typescript-v2-migration/
- 主题分组:TypeScript v2(三)
循序渐进 · 教学 · TypeScript v2(三)
# 从 TypeScript v1 迁移到 v2
这是一份逐项语法对照的迁移手册:函数声明、包引用、日期时间、SDK 生成、查询写法、过滤/分组/聚合的映射,以及对象标识和编辑。
## 先记住这几条
① 迁移是语法层面的系统改造 不是改几个字母,是整套 API 换了。
② 查询差异最大 过滤操作符、链接遍历、分组策略、聚合指标都有映射表。
③ 有些 v1 能力 v2 没有 迁移前要确认你要用的能力在 v2 里有对应实现。
④ 日期与时间戳处理变了 这是最容易出错的细节之一。
## 写在前面
本指南描述将现有 TypeScript v1 函数迁移到 v2 时,你可能遇到的语法与结构差异。请参阅特性支持文档,了解 v2 的增强以及每个版本支持的内容。
## 函数声明方式
函数声明方式
> 要点:v1 是类 + 装饰器,v2 是默认导出的 async 函数。
要在 TypeScript v1 中将函数发布到平台,你必须用 @foundry/functions-api 包中的 @Function() 装饰器标注它,并且该函数必须是仓库根 index.ts 文件导出的类的一个方法。
TypeScript v1 // src/index.ts
import { Function } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public reverseStringArray(arr: string[]): string[] {
return arr.reverse();
}
}
要在 TypeScript v2 中将函数发布到平台,你必须将它写在 src/functions 目录下的一个文件中,并用 export default 导出。每个文件只能导出一个函数。
TypeScript v2 // src/functions/reverseStringArray.ts
export default function reverseStringArray(
arr: string[]
): string[] {
return arr.reverse();
}
为了让仓库保持有序,我们建议将相关函数分组到 src/functions 目录下的子目录中。例如,下面的文件夹结构将函数组织进 payroll 与 staffing 子目录,使职责划分更清晰。

> 图:TypeScript v2 函数的示例文件夹结构。
有关更多信息,请参阅我们关于TypeScript v2 函数上手的文档。
## 改用 @osdk/functions 包
改用 @osdk/functions 包
> 要点:包引用整体更换。
在 TypeScript v1 中,你必须从 @foundry/functions-api 包导入像 Integer 与 Double 这样的基本类型,才能在签名中使用它们。而在 TypeScript v2 中,你必须改用 @osdk/functions 包。
下面的例子从 @foundry/functions-api 包导入 Integer 类型,并在一个 TypeScript v1 函数的签名中使用它,以计算两个整数的最大公约数:
TypeScript v1 import { Function, Integer } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public gcd(a: Integer, b: Integer): Integer {
if (b === 0) {
return a;
}
return gcd(b, a % b);
}
}
在 TypeScript v2 中,核心 TypeScript 逻辑完全相同,但你必须使用 @osdk/functions 包中的 Integer 类型:
TypeScript v2 import { Integer } from "@osdk/functions";
export default function gcd(a: Integer, b: Integer): Integer {
if (b === 0) {
return a;
}
return gcd(b, a % b);
}
请参阅类型参考,了解如何在 TypeScript v1 与 v2 函数的签名中导入与使用类型。
## 日期与时间戳
日期与时间戳
> 要点:处理方式的差异,细节最容易出错。
TypeScript v1 使用 @foundry/functions-api 包中的 LocalDate 与 Timestamp 类型处理时间数据。TypeScript v2 用 @osdk/functions 包中的 DateISOString 与 TimestampISOString 类型取代它们,这两个类型将日期与时间戳表示为 ISO 8601 ↗ 字符串。
TypeScript v2 函数可以使用 NPM 生态中任何可用的日期与时间戳库,例如 dayjs ↗、date-fns ↗ 与 luxon ↗。
## 生成本体 SDK
生成本体 SDK
> 要点:v2 用自动生成的本地 OSDK。
TypeScript v2 函数通过 Ontology SDK 提供一流的查询与编辑 Ontology 的支持。与 TypeScript v1 一样,TypeScript v2 仓库允许你通过 Resource imports(资源导入) 侧边栏 导入 Ontology 实体。一旦你添加了对象类型与链接类型,系统会提示你创建 Ontology SDK 的初始版本。

> 图:在 TypeScript 代码仓库中创建你的第一个 Ontology SDK 的提示。
选择 Create(创建),然后为 Ontology SDK 取一个名字。该名字在首个版本生成后无法更改。选择 Create new version(创建新版本) 以生成 Ontology SDK。

> 图:在生成第一个 Ontology SDK 之前选择一个名字。
一旦 Ontology SDK 创建完成,你会看到一个将它安装到工作区的选项。选择 Install(安装) 会将 Ontology SDK 作为依赖添加到 package.json 文件中,使其可在 TypeScript 代码中使用。

> 图:从 TypeScript 代码仓库安装你的 Ontology SDK 的提示。
查看侧边栏中的 Documentation(文档) 标签页,获取在 TypeScript 中使用你的 Ontology 的综合示例。
## 查询本体(重点)
查询本体(重点)
> 要点:过滤操作符、链接遍历、分组策略、聚合指标的逐项映射,以及没有对应实现的能力。
在 TypeScript v1 中,你必须从 @foundry/ontology-api 包导入 Objects 来执行对 Ontology 的搜索:
TypeScript v1 import { Function, Integer } from "@foundry/functions-api";
import { Objects } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public async countAircraft(): Promise {
const count = await Objects.search().aircraft().count() ?? 0;
return count;
}
}
在 TypeScript v2 中,你必须通过将 Ontology SDK 客户端指定为函数签名的第一个参数来访问它:
TypeScript v2 import { Aircraft } from "@ontology/sdk";
import { Client } from "@osdk/client";
import { Integer } from "@osdk/functions";
export default async function countAircraft(client: Client): Promise {
const aircraft = await client(Aircraft).aggregate({
$select: {
$count: "unordered"
}
});
return aircraft.$count;
}
本节其余部分将 TypeScript v1 的查询词汇映射到其 TypeScript v2 等价物。关于完整的 TypeScript v2 查询词汇,请参阅 TypeScript OSDK 参考。
你在两个版本中过滤、排序或聚合的每个属性,都必须在 Ontology Manager 中标记为 Searchable(可搜索)。Searchable 控制属性如何被索引,因此这一要求属于 Ontology 而非任何一个 SDK。变化之处在于你从何处发现:在 TypeScript v1 中,代码生成器会省略未标记属性的过滤、排序与聚合方法,因此使用它们会导致编译失败;而 Ontology SDK 在 .where()、$orderBy 与 .aggregate() 中接受对象类型上的任何属性。
:::callout{theme="warning" title="迁移前确认 Searchable"}
在迁移之前,请在 Ontology Manager 中确认你过滤、排序或聚合的每个属性都已标记为 Searchable。在 TypeScript v2 中,未标记的属性可以编译通过,因此问题只会在函数运行时出现:像 $containsAnyTerm 这样的全文谓词会返回一个空页而非报错,于是过滤器可能匹配不到任何内容却报告成功。
### Filter operator mapping
在 TypeScript v1 中,.filter() 方法接受由你过滤的属性类型决定的过滤定义。TypeScript v2 用接受子句对象的单一 .where() 调用取代了那一族方法。下表将每个 TypeScript v1 过滤方法映射到其 TypeScript v2 where 子句键,以及它适用的属性类型。
TypeScript v2 的限制比 TypeScript v1 等价物更严格:一个地理空间属性只接受 $within、$intersects 与 $isNull,一个数组属性只接受 $contains 与 $isNull。关于它所记录的每个过滤器的形态,请参阅 TypeScript OSDK 参考中的 Filtering;它不涵盖 $within、$intersects 或 $interval。
TypeScript v1 TypeScript v2 where 子句键 适用于 .exactMatch(value) $eq,或裸值 布尔、日期时间、数字、字符串 .exactMatch(...values) $in: [...] 布尔、日期时间、数字、字符串 Filters.not(exactMatch) $ne 布尔、日期时间、数字、字符串 .hasProperty() $isNull: false 数组、布尔、日期时间、地理点、地理形状、数字、字符串 Filters.not(hasProperty()) $isNull: true 数组、布尔、日期时间、地理点、地理形状、数字、字符串 .range().lt(x) $lt 日期时间、数字 .range().lte(x) $lte 日期时间、数字 .range().gt(x) $gt 日期时间、数字 .range().gte(x) $gte 日期时间、数字 .isTrue() / .isFalse() $eq: true / $eq: false 布尔 .matchAnyToken(...) $containsAnyTerm 字符串 .matchAllTokens(...) $containsAllTerms 字符串 .phrase(...) $containsAllTermsInOrder 字符串 .phrasePrefix(), .prefixOnLastToken() $interval,搜索字符串放在 $match 中,并设 $prefixOnLastTerm: true 字符串 .contains(...) $contains,恰好接受一个内部过滤器 数组 .withinDistanceOf(), .withinPolygon(), .withinBoundingBox() $within 地理点、地理形状 .intersectsPolygon(), .intersectsBoundingBox() $intersects 地理形状 .doesNotIntersectPolygon(), .doesNotIntersectBoundingBox() 包裹 $intersects 的 $not 地理形状 .isPresent() 无对应 where 子句键 链接
三个行为差异会改变转换后过滤器的形态。关于 TSv2 子句形态规则本身,请参阅 Filtering。
- 有界区间变为两个子句。 TypeScript v1 的 .range().gte(a).lte(b) 链是一个单一调用,但 TypeScript v2 每个属性只接受一个运算符键,因此同一过滤器变为 $and: [{ p: { $gte: a } }, { p: { $lte: b } }]。
- 多值 .contains() 变为 $or。 TypeScript v1 的 .contains() 接受多个值并匹配其中任意一个,而 TypeScript v2 的 $contains 恰好接受一个内部过滤器。
- 日期时间比较接受 ISO 8601 字符串,如 { $gt: "2010-10-01T00:00:00Z" }。
### Link traversal mapping
TypeScript v1 为每个对象接口上的每种链接类型生成一个字段,并为对象集上的每种链接类型生成一个 searchAround 方法。TypeScript v2 将每个链接的访问器嵌套在 $link 下,并用单一的 pivotTo() 方法取代整个 searchAround 家族。
TypeScript v1 TypeScript v2 SingleLink 字段,用 .get() 或 .getAsync() 读取 $link.{linkApiName}.fetchOne(),或用 fetchOneWithErrors() 获得 { value } / { error } 包裹而非抛错。注意缺值时的行为变化:.get() 返回 undefined,而 fetchOne() 抛错,fetchOneWithErrors() 报告 { error },与其他任何失败无法区分 MultiLink 字段,用 .all() 或 .allAsync() 读取 $link.{linkApiName},它已经是一个 ObjectSet,用 asyncIter() 迭代 对象集上的 searchAround() pivotTo("")
不要从 searchAround 方法名推导链接 API 名称;方法名不能可靠地保留它。请改为查找链接 API 名称:在你生成的 TypeScript v2 SDK 中,对象类型的 $link 容器的键正是链接 API 名称,pivotTo() 原样接受该值。例如,API 名称为 toOtherObjectType 的链接用 pivotTo("toOtherObjectType") 遍历。
TypeScript v1 还限制了你能用从单个对象实例到达的链接做什么:一个 MultiLink 无法转换为对象集,因此你必须先从对象重建一个对象集。在 TypeScript v2 中你可以直接链式调用,因为多对多的 $link 项已经是一个 ObjectSet,且 pivotTo() 返回一个 ObjectSet。关于 TSv2 API 本身,请参阅 TypeScript OSDK 参考中的 Links。
### Group-by strategy mapping
TypeScript v1 通过调用 .groupBy() 并传入由属性类型决定的分桶方法来进行聚合分组。TypeScript v2 在单次 .aggregate() 调用的 $groupBy 对象中,以值的形式提供相同的信息。下表将每个 TypeScript v1 分桶方法映射到其 TypeScript v2 $groupBy 值。
$ranges 接受一个二元组数组,$duration 接受一个 [值, 单位] 元组。范围在起点包含、终点不包含,与 TypeScript v1 一致。只有 "seconds"、"minutes"、"hours" 与 "days" 接受任意值;较粗的单位只接受 1。关于分组策略本身,请参阅 TypeScript OSDK 参考中的 Types of grouping。
TypeScript v1 TypeScript v2 $groupBy 值 .exactValues() "exact" .exactValues({ maxBuckets: n }) { $exactWithLimit: n } .topValues() "exact" .byFixedWidth(50) { $fixedWidth: 50 } .byRanges({ min: 0, max: 50 }, { min: 50, max: 100 }) { $ranges: [[0, 50], [50, 100]] } .byYear() { $duration: [1, "years"] } .byQuarter() { $duration: [1, "quarters"] } .byMonth() { $duration: [1, "months"] } .byWeek() { $duration: [1, "weeks"] } .byDays(n) { $duration: [n, "days"] } .byHours(n), .byMinutes(n), .bySeconds(n) { $duration: [n, "hours"] }, { $duration: [n, "minutes"] }, { $duration: [n, "seconds"] } .segmentBy(...) 同一 $groupBy 对象中的第二个键
每个精确值分组请求都带有一个最大桶数,且默认值在两个版本间不同:TypeScript v1 的 .topValues() 默认为 1,000,而 TypeScript v2 的 "exact" 默认为 10,000。只有当属性的不同值落在那个计数之内时,结果才准确。超出后,对象会被排除在返回的分组之外,聚合变为近似。平台在每次响应中都报告结果是准确还是近似,但 TypeScript OSDK 没有暴露该字段,因此在 TypeScript v2 函数内部,近似结果与精确结果读起来一样。对于高基数的属性,请用 { $exactWithLimit: n } 提高计数,或先用 .where() 收窄对象集。一个布尔属性最多有两个不同值,因此对它而言 "exact" 总是准确的。
### Aggregation metric mapping
对对象集分组后,TypeScript v1 通过调用诸如 .count() 或 .average() 这样的聚合方法来计算指标。TypeScript v2 通过单次 .aggregate() 调用的 $select 对象选择指标。下表将每个 TypeScript v1 聚合方法映射到其 TypeScript v2 $select 键。
每个非 count 的键都是 ":" 形式的字符串,每个值都是排序指令:"unordered"、"asc" 或 "desc"。数值属性接受所有后缀;日期时间与时间戳属性只接受 min、max、approximateDistinct 与 exactDistinct;其他所有类型只接受两个去重计数后缀。关于聚合概念,请参阅 TypeScript OSDK 参考中的 Aggregations。
TypeScript v1 TypeScript v2 $select 键 .count() $count: "unordered" .average(e => e.p) "p:avg": "unordered" .max(e => e.p) "p:max": "unordered" .min(e => e.p) "p:min": "unordered" .sum(e => e.p) "p:sum": "unordered" .cardinality(e => e.p) "p:approximateDistinct": "unordered" 无 TypeScript v1 等价物 "p:exactDistinct": "unordered"
一个差异会影响转换后调用的形态:.aggregate() 接受一个恰好有两个键的单一请求对象,必填的 $select 与可选的 $groupBy。没有 where 键,因此请在调用 .aggregate() 之前用链式 .where() 过滤对象集。
结果形态也随之改变,因此转换后的函数必须以不同方式读取自己的输出。关于 $select 指令、排序限制,以及如何读取一个分组结果,请参阅 TypeScript OSDK 参考中的 Aggregations。
### Capabilities with no TypeScript v2 equivalent
一些 TypeScript v1 查询能力没有 TypeScript v2 对应物,因此在转换搜索或聚合之前要为它们做规划。
Filtering
- 链接存在性过滤没有 where 子句键。 在 TypeScript v1 中,.isPresent() 将一个对象集过滤为至少拥有一个给定类型链接对象、或(取反时)没有任何链接对象的对象。TypeScript v2 没有能做到这一点的 $ 键。最接近的做法是派生属性:定义一个统计链接对象数量的属性,然后过滤该计数大于零。在依赖它之前,请针对你自己的数据测试;这是一种变通而非受支持的等价物。
- Fuzziness(模糊度)编辑距离没有 TypeScript v2 形式。 TypeScript v2 的术语运算符 $containsAnyTerm 与 $containsAllTerms 接受一个普通的 fuzzySearch 布尔值,不提供编辑距离控制,因此 Fuzziness.LEVENSHTEIN_ONE 与 Fuzziness.LEVENSHTEIN_TWO 没有直接的 TypeScript v2 形式。$containsAllTermsInOrder 根本不接受模糊选项。$interval 键暴露了携带编辑距离的 $fuzzy 与 $fuzziness 子键,因此在使用前请针对你自己的数据测试这一构造。
Grouping
- 开放区间的桶已移除。 TypeScript v1 允许省略 min 或 max,得到一个从负无穷到 max、或从 min 到正无穷的桶。TypeScript v2 的 $ranges 元组要求两个端点都存在。
- Long 属性无法在 TypeScript v2 中分组。 TypeScript v1 将 Long 列为可用于分组的数值类型之一,但 TypeScript v2 类型没有为 Long 属性提供 $groupBy 值。
- 在 TypeScript v2 中按数组属性分组不受支持。 TypeScript v1 为数组属性提供与其元素类型相同的分桶方法。TypeScript v2 类型接受 $groupBy 中的数组属性,因此这个错误能编译通过,但结果无法保证;请改为按标量属性分组。
- TypeScript v2 中没有 segmentBy。 TypeScript v1 在 .groupBy() 之后调用 .segmentBy() 来计算按两个属性分桶的三维聚合。TypeScript v2 的等价物是同一 $groupBy 对象中的第二个键,但它返回的并非相同形态:TypeScript v1 产生嵌套桶,而 TypeScript v2 返回一个扁平的行数组,每行携带一个 $group 对象,持有每个 group-by 键的值。因此,必须返回三维聚合的函数需要自己重建嵌套;关于每个版本期望的形态,请参阅聚合类型。
Aggregation metrics
- 对日期或时间戳求平均是 TypeScript v1 独有。 TypeScript v1 的 .average() 接受时间戳与日期属性。TypeScript v2 在日期或时间戳属性上只提供 min、max、approximateDistinct 与 exactDistinct,因此对其中之一既不可用 avg 也不可用 sum。
- TypeScript v2 没有指标别名。 结果键总是从属性与指标派生,因此除 $count 或 "property:metric" 字符串之外的任何 $select 键都是类型错误。
Ordering and loading
- TypeScript v2 中没有 .take() 或 .limit()。 排序不再是一个链式子句:它作为 $orderBy 进入 fetchPage() 或 asyncIter() 的 options 对象,你用同一 options 对象中的 $pageSize 限制结果数量。
- TypeScript v2 中没有 .all()。 TypeScript v1 的 .all() 与 .allAsync() 一次性物化整个对象集。TypeScript v2 用 asyncIter() 迭代,或用 fetchPage() 读取单页,如将对象加载到内存所述。
- 最近邻的边界扩大了。 TypeScript v1 将 k 值限制为 0 < K <= 100,而 TypeScript v2 的 nearestNeighbors() 方法接受 1 到 500 之间的 numNeighbors。因此,处于其范围顶部的 TypeScript v1 搜索,在迁移后可请求的邻居数量是原来的五倍。
- 相关性排序只适用于最近邻搜索。 在 TypeScript v2 中,$orderBy: "relevance" 应用于 nearestNeighbors() 搜索,其中 numNeighbors 限制结果,每个返回的对象携带一个 $score。它对基于 token 匹配的 where 子句无效,因此 TypeScript v1 的「用 .matchAnyToken() 过滤、按相关性排序、然后取前 N 个结果」模式没有 TypeScript v2 等价物。
## 对象标识
对象标识
> 要点:对象标识符的引用方式变化。
TypeScript v1 通过对象的 rid、primaryKey 与 typeId 字段暴露其身份。TypeScript v2 为每个内置标识符字段加上 $ 前缀,以区别于对象自身的属性,并新增了 $objectSpecifier——一个编码了对象类型与主键的单字符串。因为 $rid 仅当读取通过 $includeRid: true 选择加入时才存在,所以在 TypeScript v2 中请使用 $objectSpecifier 而非 $rid 作为身份逻辑的基础。
### Identifier reference
下表将每个 TypeScript v1 标识符与类型映射到其 TypeScript v2 等价物。
TypeScript v1 TypeScript v2 备注 obj.rid obj.$rid 仅当读取传入 $includeRid: true 时存在。 obj.primaryKey obj.$primaryKey 始终存在。 obj.typeId obj.$apiName 或 obj.$objectType 始终存在。两者都携带对象类型 API 名称;只有 $apiName 是字面量类型。 不可用 obj.$objectSpecifier 始终存在。字符串 ":"。 Employee Osdk.Instance 已加载对象实例的类型。 OntologyObject 无等价物 来自 @osdk/api 的 OsdkBase 是最接近的类型。 IsOntologyObject 无等价物 已移除,无直接替代。 以对象为键的 FunctionsMap Record, V> 以标量为键的 FunctionsMap 变为普通的 Record。参见 Object mappings。
迁移后,比较两个对象是否相等变得更简单。在 TypeScript v1 中你必须同时比较 typeId 与 primaryKey,因为主键只在单一对象类型内唯一。TypeScript v2 将两个值都编码进 $objectSpecifier,因此等价检查是一次单一的字符串比较,即便两个对象属于不同对象类型也保持正确:
TypeScript v2 function isEqual(o1: { $objectSpecifier: string }, o2: { $objectSpecifier: string }): boolean {
return o1.$objectSpecifier === o2.$objectSpecifier;
}
关于两个版本中对象为键的映射的实例,请参阅类型参考中的 Map。关于两个例子的 TypeScript v1 形式,以及为什么对象相等需要小心的概念背景,请参阅 Object identifiers。
## 编辑本体
编辑本体
> 要点:v2 里怎么写编辑操作。
要在 TypeScript v1 中编写 Ontology 编辑函数,你必须用 @foundry/functions-api 包中的 @OntologyEditFunction() 装饰器标注它,并赋予它 void 返回类型。你还必须应用 @Edits 装饰器 来预先声明所有被编辑的对象类型,从而在函数支撑的动作被调用之前,就能对这些对象类型强制执行权限。
TypeScript v1 import { Edits, OntologyEditFunction } from "@foundry/functions-api";
import { Aircraft, Employee } from "@foundry/ontology-api";
export class MyOntologyEditFunctions {
@Edits(Aircraft, Employee)
@OntologyEditFunction()
public myFunction(aircraft: Aircraft, employee: Employee): void {
aircraft.businessCapacity = 3;
employee.department = "HR";
}
}
在 TypeScript v2 中,你必须从 @osdk/functions 包导入 createEditBatch 函数来构造一个在执行期间使用的编辑存储。你必须使用 Edits 类型声明你的函数被允许编辑哪些实体。这在编译时强制类型安全;如果你试图编辑一个未被你的 Edits 类型覆盖的对象或链接类型,TypeScript 编译器会返回错误。
TypeScript v2 import { createEditBatch, Edits } from "@osdk/functions";
import { Aircraft, Employee } from "@ontology/sdk";
import { Client, Osdk } from "@osdk/client";
type OntologyEdit = Edits.Object | Edits.Object;
export default function myFunction(
client: Client,
aircraft: Osdk.Instance,
employee: Osdk.Instance
): OntologyEdit[] {
const batch = createEditBatch(client);
batch.update(aircraft, { businessCapacity: 3 });
batch.update(employee, { department: "HR" });
return batch.getEdits();
}
> 在 TypeScript v2 中,使用 Edits.Interface 通过 Ontology 接口 属性创建、更新和删除对象。细节参见 Ontology edits。
在 TypeScript v1 中,编辑不会在函数执行期间应用到 Ontology。正如我们的编辑与对象搜索文档所述,对象与链接的变更只在函数执行完毕后、且仅当在 函数支撑的动作 内部被调用时,才会传播。
TypeScript v2 让这一行为更明确。你的函数不再隐式累积编辑,而是必须使用一个编辑批次跟踪它们,并在完成时返回。
有关受支持操作的完整列表,请参阅 TypeScript v2 文档中的 Ontology edits 一节。
> TypeScript v2 还支持暂存写入,这是一种带有写后可读保障的替代执行模型。暂存写入函数使用 WriteableClient 而非 createEditBatch,且无需显式返回编辑。
## 生成对象唯一 ID
生成对象唯一 ID
> 要点:创建对象时 ID 的生成方式。
要在 TypeScript v1 中为新创建的对象生成唯一 ID,请使用 @foundry/functions-utils 包中的 Uuid 工具。
TypeScript v1 import { Edits, OntologyEditFunction } from "@foundry/functions-api";
import { Uuid } from "@foundry/functions-utils";
import { FlightScenario, Objects } from "@foundry/ontology-api";
export class ExampleEditFunctions {
@Edits(FlightScenario)
@OntologyEditFunction()
public createFlightScenario(): void {
const scenario = Objects.create().flightScenarios(Uuid.random());
scenario.scenarioName = "New scenario";
}
}
TypeScript v2 运行在完整的 Node.js 环境中,因此你可以改用 node:crypto 核心模块:
TypeScript v2 import { FlightScenario } from "@ontology/sdk";
import { Client } from "@osdk/client";
import { createEditBatch, Edits } from "@osdk/functions";
import { randomUUID } from "node:crypto";
type OntologyEdit = Edits.Object;
export default function createFlightScenario(client: Client): OntologyEdit[] {
const batch = createEditBatch(client);
batch.create(FlightScenario, {
id: randomUUID(),
scenarioName: "New scenario",
});
return batch.getEdits();
}
避免在函数体之外的模块顶层调用 randomUUID 或其他随机值生成器。TypeScript v2 函数使用预热(warm)调用,所有模块级代码在初始化时只求值一次,然后在后续调用中复用。这意味着模块级的 randomUUID 调用只会被求值一次,并为每次预热调用产生相同的值。请始终在函数体内部生成随机值以确保唯一性。
## 把对象加载进内存
把对象加载进内存
> 要点:加载方式的差异。
TypeScript v1 函数暴露 .all() 与 .allAsync() API,将特定类型的所有对象加载到内存中进行处理。然而,随着 Ontology 中对象数量的增长,这种方法可能导致高内存占用与较慢性能。
TypeScript v1 import { Edits, OntologyEditFunction } from "@foundry/functions-api";
import { Aircraft, Objects } from "@foundry/ontology-api";
export class MyFunctions {
@Edits(Aircraft)
@OntologyEditFunction()
public editAircraft(): void {
const aircraft = Objects.search().aircraft().all();
aircraft.forEach(a => {
a.arrived = true;
});
}
}
TypeScript v2 函数通过 Ontology SDK 支持流式对象处理,避免了一次性将整个对象集保存在内存中的需要。我们建议尽可能采用这种方法。
TypeScript v2 import { Aircraft } from "@ontology/sdk";
import { Client } from "@osdk/client";
import { createEditBatch, Edits } from "@osdk/functions";
type OntologyEdit = Edits.Object;
export default async function editAircraft(client: Client): Promise {
const batch = createEditBatch(client);
for await (const a of client(Aircraft).asyncIter()) {
batch.update(a, { arrived: true });
}
return batch.getEdits();
}
如果数据规模不是问题,下面的替代方案会加载特定类型的所有对象:
TypeScript v2 import { Aircraft } from "@ontology/sdk";
import { Client } from "@osdk/client";
import { createEditBatch, Edits } from "@osdk/functions";
type OntologyEdit = Edits.Object;
export default async function editAircraft(client: Client): Promise {
const batch = createEditBatch(client);
const aircraft = await Array.fromAsync(client(Aircraft).asyncIter());
aircraft.forEach(a => {
batch.update(a, { arrived: true });
});
return batch.getEdits();
}
### 常见问题速答 · FAQ
关于「从 TypeScript v1 迁移到 v2」,读者最常问的几个问题。
函数声明方式是什么? v1 是类 + 装饰器,v2 是默认导出的 async 函数。
改用 @osdk/functions 包是什么? 包引用整体更换。在 TypeScript v1 中,你必须从 @foundry/functions-api 包导入像 Integer 与 Double 这样的基本类型,才能在签名中使用它们。
日期与时间戳是什么? 处理方式的差异,细节最容易出错。TypeScript v1 使用 @foundry/functions-api 包中的 LocalDate 与 Timestamp 类型处理时间数据。
生成本体 SDK是什么? v2 用自动生成的本地 OSDK。TypeScript v2 函数通过 Ontology SDK 提供一流的查询与编辑 Ontology 的支持。
---
## Staged writes:带读后写保证的编辑(Beta)
- 页面:https://www.hanzhongpin.xyz/ontology/fn-ts-v2-staged.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/typescript-v2-staged-writes/
- 主题分组:TypeScript v2(五)
循序渐进 · 教学 · TypeScript v2(五)
# Staged writes:带读后写保证的编辑(Beta)
Staged writes 是更强的编辑模式:写入后立刻能读到、不必在结尾返回编辑、整体原子执行。目前处于 Beta 阶段。
## 先记住这几条
① 读后写保证 写进去之后,同一函数里马上能读到新值 —— 普通编辑做不到。
② 不用在结尾返回编辑 写法上更接近命令式,编辑在函数内直接生效。
③ 原子执行 整段要么全成,要么全回滚。
④ 用 WriteableClient 需要一个可写客户端,这是入口。
⑤ 目前是 Beta 功能可能变动,且不一定在你的环境开放。
## 写在前面
:::callout{theme="neutral" title="Beta"}
暂存写入(staged writes)处于测试(beta)开发阶段,在你的租户中可能不可用。功能在积极开发期间可能发生变化。请联系 Palantir 支持以申请访问。
实时预览与已发布函数预览仅在 Code Repositories 中支持,而非在本地开发或 VS Code 工作区环境中。
本页介绍 TypeScript v2 函数中的暂存写入。对于 Python,请参阅 Python 函数中的暂存写入。
暂存写入为编辑 Ontology 中对象的函数提供了一种额外的执行模型。与通过常规 Ontology 编辑函数 所做的编辑不同,暂存写入函数:
- 为函数中应用的 Ontology 编辑提供「写后可读」保障。函数内应用的所有编辑都会被暂存,并反映在函数后续对 Ontology 的查询与聚合中。
- 允许嵌套调用其他暂存写入函数来进行 Ontology 编辑。
本页展示了如何编写暂存写入函数,并记录了它们的独特属性。关于编辑函数如何工作的更多细节,请参阅概览页。
## 与普通编辑函数的差异
与普通编辑函数的差异
> 要点:读后写保证、无需返回编辑、原子执行、WriteableClient —— 四条核心差异。
暂存写入函数与常规编辑函数在几个重要方面有所不同。
### Read-after-write guarantee
在暂存写入函数内,任何对 Ontology 数据的读取都会反映函数先前所做的所有编辑(以及在同一次动作执行中,调用方暂存写入函数所做的所有编辑)。这些编辑仅被暂存,在由其他用户发起的查询中、或在本次执行上下文之外的函数中都不可见。这让你可以使用搜索请求与聚合,从函数内部查询 Ontology,而所有暂存的编辑都会在查询结果中得到反映。
### No requirement to return edits at the end of the function
常规的 Python 与 TypeScript v2 Ontology 编辑函数要求将一批 Ontology 编辑作为函数的返回值返回,这些编辑才会被应用。在暂存写入函数中,Ontology 编辑会被自动暂存,并在函数执行结束时、动作完成时应用到 Ontology。这释放了函数的返回值,使其可以向调用方返回其他信息。
例如,你可以应用一个动作,它执行一个 TypeScript v2 暂存写入函数,该函数随后做一些编辑并进一步调用一个 AIP Logic 函数。AIP Logic 函数所做的查询会返回 TypeScript v2 函数中对 Ontology 所做的更改;AIP Logic 函数所做的任何额外编辑都会并入同一批暂存编辑,而无需作为 Logic 函数返回值的一部分返回。一旦动作完成,所有暂存编辑都会被自动应用。
### Atomic execution
暂存写入函数内的所有操作,包括查询、函数调用与 AIP Logic 执行,都会将其编辑暂存到一起。这些暂存编辑在函数成功完成后被提交(即应用到 Ontology)。如果函数抛出错误,Ontology 保持未修改状态,所有暂存编辑在动作重试该函数之前被丢弃。
### WriteableClient
暂存写入函数使用 WriteableClient 而非标准的 Client。WriteableClient 提供了用于创建、更新和删除对象的直接方法,而无需构造编辑批次。
## 定义 staged-write 函数
定义 staged-write 函数
> 要点:函数签名与入口写法。
暂存写入函数必须显式声明将要被编辑的实体,使用从 @osdk/functions 包导出的 Edits 类型。第一个参数必须是 WriteableClient,其中 T 是函数将执行的所有编辑类型的并集。返回值不再被限制为编辑数组,因此你可以返回任意值。下面的例子声明了一个将编辑 Employee 对象类型的函数:
TypeScript v2 import { Employee } from "@ontology/sdk";
import { Edits, Integer } from "@osdk/functions";
import { WriteableClient } from "@osdk/functions/experimental";
type OntologyEdit = Edits.Object;
export default async function assignTicket(
client: WriteableClient,
employeeId: string,
ticketId: string
): Promise {
// ...
}
## 创建对象
创建对象
> 要点:包含用生成 ID 创建的方式。
使用 WriteableClient 上的 create 方法创建新对象。你必须指定对象类型,并为它的主键提供一个值,以及任何你想要初始化的其他属性。
TypeScript v2 import { Employee } from "@ontology/sdk";
import { Edits } from "@osdk/functions";
import { WriteableClient } from "@osdk/functions/experimental";
type OntologyEdit = Edits.Object;
async function createEmployee(
client: WriteableClient,
employeeId: string,
firstName: string,
lastName: string
): Promise {
await client.create(Employee, {
employeeId: employeeId,
firstName: firstName,
lastName: lastName
});
return employeeId;
}
export default createEmployee;
### Creating with generated IDs
当你需要生成一个 ID 并立即使用时:
TypeScript v2 import { Ticket } from "@ontology/sdk";
import { Edits, Integer } from "@osdk/functions";
import { WriteableClient } from "@osdk/functions/experimental";
import { randomUUID } from "crypto";
type OntologyEdit = Edits.Object;
async function createTicket(
client: WriteableClient,
title: string
): Promise {
const ticketId = randomUUID();
await client.create(Ticket, {
ticketId: ticketId,
title: title,
status: "open"
});
return ticketId;
}
export default createTicket;
## 更新对象
更新对象
> 要点:对象属性的更新。
### Object properties
使用 WriteableClient 上的 update 方法修改对象属性:
TypeScript v2 await client.update(employee, { lastName: newName });
你也可以通过引用对象的 API 名称与主键来更新它:
TypeScript v2 await client.update({ $apiName: "Employee", $primaryKey: 23 }, { lastName: newName });
暂存写入函数不支持接口编辑。
## 删除对象
删除对象
> 要点:删除操作。
你可以通过调用 WriteableClient 上的 delete 方法删除一个对象:
TypeScript v2 await client.delete(ticket);
也可以使用主键而非实例来删除对象:
TypeScript v2 await client.delete({ $apiName: "Ticket", $primaryKey: 12 });
## 创建或删除链接
创建或删除链接
> 要点:链接的增删。
使用 WriteableClient 上的 link 与 unlink 方法,在对象之间添加或移除多对多链接:
TypeScript v2 // 将工单分配给员工
await client.link(employee, "assignedTickets", ticket);
// 解除员工与工单的分配
await client.unlink(employee, "assignedTickets", ticket);
你也可以通过 API 名称与主键引用链接的任意一侧:
TypeScript v2 await client.link(
{ $apiName: "Employee", $primaryKey: 23 },
"assignedTickets",
{ $apiName: "Ticket", $primaryKey: 12 }
);
要编辑一对多链接,请使用创建或更新对象编辑来修改外键属性。
## 函数内的读后写
函数内的读后写
> 要点:这是 staged writes 最大的卖点,注意作用域限制。
暂存写入函数的主要优势之一,是能够读取同一次执行中刚刚写入的数据。这对于实现要求即时一致性的工作流很有用。
TypeScript v2 import { Employee, Ticket } from "@ontology/sdk";
import { Edits, Integer } from "@osdk/functions";
import { WriteableClient } from "@osdk/functions/experimental";
import { randomUUID } from "crypto";
type OntologyEdit = Edits.Object | Edits.Link;
async function assignTicketAndCheckWorkload(
client: WriteableClient,
employeeId: Integer,
title: string
): Promise<{ ticketId: string, totalAssignedTickets: number }> {
const ticketId = randomUUID();
// 创建工单
await client.create(Ticket, {
ticketId: ticketId,
title: title,
status: "open"
});
// 将工单分配给员工
await client.link(
{ $apiName: "Employee", $primaryKey: employeeId },
"assignedTickets",
{ $apiName: "Ticket", $primaryKey: ticketId }
);
// 查询员工的总工作量,包括新分配的工单。
// 这之所以可行,是因为「写后可读」保障。
// where 子句过滤的是对象类型自身的属性,因此要先用 pivotTo() 遍历
// assignedTickets 链接,再对 Ticket 做过滤。
const result = await client(Employee)
.where({ employeeId: { $eq: employeeId } })
.pivotTo("assignedTickets")
.where({ status: { $eq: "open" } })
.aggregate({ $select: { $count: "unordered" } });
return {
ticketId: ticketId,
totalAssignedTickets: result.$count
};
}
export default assignTicketAndCheckWorkload;
## 调用其他函数
调用其他函数
> 要点:在函数里再调别的函数时的注意事项。
当你在暂存写入函数内调用另一个函数或查询时,这些操作会参与到同一批暂存编辑中。任何读取都会反映执行中先前暂存的编辑,被调用函数所做的任何编辑都会加入同一批暂存编辑。这适用于:
- 其他 TypeScript 暂存写入函数
- AIP Logic 函数
- Ontology 查询
如果顶层函数成功完成,跨嵌套调用的所有编辑会一起提交。如果任何调用抛出异常,整批会被回滚。
在下面的例子中,assignTicket 是一个独立的暂存写入函数,从同一仓库发布。bulkAssignTickets 通过 OSDK 生成的 $Queries 导入来调用它;每次调用都会将其编辑加入调用函数的同一批暂存编辑中。
TypeScript v2 import { Employee, Ticket, $Queries } from "@ontology/sdk";
import { Edits, Integer } from "@osdk/functions";
import { WriteableClient } from "@osdk/functions/experimental";
type OntologyEdit = Edits.Object | Edits.Link;
async function bulkAssignTickets(
client: WriteableClient,
employeeId: Integer,
ticketIds: string[]
): Promise {
let assignedCount = 0;
for (const ticketId of ticketIds) {
// 每次对 `assignTicket` 的调用,都将其编辑与调用函数的编辑暂存到一起。
await client($Queries.assignTicket).executeFunction({
employeeId: employeeId,
ticketId: ticketId,
});
assignedCount++;
}
// 所有嵌套调用中的暂存编辑将在顶层函数完成时一起提交
return assignedCount;
}
export default bulkAssignTickets;
## 执行生命周期
执行生命周期
> 要点:理解执行的各个阶段,便于排查。
理解暂存编辑何时被提交,对于构建可靠的函数很重要:
- 函数执行: 所有操作(创建、更新、删除、读取、嵌套函数调用)都被暂存到 Ontology。它们对函数自身及所有嵌套函数可见,但在提交之前不会出现在当前执行之外。
- 提交: 如果函数成功完成,所有暂存编辑会在动作结束前被提交。
- 错误时回滚: 如果函数抛出异常,Ontology 保持未修改状态,所有暂存编辑被丢弃。然后函数由动作重试。
TypeScript v2 import { Employee } from "@ontology/sdk";
import { Edits, Integer } from "@osdk/functions";
import { WriteableClient } from "@osdk/functions/experimental";
async function updateEmployeeWithValidation(
client: WriteableClient>,
employeeId: Integer,
newSalary: number
): Promise {
// 校验输入
if (newSalary < 0) {
// 暂存编辑将被丢弃
throw new Error("Salary cannot be negative");
}
// 更新员工
await client.update(
{ $apiName: "Employee", $primaryKey: employeeId },
{ salary: newSalary }
);
// 如果我们能执行到这里,所有暂存编辑将被原子化提交
}
export default updateEmployeeWithValidation;
### 常见问题速答 · FAQ
关于「Staged writes:带读后写保证的编辑(Beta)」,读者最常问的几个问题。
与普通编辑函数的差异是什么? 读后写保证、无需返回编辑、原子执行、WriteableClient —— 四条核心差异。
定义 staged-write 函数是什么? 函数签名与入口写法。暂存写入函数必须显式声明将要被编辑的实体,使用从 @osdk/functions 包导出的 Edits 类型。第一个参数必须是 WriteableClient,其中 T 是函数将执行的所有编辑类型的并集。
创建对象是什么? 包含用生成 ID 创建的方式。使用 WriteableClient 上的 create 方法创建新对象。你必须指定对象类型,并为它的主键提供一个值,以及任何你想要初始化的其他属性。
更新对象是什么? 对象属性的更新。使用 WriteableClient 上的 update 方法修改对象属性。
---
## TypeScript v2 函数上手
- 页面:https://www.hanzhongpin.xyz/ontology/fn-ts-v2-started.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/typescript-v2-getting-started/
- 主题分组:TypeScript v2(一)
循序渐进 · 教学 · TypeScript v2(一)
# TypeScript v2 函数上手
TypeScript v2 是新一代函数写法:新的 OSDK、更贴近 Node 生态、支持本地 SDK。这篇按建仓库→写函数→预览→发布→使用走一遍。
## 先记住这几条
① v2 用全新的 OSDK 与 v1 的 SDK 不同,代码写法差异较大。
② 建仓库时选 TypeScript v2 语言在创建仓库阶段就要选对。
③ live preview 验证 发布前先在实时预览里跑通。
④ 提交并打标签才算发布 commit 之后还要 tag,版本才对外可用。
## 写在前面
TypeScript v2 让用户能够利用相比 TypeScript v1 的多项关键改进,包括 Node.js 运行时与一流的 OSDK 支持。阅读下面各节开始上手。
## 第 1 步 · 创建 v2 仓库
第 1 步 · 创建 v2 仓库
> 要点:新建仓库时选择 TypeScript v2 语言。
导航到你选择的项目,选择 + New > Repository(+ 新建 > 仓库) 创建一个新的代码仓库。选择 TypeScript v2 functions 模板来初始化你的仓库。

> 图:创建一个 TypeScript v2 函数代码仓库。
仓库创建完成后,导航到 typescript-functions/src/functions/helloWorld.ts 文件。
在向函数导入 Ontology 类型之前,请通过 Resource imports(资源导入) 侧边栏添加你的对象类型和链接类型,然后生成并安装 Ontology SDK。这些步骤参见生成 Ontology SDK。
## 第 2 步 · 写一个函数
第 2 步 · 写一个函数
> 要点:v2 的函数写法:默认导出一个 async 函数。
要编写新函数,请在仓库的 typescript-functions/src/functions 目录下新建一个文件,并取一个有描述性的名字,例如 helloWorld.ts。使用 export default 编写函数,Foundry 才能检测到它。
TypeScript v2 export default function helloWorld(): string {
return "Hello World!";
}
要使函数能被发布到 Foundry,必须满足以下条件:
- 在 typescript-functions/src/functions 目录下的 .ts 文件中定义函数。在该目录中,你也可以把相关函数分组放在子目录里。
- 文件名必须与函数名一致。例如,要发布一个名为 myFunction 的函数,它必须定义在该目录下的 myFunction.ts 文件中。
- 该 TypeScript 函数必须是文件的默认导出(default export)。
- 函数的输入与输出类型必须遵循类型参考中支持的 func 类型。
函数的文件路径用于唯一标识从中发布的那个函数,因此修改文件路径会导致发布出一个新函数。
## 第 3 步 · 实时预览
第 3 步 · 实时预览
> 要点:不发布也能跑,看返回是否符合预期。
要在实时预览中测试函数,请打开 Functions(函数) 助手并选择 Live preview(实时预览)。选择你的函数并点击 Run(运行) 执行。

> 图:在函数助手中运行你的新函数。
## 第 4 步 · 提交并发布
第 4 步 · 提交并发布
> 要点:提交代码后打标签,函数才正式发布。
选择窗口右上角的 Commit(提交),将改动提交到仓库的 master 分支。要查看函数的检查项,请打开页面顶部的 Checks(检查) 标签页。在这里提交后,你应该能看到一个正在运行的检查项。

> 图:选择检查项以查看进度。
提交工作后,你会看到 Tag version(打标签版本) 选项。这将发布仓库中的所有函数。

> 图:可用的标签选项。
选择 Tag version,基于 master 分支打一个发布标签。根据改动的范围设置标签名称,然后选择 Tag and release(打标签并发布)。

> 图:为新的发布选择要打的版本类型。
要查看函数打标签与发布时的进度,请选择 View(查看) 弹窗,或导航到 Tags(标签) 标签页。一旦 Step 2: Release(第 2 步:发布) 完成,选择已发布的函数即可在 function registry 中查看它们。
在函数发布后,权限传播期间,Workshop 或 function registry 中可能无法立即按名称搜索到这些函数。

> 图:标签与发布检查均已通过,新函数已发布。
## 第 5 步 · 使用它
第 5 步 · 使用它
> 要点:发布后在动作、Workshop 等地方调用。
当你所打标签的检查项通过后,导航回 Code Repositories(代码仓库) 中的 Code(代码) 标签页,选择 Functions(函数) 助手。你现在应该能在 Published(已发布) 分区下看到你的函数。选择并运行这个新函数:

> 图:在函数助手中运行新函数。
## 下一步
下一步
> 要点:继续深入的推荐阅读方向。
创建并发布一个基础函数后,可以探索以下能力:
- Ontology SDK: 要查询或编辑 Ontology 对象,先导入你需要的对象与链接类型,然后生成并安装 Ontology SDK。
- Ontology 编辑: 了解如何在函数中创建、更新和删除对象。
- 暂存写入 \[Beta]: 对于需要「写后可读」保障或嵌套函数调用的编辑函数,参见暂存写入。
### 常见问题速答 · FAQ
关于「TypeScript v2 函数上手」,读者最常问的几个问题。
第 1 步 · 创建 v2 仓库是什么? 新建仓库时选择 TypeScript v2 语言。导航到你选择的项目,选择 + New > Repository(+ 新建 > 仓库)创建一个新的代码仓库。选择 TypeScript v2 functions 模板来初始化你的仓库。
第 2 步 · 写一个函数是什么? v2 的函数写法:默认导出一个 async 函数。要编写新函数,请在仓库的 typescript-functions/src/functions 目录下新建一个文件,并取一个有描述性的名字,例如 helloWorld.ts。
第 3 步 · 实时预览是什么? 不发布也能跑,看返回是否符合预期。要在实时预览中测试函数,请打开 Functions(函数)助手并选择 Live preview(实时预览)。选择你的函数并点击 Run(运行)执行。
第 4 步 · 提交并发布是什么? 提交代码后打标签,函数才正式发布。选择窗口右上角的 Commit(提交),将改动提交到仓库的 master 分支。要查看函数的检查项,请打开页面顶部的 Checks(检查)标签页。在这里提交后,你应该能看到一个正在运行的检查项。
---
## 函数类型参考手册
- 页面:https://www.hanzhongpin.xyz/ontology/fn-types-reference.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/types-reference/
- 主题分组:函数(五)
循序渐进 · 教学 · 函数(五)
# 函数类型参考手册
TypeScript 函数要发布到注册表,所有入参和返回值都必须显式标注类型。这一篇是全部可用类型的完整清单,写代码时当字典查。
## 先记住这几条
① 类型必须显式标注 不写类型标注的函数无法发布,这是硬性要求。
② 七大类型族 标量 / 集合 / 聚合 / 本体 / 媒体 / 用户与组 / 几何,覆盖函数能处理的全部数据形态。
③ 本体类型是重点 Object、Object set、Interface、Ontology edit 是写业务函数最常用的几个。
④ Optional 要单独注意 可选类型在函数签名里的写法,直接影响参数的必填性。
## 写在前面
要将 TypeScript 函数发布到注册表,必须为所有输入参数添加显式类型注解,并指定显式返回类型。以下列出了当前支持的全部函数注册表类型及其对应的语言类型。
> 在 Pipeline Builder 中将 Python 函数用作用户自定义函数(UDF)?下面这些标量类型(如 str 或 int)就是 UDF 返回的值,因为函数对每一行执行一次,其返回值会成为新的一列。你不需要返回 DataFrame。详细说明请查看Python 函数在 Pipeline Builder 中如何处理数据。
Function registry type TypeScript v1 type TypeScript v2 type Python type Attachment Attachment Attachment Attachment Example Boolean boolean boolean bool Example Binary Not supported Not supported bytes Example Byte Not supported Not supported int* Example Classification marking ClassificationMarking ClassificationMarking ClassificationMarking Example Date LocalDate DateISOString datetime.date Example Decimal Not supported Not supported decimal.Decimal Example Double Double Double float* Example Float Float Float float Example GeoPoint GeoPoint Point GeoPoint Example GeoShape GeoShape Geometry GeoShape Example Group Group GroupId GroupId Example Integer Integer Integer int Example Interface Not supported Osdk.Instance Not supported Example Interface object set Not supported ObjectSet Not supported Example List T[] or Array T[] or Array list[T] Example Long Long Long int* Example Mandatory marking MandatoryMarking MandatoryMarking MandatoryMarking Example Map FunctionsMap Record dict[K, V] Example Media reference MediaItem Media Media Example Notification Notification Notification Notification Example Object MyObjectType Osdk.Instance MyObjectType Example Object set ObjectSet ObjectSet MyObjectTypeObjectSet Example Ontology edit void Edits OntologyEdit Example Optional `T \ undefined` `T \ undefined` typing.Optional or `T \ None` Example Principal Principal Principal Principal Example Range IRange Range Range[T] Example Set Set Not supported set[T] Example Short Not supported Not supported int* Example String string string str Example Struct/custom type interface interface dataclasses.dataclass Example Timestamp Timestamp TimestampISOString datetime.datetime Example Two-dimensional aggregation TwoDimensionalAggregation TwoDimensionalAggregation TwoDimensionalAggregation[K, V] Example Three-dimensional aggregation ThreeDimensionalAggregation ThreeDimensionalAggregation ThreeDimensionalAggregation[K, S, V] Example User User UserId UserId Example
> 尽管 Integer 和 Long 都对应 Python 的 int 类型,但函数签名中直接标注为 int 的字段会被注册为 Integer 类型。因此,我们建议改用 API 中的 Integer 或 Long 类型来注册数值型数据。Float 和 Double 同理:如果函数签名中直接写了 Python 的 float 类型,默认会被注册为 Float。
## 标量类型
标量类型
> 要点:Boolean / String / 各种数字 / Date / Timestamp / Binary 等基础类型,以及必填与安全分级标记。
标量类型表示单个值,通常用于保存文本、数值或时间数据。
在 JavaScript 和 TypeScript 中,只有一个 number 类型,通常既用来表示整数也表示浮点数。为了提供更强的类型校验与结构约束,我们仅支持从 @foundry/functions-api 包(TypeScript v1 函数)和 @osdk/functions 包(TypeScript v2 函数)导出的数值别名类型。类似地,在 Python 函数中使用数值类型时,我们建议使用 functions.api 模块导出的类型别名。
### Boolean
TypeScript v1 TypeScript v2 Python import { Function, Integer } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public isEven(num: Integer): boolean {
return num % 2 === 0;
}
} import { Integer } from "@osdk/functions";
function isEven(num: Integer): boolean {
return num % 2 === 0;
}
export default isEven; from functions.api import function, Integer
@function
def is_even(num: Integer) -> bool:
return n % 2 == 0
### String
TypeScript v1 TypeScript v2 Python import { Function } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public greet(name: string): string {
return `Hello, ${name}!`;
}
} function greet(name: string): string {
return `Hello, ${name}!`;
}
export default greet; from functions.api import function
@function
def greet(name: str) -> str:
return f"Hello, {name}!"
### Short
表示 -32,768 到 32,767 之间的整数值。
在 Python 函数中,Short 类型是内置 int 类型的别名。
Python from functions.api import function, Short
@function
def increment(num: Short) -> Short:
return num + 1
### Integer
表示 (-231) 到 (231 - 1) 之间的整数值。
- 在 TypeScript v1 和 v2 函数中,Integer 类型都是内置 number 类型的别名。
- 在 Python 函数中,Integer 类型是内置 int 类型的别名。
TypeScript v1 TypeScript v2 Python import { Function, Integer } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public sum(a: Integer, b: Integer): Integer {
return a + b;
}
} import { Integer } from "@osdk/functions";
function sum(a: Integer, b: Integer): Integer {
return a + b;
}
export default sum; from functions.api import function, Integer
@function
def sum(a: Integer, b: Integer) -> Integer:
return a + b
### Long
表示 -(253 - 1) 到 (253 - 1) 之间的整数值。这些边界对应 JavaScript 中的 Number.MIN_SAFE_INTEGER 和 Number.MAX_SAFE_INTEGER,用于在函数从浏览器上下文调用时避免精度丢失。
- 在 TypeScript v1 函数中,Long 类型是内置 number 类型的别名;在 TypeScript v2 函数中,Long 类型是内置 string 类型的别名。
- 在 Python 函数中,Long 类型是内置 int 类型的别名。
TypeScript v1 TypeScript v2 Python import { Function, Long } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public subtract(a: Long, b: Long): string {
return (BigInt(a) - BigInt(b)).toString();
}
} import { Long } from "@osdk/functions";
function subtract(a: Long, b: Long): string {
return (BigInt(a) - BigInt(b)).toString();
}
export default subtract; from functions.api import function, Long
@function
def subtract(a: Long, b: Long) -> str:
return str(a - b)
### Float
表示 32 位浮点数。
- 在 TypeScript v1 和 v2 函数中,Float 类型都是内置 number 类型的别名。
- 在 Python 函数中,Float 类型是内置 float 类型的别名。
TypeScript v1 TypeScript v2 Python import { Float, Function } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public multiply(a: Float, b: Float): Float {
return a * b;
}
} import { Float } from "@osdk/functions";
function multiply(a: Float, b: Float): Float {
return a * b;
}
export default multiply; from functions.api import function, Float
@function
def multiply(a: Float, b: Float) -> Float:
return a * b
### Double
表示 64 位浮点数。
- 在 TypeScript v1 和 v2 函数中,Double 类型都是内置 number 类型的别名。
- 在 Python 函数中,Double 类型是内置 float 类型的别名。
TypeScript v1 TypeScript v2 Python import { Double, Function } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public divide(a: Double, b: Double): Double {
return a / b;
}
} import { Double } from "@osdk/functions";
function divide(a: Double, b: Double): Double {
return a / b;
}
export default divide; from functions.api import function, Double
@function
def divide(a: Double, b: Double) -> Double:
return a / b
### Decimal
Python from decimal import Decimal
from functions.api import function
@function
def return_pi() -> Decimal:
return Decimal('3.1415926535')
### Date
表示日历日期。
TypeScript v1 TypeScript v2 Python import { Function, LocalDate } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public returnDate(): LocalDate {
return LocalDate.fromISOString("1999-10-17");
}
} import { DateISOString } from "@osdk/functions";
function returnDate(): DateISOString {
return "1999-10-17";
}
export default returnDate; from datetime import date
from functions.api import function, Date
@function
def return_date() -> Date:
return date.fromisoformat('1999-10-17')
### Timestamp
表示时间轴上的一个时间点(时刻)。
TypeScript v1 TypeScript v2 Python import { Function, Timestamp } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getCurrentTimestamp(): Timestamp {
return Timestamp.now();
}
} import { TimestampISOString } from "@osdk/functions";
function getCurrentTimestamp(): TimestampISOString {
const now = new Date();
return now.toISOString();
}
export default getCurrentTimestamp; from datetime import datetime
from functions.api import function, Timestamp
@function
def get_current_timestamp() -> Timestamp:
return datetime.now()
### Binary
在 Python 函数中,Binary 类型是内置 bytes 类型的别名。
Python from functions.api import function
@function
def encode_utf8(param: str) -> bytes:
return param.encode('utf-8')
### Byte
在 Python 函数中,Byte 类型是内置 int 类型的别名。
Python from functions.api import function, Byte
@function
def get_first_byte(param: str) -> Byte:
if len(param) == 0:
raise Exception("String length cannot be zero.")
return param.encode('utf-8')[0]
### Mandatory marking
标记(Marking)是一种强制访问控制,要求用户必须拥有特定标记才能访问相应数据。
TypeScript v1 TypeScript v2 Python import { OntologyEditFunction, MandatoryMarking } from "@foundry/functions-api";
import { Employee, Objects } from "@foundry/ontology-api";
export class MyFunctions {
@Edits(Employee)
@OntologyEditFunction()
public async editMandatoryMarkings(markings: MandatoryMarking[]): Promise {
const employeeOne = Objects.search().employee().filter(e => e.id.exactMatch(1)).all()[0];
employeeOne.markingsProperty = markings;
}
} import { Client } from "@osdk/client";
import { Employee } from "@ontology/sdk";
import { Edits, createEditBatch, MandatoryMarking } from "@osdk/functions";
type OntologyEdit = Edits.Object;
function editMandatoryMarkings(markings: MandatoryMarking[]): OntologyEdit[] {
const batch = createEditBatch(client);
const employeeOne = await client(Employee).fetchOne(1);
batch.update(employeeOne, { markingsProperty: markings });
return batch.getEdits();
}
export default editMandatoryMarkings; from foundry_sdk_runtime import Marking
from functions.api import function, MandatoryMarking, OntologyEdit
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Employee
@function
def edit_mandatory_markings(markings: list[MandatoryMarking]) -> list[OntologyEdit]:
ontology_edits = FoundryClient().ontology.edits()
employee: Optional[Employee] = client.ontology.objects.Employee.get("primary_key")
if employee is None:
return []
editable_employee = ontology_edits.objects.Employee.edit(employee)
editable_employee.markings_property = [Marking(m) for m in markings]
# Assigning type "list[MandatoryMarking]" also works, but gives an LSP warning:
# editable_employee.markings_property = markings
return ontology_edits.get_edits()
### Classification marking
基于分类的访问控制(CBAC)是一种强制访问控制,用于保护敏感的政府信息。它要求用户必须拥有特定分类标记才能访问相应信息。
TypeScript v1 TypeScript v2 Python import { OntologyEditFunction, ClassificationMarking } from "@foundry/functions-api";
import { Employee, Objects } from "@foundry/ontology-api";
export class MyFunctions {
@Edits(Employee)
@OntologyEditFunction()
public async editClassificationMarkings(markings: ClassificationMarking[]): Promise {
const employeeOne = Objects.search().employee().filter(e => e.id.exactMatch(1)).all()[0];
employeeOne.markingsProperty = markings;
}
} import { Client } from "@osdk/client";
import { Employee } from "@ontology/sdk";
import { Edits, createEditBatch, ClassificationMarking } from "@osdk/functions";
type OntologyEdit = Edits.Object;
function editClassificationMarkings(markings: ClassificationMarking[]): OntologyEdit[] {
const batch = createEditBatch(client);
const employeeOne = await client(Employee).fetchOne(1);
batch.update(employeeOne, { markingsProperty: markings });
return batch.getEdits();
}
export default editClassificationMarkings; from foundry_sdk_runtime import Marking
from functions.api import ClassificationMarking, function, OntologyEdit
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Employee
@function
def edit_classification_markings(markings: list[ClassificationMarking]) -> list[OntologyEdit]:
ontology_edits = FoundryClient().ontology.edits()
employee: Optional[Employee] = client.ontology.objects.Employee.get("primary_key")
if employee is None:
return []
editable_employee = ontology_edits.objects.Employee.edit(employee)
editable_employee.markings_property = [Marking(m) for m in markings]
# Assigning type "list[ClassificationMarking]" also works, but gives an LSP warning:
# editable_employee.markings_property = markings
return ontology_edits.get_edits()
## 集合类型
集合类型
> 要点:List / Map / Set / Optional / 自定义结构体,用来描述复合数据。
集合类型由其他类型参数化。例如,Array[String] 是字符串列表,Map[String, Integer] 是以字符串为键、整数为值的字典。必须显式指定参数化类型,且该类型必须是另一种受支持的类型。Map 的键只能是标量类型或 Ontology 对象类型。
### List
TypeScript v1 TypeScript v2 Python import { Function, Integer } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public filterForEvenIntegers(nums: Integer[]): Integer[] {
return nums.filter(num => num % 2 === 0);
}
} import { Integer } from "@osdk/functions";
function filterForEvenIntegers(nums: Integer[]): Integer[] {
return nums.filter(num => num % 2 === 0);
}
export default filterForEvenIntegers; from functions.api import function, Integer
@function
def filter_for_even_integers(nums: list[Integer]) -> list[Integer]:
return [n for n in nums if n % 2 == 0]
### Map
Map 通常用于以标量类型为键,访问与之关联、且可为任何其他函数注册表类型的值。
TypeScript v1 TypeScript v2 Python import { Function, FunctionsMap } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getMap(): FunctionsMap {
const myMap = new FunctionsMap();
myMap.set("Name", "Phil");
myMap.set("Favorite Color", "Blue");
return myMap;
}
} function getMap(): Record {
const myMap: Record = {};
myMap["Name"] = "Phil";
myMap["Favorite Color"] = "Blue";
return myMap;
}
export default getMap; from functions.api import function
@function
def get_map() -> dict[str, str]:
my_map = {}
my_map["Name"] = "Phil"
my_map["Favorite Color"] = "Blue"
return my_map
此外,Map 还支持以 Ontology 对象作为键。
TypeScript v1 TypeScript v2 Python import { Function, FunctionsMap } from "@foundry/functions-api";
import { Airplane } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public getObjectMap(aircraft: Airplane[]): FunctionsMap {
const myMap = new FunctionsMap();
aircraft.forEach(obj => {
myMap.set(obj, obj.capacity);
});
return myMap;
}
} import { ObjectSpecifier, Osdk } from "@osdk/client";
import { Integer } from "@osdk/functions";
import { Airplane } from "@ontology/sdk";
function getObjectMap(aircraft: Osdk.Instance[]): Record, Integer | undefined> {
const myMap: Record, Integer | undefined> = {};
aircraft.forEach(obj => {
myMap[obj.$objectSpecifier] = obj.capacity;
});
return myMap;
}
export default getObjectMap; from functions.api import function, Integer
from ontology_sdk.ontology.objects import Airplane
@function
def get_object_map(aircraft: list[Airplane]) -> dict[Airplane, Integer | None]:
my_map = {}
for a in aircraft:
my_map[a] = a.capacity
return my_map
### Set
TypeScript v1 Python import { Function, Integer } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getSizeOfSet(mySet: Set): Integer {
return mySet.size;
}
} from functions.api import function, Integer
@function
def get_size_of_set(my_set: set[Integer]) -> Integer:
return len(my_set)
### Optional
- 在 TypeScript 函数中,可选参数声明为 varName?: T 或 varName: T | undefined。例如,一个带有名为 value 的可选整数参数的函数,可声明为 value?: Integer 或 value: Integer | undefined。TypeScript 函数也可以通过指定 T | undefined 类型来声明可选返回类型。例如,一个可能返回 Integer 或不返回任何值的函数,其返回类型为 Integer | undefined。
- 在 Python 函数中,可选参数和返回值可使用 typing.Optional[T] 或 T | None 声明。T | None 语法需要 Python 3.10 或以上版本。
- 在 TypeScript 和 Python 函数中,都必须显式指定参数化类型 T,且它必须是另一种受支持的类型。
TypeScript v1 TypeScript v2 Python import { Function } from "@foundry/functions-api";
export class MyFunction {
@Function()
public greet(name?: string): string | undefined {
if (name === undefined) {
return undefined;
}
return `Hello, ${name}!`;
}
} function greet(name?: string): string | undefined {
if (name === undefined) {
return undefined;
}
return `Hello, ${name}!`;
}
export default greet; from functions.api import function
@function
def greet(name: str | None) -> str | None:
if name is None:
return None
return f"Hello, {name}!"
函数还支持在函数签名中使用默认值。
TypeScript v1 TypeScript v2 Python import { Double, Function } from "@foundry/functions-api";
import { Customer } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public computeRiskFactor(customer: Customer, weight: Double = 0.75): Double {
// ...
}
} import { Double } from "@osdk/functions";
import { Osdk } from "@osdk/client";
import { Customer } from "@ontology/sdk";
function computeRiskFactor(customer: Osdk.Instance, weight: Double = 0.75): Double {
// ...
}
export default computeRiskFactor; from functions.api import function, Double
from ontology_sdk.ontology.objects import Customer
@function
def compute_risk_factor(customer: Customer, weight: Double = 0.75) -> Double:
# ...
### Struct/custom type
自定义类型由其他受支持的类型(包括其他自定义类型)组合而成,可用于函数签名。
> 函数签名中使用的自定义类型,与用于 Ontology 结构体属性的生成类不同。若要在 Python 函数中编辑 Ontology 结构体属性,请使用生成的 struct 属性类,详见编辑结构体属性。
- 在 TypeScript 函数中,自定义类型是使用 interface 关键字定义的 TypeScript 接口。
- 可选字段可通过 ? 可选标记,或与 undefined 组成的联合类型来支持。
- 在 Python 函数中,自定义类型是用户自定义的 Python 类。
- 要成为有效的自定义类型,该类必须满足以下要求:
- 类的所有字段都必须有类型注解。
- 字段类型必须是受支持的类型;可使用基础 API 类型或原生 Python 类型(如上文表格中所定义)。
- __init__ 方法只能接受命名参数,且参数名与类型注解必须与字段一致。
- 可使用 dataclasses.dataclass ↗ 装饰器自动生成符合上述要求的 __init__ 方法。
TypeScript v1 TypeScript v2 Python import { Function, Integer } from "@foundry/functions-api";
import { Passenger } from "@foundry/ontology-api";
interface PassengerInfo {
name?: string;
age?: Integer;
}
export class MyFunctions {
@Function()
public getPassengerInfo(passenger: Passenger): PassengerInfo {
return {
name: passenger.name,
age: passenger.age,
};
}
} import { Osdk } from "@osdk/client";
import { Integer } from "@osdk/functions";
import { Passenger } from "@ontology/sdk";
interface PassengerInfo {
name?: string;
age?: Integer;
}
function getPassengerInfo(passenger: Osdk.Instance): PassengerInfo {
return {
name: passenger.name,
age: passenger.age,
};
}
export default getPassengerInfo; from dataclasses import dataclass
from functions.api import function, Integer
from ontology_sdk.ontology.objects import Passenger
@dataclass
class PassengerInfo:
name: str | None
age: Integer | None
@function
def get_passenger_info(passenger) -> PassengerInfo:
return PassengerInfo(
name=passenger.name,
age=passenger.age
)
## 聚合类型
聚合类型
> 要点:Range 与二维、三维聚合,用于统计结果的表示。
聚合类型可从函数返回,供平台的其它部分使用,例如 Workshop 中的图表。
支持两种聚合类型:
- 二维聚合 将单个分桶键映射到一个数值。例如,可用于表示「具有特定职位的员工数量」这样的聚合。
- 三维聚合 将两个分桶键映射到一个数值。例如,可用于表示「按员工职位和所属办公室统计的员工数量」这样的聚合。
聚合可以按以下几种类型作为键:
- Boolean 分桶表示值为 true 或 false。
- String 分桶可用于表示分类值。
- Range 分桶表示以值区间作为分桶键的聚合。可用于在图表中表示直方图或日期轴。
- 数值区间(包括 Integer 和 Double)表示对数值的分桶聚合。
- 日期与时间区间(包括 Date 和 Timestamp)表示对日期区间的分桶聚合。
### Range
各版本字段名不同。TSv1 的 IRange 和 Python 的 Range[T] 使用 min 和 max;TSv2 的 Range 使用 startValue 和 endValue,且可省略其中之一以表示开区间。
TypeScript v1 TypeScript v2 Python import { Function, Integer, IRange } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getRange(min: Integer, max: Integer): IRange {
return {
min,
max,
};
}
} import { Integer, Range } from "@osdk/functions";
function getRange(min: Integer, max: Integer): Range {
return {
startValue: min,
endValue: max,
};
}
export default getRange; from functions.api import function, Integer, Range
@function
def get_range(min: Integer, max: Integer) -> Range[Integer]:
return Range(
min=min,
max=max
)
### Two-dimensional aggregation
TypeScript v1 TypeScript v2 Python import { Double, Function, TwoDimensionalAggregation } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public myTwoDimensionalAggregation(): TwoDimensionalAggregation {
return {
buckets: [
{ key: "bucket1", value: 5.0 },
{ key: "bucket2", value: 6.0 },
],
};
}
} import { Double, TwoDimensionalAggregation } from "@osdk/functions";
function myTwoDimensionalAggregationFunction(): TwoDimensionalAggregation {
return [
{ key: "bucket1", value: 5.0 },
{ key: "bucket2", value: 6.0 },
];
}
export default myTwoDimensionalAggregationFunction; from functions.api import (
function,
Double,
TwoDimensionalAggregation,
SingleBucket
)
@function
def my_two_dimensional_aggregation_function() -> TwoDimensionalAggregation[str, Double]:
return TwoDimensionalAggregation(
buckets=[
SingleBucket(key="bucket1", value=Double(5.0)),
SingleBucket(key="bucket2", value=Double(6.0)),
]
)
### Three-dimensional aggregation
分桶结构在各版本间不同。TSv1 将外层分桶包裹在 buckets 键下,内层以 value 为键。TSv2 返回一个扁平数组,内层位于 groups 下,因此 ThreeDimensionalAggregation 解析为 { key: T; groups: { key: U; value: V }[] }[]。Python 与 TSv1 一样包裹外层分桶,并通过 NestedBucket 和 SingleBucket 类构建。
TypeScript v1 TypeScript v2 Python import { Double, Function, ThreeDimensionalAggregation } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public myThreeDimensionalAggregation(): ThreeDimensionalAggregation {
return {
buckets: [
{
key: "group-by-1",
value: [
{ key: "partition-by-1", value: 5.0 },
{ key: "partition-by-2", value: 6.0 },
],
},
{
key: "group-by-2",
value: [
{ key: "partition-by-1", value: 7.0 },
{ key: "partition-by-2", value: 8.0 },
],
},
]
};
}
} import { Double, ThreeDimensionalAggregation } from "@osdk/functions";
function myThreeDimensionalAggregation(): ThreeDimensionalAggregation {
return [
{
key: "group-by-1",
groups: [
{ key: "partition-by-1", value: 5.0 },
{ key: "partition-by-2", value: 6.0 },
],
},
{
key: "group-by-2",
groups: [
{ key: "partition-by-1", value: 7.0 },
{ key: "partition-by-2", value: 8.0 },
],
},
];
}
export default myThreeDimensionalAggregation; from functions.api import (
function,
Double,
ThreeDimensionalAggregation,
SingleBucket,
NestedBucket,
)
@function
def my_three_dimensional_aggregation_function() -> (
ThreeDimensionalAggregation[str, str, Double]
):
return ThreeDimensionalAggregation(
buckets=[
NestedBucket(key="group-by-1", buckets=[
SingleBucket(key="partition-by-1", value=Double(5.0)),
SingleBucket(key="partition-by-2", value=Double(6.0)),
]),
NestedBucket(key="group-by-2", buckets=[
SingleBucket(key="partition-by-1", value=Double(7.0)),
SingleBucket(key="partition-by-2", value=Double(8.0)),
])
]
)
## 本体类型
本体类型
> 要点:Object、Object set、Interface、Ontology edit、Attachment、Notification —— 业务函数的核心。
要在函数签名中使用对象类型,必须先将它们导入到你的代码仓库。了解有关 Ontology 导入的更多信息。
### Object
来自你的 Ontology 的对象类型,既可作为函数签名的输入,也可作为输出。若要接收或返回单个对象类型实例,请从 Ontology SDK 导入该对象类型,并用它来注解你的函数。
TypeScript v1 TypeScript v2 Python import { Function, Integer } from "@foundry/functions-api";
import { Airplane } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public getCapacity(airplane: Airplane): Integer {
return airplane.capacity;
}
} import { Osdk } from "@osdk/client";
import { Integer } from "@osdk/functions";
import { Airplane } from "@ontology/sdk";
function getCapacity(airplane: Osdk.Instance): Integer {
return airplane.capacity;
}
export default getCapacity; from functions.api import function, Integer
from ontology_sdk.ontology.objects import Airplane
@function
def get_capacity(airplane: Airplane) -> Integer:
return airplane.capacity
在 TypeScript v2 中,对对象类型的引用可作为 struct 参数字段使用。若要接收包含对象类型实例的 struct 或 struct 列表,请创建一个带有 Ontology SDK 对象类型字段的自定义类型输入。它可以与 Ontology 编辑 配合,支持诸如「从其它对象类型派生出多个对象类型实例」之类的工作流。
TypeScript v2 import { Osdk } from "@osdk/client";
import { Integer } from "@osdk/functions";
import { Airplane, Passenger, Ticket } from "@ontology/sdk";
type TicketEdit = Edits.Object
interface TicketInfo {
airplane?: Osdk.Instance;
passenger?: Osdk.Instance;
seat?: String;
}
function createTickets(ticketInfo: TicketInfo[]): TicketEdit[] {
const batch = createEditBatch(client);
ticketInfo.forEach(i => batch.create(TicketEdit, {
flightNumber: i.airplane.flightNumber,
passengerName: i.passenger.name,
seat: i.seat}))
return batch.getEdits();
}
export default createTickets;
### Object set
将对象集合传入或传出函数有两种方式:具体的对象集合(如数组),或对象集(object set)。
将对象数组传入函数,可以对一份具体的对象列表执行逻辑,代价是需要预先将所有对象加载到函数执行环境中。而对象集允许你执行筛选、周边检索和聚合操作,并且仅在请求时才加载最终结果。
> 我们建议使用对象集而非数组,因为对象集通常性能更好,且允许向函数传入超过 10,000 个对象。
下面的示例展示了如何在不将对象加载到内存的情况下筛选对象集,从而可将筛选后的对象集返回给应用的其他部分。
TypeScript v1 TypeScript v2 Python import { Function } from "@foundry/functions-api";
import { Airplane, ObjectSet } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public filterAircraft(aircraft: ObjectSet): ObjectSet {
return aircraft.filter(a => a.capacity.range().gt(200));
}
} import { ObjectSet } from "@osdk/client";
import { Airplane } from "@ontology/sdk";
function filterAircraft(aircraft: ObjectSet): ObjectSet {
return aircraft
.where({
capacity: {
$gt: 200,
}
});
}
export default filterAircraft; from functions.api import function
from ontology_sdk.ontology.objects import Airplane
from ontology_sdk.ontology.object_sets import AirplaneObjectSet
@function
def filter_aircraft(aircraft: AirplaneObjectSet) -> AirplaneObjectSet:
return aircraft.where(Airplane.object_type.capacity > 200)
### Interface
来自你的 Ontology 的接口类型,在 TypeScript v2 函数签名中既可作为输入也可作为输出。TypeScript v1 和 Python 不支持接口类型。
TypeScript v2 import { Osdk } from "@osdk/client";
import { Integer } from "@osdk/functions";
import { Person } from "@ontology/sdk";
function getAge(person: Osdk.Instance): Integer {
return person.age;
}
export default getAge;
### Interface object set
接口对象集在 TypeScript v2 函数签名中既可作为输入也可作为输出。
TypeScript v2 import { ObjectSet } from "@osdk/client";
import { Person } from "@ontology/sdk";
function filterPeople(people: ObjectSet): ObjectSet {
return people
.where({
age: {
$gt: 200,
}
});
}
export default filterPeople;
### Ontology edit
除了编写从 Ontology 读取数据的函数,你还可以编写创建对象、编辑对象属性及对象间链接的函数。有关编辑函数工作方式的更多细节,请参阅概览页。
要注册为编辑函数,TypeScript v1 函数需要在签名中声明 void 返回类型;而 TypeScript v2 和 Python 函数则需要显式返回一组 Ontology 编辑。
TypeScript v1 TypeScript v2 Python import { Edits, OntologyEditFunction } from "@foundry/functions-api";
import { Employee, LaptopRequest, Objects } from "@foundry/ontology-api";
export class MyFunctions {
@Edits(Employee, LaptopRequest)
@OntologyEditFunction()
public assignEmployee(newEmployee: Employee, leadEmployee: Employee): void {
const newLaptopRequest = Objects.create().laptopRequest(Date.now().toString());
newLaptopRequest.employeeName = newEmployee.name;
newEmployee.lead.set(leadEmployee);
}
} import { Client } from "@osdk/client";
import { createEditBatch, Edits } from "@osdk/functions";
import { Employee, LaptopRequest } from "@ontology/sdk";
type EmployeeEdit =
| Edits.Object
| Edits.Object
| Edits.Link;
function assignEmployee(
client: Client,
newEmployee: Osdk.Instance,
leadEmployee: Osdk.Instance
): EmployeeEdit[] {
const batch = createEditBatch(client);
batch.create(LaptopRequest, {
id: Date.now().toString(),
employeeName: newEmployee.name,
});
batch.link(newEmployee, "lead", leadEmployee);
return batch.getEdits();
}
export default assignEmployee; from functions.api import function, OntologyEdit
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Employee, LaptopRequest
from time import time
@function
def assign_employee(new_employee: Employee, lead_employee: Employee) -> list[OntologyEdit]:
ontology_edits = FoundryClient().ontology.edits()
new_laptop_request = ontology_edits.objects.LaptopRequest.create(str(int(time() * 1000)))
new_laptop_request.employee_name = new_employee.name
new_employee.lead.set(lead_employee)
return ontology_edits.get_edits()
### Attachment
TypeScript v1 TypeScript v2 Python import { Attachment, Function } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public loadAttachmentContents(attachment: Attachment): Promise {
return attachment.readAsync().then(blob => blob.text());
}
} import { Attachment } from "@osdk/functions";
function loadAttachmentContents(attachment: Attachment): Promise {
return attachment.fetchContents().then(response => response.text());
}
export default loadAttachmentContents; from functions.api import function, Attachment
@function
def load_attachment_contents(attachment: Attachment) -> str:
return attachment.read().getvalue().decode('utf-8')
### Notification
Notification 类型可从函数返回,用于灵活配置平台中应发送的通知。例如,你可以编写一个函数,接收 User 和某个对象类型等参数,并返回一条带有配置好消息内容的 Notification。
- Notification 由两个字段组成:ShortNotification 和 EmailNotificationContent。
- ShortNotification 表示通知的精简版本,会在 Foundry 平台内展示。它包含一个简短的 heading、content,以及一组 Link。
- EmailNotificationContent 表示通知的富文本版本,可通过邮件外发。它包含一个 subject、由无头(headless)HTML 组成的 body,以及一组 Link。
- Link 具有面向用户的 label 和 linkTarget。LinkTarget 可以是 URL、一个 OntologyObject,或 Foundry 中任意资源的 rid。
有关如何使用 Notifications API 的示例,请参阅我们的指南。
TypeScript v1 TypeScript v2 Python import {
EmailNotificationContent,
Function,
Notification,
ShortNotification,
} from "@foundry/functions-api";
export class MyFunctions {
@Function()
public buildNotification(): Notification {
return Notification.builder()
.shortNotification(ShortNotification.builder()
.heading("Issue reminder")
.content("Investigate this issue.")
.build())
.emailNotificationContent(EmailNotificationContent.builder()
.subject("New issue")
.body("hello")
.build())
.build();
}
} import {
Notification
} from "@osdk/functions";
export default function buildNotification(): Notification {
return {
platformNotification: {
heading: "Issue reminder",
content: "Investigate this issue.",
links: []
},
emailNotification: {
subject: "New issue",
body: "hello",
links: []
}
};
} from functions.api import function, Notification, PlatformNotification, EmailNotification
@function()
def buildNotification() -> Notification:
return Notification(
platform_notification=PlatformNotification(
heading="Issue reminder",
content="Investigate this issue.",
links=[]
),
email_notification=EmailNotification(
subject="New issue",
body="hello",
links=[]
),
)
## 媒体类型
媒体类型
> 要点:Media 类型用于承载媒体集里的文件。
### Media
函数可以接收和返回媒体项。在 TypeScript v1 中使用 MediaItem 类型;在 TypeScript v2 和 Python 中,使用 Media 作为入参和出参类型。调用方可以将已有的 MediaReference(例如对象上的媒体属性)传入函数。下游使用者可利用返回值获取内容、获取元数据,或将其附加到另一个对象上。更多信息请参阅媒体指南。
TypeScript v1 TypeScript v2 Python import { Function, MediaItem } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public async echoMedia(media: MediaItem): Promise {
const mimeType: string = media.mimeType;
// Fetch type-specific metadata (page count, dimensions, duration, and so on)
const metadata = await media.getMetadataAsync();
// Read the binary contents as a Blob
const contents: Blob = await media.readAsync();
// Narrow to a specialized subtype to call type-specific methods
if (MediaItem.isDocument(media)) {
const text = await media.extractTextAsync({ startPage: 0, endPage: 1 });
} else if (MediaItem.isAudio(media)) {
const transcript = await media.transcribeAsync();
}
return undefined;
}
} import type { Media } from "@osdk/client";
export default async function echoMedia(media: Media): Promise {
// Get the underlying MediaReference
const mediaReference = media.getMediaReference();
// Fetch slim metadata: path, sizeBytes, mediaType
const metadata = await media.fetchMetadata();
// Fetch contents as a Response; call .blob() or .arrayBuffer() for bytes
const response = await media.fetchContents();
const contents = await response.blob();
return media;
} from foundry_sdk.v2.core.models import MediaReference
from functions.api import function, Media
@function
def echo_media(media: Media) -> Media:
# Get the underlying MediaReference
media_reference: MediaReference = media.get_media_reference()
# Fetch slim metadata: path, size_bytes, media_type
metadata = media.get_media_metadata()
# Fetch type-specific metadata (page count, dimensions, duration, and more by type)
full_metadata = media.get_media_full_metadata()
# Fetch the binary contents as a BytesIO stream
contents = media.get_media_content()
return media
## 用户、组与主体
用户、组与主体
> 要点:User / Group / Principal,涉及权限与通知时会用到。
Principal 表示 Foundry 用户账户或用户组。这些类型可以传入函数,以便访问与用户或用户组关联的信息,例如用户组名称、用户的姓与名或电子邮件地址。所有 Principal 类型都从 @foundry/functions-api 包导出。
- User 始终拥有 username,并可能拥有 firstName、lastName 或 email。它还包含与 Principal 关联的所有字段。
- Group 拥有一个 name。它还包含与 Principal 关联的所有字段。
- Principal 可以是 User 或 Group。你可以检查 type 字段来判断某个 Principal 是 User 还是 Group。除了 User 和 Group 各自的字段外,Principal 还拥有 id、realm,以及一个 attributes 字典。
### User
TypeScript v1 TypeScript v2 Python import { Function, User } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getUserEmail(user: User): string {
return user.email;
}
} import { UserId } from "@osdk/functions";
import { Users } from "@osdk/foundry.admin";
import { Client } from "@osdk/client";
export default function getUserEmail(client:Client, userId: UserId): string {
const user = Users.get(client, userId)
return user.email;
} from functions.api import function, UserId
from foundry_sdk import FoundryClient
import foundry_sdk
@function()
def getUserEmail(user_id: UserId) -> string:
client = FoundryClient(auth=foundry_sdk.UserTokenAuth(...), hostname="example.palantirfoundry.com")
user = client.admin.User.get(user_id)
return user.email
### Group
TypeScript v1 TypeScript v2 Python import { Function, Group } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getGroupName(group: Group): string {
return group.name;
}
} import { GroupId } from "@osdk/functions";
import { Groups } from "@osdk/foundry.admin";
import { Client } from "@osdk/client";
export default function getGroupName(client: Client, groupId: GroupId): string {
const group = Groups.get(client, groupId)
return group.name;
} from functions.api import function, GroupId
from foundry_sdk import FoundryClient
import foundry_sdk
@function()
def getGroupName(group_id: GroupId) -> string:
client = FoundryClient(auth=foundry_sdk.UserTokenAuth(...), hostname="example.palantirfoundry.com")
group = client.admin.Group.get(group_id)
return group.name
### Principal
TypeScript v1 TypeScript v2 Python import { Function, Principal } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public getPrincipalType(principal: Principal): string {
switch (principal.type) {
case "user":
return "User";
case "group":
return "Group";
default:
return "Unknown";
}
}
} import { GroupId, Principal, UserId } from "@osdk/functions";
export default async function getPrincipals(client: Client, userId: UserId, groupId: GroupId): Principal[] {
return [{type: "user", id: userId}, {type: "group", id: groupId}];
} from functions.api import Array, function, GroupId, Principal, UserId
@function()
def getPrincipals(user_id: UserId, group_id: GroupId) -> Array[Principal]:
return [Principal.user(user_id), Principal.group(group_id)]
## 几何类型
几何类型
> 要点:GeoPoint 与 GeoShape,处理地理位置数据。
几何类型表示函数中的空间数据与地理形状。支持两种几何类型:
- GeoPoint 表示具有经纬度坐标的单个地理点。
- GeoShape 表示任意合法的 GeoJSON 几何,包括点(Points)、多边形(Polygons)、线(LineStrings)及其它形状。
这些类型遵循 GeoJSON 规范 ↗,可用于空间运算、地图绘制和地理分析。位置参数遵循 GeoJSON 规范中的「经度、纬度」顺序。
### GeoPoint
下面的示例展示了如何创建并返回 GeoPoint。
TypeScript v1 TypeScript v2 Python import { Function, GeoPoint } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public createPoint(): GeoPoint {
return GeoPoint.fromCoordinates({
latitude: 37.7749,
longitude: -22.4194
});
}
} import { Point } from "@osdk/functions";
function createPoint(): Point {
return {
type: "Point",
coordinates: [-22.4194, 37.7749]
};
}
export default createPoint; from functions.api import function, GeoPoint
@function
def create_point() -> GeoPoint:
return GeoPoint(type="Point", coordinates=[-22.4194, 37.7749])
### GeoShape
下面的示例展示了如何创建并返回 Polygon。
TypeScript v1 TypeScript v2 Python import { Function, Polygon, GeoPoint } from "@foundry/functions-api";
export class MyFunctions {
@Function()
public createPolygon(): Polygon {
const ring: GeoPoint[] = [
GeoPoint.fromCoordinates({ latitude: 37.8, longitude: -22.4 }),
GeoPoint.fromCoordinates({ latitude: 37.8, longitude: -22.5 }),
GeoPoint.fromCoordinates({ latitude: 37.7, longitude: -22.5 }),
GeoPoint.fromCoordinates({ latitude: 37.7, longitude: -22.4 }),
GeoPoint.fromCoordinates({ latitude: 37.8, longitude: -22.4 })
];
return Polygon.fromLinearRings([ring]);
}
} import { Geometry } from "@osdk/functions";
function createPolygon(): Geometry {
return {
type: "Polygon",
coordinates: [[
[-22.4, 37.8],
[-22.5, 37.8],
[-22.5, 37.7],
[-22.4, 37.7],
[-22.4, 37.8]
]]
};
}
export default createPolygon; from functions.api import function, Polygon
@function
def create_polygon() -> Polygon:
return Polygon(
type="Polygon",
coordinates=[[
[-22.4, 37.8],
[-22.5, 37.8],
[-22.5, 37.7],
[-22.4, 37.7],
[-22.4, 37.8]
]])
Ontology 编辑函数 可以从 GeoJSON 字符串设置 geoshape 属性,但转换步骤因语言而异:
- TypeScript v1: GeoShape.fromGeoJson() 接受已解析的 GeoJSON 几何或几何集合,因此传入前需先将字符串解析。
- TypeScript v2: Geometry 就是一个普通的 GeoJSON 对象,因此无需转换函数,直接将解析后的值赋值即可。
- Python: 每个具体几何类(如 Polygon 或 LineString)都提供 from_geo_json() 方法,可直接接收 JSON 字符串。GeoShape 类型不提供此方法,因此请使用与实际几何相符的类。
下面的示例从 JSON 字符串设置 Region 对象的 geoshape 属性。
TypeScript v1 TypeScript v2 Python import { OntologyEditFunction, Edits, GeoShape } from "@foundry/functions-api";
import { Region } from "@foundry/ontology-api";
export class MyFunctions {
@Edits(Region)
@OntologyEditFunction()
public updateBoundary(region: Region, boundary: string): void {
region.boundary = GeoShape.fromGeoJson(JSON.parse(boundary));
}
} import { Region } from "@ontology/sdk";
import { Client, Osdk } from "@osdk/client";
import { createEditBatch, Edits, Geometry } from "@osdk/functions";
type RegionEdit = Edits.Object;
function updateBoundary(
client: Client,
region: Osdk.Instance,
boundary: string
): RegionEdit[] {
const batch = createEditBatch(client);
batch.update(region, { boundary: JSON.parse(boundary) as Geometry });
return batch.getEdits();
}
export default updateBoundary; from functions.api import function, OntologyEdit, Polygon
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Region
@function(edits=[Region])
def update_boundary(region: Region, boundary: str) -> list[OntologyEdit]:
ontology_edits = FoundryClient().ontology.edits()
editable_region = ontology_edits.objects.Region.edit(region)
editable_region.boundary = Polygon.from_geo_json(boundary)
return ontology_edits.get_edits()
### 常见问题速答 · FAQ
关于「函数类型参考手册」,读者最常问的几个问题。
标量类型是什么? Boolean / String / 各种数字 / Date / Timestamp / Binary 等基础类型,以及必填与安全分级标记。
集合类型是什么? List / Map / Set / Optional / 自定义结构体,用来描述复合数据。
聚合类型是什么? Range 与二维、三维聚合,用于统计结果的表示。聚合类型可从函数返回,供平台的其它部分使用,例如 Workshop 中的图表。
本体类型是什么? Object、Object set、Interface、Ontology edit、Attachment、Notification —— 业务函数的核心。
---
## 面向用户的错误(UserFacingError)
- 页面:https://www.hanzhongpin.xyz/ontology/fn-user-error.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/user-facing-error/
- 主题分组:函数(十九)
循序渐进 · 教学 · 函数(十九)
# 面向用户的错误(UserFacingError)
函数在 Workshop 或动作里运行时,抛普通异常用户看不懂。用 UserFacingError 可以把一句人话直接显示给用户。
## 先记住这几条
① 普通异常对用户是黑盒 用户只会看到无意义的报错,不知道该怎么改。
② UserFacingError 带人话消息 抛这个错误,消息会原样展示给终端用户。
③ 三种语言写法一致 TS v1、TS v2、Python 都是 throw/raise 一个 UserFacingError。
④ 用途:引导用户自助修正 好的错误文案能直接告诉用户「你哪里填错了」。
## 写在前面
当函数在平台的其他地方(比如 Workshop 或动作)运行时,你可能希望抛出一个带有详细说明的错误。做法是抛出 UserFacingError。例如:
TypeScript v1 TypeScript v2 Python import { Function, UserFacingError } from "@foundry/functions-api";
import { Employee } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public async searchExactlyFiveEmployees(employees: Employee[]): Proimse {
if (employees.length != 5) {
throw new UserFacingError(`请传入正好 5 名员工。实际收到 ${employees.length} 名。`);
}
// 搜索员工
}
} import { Osdk } from "@osdk/client";
import { Employee } from "@ontology/sdk";
import { UserFacingError } from "@osdk/functions";
export default async function searchExactlyFiveEmployees(employees: Array>): Promise {
if (employees.length != 5) {
throw new UserFacingError(`请传入正好 5 名员工。实际收到 ${employees.length} 名。`);
}
// 搜索员工
} from functions.api import function, UserFacingError
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Aircraft
@function()
def search_exactly_five_employees(
employees: list[Aircraft]
) -> str:
if not len(aircraft) == 5:
raise UserFacingError(f"请传入正好 5 名员工。实际收到 ${len(aircraft)} 名。")
# 搜索员工
如果把它作为函数动作在一个 Workshop 应用里运行,并且传入的员工数量不对,用户会看到下面这个错误:

> 图:函数抛出的面向用户错误提示
当一个用在函数导出里的函数抛出 UserFacingError 时,导出失败的提示条会显示这条错误信息。
一句详细的面向用户错误信息,能帮用户自己定位并解决问题。
---
## 函数版本管理:语义化版本与兼容性
- 页面:https://www.hanzhongpin.xyz/ontology/fn-versioning.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/functions-versioning/
- 主题分组:函数(六)
循序渐进 · 教学 · 函数(六)
# 函数版本管理:语义化版本与兼容性
函数版本号由发布者选定,一经创建不可更改。这一篇讲清:什么算破坏性变更、SemVer 三段号怎么选、平台如何自动做兼容性检查。
## 先记住这几条
① 版本不可变 发布后版本号固化,不能改,只能发新版本。
② 破坏性 vs 向后兼容 删参数、改类型算破坏性;加可选参数通常兼容 —— 这决定版本号怎么跳。
③ SemVer 三段号 主版本.次版本.修订号,配合平台的自动兼容性检查。
④ 0.y.z 阶段特殊 初始开发阶段(0.x)的版本选择有单独约定。
## 写在前面
本文档描述函数所使用的版本管理系统。函数发布的版本由其发布者选定,且在创建后不可变。应用合适的版本,对于为函数的使用者提供稳定可靠的体验至关重要。
## 什么算破坏性变更
什么算破坏性变更
> 要点:先建立判断标准:哪些改动会让老调用方崩掉。
函数的版本系统区分向后兼容的变更与破坏性(breaking)变更。向后兼容的变更是不会干扰你函数现有使用者的变更。不向后兼容的变更可称为向后不兼容或破坏性变更。
向后兼容变更的一些例子:
- 为函数签名增加一个可选输入。
- 在不改变预期行为的前提下优化函数性能。
- 在不改变预期行为的前提下修复函数中的一个 bug。
破坏性变更的一些例子:
- 为函数签名增加一个必填输入。
- 将函数签名的输出类型从整数改为字符串。
- 删除一个函数。
在判断对现有版本的变更是否向后兼容时,问问自己:该变更是否会给现有版本的使用者带来中断,或需要其显式关注。
请记住,最终由你来决定函数的预期消费模式。
## 语义化版本体系
语义化版本体系
> 要点:三段号怎么选、平台如何自动校验、能否限制 stable 标签。
函数按照 语义化版本(Semantic Versioning)↗ 系统来版本管理。
在语义化版本中,版本形式为 X.Y.Z,其中 X、Y、Z——分别称为主版本、次版本、修订版本——是非负整数(例如 1.2.3)。版本也可以包含一个预发布标识符,由字母数字字符组成,紧跟在修订版本之后加连字符(例如 1.2.3-rc1)。
> 本页简要总结了语义化版本。我们鼓励你阅读完整规范 ↗,因为遵守规范是发布可被其他应用可靠消费的函数的重要一环。
### Choosing a release version
发布函数的新版本时,请考虑语义化版本规范中的以下几点:
- 主版本 0(0.y.z)用于初始开发阶段。在初始开发期间,函数可能随时变更,使用者不应认为你的函数是稳定的。
- 当你做出向后不兼容的变更时,应递增主版本。
- 当你以向后兼容的方式新增功能时,应递增次版本。
- 当你做出向后兼容的 bug 修复时,应递增修订版本。
- 预发布版本表示该版本不稳定,可能不满足其关联正式版本所表示的兼容性要求。
### Backward compatibility checks
在你发布新版本之前,会对你的函数执行向后兼容性检查。具体而言,遇到以下任何破坏性变更时你会收到警告:
- 弃用一个函数。包括在 Python 或 TypeScript 函数代码仓库中删除一个函数。
- 移除函数签名上的某个输入(即便是可选输入)。
- 重排函数签名上的输入顺序。
- 为函数签名增加必填输入。
- 错误的输入类型变更(例如整数改字符串)。将数值输入类型放宽(如整数改浮点)也会触发警告。
- 错误的输出类型变更(例如字符串改可选字符串)。
如果这些检查因任何原因失败,建议发布一个主版本。但这不适用于你仍处于初始开发阶段(即主版本仍为 0)的情况。
Palantir 的内置检查并未穷尽所有类型的破坏性变更。例如,你的内部实现所带来的破坏性变更可能不会被检测到。仅根据这些检查的成功结果就发布次版本或修订版本是不安全的。
Caveat: Custom types
函数数据类型内部的表示目前缺乏关于自定义类型字段可选性的足够信息。因此,你可能会注意到,对于自定义类型的输入与输出,向后兼容性检查会在移除或新增任何字段(包括可选字段,例如 TypeScript 中的 quantity?: Integer 或 Python 中的 quantity: Integer = 0)时发出警告。
我们目前正在做出改变,以便今后在移除输出自定义类型上的可选字段、或新增输入自定义类型上的可选字段时,不会再对你发出警告。
> 移除输入自定义类型上的可选字段时,你仍会收到警告。忽略使用者提供的任何字段通常被认为是不好的做法,因为他们很可能期望所提供字段能够决定你函数的行为。
### Restrict stable version tags
稳定语义化版本发布(非预发布版本)在下游生产应用配置为按版本范围引用函数(例如 >=1.2.3 <2.0.0)时,可能被立即消费。这使得在发布新的稳定版本之前审查并测试代码变更变得很重要。
可以通过在受保护分支的仓库设置中启用一个开关,来强制限制函数稳定版本的发布。
## 常见问题
常见问题
> 要点:0.y.z 阶段怎么选号、误把破坏性变更当补丁发出去怎么办。
### Choosing release versions in the 0.y.z initial development phase
常见的做法是:任何破坏性变更都在次版本中发布,任何向后兼容的变更都在修订版本中发布。这是许多开发领域(例如 Node/NPM 生态)中使用者所做出的假设,其广泛使用插入符范围(caret ranges)↗即为例证。
### Accidentally releasing a backward incompatible change as a patch or minor version
一旦你意识到发布了一个破坏性变更,就应立即纠正问题,并在一个新的次版本中恢复向后兼容。
考虑以下例子。
- 你有一个名为 myFunction 的函数,版本 1.0.0,它接受一个字符串输入。
- 你为 myFunction 新增了一个必填输入,并不慎以次版本 1.1.0 发布了这一变更。
为了补救,你可以撤销该签名上的破坏性变更(即移除你在 1.1.0 中新增的必填输入),并以版本 1.2.0 发布这一变更。
### Checking backward compatibility when a release fails or has not yet been published
对于 TypeScript 或 Python 函数,你的函数可能发布失败或需要几分钟才能发布。在这两种情况下,内置的向后兼容性检查都无法运行。如果你想在发布新版本前看到这些检查结果,有以下选项:
- 如果上一次发布失败,应使用「custom tag(自定义标签)」选项,与上一个成功的标签进行比较。
- 如果上一次发布尚未发布,应等待它完成。
### 常见问题速答 · FAQ
关于「函数版本管理:语义化版本与兼容性」,读者最常问的几个问题。
什么算破坏性变更? 先建立判断标准:哪些改动会让老调用方崩掉。函数的版本系统区分向后兼容的变更与破坏性(breaking)变更。向后兼容的变更是不会干扰你函数现有使用者的变更。不向后兼容的变更可称为向后不兼容或破坏性变更。
语义化版本体系是什么? 三段号怎么选、平台如何自动校验、能否限制 stable 标签。
还有哪些问题? 0.y.z 阶段怎么选号、误把破坏性变更当补丁发出去怎么办。
---
## 函数动作·批量(Batched Execution)
- 页面:https://www.hanzhongpin.xyz/ontology/function-actions-batched-execution.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/function-actions-batched-execution/
- 主题分组:动作类型详解
动作类型详解
# 函数动作·批量(Batched Execution)
当同一个函数动作被一批触发时,默认是一次请求调一次函数。这一篇讲如何把它改成
一次执行吃下整批,以提升性能、规避编辑冲突。
## 一句话速览
函数动作·批量(Batched Execution):当同一个函数动作被一批触发时,默认是一次请求调一次函数。这一篇讲如何把它改成 一次执行吃下整批,以提升性能、规避编辑冲突。
1 让一次执行吃下整批调用 当一个动作被批量触发时——例如在 Workshop 的行内编辑(inline edits)里,或在 Automate 里——背后的函…
2 启用批量执行 要启用批量执行,函数必须接收一个输入参数,而这个参数包含一个 struct 的列表 (也常被称为 "map" 或 "dictiona…
3 从逐条到批量 默认逐条的写法(一次处理一个 flight 与 destination)
## 一句话:让一次执行吃下整批调用
批量执行 = 把整批动作调用合并进一次函数执行。
当一个动作被批量触发时——例如在 Workshop 的行内编辑(inline edits)里,或在
Automate 里——背后的函数通常每个请求依次调用一次,并且所有编辑会在动作调用结束时原子地(atomically)应用。
Alternatively, to improve performance or resolve edit conflicts, you may wish to configure a function to receive the whole batch of action calls in a single execution.
或者,为了提升性能或解决编辑冲突,你也可以配置函数,让它在一个执行里接收整批动作调用。
也就是说,存在另一种选择:配置函数一次性接收整批,在一次执行里处理完所有调用。这常用于优化性能或规避编辑冲突。
## 默认行为 vs 批量配置
两种模式,按需取舍。
× 默认(逐条)
行为
· 每次请求顺序调用一次函数
· 所有编辑在动作调用结束时原子应用
· 批量大时调用次数多、易冲突
→
✓ 批量(一次吃整批)
行为
· 函数一次执行收下整批调用
· 适合提升性能、规避编辑冲突
· 需把函数改成"接收列表"的签名
## 如何启用批量执行
函数必须接收一个"包含 struct 列表"的单一参数。
要启用批量执行,函数必须接收一个输入参数,而这个参数包含一个 struct 的列表
(也常被称为 "map" 或 "dictionary")。
>
怎么传数据:启用批量执行后,你仍像往常一样把数据传进这个 struct 的各个字段——
只是现在这些字段挂在一个"列表元素"上,整批列表作为单一参数传入。
## 单条调用 vs 批次调用
看列表参数里有几个 entry。
单次动作调用
触发一次函数执行,列表输入参数里有 1 个 entry。
批量动作调用
触发一次函数执行,列表输入参数里有 多个 entry。
关键区别:无论单条还是批次,都是"一次函数执行";差别只在列表参数里 entry 的数量。
这让批量场景的开销从"N 次执行"降到"1 次执行"。
## 示例:从逐条到批量
把"逐对象"的签名改成"收列表"的签名。
默认逐条的写法(一次处理一个 flight 与 destination):
@OntologyEditFunction()
public updateDestination(flight: Flight, destination: Airport): void {
// update flight object
}
改成批量写法(一次收下整批,在单次执行里遍历处理):
@OntologyEditFunction()
public updateDestinationBatch(batch: {flight: Flight, destination: Airport}[]): void {
batch.forEach(({flight, destination}) => {
// update flight object
});
}
把函数改成接收 {flight, destination}[] 这样的列表后,就能在配置动作类型时启用批量执行,
让整批请求合并进这一次函数执行。
>
记忆口诀:批量执行 = 把"N 个独立入参"改成"1 个 struct 列表入参",再开启批量——单条 1 个 entry、批次多个 entry,都是一次执行。
## 动手:关于批量执行,哪句对?
逐个判断。点选项看解析。
## 一页带走
① 批量执行 让函数一次执行收下整批调用,而非逐条调用。
② 签名要求 单一参数 + struct 列表(map/dictionary)。
③ 单条 vs 批次 都是一次执行;区别在列表 entry 数:单条 1 个、批次多个。
④ 动机 提升性能、规避编辑冲突;默认仍是逐条 + 原子应用。
### 常见问题速答 · FAQ
关于「函数动作·批量(Batched Execution)」,读者最常问的几个问题。
一句话:让一次执行吃下整批调用是什么? 当一个动作被批量触发时——例如在 Workshop 的行内编辑(inline edits)里,或在 Automate 里——背后的函数通常每个请求依次调用一次,并且所有编辑会在动作调用结束时原子地(atomically)应用。
如何启用批量执行? 要启用批量执行,函数必须接收一个输入参数,而这个参数包含一个 struct 的列表 (也常被称为 "map" 或 "dictionary")。
示例:从逐条到批量是什么? 默认逐条的写法(一次处理一个 flight 与 destination)。
---
## 函数动作·开始(Getting Started)
- 页面:https://www.hanzhongpin.xyz/ontology/function-actions-getting-started.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/function-actions-getting-started/
- 主题分组:动作类型详解
动作类型详解
# 函数动作·开始(Getting Started)
这一篇是实操手册:从写一个 Ontology 编辑函数,到把它接进动作类型,
再到管理函数版本。跟着做,你就能跑通第一个函数动作。
## 一句话速览
函数动作·开始(Getting Started):这一篇是实操手册:从写一个 Ontology 编辑函数,到把它接进动作类型,再到管理函数版本。跟着做,你就能跑通第一个函数动作。
1 先把函数准备好 动手前,需要先写一个能完成你想要的编辑的 Ontology 编辑函数(Ontology edit function)
2 写 Ontology 编辑函数 教程里给出的例子函数(TypeScript)长这样
3 函数版本与自动升级 你也可以选择开启自动升级(auto upgrade):在 Rules 区选中 Function 参数,于 Function 下拉里选…
## 前置条件:先把函数准备好
函数动作的前提,是一个已发布、可被动作读取的 Ontology 编辑函数。
动手前,需要先写一个能完成你想要的编辑的 Ontology 编辑函数(Ontology edit function)。这要求你:
- 建仓库用 functions on objects 的 TypeScript 模板初始化一个代码仓库。
- 导入对象类型把动作要用到的对象类型导入到你的仓库中。
- 发布函数把 Ontology 编辑函数 发布(publish)出去,动作才能读取它。
>
关键标注:用于动作类型的函数,必须用 @OntologyEditFunction() 标注,
而不是普通的 @Function()。这是它能被动作接上的前提。
## 写 Ontology 编辑函数
一个最小的例子:把优先级前缀加到工单标题上。
教程里给出的例子函数(TypeScript)长这样:
@OntologyEditFunction()
public addPriorityToTitle(ticket: DemoTicket): void {
let newTitle: string = "[" + ticket.ticketPriority + "]" + ticket.ticketTitle;
ticket.ticketTitle = newTitle;
}
它接收一个 DemoTicket 对象,读它的优先级,构造出带前缀的新标题,再写回该对象的 ticketTitle 属性。
注意签名:参数是本体对象,返回 void——编辑通过"修改对象"本身完成。
>
写回方式:这类函数通过直接修改传入的对象属性来产生编辑,框架会据此生成本体编辑(Ontology edits)。
## 把函数接到动作类型
在 Rules 里加一条 Function 规则,搜索并选函数。
步骤 1加 Function 规则
在动作类型的 Rules 区,添加一条类型为 Function 的规则。
函数规则不能与其它 Ontology 规则混用在同一动作里。
步骤 2选已发布函数
搜索你在前置里发布的那个函数,并挑选最新版本。
选定后,函数的所有输入会自动变成参数并加入 Parameters 标签(例如生成一个 DemoTicket 的 Object reference 参数)。
步骤 3对齐输入并保存
把函数输入配置到与动作参数对应;按需进一步自定义参数。
保存后,即可像其它动作一样跨平台配置使用。
提示:点击每条可展开更多细节。
## 函数版本与自动升级
默认不自动跟随函数改动;可开启 auto upgrade。
>
默认行为:如果函数逻辑改了,动作不会自动更新去匹配它。你必须回到动作的
Rules 区,手动升级动作所引用的函数版本(例如从 0.1.2 升到新版本)。
你也可以选择开启自动升级(auto upgrade):在 Rules 区选中 Function 参数,于 Function 下拉里选一个
最小版本并启用 Auto upgrade。这会让动作依赖该函数的版本区间(所有向后兼容的版本,如小版本/补丁升级),
并在运行时解析具体版本。
注意:形如 0.y.z 的版本禁用自动升级——这类版本留给初期开发,API 与行为可能频繁变动,不应视为稳定。
## 安全与注意:三个坑
自动升级带来便利,也带来风险。
安全 Security
若开启自动升级,没有动作编辑权限的用户,可能通过修改被引用的函数来改变动作行为——因为函数的编辑权限不绑定动作的权限。
破坏性变更 Breaking changes
自动升级可能因糟糕的函数发布引入了破坏性变更,导致动作执行失败。
来源 Provenance
动作的来源依据所选最小函数版本的来源设定;若新版本返回该来源之外的编辑(如多了一个对象类型),执行会失败。
来源范围
目前来源仅包含动作运行时可能编辑的对象类型。
## 动手:步骤归类
给每个节点选正确的操作。点选项看解析。
## 一页带走
① 前置 TypeScript 模板建仓库、导入对象类型、发布 @OntologyEditFunction() 函数。
② 接动作 Rules 加 Function 规则,选已发布函数最新版;输入自动成参数。
③ 版本 默认不自动跟随,需手动升级;可开 auto upgrade(0.y.z 禁用)。
④ 注意 auto upgrade 的安全/破坏性变更/来源三坑要留意。
### 常见问题速答 · FAQ
关于「函数动作·开始(Getting Started)」,读者最常问的几个问题。
前置条件:先把函数准备好是什么? 动手前,需要先写一个能完成你想要的编辑的 Ontology 编辑函数(Ontology edit function)。这要求你。
写 Ontology 编辑函数是什么? 教程里给出的例子函数(TypeScript)长这样。
函数版本与自动升级是什么? 你也可以选择开启自动升级(auto upgrade):在 Rules 区选中 Function 参数,于 Function 下拉里选一个 最小版本并启用 Auto upgrade。
---
## 函数动作·总览(Function-backed Actions)
- 页面:https://www.hanzhongpin.xyz/ontology/function-actions-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/function-actions-overview/
- 主题分组:动作类型详解
动作类型详解
# 函数动作·总览(Function-backed Actions)
简单规则搞不定的复杂改动,可以让一个函数(function)来定义编辑逻辑。这一篇讲清
什么是函数动作、什么时候该用它、以及它的能力边界。
## 一句话速览
函数动作·总览(Function-backed Actions):简单规则搞不定的复杂改动,可以让一个函数(function)来定义编辑逻辑。这一篇讲清 什么是函数动作、什么时候该用它、以及它的能力边界。
1 让一个函数来决定"怎么改" 在动作类型里,规则(rules)定义了"动作被应用时对象该如何变化"
2 灵活也要守规矩 函数动作虽然灵活,但仍然受双重约束
## 一句话:让一个函数来决定"怎么改"
函数动作 = 用函数承载动作类型的编辑逻辑。
在动作类型里,规则(rules)定义了"动作被应用时对象该如何变化"。很多动作类型用简单规则就能搞定
(创建/修改/删除对象,或创建/删除对象间链接)。
action types can be configured to call a function that defines the logic of how objects should be modified. These action types are often referred to as function-backed actions.
动作类型可以被配置为调用一个函数,由它定义"对象该如何被修改"的逻辑。这类动作类型常被称为"函数动作"。
但当简单规则不够用时,你可以把动作类型配置成调用一个函数来定义编辑逻辑——这就是
函数动作(function-backed action)。借助函数,你可以构造任意复杂度的动作:读取任意数量的对象、按需修改对象。
## 什么时候该用函数动作?
简单规则表达不了的改动,就交给函数。
改一组关联对象
例如把某 Incident 的状态置为 Closed,同时把所有关联 Alert 的状态置为 Resolved。
复杂计算后写回
基于较复杂的业务逻辑(读多个对象的数据)算出一个值,再写回某对象属性。
批量建多种对象
一次性创建多种不同类型的对象,并在它们之间建立链接。
任意复杂度
只要逻辑写得出,函数就能承载——这是它相对简单规则的最大优势。
## 函数动作 vs 简单规则
不是替代,而是互补。
× 只用简单规则
局限
· 只能表达"创建/修改/删除对象"或"建/删链接"
· 跨多个关联对象、复杂读取与计算的改动难表达
· 一次创建多类对象并互连较繁琐
→
✓ 上函数动作
获得
· 任意复杂逻辑:读任意多对象、按需改
· 把"计算 + 改对象"打包进一次动作
· 适合批量、跨对象、条件复杂的场景
>
选择原则:能用简单规则清楚表达的,就别上函数;当"改什么"依赖复杂读取/计算、或要跨多个关联对象时,再选函数动作。
## 限制:灵活也要守规矩
受动作类型上限与函数执行上限双重约束。
函数动作虽然灵活,但仍然受双重约束:
- 动作类型上限(action type limits):动作类型本身的规模/数量等限制仍然适用。
- 函数执行上限(function execution limits):函数运行的时间、资源等限制同样适用。
>
设计提示:因为函数动作背后是真实的函数执行,写函数时要留意执行上限——尤其批量或跨大量对象时,
必要时考虑后面的"批量执行"篇来优化。
## 上手路径
从"函数入门"到"接到动作"。
第 1 步学函数基础
先按函数文档入门,建一个基础函数仓库并发布一个函数。
参考 Functions 的 Getting started 与 Functions on objects 教程。
第 2 步写 Ontology 编辑函数
用 Ontology edits 参考,写一个带 @OntologyEditFunction() 标注的编辑函数。
注意:用于动作的函数要用 @OntologyEditFunction() 而非 @Function()。
第 3 步接到动作类型
在动作类型的 Rules 里加一条 Function 规则,把函数接上。
详见下一篇《函数动作·开始》。
提示:点击每条可展开更多细节。
## 动手:这个场景该用函数动作吗?
逐个判断。点选项看解析。
## 一页带走
① 函数动作 = 函数承载编辑 把"怎么改"的逻辑交给一个函数定义。
② 何时用 跨关联对象、复杂计算写回、批量建多类对象并互连。
③ 与简单规则互补 简单规则能表达的就别上函数;表达不了再用。
④ 双重限制 同时受动作类型上限与函数执行上限约束。
### 常见问题速答 · FAQ
关于「函数动作·总览(Function-backed Actions)」,读者最常问的几个问题。
一句话速览是什么? 函数动作·总览(Function-backed Actions):简单规则搞不定的复杂改动,可以让一个函数(function)来定义编辑逻辑。这一篇讲清 什么是函数动作、什么时候该用它、以及它的能力边界。
一句话:让一个函数来决定"怎么改"? 在动作类型里,规则(rules)定义了"动作被应用时对象该如何变化"。很多动作类型用简单规则就能搞定 (创建/修改/删除对象,或创建/删除对象间链接)。
---
## 函数(Functions):把业务逻辑写成可复用的代码
- 页面:https://www.hanzhongpin.xyz/ontology/functions.html
- 官方原文:https://www.palantir.com/docs/foundry/functions/overview/
- 主题分组:本体零件(十一)
循序渐进 · 教学 · 本体零件(十一)
# 函数(Functions):把业务逻辑写成可复用的代码
当规则复杂到没法用配置表达,就需要写代码。函数让代码作者把逻辑写在
本体之上,在运营场景里被快速执行。这一篇讲清它是什么、能做什么、怎么用。
## 一句话速览
函数(Functions):把业务逻辑写成可复用的代码:当规则复杂到没法用配置表达,就需要写代码。函数让代码作者把逻辑写在 本体之上,在运营场景里被快速执行。这一篇讲清它是什么、能做什么、怎么用。
1 function 是"在本体上跑的可复用逻辑" 函数(function)让代码作者把一段逻辑写出来,在 运营场景(operational contexts)——比如仪表盘、辅助决策…
2 对本体的原生支持 函数最值得强调的特性是:它对本体(Ontology)是一等公民(first-class)级别的支持
3 常见用途清单 原文列出了一长串常见用法,挑重点记
4 支持哪种语言 函数支持两种语言:TypeScript 与 Python
## 一句话:function 是"在本体上跑的可复用逻辑"
Functions enable code authors to write logic executed quickly in operational contexts.
函数(function)让代码作者把一段逻辑写出来,在
运营场景(operational contexts)——比如仪表盘、辅助决策的应用——里被快速执行。
Functions enable code authors to write logic that can be executed quickly in operational contexts, such as dashboards and applications designed to empower decision-making processes. This logic is executed on the server side in an isolated environment.
函数让代码作者写出可在运营场景(仪表盘、应用)中快速执行的逻辑;它在服务端、隔离环境中运行。
一句话区分它和动作类型:函数是一段"计算逻辑",负责读、算、甚至改;
而动作类型(action type)是"人/系统做出的一次受治理的改动"。函数常被动作类型调用。
>
关键句:函数运行在服务端隔离环境——你写的代码不会塞进浏览器,而是安全地在平台上跑。
## 一等公民:对本体的原生支持
读属性、遍历链接、灵活编辑,都是内建能力。
函数最值得强调的特性是:它对本体(Ontology)是一等公民(first-class)级别的支持。也就是说,写函数时能直接:
读属性
读取各种对象类型的属性值,作为计算的输入。
遍历链接
顺着 link 在对象之间游走,拿到关联对象的数据。
做编辑
灵活地对任意对象做出本体编辑(常配合 function-backed action)。
>
为什么重要:因为函数"懂"本体,你不用自己拼 SQL 或写胶水代码去拿数据——
直接基于对象、属性、链接来写逻辑即可。
## 常见用途清单
从展示、聚合到实时流式,覆盖面很广。
原文列出了一长串常见用法,挑重点记:
- 返回对象集合 / 变量值给 Workshop 使用。
- 显示换算后的值:通过 Workshop 的"函数支撑列(function-backed columns)"在派生表里展示。
- 聚合对象值:作为 Workshop 图表的来源。
- 表达复杂编辑:通过"函数支撑的动作(function backed action)"一次性更新大量对象。
- 后端跑逻辑、返给前端:在 Slate 中返回要展示的信息。
- 计算自定义指标 / 聚合:在 Quiver 中展示。
- 查外部系统丰富本体:通过 external functions(外部函数 / webhooks)。
- 实时流式结果:增量返回,尤其配合语言模型(language models)。
- Python 作旁路容器:在 Pipeline Builder 里使用。
>
看规律:凡是"展示/计算/聚合/编排改动"的需求,都落到函数;
而"把原料数据搬进本体"不归它管(那是数据集成)。
## 支持哪种语言?
TypeScript 与 Python。
函数支持两种语言:TypeScript 与 Python。
原文还提示:不同语言、不同版本的功能支持程度不同,选择前应先参考
「language feature support(语言功能支持规格)」。
>
给初学者的提醒:如果你要跟着官方教程上手,原文给了三条路径——
TypeScript v1、TypeScript v2、Python 的入门教程,
以及一个 "Speedrun: Your first Ontology function" 速通课程。
## 函数和动作类型怎么配合?
函数算/改,动作类型收口成"一次受治理的改动"。
一个很常见的组合是 function backed action(函数支撑的动作):
复杂编辑的逻辑写在函数里,动作类型负责把它包装成"用户可触发、带权限校验、带副作用"的一次提交。
✓ 函数 function
职责
· 读属性、遍历链接、做计算
· 可灵活编辑本体(逻辑层)
· 不自带权限/副作用收口
+
✓ 动作类型 action type
职责
· 把函数的逻辑收口成一次事务
· 带参数、权限校验、通知等副作用
· 提交即写回,跨应用一致
>
一句话:函数提供"能力",动作类型提供"治理"。只读计算只用函数;要改动且需合规,就用函数支撑的动作。
## 动手:这段代码该放哪儿?
判断每一项最适合落在 函数 / 动作类型 / 数据集成管道。
记忆锚点:只读/计算/聚合/展示 → 函数;受治理的改动 → 动作类型;把原料搬进本体 → 数据集成管道。
## 从哪里上手?
点开看函数"跑在哪里"。
点我看函数"跑在哪里" →
原文推荐的入门路径(均可在官方文档找到):
- Getting started with TypeScript v1 functions
- Getting started with TypeScript v2 functions
- Getting started with Python functions
- 速通课程:Speedrun: Your first Ontology function(learn.palantir.com)
>
选语言前:先查「language feature support」,确认你需要的特性在目标语言/版本里受支持。
## 一页带走
① 函数 = 可复用逻辑 在运营场景快速执行;运行于服务端隔离环境。
② 本体一等公民 读属性、遍历链接、灵活编辑,都是内建能力。
③ 用途广 展示换算、聚合、复杂编辑、查外部系统、实时流式等。
④ 与动作配合 函数提供能力,动作类型提供治理(function backed action)。
### 常见问题速答 · FAQ
关于「函数(Functions):把业务逻辑写成可复用的代码」,读者最常问的几个问题。
一等公民:对本体的原生支持是什么? 函数最值得强调的特性是:它对本体(Ontology)是一等公民(first-class)级别的支持。也就是说,写函数时能直接。
支持哪种语言?是什么? 函数支持两种语言:TypeScript 与 Python。原文还提示:不同语言、不同版本的功能支持程度不同,选择前应先参考 「language feature support(语言功能支持规格)」。
函数和动作类型怎么配合? 一个很常见的组合是 function backed action(函数支撑的动作):复杂编辑的逻辑写在函数里,动作类型负责把它包装成"用户可触发、带权限校验、带副作用"的一次提交。
---
## 动作类型上手:十分钟做出第一个"改字段"动作
- 页面:https://www.hanzhongpin.xyz/ontology/getting-started.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/getting-started/
- 主题分组:动作类型详解
动作类型详解
# 动作类型上手:十分钟做出第一个"改字段"动作
跟着向导,在 Ontology Manager 里新建一个把工单优先级改成 P0/P1/P2 的动作类型,并让它出现在对象页面上。
## 一句话速览
动作类型上手:十分钟做出第一个"改字段"动作:跟着向导,在 Ontology Manager 里新建一个把工单优先级改成 P0/P1/P2 的动作类型,并让它出现在对象页面上。
1 我们要做一件什么事 本篇要带你在 Ontology Manager(本体管理器)里新建一个动作类型(action type),它的作用是:把某张工单的优…
2 走一遍新建向导 在 Ontology Manager 左侧边栏选择 Action types,再点右上角的 New action type
3 把优先级限制成可选项 切到 Parameters 标签,可以看到系统已经根据规则自动建好了 Ticket 和 Priority 两个参数
4 只对 Open 的工单生效 打开侧边栏 Security & Submission Criteria 标签里的 submission criteria 区块,在…
## 准备与目标:我们要做一件什么事
这篇用到的例子,是一个能"修改工单优先级"的动作类型。
本篇要带你在 Ontology Manager(本体管理器)里新建一个动作类型(action type),它的作用是:把某张工单的优先级(priority)改成 P0、P1 或 P2,并且只允许对状态(status)为 Open 的工单执行。
官方示例用了一个名为 Demo Ticket 的对象类型(object type),它至少包含 Ticket ID、Title、Status、Priority 几个属性(property)。你不必真的建出这些对象,跟着理解流程即可。
前置条件:用户要能"应用"某个动作,本体必须开启可编辑。若运行 Object Storage v2,需在开关处开启编辑(edit);若是旧的 Object Storage v1(Phonograph),则要创建一个写回数据集(writeback dataset)。
## 创建动作类型:走一遍新建向导
向导会帮你配好动作类型最重要的几项特征。
在 Ontology Manager 左侧边栏选择 Action types,再点右上角的 New action type。向导分几步收集信息,下面这层叠图可以逐层点开看每一步在做什么。
第 1 步Action type(动作类型)
选对象类型,并指定"这个动作对对象做什么"
打开 Object 标签页,选择 Demo Ticket 对象类型,然后在 Object actions 下选择 Modify object(s)(修改对象)。也就是:这个动作会去改一张已有工单。
第 2 步Mapping(映射)
决定动作会修改哪些属性
点击 Add property,把 Priority 属性加进来。这一步就定义了"动作能改什么字段"。
第 3 步Metadata(元数据)
给动作起名字
在 Action type name 里填写动作类型的名称,例如"Change Ticket Priority"。走到最后一步点 Create 即可。
创建完成后,你会看到动作类型的完整详情视图,之后还能继续微调——比如在 Overview 标签加一段描述(description),或在 Rules 标签追加可修改的属性。
## 调整参数:把优先级限制成可选项
参数(parameter)决定了用户执行动作时能填什么。
切到 Parameters 标签,可以看到系统已经根据规则自动建好了 Ticket 和 Priority 两个参数。点开 Priority 参数,我们要限制它能取的值。
把约束从 User input(用户自由输入)改成 Multiple choice(多选一),这样就能限定可选值。接着把 P0、P1、P2 加为选项。现在如果用户把这个动作用在一张工单上,就只能在 P0/P1/P2 之间挑一个优先级。
> 提示:参数可以自动从规则生成,也可以手动追加。先理解"规则决定参数"这条主线,后面会反复用到。
## 加提交条件:只对 Open 的工单生效
提交条件(submission criteria)决定动作什么时候"允许"被执行。
打开侧边栏 Security & Submission Criteria 标签里的 submission criteria 区块,在 Execution 部分点 Condition 新建一个条件。
用 Parameter 条件模板,对 Ticket 对象参数的 Status 属性设条件:用 is 运算符,把工单状态与具体值 Open 做精确字符串比较。还可以加一条失败消息(failure message),让用户知道为什么动作没跑成。
Actions can be seamlessly integrated across applications in Foundry.动作类型可以在 Foundry 的各个应用间无缝集成。(含义:配置好一次,到处可用)
到这里,我们的动作定义就完成了,接下来要让它出现在 Object Explorer 的对象页面旁边。
## 挂到 Object View:让按钮出现在页面上
把动作放进对象的"动作"组件,用户就能一键触发。
打开 Demo Ticket One 并编辑它的 Object View(对象视图)。在顶部加一个新组件,选择 Actions widget(动作组件)。在侧边栏点 Add Item,把在 Ontology Manager 里复制到的动作 RID 粘进 Action RID 字段,并把标签命名为"Change Ticket Priority"。
默认情况下,动作表单会把每个参数都显示成一个字段,连 Ticket 参数也会显示出来——但动作并不知道该把"当前对象"自动填进 Ticket。我们要这样处理:
- 在 Default value 下 Add Item,填入 Ticket 参数的参数 ID(本例设为 ticket);
- 把值类型改成 Environment variable(环境变量),选择 Current object(当前对象);
- 再把显示选项改成 Hidden(隐藏),这样用户不能拿它去改别的工单。
保存并发布 Object View 后,预览页就会出现这个动作按钮。
## 试跑与应用:真的点一下看看
上线前先在 Ontology Manager 里做一次 test run,确认逻辑无误。
访问一张状态为 Open 的工单,点我们配置好的 Change Ticket Priority 按钮,动作表单会浮现在视图上。点开 Priority 字段,会看到我们加在参数上的那条提交条件;挑一个优先级再点 Submit,表单消失,对象视图随即更新成新的优先级。
而我们的提交条件规定:不能对"已关闭"的工单跑这个动作。如果打开状态为 Closed 的 Demo Ticket Two,动作就不会被允许执行。
> 下一步:在正式应用前,可到 Ontology Manager 里用 test run(试跑)验证提交条件、规则与最终编辑,详见本系列《动作·试跑》。
动作"不知道"该把当前对象填进 Ticket 参数,推荐怎么解决?点我看推荐 →
## 一页带走
① 向导四步建动作 Action type → Mapping → Metadata → Create,先选对象再选改什么。
② 参数由规则生成 改 Priority 用 Multiple choice 限定可选值,约束用户的输入。
③ 提交条件管"能不能跑" 用 Condition 限定只对 Open 工单生效,并给出失败提示。
④ 挂到视图才可见 把 Ticket 固定为当前对象并隐藏,再发布 Object View 即可用。
### 常见问题速答 · FAQ
关于「动作类型上手:十分钟做出第一个"改字段"动作」,读者最常问的几个问题。
准备与目标:我们要做一件什么事? 本篇要带你在 Ontology Manager(本体管理器)里新建一个动作类型(action type),它的作用是:把某张工单的优先级(priority)改成 P0、P1 或 P2,并且只允许对状态(status)为 Open 的工单执行。
创建动作类型:走一遍新建向导是什么? 在 Ontology Manager 左侧边栏选择 Action types,再点右上角的 New action type。向导分几步收集信息,下面这层叠图可以逐层点开看每一步在做什么。
调整参数:把优先级限制成可选项是什么? 切到 Parameters 标签,可以看到系统已经根据规则自动建好了 Ticket 和 Priority 两个参数。点开 Priority 参数,我们要限制它能取的值。
加提交条件:只对 Open 的工单生效是什么? 打开侧边栏 Security & Submission Criteria 标签里的 submission criteria 区块,在 Execution 部分点 Condition 新建一个条件。
---
## 让对象类型实现接口
- 页面:https://www.hanzhongpin.xyz/ontology/implement-interface.html
- 官方原文:https://www.palantir.com/docs/foundry/interfaces/implement-interface/
- 主题分组:接口(三)
循序渐进 · 教学 · 接口(三)
# 让对象类型实现接口
接口定义好之后,任何符合形状的对象类型都可以实现它。这一篇给出两条路径:在 Ontology Manager 里手动映射,或在 Pipeline Builder 里配置产出类型。
## 先记住这几条
① 实现 = 属性对上号 对象类型必须有满足接口要求的属性,这就是"符合形状"。
② 两条实现路径 Ontology Manager 手动映射,或 Pipeline Builder 配置输出。
③ 要映射三层内容 本地属性、链接类型约束、动作类型约束,三层都要对上。
④ 保存后接口才生效 映射完成必须保存变更。
## 写在前面
一旦定义完成,任何符合接口定义的对象类型都可以实现该接口。这意味着对象类型必须拥有能满足接口必填属性的属性、能满足所有必填链接类型约束的链接,以及能满足接口上定义的所有必填动作类型约束的动作类型。
用一个对象类型实现接口,表明该对象类型在 Ontology 中是接口的一个具体实例。这一声明为对象类型带来额外的功能,即:
- 针对该接口的 Object Set Service 搜索会返回实现该对象类型的匹配对象。
- 实现该对象类型的对象既可以使用其本地 API 名称(当被当作具体对象类型时),也可以使用接口 API 名称来访问其属性与链接(当被当作接口类型时)。
简而言之,实现一个接口让应用消费方能够通过接口定义与任意及所有实现对象交互。这使得应用代码可以基于接口作为 API 层来编写,而无需应用单独支持每个实现对象类型。此外,通过把接口作为应用 API 层,新对象类型只需实现该应用接口即可被加入应用,无需为了显式支持新对象类型而改动代码。
## 在 Ontology Manager 中实现
在 Ontology Manager 中实现
> 要点:五步:选接口与对象类型 → 映射属性 → 映射链接约束 → 映射动作约束 → 保存。
按照以下步骤,用一个对象类型实现接口。
### 1. Select your interface and object type
首先,在 Ontology Manager 中导航到该对象类型,打开 Interfaces(接口) 标签页。选择页面右上角的 + Implement new interface(+ 实现新接口)。

> 图:从一个对象类型实现一个接口。
在弹出的对话框中,选择要实现的接口。

> 图:选择要实现的接口。
或者,导航到接口概览页,在 Implementations(实现) 分区选择 + New(+ 新建)。

> 图:从接口概览页实现一个接口。
然后,选择要实现该接口的对象类型。

> 图:选择要实现的接口。
### 2. Map local properties
要实现一个接口,一个对象类型必须声明将现有对象属性映射到接口必填属性的映射。如果某个接口属性被标记为可选(optional),则可以跳过映射。

> 图:在接口与实现对象类型之间映射属性。
### 3. Map link type constraints
如果接口上声明了任何必填的链接类型约束,你必须在该对象类型上为每个必填链接类型约束选择一个满足条件的链接类型。你也可以选择性地为任何非必填链接类型约束提供链接映射。你可以选择已有的链接类型,或新建一个来满足每个约束。

> 图:映射链接类型以满足链接类型约束。
### 4. Map action type constraints
如果接口上声明了任何必填的动作类型约束,你必须在该对象类型上为每个必填动作类型约束选择一个满足条件的动作类型。你也可以选择性地为任何非必填动作类型约束提供动作映射。
接口实现创建完成后,从对象类型的 Interfaces(接口) 标签页配置参数映射。在将改动保存到 Ontology 之前,你必须将任何必填参数约束映射到具体动作类型上兼容的必填参数。
### 5. Save changes
选择 Save(保存),将改动应用到你的 Ontology。
## 在 Pipeline Builder 中实现
在 Pipeline Builder 中实现
> 要点:四步:打开输出类型配置 → 选接口 → 映射属性 → 复查已实现接口。
按照以下步骤,在 Pipeline Builder 中的对象类型输出上实现一个接口。
### 1. Open output type configuration
选择你想要实现接口的那个对象类型输出,然后选择 Edit(编辑) 选项。

> 图:编辑对象类型输出。
### 2. Select the interface to implement
选择 Implement interface(实现接口)。

> 图:选择 Implement interface。
然后,选择要实现的接口,并选择 Implement and go to mapping(实现并前往映射)。

> 图:选择接口并前往映射。
### 3. Map local properties
要实现一个接口,一个对象类型必须包含接口的共享属性,或声明将现有对象属性映射到接口共享属性的映射。同时存在于接口和对象类型上的共享属性会被自动映射。任何不在对象类型上的共享属性,都需要你手动输入映射以满足接口定义。

> 图:映射本地属性。
### 4. Review implemented interfaces
你可以从输出类型配置面板查看该对象类型输出所实现的接口。

> 图:查看已实现的接口。
Pipeline Builder 目前在实现接口时不支持链接类型约束或动作类型约束的映射。如果你的接口包含必填的链接类型约束或必填的动作类型约束,你必须通过 Ontology Manager 来实现该接口。
---
## Palantir 本体,从零到能上手
- 页面:https://www.hanzhongpin.xyz/ontology/index.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/overview/
- 主题分组:教学系列
Palantir 本体教学系列 · 全部目录
-
循序渐进 · 教学系列
# Palantir 本体,从零到能上手
101 篇教学网页,全部来自 Palantir Foundry 官方文档,按学习顺序排列。
每篇都有逐步讲解和可亲手点的互动演示。零基础也能顺着读完。
101 篇教学页面
8 个模块
0 行前置知识要求
## 另一个系列:AI Platform (AIP)
把 AI 接进数据与运营流程。84 篇中文教学页,按 10 个模块编排,从全局认知到 AIP Logic、Evals、Chatbot Studio 逐层深入。
进入 AIP 教学系列 →
## 建议的学习路径
不确定从哪开始?按这个顺序走一遍就够了。
先建立直觉(模块一):本体是什么、为什么需要、核心概念长什么样。
- 再认零件(模块二):对象类型、属性、派生属性、接口,以及让本体"动起来"的动作与函数。
- 动作类型深潜(模块三):37 篇从快速开始、参数、函数动作,到通知、权限、监控日志,按需查阅或顺着读。
- 然后学怎么设计好(模块四):原则、反模式、验证方法、落地结构规范。
- 最后接 AI(模块五):模型、语义搜索、文档处理、多模态嵌入、本体增强生成、搜索语法。
- 深入函数(模块六):语言选型、开发流程、版本、权限、监控、部署,以及 TypeScript v2 全套。
- 补上接口(模块七):接口的概念、创建与实现。
- 看清全局(模块八):十一个平台能力域的地图,按需定位。
模块一
## 入门:本体是什么
建立整体直觉。读完这五篇,你应该能向别人解释"本体"是什么。
01
### 总览:组织的运营层
语义元素(是什么)+ 动力元素(怎么变),一次讲清全文主线。
4 个互动
02
### 为什么需要本体
决策中心与"四件套",看懂本体到底解决了什么问题。
开关实验室
03
### 核心概念
本体四大核心概念,与"数据集"逐项对照着理解。
对照实验室
04
### Ontologies 资源管理
本体也有容器:私有的和共享的,什么时候该用哪个。
场景选择器
05
### 场景示例
在本体上开个沙盒做 what-if 推演,改动不落库。
沙盒模拟器
模块二
## 建模元素:本体的零件
一个个认全:对象、属性、派生属性、接口,以及让本体"动起来"的动作与函数。
06
### 对象类型
对象类型与数据集的三层类比,含归类练习。
双栏点选
07
### 属性
认全属性类型,顺手做一轮命名与类型的"诊所"。
命名诊所
08
### 派生属性
查询时自动算值,从此告别手动维护的计数器。
对照实验室
09
### 接口
接口定义"形状与能力",让多个类型共享一套逻辑。
形状判定
10
### 动作类型
把一次受治理的变更及其副作用封装起来;点进可展开 37 篇详解。
总览+37篇详解
11
### 函数
把本体上的业务逻辑写成可复用、可演进的代码。
代码归类
12
### Ontology Manager
搭建和维护本体的工作台:从草稿到发布。
流程展开
模块三
## 动作类型详解(37 篇)
动作类型(action type)的纵深专题:从快速开始、参数、接口与函数动作,到副作用、通知、Webhook、权限、监控与日志。可顺着读,也可按需查。
01
### 动作类型上手
跟着向导建第一个"改字段"动作并挂到页面。
向导
02
### 动作能做什么
认识规则能表达的增删改、链接、函数等能力。
分类
03
### 在页面中触发
动作在 Object Explorer 与 Workshop 中如何出现。
选择
04
### 上线前试跑
用 test run 模拟动作、预览改动而不动真数据。
分层
05
### 规则全解
规则类型、值映射与组合禁忌。
分类
06
### 参数总览
参数的本质、形态与提交时的流向。
实验
07
### 参数默认值
默认值来源与局部优先全局规则。
实验
08
### 参数过滤
收窄下拉选项的三类来源。
分类
09
### 下拉安全
静态值过滤的隐私泄露与防范。
实验
10
### 参数覆盖
if/then 覆盖块随条件变行为。
模拟
11
### 参数性能
依赖层级扁平化缩短加载。
模拟
12
### 提交条件
提交条件的定义、组成与配置。
选择
13
### 接口上的动作
规则与引用参数作用于所有实现对象。
实验室
14
### 结构体上的动作
用结构体参数修改 struct 属性与约束。
选择
15
### 函数动作·总览
何时用函数承载编辑逻辑及其边界。
选择
16
### 函数动作·上手
从写编辑函数到接动作并管理版本。
分类
17
### 函数动作·批量
合并整批动作进一次函数提性能。
选择
18
### 副作用·总览
副作用是什么、两类区别。
选择
19
### 通知
通知能发给谁、内容怎么配、限制。
分类
20
### 配置通知
手把手给动作加通知并测试。
选择
21
### Webhook
写回与副作用两种模式及参数机制。
分类
22
### 配置 Webhook
手把手给动作加 Webhook 并选模式。
选择
23
### 定时触发构建
动作应用即触发构建并跟踪进度。
分层
24
### 配置分组
用 section 归组、分栏、折叠条件显示。
选择
25
### 上传媒体
媒体集承载海量文件与转换。
对比
26
### 上传附件
把文件挂到对象上(限 200MB)。
选择
27
### 规模与限制
配置/编辑/批量三层上限。
选择
28
### 内联编辑
表格里逐格改值、批量提交。
演示
29
### 动作权限
运行靠对象权限、默认收紧编辑。
矩阵
30
### 读写授权
读设上限、写设底线。
选择
31
### 一致性保证
事务、写模式与隔离级别。
实验
32
### 监控
性能与可靠性的两类告警。
选择
33
### 动作回滚
成功提示里撤销动作及注意。
实验
34
### 分支动作
隔离分支安全试跑与验证。
实验
35
### 动作指标
近 30 天用量与失败细分。
速览
36
### 动作日志
成功提交建模为可审计对象。
实验
37
### 市场动作
打包进产品供他人复用。
实验
模块四
## 设计质量:怎么算设计得好
原则、反面教材、验证方法,以及具体到属性与权限的落地规范。
13
### 本体驱动的应用
逐个认识对象感知类应用,并为需求选对工具。
场景匹配
14
### 设计最佳实践
四条核心原则(按优先级)+ 八条速查清单。
原则篇
15
### 设计反模式
拆解官方点名的 8 个反模式,并做一轮病例诊断。
病例诊断室
16
### 设计验证
拿真实业务问题演练,验证本体是真好用还是只是好看。
验证清单
17
### 结构指南
属性、关系、命名、权限的落地施工规范。
施工篇
模块五
## AI 与语义搜索
当本体遇上大模型:怎么让 AI 真正"懂"你的业务对象。
18
### 把 AI 模型接进本体
部署评估好的模型,在本体里做实时或批量推理。
检索对照实验
19
### 语义搜索
用"意思"来搜而不是用"字",并把结果关联回本体对象。
相似度排序
20
### 文档处理
PDF 提取 → 分块 → 嵌入,变成可检索的知识。
流水线推进
21
### 多模态与嵌入模型
文本、图片、表格如何被编码进同一个向量空间。
嵌入空间演示
22
### 本体增强生成(OAG)
把最相关的本体对象喂给大模型,而不是一堆文本碎片。
检索流水线
23
### 用官方模型做语义搜索
不自己部署模型,也能把语义搜索搭起来。
分步配置
24
### 用自定义模型做语义搜索
什么时候该上自己的模型,以及怎么接进去。
方案选择
25
### 搜索语法
本体的查询语法怎么写才查得到你要的东西。
命中判断练习
模块六
## 函数(Functions)· 25 篇
从选语言、建仓库、写函数,到版本、权限、监控、部署;TypeScript v2 单独成体系。
01
### 函数语言特性对照:TS v1 / TS v2 / Python
① 三种语言,能力不等价
循序渐进含代码示例
02
### 函数上手:从建仓库到跑通第一个函数
含 5 张原文截图
循序渐进含原文图
03
### 在 VS Code 里开发函数
① 扩展 = 平台能力搬进编辑器
循序渐进含代码示例
04
### 函数类型参考手册
① 类型必须显式标注
循序渐进含代码示例
05
### 函数版本管理:语义化版本与兼容性
① 版本不可变
循序渐进含代码示例
06
### 管理已发布的函数
含 3 张原文截图
循序渐进含原文图
07
### 分支上的函数开发
含 5 张原文截图
循序渐进含原文图
08
### 把函数打包进 Marketplace
含 2 张原文截图
循序渐进含原文图
09
### 函数监控
含 2 张原文截图
循序渐进含原文图
10
### 函数里的日志与埋点
① 两类遥测:日志与 span
循序渐进含代码示例
11
### 函数权限:编写与执行分别受什么约束
含 3 张原文截图
循序渐进含原文图
12
### 本体编辑(Ontology edits)总览
① 编辑 = 增删改对象
循序渐进含代码示例
13
### 用函数配置通知
① 函数决定通知内容与收件人
循序渐进含代码示例
14
### 查询函数:通过 API 网关对外提供只读能力
含 1 张原文截图
循序渐进含原文图
15
### 从函数里调用外部 API
① 必须先配置外部源
循序渐进含代码示例
16
### 用 Platform SDK 调用平台 API
① 平台 SDK ≠ 本体 SDK
循序渐进含代码示例
17
### 部署型函数:常驻执行模式
含 8 张原文截图
循序渐进含原文图
18
### 面向用户的错误(UserFacingError)
含 1 张原文截图
循序渐进含原文图
19
### 流式函数:分块返回结果
① 流式 = 边算边给
循序渐进含代码示例
20
### Functions settings:管理员全局设置
含 1 张原文截图
循序渐进含原文图
21
### TypeScript v2 函数上手
含 4 张原文截图
循序渐进含原文图
22
### 本地本体 SDK(Local OSDK)
含 2 张原文截图
循序渐进含原文图
23
### 从 TypeScript v1 迁移到 v2
含 4 张原文截图
循序渐进含原文图
24
### TypeScript v2 的本体编辑
① 编辑要打包成 batch
循序渐进含代码示例
25
### Staged writes:带读后写保证的编辑(Beta)
① 读后写保证
循序渐进含代码示例
模块七
## 接口(Interfaces)· 3 篇
接口是什么、怎么创建、怎么让对象类型实现它。
01
### 接口(Interface):描述"形状"的本体类型
① 接口描述"形状"
循序渐进含代码示例
02
### 在 Ontology Manager 里创建接口
① 创建入口是 Ontology Manager
循序渐进含代码示例
03
### 让对象类型实现接口
① 实现 = 属性对上号
循序渐进含代码示例
模块八
## 平台模块总览 · 11 篇
AIP、数据集成、模型、本体、开发工具链、应用、可观测性、分析、交付、安全、管理 —— 十一个平台能力域的地图。
01
### AIP(人工智能平台)总览
含 1 张原文截图
循序渐进含原文图
02
### Data connectivity & integration(数据连接与集成)总览
含 1 张原文截图
循序渐进含原文图
03
### Model connectivity & development(模型接入与开发)总览
含 1 张原文截图
循序渐进含原文图
04
### Ontology building(本体构建)总览
含 1 张原文截图
循序渐进含原文图
05
### Developer toolchain(开发工具链)总览
含 1 张原文截图
循序渐进含原文图
06
### Use case development(业务应用开发)总览
含 1 张原文截图
循序渐进含原文图
07
### Observability(可观测性)总览
含 3 张原文截图
循序渐进含原文图
08
### Analytics(分析)总览
含 1 张原文截图
循序渐进含原文图
09
### Product delivery(产品交付)总览
含 1 张原文截图
循序渐进含原文图
10
### Security & governance(安全与治理)总览
含 1 张原文截图
循序渐进含原文图
11
### Management & enablement(管理与赋能)总览
含 1 张原文截图
循序渐进含原文图
---
## 内联编辑(Inline edits):在表格里逐格改值
- 页面:https://www.hanzhongpin.xyz/ontology/inline-edits.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/inline-edits/
- 主题分组:动作类型详解
动作类型详解
# 内联编辑(Inline edits):在表格里逐格改值
内联编辑让你不用打开完整表单,直接在表格/列表里改对象的单个属性。它和普通动作"先填全再提交"不同:每个参数都可省略、默认取对象现有值。但批量提交的机制,也带来了独特的坑。
## 一句话速览
内联编辑(Inline edits):在表格里逐格改值:内联编辑让你不用打开完整表单,直接在表格/列表里改对象的单个属性。它和普通动作"先填全再提交"不同:每个参数都可省略、默认取对象现有值。但批量提交的机制,也带来了独特的坑。
1 action-backed inline edit 普通动作需要设置多个参数才算有效;而 action-backed inline edit(动作支撑的内联编辑)相反:每个参数都是可选…
2 在 Object Explorer 里配置内联编辑 要设置内联编辑动作,进入对象类型的 Properties(属性)标签页,再到 Ontology Manager 的 Interact…
3 内联编辑对动作类型的要求 一个动作要被接受为内联编辑动作,必须满足
4 Workshop 中的内联编辑 在 Workshop 里把某个动作类型用作内联编辑,不需要额外配置
## 什么是 action-backed inline edit
和普通动作校验/提交方式都不同。
普通动作需要设置多个参数才算有效;而 action-backed inline edit(动作支撑的内联编辑)相反:每个参数都是可选的(optional),并默认取对象的现有值(existing value)。于是用户可以一次只改一个属性。
内联编辑在 Workshop 与 Object Explorer 里都可用;它的具体配置取决于动作在哪里被使用。
## 在 Object Explorer 里配置内联编辑
从对象的 Interaction(交互)标签页下手。
要设置内联编辑动作,进入对象类型的 Properties(属性)标签页,再到 Ontology Manager 的 Interaction(交互)标签页。选中一个属性,在侧栏找到 Inline edit,从下拉里选一个可用动作类型,或新建一个(会触发动作类型创建流程)。
要点:每个属性只能有一个内联编辑动作类型。你可以把同一个动作类型复用作多个属性的内联编辑,也可以为不同属性分别建不同动作。
## 内联编辑对动作类型的要求
不是任何动作都能当内联编辑用。
一个动作要被接受为内联编辑动作,必须满足:
- 只能修改单个对象类型里的单个对象;
- 必须启用默认值(default values);
- 默认值必须来自定义该内联动作的对象引用参数(object reference parameter)——因此正在被改的属性,不能映射到静态值或"当前用户/当前时间"这类特殊值;
- 可以设置可见性状态与覆盖,但在 Object Explorer / Object Views 里会被忽略;
- 不能启用副作用 webhook 或副作用通知。
## Workshop 中的内联编辑
无需额外配置,但并非都合适。
在 Workshop 里把某个动作类型用作内联编辑,不需要额外配置。但要注意:并非所有动作都适合"单元格级"的编辑。
"Inline edits are validated and submitted in bulk."内联编辑是批量校验与提交的。
正因为是批量(bulk)提交,一些动作可能失败或产生意外结果,例如:试图读取"另一动作可能已写入的数据",或两个不同的动作试图写入同一个对象。
## 批量提交与冲突:哪些会报错
这是内联编辑最容易踩的坑。
普通动作逐个(顺序)校验与提交;内联编辑则是批量校验与提交。因此"有效内联动作"必须提交互不冲突(non-conflicting)的编辑。实践中,同一表格编辑组件里配置的多个动作不能:
- 写入同一个对象;
- 创建同一个链接;
- 试图维持聚合值(aggregate)一致。
若内联编辑两次编辑同一对象,会直接返回错误;增删连接表链接(join table links)也不被支持,会报错。提交条件(submission criteria)会对每次编辑求值,但因批量提交,依赖共享/关联对象的累积式条件可能失效。
动手试:这个动作适合做内联编辑吗?
看有效例子
看无效例子
有效
互不冲突
多个动作分别改不同对象的独立属性,不写同对象、不建同链接、不维护聚合。
无效
会报错
两次编辑同一对象,或增删 join table links,都会触发用户可见的错误。
内联编辑的提交方式是?点击揭晓。
## 一页带走
① 逐格改值 每个参数可选、默认取现有值;在 Workshop 与 Object Explorer 可用。
② 动作有硬要求 仅改单对象类型的单对象、启用默认值、禁用副作用 webhook/通知。
③ 批量提交 内联编辑批量校验提交;因此累积式提交条件可能不像逐个跑那样有效。
④ 别冲突 不写同对象、不建同链接、不维护聚合;二次改同对象会报错。
### 常见问题速答 · FAQ
关于「内联编辑(Inline edits):在表格里逐格改值」,读者最常问的几个问题。
内联编辑对动作类型的要求是什么? 一个动作要被接受为内联编辑动作,必须满足。
Workshop 中的内联编辑是什么? 在 Workshop 里把某个动作类型用作内联编辑,不需要额外配置。但要注意:并非所有动作都适合"单元格级"的编辑。
批量提交与冲突:哪些会报错? 普通动作逐个(顺序)校验与提交;内联编辑则是批量校验与提交。因此"有效内联动作"必须提交互不冲突(non-conflicting)的编辑。实践中,同一表格编辑组件里配置的多个动作不能。
---
## 接口(Interface):描述"形状"的本体类型
- 页面:https://www.hanzhongpin.xyz/ontology/interface-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/interfaces/interface-overview/
- 主题分组:接口(一)
循序渐进 · 教学 · 接口(一)
# 接口(Interface):描述"形状"的本体类型
接口描述对象类型的形状和能力,让共享同一形状的对象类型能被一致地建模和使用。这一篇讲清接口是什么、和对象类型有什么区别。
## 先记住这几条
① 接口描述"形状" 它规定有哪些属性、链接和能力,但不规定具体实现。
② 与对象类型是两类东西 对象类型是具体实体,接口是抽象契约 —— 这是最容易混淆的点。
③ 作用是一致性 不同对象类型只要实现同一接口,就能被同一套逻辑处理。
④ 支持程度有边界 接口不是所有功能都支持,要看当前支持矩阵。
## 写在前面
接口(interface)是一种描述对象类型形态及其能力的 Ontology 类型。接口使得对共享相同形态的对象类型能够进行一致的建模与交互。例如,Facility 接口可以包含 Facility Name(设施名称)和 Location(位置)属性。Facility 可由 Airport(机场)、Manufacturing Plant(制造工厂)或 Maintenance Hangar(维修机库)等对象类型实现,这些对象类型各自还可以包含额外的、特定于类型的属性。

> 图:一个 `Facility` 接口的示例。
通过使用 Facility 接口,工作流既可以在聚合层面、也可以独立地与 Airport、Manufacturing Plant、Maintenance Hangar 对象类型交互,而无需了解这些对象类型的具体细节。此外,如果引入了新实现 Facility 接口的对象类型,该工作流将立即与新对象类型兼容,无需额外的重构。
查阅当前支持程度,了解在平台的哪些位置可以使用接口。
## 接口能提供什么
接口能提供什么
> 要点:先看清接口能表达哪些内容:属性、链接类型、动作类型约束等。
一个接口由接口属性、链接类型约束、动作类型约束以及关于接口的元数据组成。接口属性可以在接口本地定义(推荐),也可以使用共享属性。一个接口可以被多个对象类型实现。
与编程语言中的接口非常相似,你可以扩展一个接口以创建一个继承原接口属性的子接口,然后再为子接口添加新的、更具体的属性。对象类型随后可以实现该接口,表明它们符合该接口定义。一个对象类型可以实现多个接口,用于不同的工作流。接口也可以扩展多个其他接口,包括那些本身又扩展了其他接口的接口,从而形成通过多层接口继承而来的属性。
## 接口 vs 对象类型
接口 vs 对象类型
> 要点:最核心的一节:两者的本质区别,理解了这个才算懂接口。
接口与对象类型在 Ontology 中既有功能差异,也有风格差异。
对象类型是具体的:它们由共享或本地属性定义 schema,由包含属性值的数据集支撑,并且可以被实例化为对象。
相比之下,接口是抽象的:它们由接口属性定义 schema,不由数据集支撑,不能直接实例化,而必须作为某个具体的对象类型实例化。
在风格上,接口在平台中通过图标周围的虚线,与对象类型在视觉上区分开来。

> 图:接口图标示例
## 接口权限
接口权限
> 要点:接口上的权限如何生效,与对象权限的关系。
接口通过 Ontology 角色进行权限控制。
## 当前支持程度
当前支持程度
> 要点:哪些能力已支持、哪些还不行 —— 动手前必看。
随着对接口这一 Ontology 类型的支持不断扩大,其可用性在 Palantir 平台各处会有所不同。
以下应用与服务当前已支持接口:
- Ontology Manager: 定义、编辑和实现接口。
- Marketplace: 打包并安装接口。
- Functions: TypeScript v2 函数。
以下应用与服务部分支持接口:
- Actions: 定义用于创建、修改、删除或链接实现某接口的对象类型的动作。接口动作类型约束处于 Beta 阶段,可用于定义跨实现该接口的对象类型的预期动作能力。
- Object Set Service: 按接口搜索和排序对象。按接口聚合的支持正在开发中。接口链接类型的支持正在开发中。
- Ontology SDK: 使用接口作为与实现对象类型交互的 API 层。支持程度因语言而异;目前支持 TypeScript,Java 与 Python 的支持正在开发中。
以下位置接口仍在积极开发中,但尚未支持:
- Workshop
- Functions: TypeScript v1 与 Python 函数
## 开始使用接口
开始使用接口
> 要点:下一步该看什么。
要为你的 Ontology 添加接口,你可以创建新接口,或扩展已有接口。一旦有了接口,你可以让一个形态合适的对象类型实现该接口,或随着 Ontology 演进编辑它,以更好地贴合你的组织。
### 常见问题速答 · FAQ
关于「接口(Interface):描述"形状"的本体类型」,读者最常问的几个问题。
接口能提供什么? 先看清接口能表达哪些内容:属性、链接类型、动作类型约束等。一个接口由接口属性、链接类型约束、动作类型约束以及关于接口的元数据组成。接口属性可以在接口本地定义(推荐),也可以使用共享属性。一个接口可以被多个对象类型实现。
接口 vs 对象类型是什么? 最核心的一节:两者的本质区别,理解了这个才算懂接口。接口与对象类型在 Ontology 中既有功能差异,也有风格差异。
接口权限是什么? 接口上的权限如何生效,与对象权限的关系。接口通过 Ontology 角色进行权限控制。
当前支持程度是什么? 哪些能力已支持、哪些还不行 —— 动手前必看。随着对接口这一 Ontology 类型的支持不断扩大,其可用性在 Palantir 平台各处会有所不同。
---
## 接口(Interface):让不同对象"长得一样"
- 页面:https://www.hanzhongpin.xyz/ontology/interfaces.html
- 官方原文:https://www.palantir.com/docs/foundry/interfaces/interface-overview/
- 主题分组:本体零件(九)
循序渐进 · 教学 · 本体零件(九)
# 接口(Interface):让不同对象"长得一样"
当你有十几种"长得差不多"的对象类型,却想用同一套逻辑去操作它们时,接口就是答案。
这一篇讲清接口是什么、它和对象类型的区别、怎么用继承与实现搭出多态。
## 一句话速览
接口(Interface):让不同对象"长得一样":当你有十几种"长得差不多"的对象类型,却想用同一套逻辑去操作它们时,接口就是答案。这一篇讲清接口是什么、它和对象类型的区别、怎么用继承与实现搭出多态。
1 接口描述"形状与能力" 在中文里,「接口(interface)」常被翻译得太技术化
2 Facility 接口 设想你有一个 Facility(设施)接口,它规定:任何实现者都要有 Facility Name(设施名称)和 Location(位…
3 接口由什么组成 一个接口由四类东西拼成,我们可以对照着理解
4 像搭积木一样复用 接口和编程语言里的接口很像,支持继承(extend)
## 一句话:接口描述"形状与能力"
An interface describes the shape of an object type and its capabilities.
在中文里,「接口(interface)」常被翻译得太技术化。你可以把它理解成一张
规格清单:一份对象类型要想"长得合规",就必须具备清单上列出的属性、链接和动作。
接口本身不存任何数据,它只定义形状(shape)与能力(capabilities)。
Interfaces allow for consistent modeling of and interaction with object types that share a common shape.
接口让"共享同一形状"的对象类型,能够被一致地建模与交互。
关键价值在"共享"二字:只要多种对象类型都符合同一张清单,同一段工作流就能
一次写好、处处适用——这就是后面要反复提到的多态(polymorphism)。
>
先记住一句对比:对象类型(object type)是具体的东西;接口是
抽象的规格。接口不装数据,它只说"想当我的实现者,你得有这些字段"。
## 一个例子:Facility 接口
同样的形状,三种完全不同的现实事物。
设想你有一个 Facility(设施)接口,它规定:任何实现者都要有
Facility Name(设施名称)和 Location(位置)这两个属性。
下面这三种对象类型,现实里毫无关系,却都"长得合规",于是都能实现(implement)这个接口:
Airport 机场
facilityName · location + 自己专属的 iataCode、跑道数等。
Manufacturing Plant 工厂
facilityName · location + 自己专属的生产线、产能等。
Maintenance Hangar 机库
facilityName · location + 自己专属的机位容量等。
>
多态的威力:一段"列出所有位于某城市的设施"的工作流,只要面向
Facility 接口来写,就能同时覆盖机场、工厂、机库——
将来再加一个新的对象类型(比如 Warehouse 仓库),只要它实现了接口,工作流立刻兼容,无需重写。
## 接口由什么组成?
接口 = 属性 + 链接约束 + 动作约束 + 元数据。
一个接口由四类东西拼成,我们可以对照着理解:
组成部分 说明
Interface properties 接口属性 接口要求的属性。可以直接定义在接口上(推荐),也可以复用「共享属性(shared properties)」。
Link type constraints 链接类型约束 规定实现接口的对象类型"应当有哪些链接",以及链接的两端长什么样。
Action type constraints 动作类型约束 规定实现接口的对象类型"应当具备哪些动作能力"。原文注明这部分处于 beta 阶段。
Metadata 元数据 关于接口本身的描述信息,便于在平台里检索与治理。
最重要的一点:一个接口可以被多个对象类型实现,反过来,一个对象类型也可以同时实现多个接口,
分别服务于不同的工作流。
>
推荐做法:接口属性优先本地定义在接口上,而不是依赖对象类型各自的属性。
这样接口的形状由接口自己掌控,实现者只是"填空"。
## 继承与实现:像搭积木一样复用
extend 继承属性,implement 声明符合规格。
接口和编程语言里的接口很像,支持继承(extend)。你可以从已有接口
扩展(extend)出一个"子接口",它自动继承父接口的全部属性,
再往上加更具体的属性。
You can extend an interface to create a child interface that inherits the properties of the original interface, then add new, more specific properties.
扩展接口可生成子接口,继承原接口属性,再追加更具体的属性。
两条规则值得记牢:
- 对象类型实现接口(implement):声明"我符合这张规格清单",从而能被面向接口的工作流使用。
- 层层继承:一个接口可以 extend 多个其他接口,被继承的接口还能再继承别的接口,属性会"穿透"多层传递下来。
## 接口 vs 对象类型:抽象 vs 具体
一句话区分两者最常被混淆的地方。
原文把两者的差异拆成"功能"和"外观"两层。先看成功能:
对象类型 OBJECT TYPE
具体 concrete
· 由 shared / local properties 定义 schema
· 背后有数据集支撑(含属性值)
· 可以实例化为一个个对象
⇄
接口 INTERFACE
抽象 abstract
· 由 interface properties 定义 schema
· 不被数据集支撑
· 不能直接实例化,必须作为某个对象类型来实例化
外观上也有一处很贴心的区分:在平台界面里,
接口的图标用虚线边框圈起来,一眼就能和实心的对象类型分开。
常见坑:接口"不被数据集支撑、不能直接实例化"——你不能像查对象那样去查一个接口里的"数据行"。
接口是给对象类型当模板用的,真正的实例永远落在某个具体的对象类型上。
### 练一练:它属于哪一类?
## 权限与当前支持范围
接口还在快速演进,支持情况因应用而异。
接口的权限通过「本体角色(Ontology roles)」来管理——和本体里其它资源走同一套授权体系。
原文特别提示:接口仍在积极开发中,支持范围会随平台更新而变化。目前大致分三档:
支持程度 涉及的应用 / 服务
已支持 Ontology Manager(定义/编辑/实现接口)、Marketplace(打包与安装接口)、Functions(TypeScript v2 函数)
部分支持 Actions(可定义对"实现接口的对象"做增改删与链接,接口动作约束在 beta)、Object Set Service(按接口搜索排序)、Ontology SDK(作 API 层,TypeScript 已支持,Java/Python 在开发中)
暂不支持 Workshop;Functions 的 TypeScript v1 与 Python 版本
>
给初学者的提醒:如果你照着教程想在某个应用里用接口却找不到入口,
先回到 Ontology Manager——它是目前定义、编辑和实现接口的主阵地。
## 动手:这个类型实现了接口吗?
判断依据只有"形状"——有没有那几个必填字段。
假设有接口 Facility,它要求实现者必须具备 facilityName 与 location 两个属性。
下面每个卡片列出一种对象类型所拥有的属性。
点击卡片,判断它是否实现了 Facility 接口。
候选对象类型(点我判定)
判定结果
← 点击左侧卡片,看它是否实现了 Facility 接口。
判断只看"形状"(有没有那两个字段),不看这个类型现实里叫什么、属于哪个行业。
## 一页带走
① 接口 = 形状与能力 抽象的规格清单,定义属性 / 链接约束 / 动作约束 / 元数据,自己不装数据。
② 多态:一次写好 面向接口写工作流,所有实现者自动兼容,新增类型无需重构。
③ 可继承可多实现 extend 继承并追加属性;对象类型可 implement 多个接口。
④ 抽象≠具体 接口不被数据集支撑、不能实例化;界面用虚线边框区分;支持范围仍在扩展。
### 常见问题速答 · FAQ
关于「接口(Interface):让不同对象"长得一样"」,读者最常问的几个问题。
一句话:接口描述"形状与能力"是什么? 在中文里,「接口(interface)」常被翻译得太技术化。你可以把它理解成一张 规格清单:一份对象类型要想"长得合规",就必须具备清单上列出的属性、链接和动作。接口本身不存任何数据,它只定义形状(shape)与能力(capabilities)。
一个例子:Facility 接口是什么? 设想你有一个 Facility(设施)接口,它规定:任何实现者都要有 Facility Name(设施名称)和 Location(位置)这两个属性。
接口由什么组成? 一个接口由四类东西拼成,我们可以对照着理解。
继承与实现:像搭积木一样复用是什么? 接口和编程语言里的接口很像,支持继承(extend)。你可以从已有接口 扩展(extend)出一个"子接口",它自动继承父接口的全部属性,再往上加更具体的属性。
---
## 市场动作(Marketplace action types)
- 页面:https://www.hanzhongpin.xyz/ontology/marketplace-action-types.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/marketplace-action-types/
- 主题分组:动作类型详解
动作类型详解
# 市场动作(Marketplace action types)
把做好的动作分享给全公司复用,而不是每人重造一遍?把它打包进 Marketplace 产品即可。这一篇讲清 Marketplace 动作是什么、怎么打包、打包前要注意什么。
## 一句话速览
市场动作(Marketplace action types):把做好的动作分享给全公司复用,而不是每人重造一遍?把它打包进 Marketplace 产品即可。这一篇讲清 Marketplace 动作是什么、怎么打包、打包前要注意什么。
1 市场动作(Marketplace action types) 通过 Foundry DevOps,你可以把动作类型(action types)纳入 Marketplace 产品(Marketpl…
2 推荐做法与打包自检 虽然可以直接选动作类型,但官方推荐:先添加像 Workshop 应用这样的内容,再经由依赖面板(dependencies panel…
## 什么是市场动作(Marketplace action types)
用 Foundry DevOps 把动作变成可安装、可复用的"产品"。
通过 Foundry DevOps,你可以把动作类型(action types)纳入 Marketplace 产品(Marketplace products),让其他用户安装(install)并复用(reuse)。这把你精心设计的动作,从"自己用"变成"大家装了就能用"。
"Use Foundry DevOps to include your action types in Marketplace products for other users to install and reuse."使用 Foundry DevOps 将你的动作类型纳入 Marketplace 产品,供其他用户安装与复用。
> 提示:Marketplace 产品是 Foundry DevOps 的核心概念之一;先把动作"产品化",才能让它在组织内被分发。
## 支持的特性与打包前的准备
大部分动作特性都支持,但有一个"用户引用"的坑必须先填。
通常支持
大多数动作特性
→ 可纳入 Marketplace 产品。
例外:引用了「不支持特性」的对象类型的动作。
注意
打包前必须改
Security & Submission criteria 引用了具体用户
→ 不可直接分发。
须把用户引用改为「群组(group)」引用。
点击揭晓:为什么要把"用户引用"换成"群组引用"?
点击这里揭晓 →
## 如何把动作添加进产品
先把产品建好,再选内容类型、挑动作。
第一步创建产品(product)
先有一个 Marketplace 产品作为容器。
参考官方"创建你的第一个产品"指南,先在 Foundry DevOps 中创建产品。
第二步选择内容类型「Action type」
在产品中把内容类型选为 Action type。
创建产品后,按界面提示选择 Action type 这一内容类型,然后系统会让你挑一个动作类型加入。
## 推荐做法与打包自检
官方建议先放"壳应用"再选依赖动作;顺便自检你的动作是否就绪。
虽然可以直接选动作类型,但官方推荐:先添加像 Workshop 应用这样的内容,再经由依赖面板(dependencies panel)选择相关的动作。这样动作会作为应用的依赖被一并打包,结构更清晰。
互动实验:Marketplace 打包就绪检查
> 准备把一个动作打包进 Marketplace 产品,先检查它的 Security 是否引用了具体用户。
Security 引用了具体用户
已改用群组(group)引用
重置
>
> 提示:只要动作不引用"不支持特性"的对象类型,且安全/提交标准已用群组替代用户,就可以安心加入产品。
## 要点回顾
确认你理解了市场动作的分发逻辑。
点击揭晓:打包前,Security & Submission criteria 里若写死了用户,该怎么办?
点击这里揭晓 →
## 一页带走
① 市场动作 = 可复用 用 Foundry DevOps 把动作纳入 Marketplace 产品,他人安装复用。
② 准备:换群组 打包前把 Security 里用户引用改为群组引用;避开采不支持特性的对象类型。
③ 添加步骤 建产品 → 选 Action type 内容类型 → 挑动作。
④ 推荐做法 先加 Workshop 应用,再经依赖面板把相关动作一并打包。
### 常见问题速答 · FAQ
关于「市场动作(Marketplace action types)」,读者最常问的几个问题。
支持的特性与打包前的准备是什么? 点击揭晓:为什么要把"用户引用"换成"群组引用"?
推荐做法与打包自检是什么? 虽然可以直接选动作类型,但官方推荐:先添加像 Workshop 应用这样的内容,再经由依赖面板(dependencies panel)选择相关的动作。这样动作会作为应用的依赖被一并打包,结构更清晰。
要点回顾是什么? 点击揭晓:打包前,Security & Submission criteria 里若写死了用户,该怎么办?
---
## 把 AI 模型接进本体
- 页面:https://www.hanzhongpin.xyz/ontology/models.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/models/
- 主题分组:模型 Models
循序渐进 · 教学 · 模型 Models
# 把 AI 模型接进本体
本体让你用"现实概念"组织数据;模型让你用"现实概念"做预测。这一篇讲怎样把一个训练好、评估过的模型
部署进本体,让普通用户不用懂机器学习也能用到预测结果。
## 一句话速览
把 AI 模型接进本体:本体让你用"现实概念"组织数据;模型让你用"现实概念"做预测。这一篇讲怎样把一个训练好、评估过的模型 部署进本体,让普通用户不用懂机器学习也能用到预测结果。
1 这一篇在讲什么 组织都想用 AI / 机器学习(ML)来加速决策,但真正把模型用起来并不容易,投资回报率(ROI)常常达不到预期
2 为什么要把模型"接进"本体 把数据集映射成本体概念能带来好处;原文指出,把模型也映射成本体概念,会再叠加三层收益
3 实时 vs 批量 原文点出模型接入本体的两条路径,对应不同的使用节奏
4 模型结果,变成本体里的属性 把模型接进本体的最大好处,是终端用户根本感知不到"这是 ML"
## 这一篇在讲什么?
原文聚焦的是"运营 AI/ML"的最后一步:把评估过的模型部署上线。
组织都想用 AI / 机器学习(ML)来加速决策,但真正把模型用起来并不容易,
投资回报率(ROI)常常达不到预期。Foundry 提供三块能力来弥合这道鸿沟:
可信数据底座 模型喂的是干净、可追溯、可治理的数据。
评估与比较 用组织目标去衡量、对比不同模型的好坏。
部署到工作流 把模型放进面向用户的运营流程里真正用起来。
本篇只讲最后一块——如何把一个已经评估好的模型,部署进生产环境、接入本体(Ontology),
让它在 Workshop、Vertex 这类终端应用里被实时调用。
Foundry provides the key capabilities necessary to bridge this gap: a trustworthy data foundation, tools for evaluating and comparing models against organizational objectives, and functionality for deploying models into user-facing operational workflows. This page focuses on the last step: deploying an evaluated model into production.
Foundry 提供弥合这道鸿沟的关键能力:可信数据底座、按组织目标评估对比模型的工具,以及把模型部署进用户工作流的能力。本页聚焦最后一步:把评估过的模型部署到生产。
## 为什么要把模型"接进"本体?
原文给出三大收益:可解释、可积累、可连通。
把数据集映射成本体概念能带来好处;原文指出,把模型也映射成本体概念,会再叠加三层收益:
1
### 可解释性 Interpretability
Users interact with forecasts, estimates, classifications — not ML internals.
所有建模结果都用"现实概念"来表达——也就是某个对象类型的属性。
终端用户不需要懂机器学习就能用上结果,他们只是和"预测(forecast)、估算(estimate)、分类(classification)"
这样简单的概念打交道。
2
### 规模效应 Economies of scale
Modeling efforts build on each other over time.
每个建模项目不再是只为某一个场景临时定制的孤例。为一个用例产出的预测,
可以立刻被后续用例复用,减少重复劳动,更快产生用户价值。
3
### 连通到全局 Connectivity at scale
The Ontology becomes a single source of truth for logic, not just data.
引入 ML 后,本体成为组织的唯一事实来源——不只是数据,更是"逻辑"。
模型编码了组织对"事情未来会怎样变化"的预期,于是本体变成整个企业的"数字孪生(digital twin)",
让跨组织的模拟推演成为可能。
>
一句话记住:数据进本体 → 人看得懂;模型进本体 → 预测也用"现实概念"表达,还能跨场景复用、连成全局逻辑。
## 端到端四步流程
在 Foundry 里用本体做"实时推理(live inference)"的高层步骤。
步骤 1在 Foundry 里创建模型
Create a model
先在 Foundry 中准备好一个模型(训练、注册、评估都在这一步完成)。本篇假设它已经"评估过、值得上线"。
步骤 2配置直接模型部署
Configure a direct model deployment
为模型配置一个"直接部署(direct model deployment)",让它能被实时调用,而不是只在离线 pipeline 里跑。
步骤 3发布一个包装函数
Publish a wrapper function
发布一个简单包裹函数(wrapper function)来调用模型;可选地再被别的函数调用,围绕模型编排更复杂的逻辑。这一步让"模型"变成本体里可调用的能力。
步骤 4在终端应用里实时推理
Use for live inference in Workshop / Vertex
用那个函数做实时推理,落在 Workshop、Vertex 等面向终端用户的程序里。用户在前端输入,立刻拿到模型结果。
点开上面每一层,看这一步具体在做什么。四步是"评估好的模型 → 部署 → 包装成函数 → 应用里实时调用"。
## 两种推理方式:实时 vs 批量
同一个模型,既可以"按需即时算",也可以"离线算好存着"。
原文点出模型接入本体的两条路径,对应不同的使用节奏:
方式 特征 适合
实时推理 Live inference
经"模型部署 + 包装函数",在应用里每次请求算一次,即时返回。
Workshop / Vertex 里用户随用随算
批量推理 Batch inference
Ontology 对象由"用模型算出的数据集"来支撑,结果落为对象属性。
全量对象一次性算好、长期展示
### 练一练:该选哪种?
## 模型结果,变成本体里的属性
预测、估算、分类——都是对象类型上一个普通人能懂的属性。
把模型接进本体的最大好处,是终端用户根本感知不到"这是 ML"。
他们看到的只是某个对象上多了一个属性:
预测 forecast Customer.churnRiskScore 客户流失风险分
估算 estimate Equipment.remainingUsefulLife 剩余寿命估算
分类 classification Ticket.priority 工单优先级分类
因为结果定义在"现实概念"上,用户无需理解模型内部,就能直接用这些结果做决策、建规则、画看板。
又因为它落在本体里,一个用例算出的预测,下一个用例能直接复用——这就是第 2 步说的"规模效应"。
>
连接回前面的系列:这些"模型产出的属性"和你在《结构指南》里学的普通属性没有区别——
它们同样要遵循命名规范、可被链接、可被权限策略保护。
## 动手对照实验:关键词检索 vs 语义检索
为什么"嵌入模型(embedding model)"值得接入?点查询词,看两种检索各命中什么。
下面是一份极简文档库(8 篇)。请点一个查询词:左栏是"关键词检索"——只匹配标题里字面出现的字;
右栏是"语义检索"——靠嵌入模型把意思转成向量,找意思相近的文档。
你会看到:语义检索能找到关键词检索漏掉的相关文档。
动手试试 · 关键词检索 vs 语义检索
查询:口罩
查询:呼吸防护
查询:面部遮挡
重置
✗ 关键词检索(字面匹配)
0
标题里出现该字才命中
点上方查询词试试
✓ 语义检索(嵌入模型 / 向量)
0
意思相近即命中
点上方查询词试试
说明:这是教学用的简化模型——真实语义检索由嵌入模型把文本转成向量、在 N 维空间里找最近邻,并非靠预设同义词。这里只是让你直观感受"按意思找"比"按字面找"能多覆盖多少。
## 一页带走
① 聚焦部署 本篇只讲最后一步:把评估过的模型部署进生产、接入本体。
② 三大收益 可解释、规模效应、连通成全局逻辑(数字孪生)。
③ 四步上线 创建模型 → 直接部署 → 包装函数 → 应用实时推理。
④ 两条路径 实时推理随用随算;批量推理算好落为属性。
### 常见问题速答 · FAQ
关于「把 AI 模型接进本体」,读者最常问的几个问题。
这一篇在讲什么? 组织都想用 AI / 机器学习(ML)来加速决策,但真正把模型用起来并不容易,投资回报率(ROI)常常达不到预期。Foundry 提供三块能力来弥合这道鸿沟。
为什么要把模型"接进"本体? 把数据集映射成本体概念能带来好处;原文指出,把模型也映射成本体概念,会再叠加三层收益。
两种推理方式:实时 vs 批量是什么? 原文点出模型接入本体的两条路径,对应不同的使用节奏。
模型结果,变成本体里的属性是什么? 把模型接进本体的最大好处,是终端用户根本感知不到"这是 ML"。他们看到的只是某个对象上多了一个属性。
---
## 监控(Monitoring)
- 页面:https://www.hanzhongpin.xyz/ontology/monitoring.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/monitoring/
- 主题分组:动作类型详解
动作类型详解
# 监控(Monitoring)
动作上线后会不会变慢、会不会悄悄失败?这一篇讲 Foundry 如何对动作做性能与可靠性监控,以及怎样在出问题时收到告警。
## 为什么要监控动作
动作是修改本体的主要方式,它的性能与可靠性直接影响业务。
在 Foundry 中,动作(action)可以被监控,用来跟踪其性能与可靠性。当动作变慢或开始失败时,监控能帮你尽早发现、主动排查。
"Actions in Foundry can be monitored to track performance and reliability."Foundry 中的动作可以被监控,以跟踪其性能与可靠性。
监控不是孤立的功能:它和上一篇的一致性保证(consistency guarantee)、本模块后续的动作指标(action metrics)与动作日志(action log)共同构成"观察—度量—追责"的闭环。
## 两类监控规则(Monitoring rules)
Foundry 为动作监控内置了两种关键规则类型,点击展开看它们分别"盯"什么。
规则一动作时长 P95(Action duration p95)
当第 95 百分位执行时间超过阈值时告警。
用来发现"拖慢整体"的性能瓶颈:P95 表示把执行时间排序后,最慢的 5% 动作的平均水平。一旦它超过设定阈值,说明有相当一部分动作偏慢,需要优化工作流。
规则二窗口内失败次数(Number of action failures in window)
当一段窗口时间内的失败次数超过阈值时告警。
用来捕捉"突然开始失败"的可靠性问题:在一个时间窗口里,如果失败次数累计超过阈值,就触发告警,让你在故障扩大前介入。
> 提示:更细的配置项(阈值、严重级别等)参见官方 monitoring rules reference 文档;本篇只讲概念和流程。
## 四步配置动作监控
配置监控遵循 Foundry 监控视图(monitoring view)的标准流程。
- 创建监控视图按官方流程新建一个 monitoring view,作为承载规则的容器。
- 添加监控规则为某个动作(action)或动作类型(action type)添加一条监控规则(monitoring rule)。
- 配置阈值与严重级别设置合适的阈值(threshold)和严重级别(severity),决定何时、多严重才告警。
- 订阅告警通知按告警订阅指南配置 alert notification,把告警推给该收到的人。
点击揭晓:监控规则除了绑定单个动作,还能用什么"动态作用域"自动覆盖一批动作?
点击这里揭晓 →
## 动态作用域(Dynamic scopes)
与其逐个绑定动作,不如让监控"跟着资源走"。把作用域匹配到它的描述(点击右侧)。
## 告警与订阅:从"看见"到"被通知"
监控的价值在于出问题时有人知道。来模拟一次"窗口内失败"的告警判定。
互动实验:窗口内失败告警
窗口内失败数 0 点击"模拟一次失败"累加
阈值 5 超过则触发告警
模拟一次动作失败
重置
> 尚未达到阈值。
## 一页带走
① 监控的目的 跟踪动作的性能与可靠性,尽早发现变慢与失败。
② 两类规则 动作时长 P95 与窗口内失败次数。
③ 四步配置 建视图 → 加规则 → 配阈值/严重级别 → 订阅告警。
④ 动态作用域 Workflow Lineage / Workshop / OSDK 自动覆盖其动作。
### 常见问题速答 · FAQ
关于「监控(Monitoring)」,读者最常问的几个问题。
为什么要监控动作? 在 Foundry 中,动作(action)可以被监控,用来跟踪其性能与可靠性。当动作变慢或开始失败时,监控能帮你尽早发现、主动排查。
四步配置动作监控是什么? 点击揭晓:监控规则除了绑定单个动作,还能用什么"动态作用域"自动覆盖一批动作?
---
## 让文本、图片、表格都能被「算」进同一个空间
- 页面:https://www.hanzhongpin.xyz/ontology/multimodal-embeddings.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/aip-multimodal-and-embedding-models/
- 主题分组:多模态与嵌入 Multimodal & Embedding
循序渐进 · 教学 · 多模态与嵌入 Multimodal & Embedding
# 让文本、图片、表格都能被「算」进同一个空间
这一篇讲两类模型:多模态模型(能读懂图、表)和嵌入模型(把文本变成可计算的向量)。
学完你会知道什么时候该用现成模型、怎么为多语言或长文本调整策略。
## 一句话速览
让文本、图片、表格都能被「算」进同一个空间:这一篇讲两类模型:多模态模型(能读懂图、表)和嵌入模型(把文本变成可计算的向量)。学完你会知道什么时候该用现成模型、怎么为多语言或长文本调整策略。
1 这一篇在讲什么 做语义搜索或检索增强生成(RAG),光有「文本进、文本出」的大语言模型(LLM)往往不够
2 让 LLM 看懂图与表 原文开篇就点明了一个朴素的现实
3 把文本变成向量 嵌入模型(embedding model)的输出是一串数字——也就是向量(vector)
4 Ada 与查询 / 片段 原文把嵌入模型分成两类使用场景,这直接影响你该选哪种模型
## 这一篇在讲什么?
两类模型:多模态模型读懂图/表,嵌入模型把文本变成向量。
做语义搜索或检索增强生成(RAG),光有「文本进、文本出」的大语言模型(LLM)往往不够。
原文这页标题就叫 Process multimodal and embedding models(处理多模态与嵌入模型),
它把模型分成两条线来讲:
多模态模型 Multimodal 能直接吃图片、表格等非文本输入,弥补纯文本 LLM 的短板。
嵌入模型 Embedding 把文本编码成一串数字(向量),让「含义相近」的东西在向量空间里离得近。
这一篇偏「选型与原理」,具体的搭建步骤会在本系列后面的语义搜索、本体增强生成两篇里展开。
## 多模态模型:让 LLM 看懂图与表
文本进文本出的 LLM,对图表往往束手无策。
原文开篇就点明了一个朴素的现实:
If you want to answer questions based on diagrams, LLMs with the text-in-text-out architecture will be of no help.
如果你想基于图表来回答问题,那种「文本进、文本出」架构的 LLM 帮不上忙。
也就是说,当你要回答「这张表格里哪个值超标了」「这张图说明了什么」,纯文本 LLM 读不进去。
原文提到几种能处理图像输入的选项:
模型 / 方案 特点
GPT-4o / GPT-4o mini
都能接受图像输入,是官方闭源里能直接读图的现成选择。
Pix2Struct
开源模型;原文在德语表格的质量检查(QA)上初测表现不错,可在 Hugging Face 试用。
Microsoft UDOP
开源的「通用文档处理」模型,但未上架 Hugging Face。
>
一种常见组合:先用文本提取得到文字(方便先搜一轮),再在原始来源页面(图片)上跑多模态模型,
让它真正「看」图/表作答。这样检索和精读各取所长。
## 嵌入模型:把文本变成向量
含义相近的文本,在 N 维空间里离得近。
嵌入模型(embedding model)的输出是一串数字——也就是向量(vector)。
如果模型够好,在 N 维空间里彼此靠近的向量,就代表含义相近的文本;检索本质就是「找最近的向量」。
原文特别提到,如果你的语料是英文,可以试试 MSMARCO 系列模型(来自 sentence-transformers)。
MS MARCO 是一批基于真实 Bing 搜索查询构建的大规模信息检索数据集,而这些模型:
these models were specifically trained to put queries and relevant passages close together in embedding space.
这些模型经过了专门训练,让「查询」和「相关段落」在嵌入空间里彼此靠近。
这一点很关键:它意味着 MSMARCO 这类模型天生适合「从用户查询出发」的语义搜索——
你给一个关键词、一句话或一个问题,它就能找出相关的段落。
>
对照理解:这和上一页讲的概念一脉相承——向量越近 = 含义越近。多模态模型解决「怎么读图」,
嵌入模型解决「怎么把文本变成可比的距离」。
## 等长 vs 非对称:Ada 与查询 / 片段
从「查询」出发、还是从「已有片段」出发,选模型的逻辑不同。
原文把嵌入模型分成两类使用场景,这直接影响你该选哪种模型:
✗ 直接拿 Ada 嵌入「查询」
场景:用查询去比一堆 chunk 的嵌入
查询和段落是「不同类型」的文本
直接比 → 不是同一个概念
效果可能不如专门的模型
→
✓ 用「非对称」嵌入模型
场景:从用户查询出发的语义搜索
MSMARCO 类模型专为「查询↔段落」靠近而训
或先用 LLM 生成「假设片段」(HyDE) 再嵌入
桥接查询与答案之间的不对称
反过来讲,OpenAI Ada 更适合「从已有片段出发,找相似的片段」——
比如你手里已经有一个 chunk,想找和它语义相近的其他 chunk。
还有一个实操坑:原文提醒,大多数非 Ada 的嵌入模型只支持 512 个 token,所以你的分块(chunking)策略必须相应调整——块不能太长。
Most non-ada embedding models only support 512 tokens, so you need to adapt your chunking strategy accordingly.
大多数非 Ada 嵌入模型只支持 512 个 token,因此你需要相应地调整分块策略。
## 动手演示:不同模态进入同一嵌入空间
点一个模态,看它被编码后落在共享嵌入空间的哪个位置。
下面这个空间(横竖只是示意)里,三种不同模态的「内容」最终都被表示成同一个空间里的点。
点按钮看看每种模态靠什么模型被编码、又落在哪里——这正是「多模态 + 嵌入」能一起工作的原因。
动手试试 · 模态 → 嵌入空间
一段文本
一张图片
一张表格
重置
语义空间 →
语义空间 ↑
点上面的模态,看它被编码后落在共享嵌入空间的哪个位置。
说明:点的位置是教学示意(真实坐标由模型算出)。重点在于——无论文本、图片还是表格,最终都被映射进「同一个可比空间」,检索时才能量化「谁离谁更近」。
## 选型与踩坑:照着原文的建议来
语言、模型可得性、token 限制,都是选型变量。
原文最后给了几条非常落地的建议,我们整理成「照着做」的清单:
- 英文语料:优先试 MSMARCO 系列(sentence-transformers),专为查询-段落靠近而训。
- 从查询出发搜:用非对称嵌入模型,或先让 LLM 生成「假设片段」(HyDE)再嵌入,弥合查询与答案的不对称。
- 从已有片段出发找相似:Ada 更合适。
- 非 Ada 模型多限制 512 token:务必把分块切小,配合文档处理那一篇的 chunking 策略。
- 德语等小语种:原文提到,目前 GPT 是少数表现还行的 LLM,德语语料可尝试 ada。
>
一句话心法:先想清楚你的搜索是「从一句话出发」还是「从一段已有文本出发」,
再决定用哪种嵌入模型——这一步选对了,后面的语义搜索才站得住。
## 一页带走
① 多模态读图 文本 LLM 读不进图/表,需 GPT-4o、Pix2Struct、UDOP 等。
② 嵌入即向量 文本被编码成向量,近邻=近义,检索即找最近点。
③ 选对不对称 查询出发用非对称/HyDE;片段找相似用 Ada。
④ 注意 512 非 Ada 多限 512 token,分块要切小。
### 常见问题速答 · FAQ
关于「让文本、图片、表格都能被「算」进同一个空间」,读者最常问的几个问题。
这一篇在讲什么? 做语义搜索或检索增强生成(RAG),光有「文本进、文本出」的大语言模型(LLM)往往不够。原文这页标题就叫 Process multimodal and embedding models(处理多模态与嵌入模型),它把模型分成两条线来讲。
嵌入模型:把文本变成向量是什么? 嵌入模型(embedding model)的输出是一串数字——也就是向量(vector)。如果模型够好,在 N 维空间里彼此靠近的向量,就代表含义相近的文本;检索本质就是「找最近的向量」。
Ada 与查询 / 片段是什么? 原文把嵌入模型分成两类使用场景,这直接影响你该选哪种模型。
动手演示:不同模态进入同一嵌入空间是什么? 下面这个空间(横竖只是示意)里,三种不同模态的「内容」最终都被表示成同一个空间里的点。点按钮看看每种模态靠什么模型被编码、又落在哪里——这正是「多模态 + 嵌入」能一起工作的原因。
---
## 通知(Notifications)
- 页面:https://www.hanzhongpin.xyz/ontology/notifications.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/notifications/
- 主题分组:动作类型详解
动作类型详解
# 通知(Notifications)
通知让动作"喊人来看":当动作被应用,按你的配置给平台用户发提醒(平台内弹窗 + 邮件)。这一篇讲清它能发给谁、内容怎么配、有哪些硬性限制。
## 一句话速览
通知(Notifications):通知让动作"喊人来看":当动作被应用,按你的配置给平台用户发提醒(平台内弹窗 + 邮件)。这一篇讲清它能发给谁、内容怎么配、有哪些硬性限制。
1 通知(notification)是什么 通知是通过动作的 Add new rule 下拉菜单添加进去的
2 接收人(recipients)怎么定 Foundry 支持多种指定接收人的方式
3 内容(content)怎么配 内容有两种来源:Template(模板)直接在配置对话框里写;Function(函数)则需要一个已发布的、返回 Notificati…
4 数据权限与脱敏(redaction) 通知不是"谁都能看"
## 通知(notification)是什么
在动作里"加一条规则",让系统在动作运行时去提醒人。
通知是通过动作的 Add new rule 下拉菜单添加进去的。配置一条通知,需要指定两件事:接收人(recipients) 和 内容(content)。
Notifications will be sent to each recipient individually. Adding users as CC (carbon copy) recipients to email notifications is not supported.通知会分别发送给每位接收人。邮件通知不支持把用户添加为抄送(CC)接收人。
也就是说:每条通知是"一对一"地送达每个人的,没有抄送这一概念。用户还能在自己的偏好里决定如何接收——有人只在浏览器里看,有人既收平台弹窗也收邮件。如果某人整体关闭了动作通知,他就收不到,但仍可在 Workspace 的"Notifications → See All"里事后查看。
## 接收人(recipients)怎么定
四种指定方式,从"写死"到"用函数算"。点一下,把描述归到正确的方式上。
Foundry 支持多种指定接收人的方式。下面每一行是一个场景,请点击右侧最匹配的方式:
> 提醒:如果接收人来自对象属性,该属性必须存的是 Foundry 用户/组 ID 字符串;存成普通邮箱地址是发不出去的。直接填邮箱地址发送也不被支持。
## 内容(content)怎么配
模板(Template)直接配,或函数(Function)返回完整通知对象。
内容有两种来源:Template(模板) 直接在配置对话框里写;Function(函数) 则需要一个已发布的、返回 Notification 对象的函数。
模板可配置的组成部分
- Subject(主题):默认对所有送达方式一致;
- Body(正文):平台内显示在弹窗里,邮件里渲染在邮件正文中;
- Link(链接):正文下方一个按钮,文字可自定义,可指向对象参数、Workshop 应用、Carbon workspace、或新建的对象;
- Advanced Email Configuration(高级邮件配置):用 HTML 做更丰富的排版(仅邮件生效)。
在主题、正文、链接里,可以用 三重花括号 {{{ }}} 引用参数和用户属性——编辑时点一下可用参数,就会自动生成正确的 handlebar 引用。需要"按接收人/参数完全不同内容""邮件与平台用不同主题""用外部系统完整 URL""做 Search Around / 聚合"等场景时,才需要改用函数。
点击揭晓:什么情况下必须改用"函数"来生成通知内容?
## 硬性限制与注意
长度、人数都有上限,超出会被截断或报错。
限制项 上限 超出会怎样
接收人(模板方式) 500 人/次 正常上限
接收人(函数方式) 50 人/次 超限会显示红色错误并导致动作运行失败
主题(Subject) 250 字符 被截断并加 ...
正文(Body) 1,000 字符 被截断并加 ...
邮件自定义 HTML 51,200 字符 被截断并加 ...
注意:这些长度是"渲染后"校验的。如果内容里嵌了对象数据(动态长度),超出部分会被截断并在末尾补 ...。
## 数据权限与脱敏(redaction)
用户只能收到自己有权查看的数据;脱敏会影响自定义内容。
通知不是"谁都能看":
- 用户只能收到包含其有权查看数据的通知;多人接收时,所有接收人都必须能访问内容里渲染的对象数据;
- 在动作侧栏的 Security & Submission Criteria 标签页底部,有两种失败处理:Require all users to have permissions(默认)——任一接收人无权则整体报错、不改动也不发通知;Require any user to have permissions——只要有一人能看就成功,只有有权者收到;
- 若实例开启了 Strict / Group Redaction(严格/分组脱敏),自定义通知内容不会被渲染,用户只会收到一句通用提示,点"View"进 Foundry 看全文。
新建对象链接:链接新建对象时,必须引用其主键——因为渲染通知时对象 RID 还没生成。用 Object Explorer 提供的参数选项即可生成正确链接。
## 一页带走
① 通知 = 喊人看 通过 Add new rule 添加,分别送达每位接收人,无抄送概念。
② 接收人四法 固定 / 来自参数 / 来自对象属性 / 来自函数,从写死到动态算。
③ 内容两源 模板直接写({{{}}} 引用参数)或函数返回 Notification 对象。
④ 上限与权限 主题250/正文1000/邮件HTML 51200 字符;按权限与脱敏规则送达。
### 常见问题速答 · FAQ
关于「通知(Notifications)」,读者最常问的几个问题。
通知(notification)是什么? 通知是通过动作的 Add new rule 下拉菜单添加进去的。配置一条通知,需要指定两件事:接收人(recipients)和 内容(content)。
接收人(recipients)怎么定? Foundry 支持多种指定接收人的方式。下面每一行是一个场景,请点击右侧最匹配的方式。
内容(content)怎么配? 内容有两种来源:Template(模板)直接在配置对话框里写;Function(函数)则需要一个已发布的、返回 Notification 对象的函数。
---
## 对象类型(Object Type)入门
- 页面:https://www.hanzhongpin.xyz/ontology/object-types.html
- 官方原文:https://www.palantir.com/docs/foundry/object-link-types/object-types-overview/
- 主题分组:对象类型
循序渐进 · 教学 · 对象类型
# 对象类型(Object Type)入门
本体(Ontology)里最核心的一个词就是"对象类型"。这一篇用最生活化的例子,带你看懂它是什么、和数据集有什么关系,以及怎样把一堆数据行整理成清晰的对象类型。
## 一句话速览
对象类型(Object Type)入门:本体(Ontology)里最核心的一个词就是"对象类型"。这一篇用最生活化的例子,带你看懂它是什么、和数据集有什么关系,以及怎样把一堆数据行整理成清晰的对象类型。
1 对象类型就是现实事物的"模板" 在 Palantir Foundry 的本体里,对象类型(object type)是一个"真实世界实体或事件"的结构定义
2 三层类比 本体里的概念,和数据集的结构几乎一一对应
3 员工(Employee)与航班(Flight) 官方文档给了两个最经典的例子,我们用它们贯穿全篇
4 一个对象类型由哪些部件构成 一个可用的对象类型,通常包含以下部件
## 一句话说清:对象类型就是现实事物的"模板"
先记住一个定义,后面所有例子都围绕它展开。
在 Palantir Foundry 的本体里,对象类型(object type)是一个"真实世界实体或事件"的结构定义。它规定了"这一类东西"长什么样、有哪些特征,但不关心具体是哪一个。
An object type is the schema definition of a real-world entity or event.对象类型,是对一个真实世界实体或事件的结构(schema)定义。
打个比方:Employee(员工)这个对象类型,定义了"所有员工"长什么样;而"Melissa Chang""Akriti Patel"这些人,就是 Employee 的对象实例(object / object instance)——也就是这个模板下具体的某一个。
> 提示:"对象类型"谈的是规则(schema),"对象实例"谈的是具体的一条数据。两者不要混淆,这是后面所有概念的地基。
## 它和数据集是同一套思维:三层类比
如果你熟悉表格(数据集),本体只是换了个名字。
本体里的概念,和数据集的结构几乎一一对应。理解这张表,你就理解了一半的本体:
本体概念 数据集里的对应物 一句话解释
对象类型 object type 整张表的 schema(结构) "所有员工"这一类事物的定义
对象 object 表中的一行 row 某一个具体员工,如 Melissa Chang
对象集 object set 筛选后的一组行 "所有资深员工"这样的一批对象
点开下面三层,看看它们各自的角色:
层 1对象类型 Object Type
定义"这一类事物"的规则
例如 Employee 对象类型,规定了员工要有工号、入职日期、岗位等特征。它对应的是整张员工表的 schema,本身不包含任何具体的人。
层 2对象 Object
模板下的一个具体实例
例如对象 "Melissa Chang",工号 11502、2016-10-09 入职、岗位 software engineer。它对应的是表中的一行。
层 3对象集 Object Set
一批对象组成的集合
例如"所有资深员工""所有已到达的航班"。它对应的是按条件筛选后的一组行,可以再拿去做统计、展示或下钻。
> 关键点:对象集不是新类型,它只是"满足某些条件的对象们",常用于看板、筛选和下钻分析。
## 真实例子:员工(Employee)与航班(Flight)
同一个套路,套到不同业务上长什么样。
官方文档给了两个最经典的例子,我们用它们贯穿全篇:
Employee 对象类型 代表"公司里的每一位员工"。实例如 Melissa Chang、Akriti Patel、Diego Rodriguez。常见属性:员工工号、入职日期、岗位。
Flight 对象类型 代表"每一次航班"。实例如 JFK→SFO 2021-02-24、TLV→LHR 2020-04-16。常见属性:起飞日期、到达日期、乘客数。
### 动手练:把这些数据片段,归到正确的对象类型
左边是一些零散的数据片段,右边是两个候选对象类型。点击左边的片段,看它该归到哪一类——也想清楚:它是"类型"还是"实例"还是"属性值"?
这些数据片段
员工工号 11502 来自员工目录的一行
航班 JFK→SFO 2021-02-24 一趟具体的飞行
员工 Melissa Chang 一个具体的人
航班乘客数 150 航班的某个特征
员工入职日 2016-10-09 员工的一个字段
航班 TLV→LHR 2020-04-16 一趟具体的飞行
→
属于哪个对象类型?
Employee 所有"员工"这种实体
主键:员工工号
Flight 所有"航班"这种实体
主键:航班编号
点击左边任意数据片段,看它该归到哪个对象类型。
> 想一想:"员工工号"和"员工 Melissa Chang"不一样——前者是属性,后者是对象。把"属性值"误当成"对象类型"是初学者最常犯的错。
## 一个对象类型由哪些部件构成
在 Ontology Manager 里新建对象类型时,你其实在填这几样东西。
一个可用的对象类型,通常包含以下部件:
- 主键(primary key):唯一标识每个对象的字段,例如员工工号。没有它,系统分不清"哪个是哪个"。
- 标题(title):在界面上给人看的那行字,例如员工姓名、航班号。可以是一到多个属性拼成。
- 属性(properties):描述这个实体的各项特征,如入职日期、岗位、乘客数。
- 图标与颜色:纯展示用,帮助用户在应用里一眼认出这类对象。
- 背后数据源 / 创建方式:对象从哪来?靠数据集接入,还是靠动作(action)创建。
Objects are created and displayed in user applications by adding backing datasources or configuring actions that create objects of an object type in Ontology Manager.对象通过"添加背后数据源"或"配置能创建该类型对象的动作"来生成并展示。
> 记住:主键负责"认人",标题负责"好认",属性负责"说清楚",数据源负责"有数据"。
## 它怎么接上真实数据:backing datasource
本体不是空想的数据模型,它必须映射到你公司的真实数据。
Foundry 的本体之所以有用,是因为它把每个本体概念映射到了组织真实的数据库,从而能驱动真实应用。具体到对象类型,有两条路让对象"活"起来:
常见做法
接背后数据源(backing datasource)
把员工目录、企业系统等数据集连到 Employee 对象类型,已有数据自动变成对象。
⇄
另一种做法
靠动作(action)创建
如果每个对象都通过用户在应用里新建(如录入一张工单),可以创建不带背后数据源的对象类型,由 action 负责生成对象。
> 提示:两者并非二选一。很多对象类型既接数据源做初始批量导入,又允许后续用 action 增改。
## 怎样挑一个好的对象类型:粒度与取舍
不是什么都该建模成对象类型,选对"颗粒度"最重要。
建模时最容易走偏。下面几条经验帮你判断"这个东西该不该是一个对象类型":
- 它得是真实存在的实体或事件。员工、航班、订单、设备——这些是对象类型的好候选。
- 颗粒度要对。把"一次航班"建为对象,比把"航班表"建为对象更合理;对象应对应能被单独指代、单独操作的那一层。
- 它要有稳定的主键。能被唯一辨认,才值得成为对象类型。
- 别把"属性"或"计算结果"当成对象类型。"员工姓名"是属性,"本月销售额"通常是派生值,不应单独成类型。
反例:把"一个 Excel 工作表""一个字段"直接建为对象类型,往往会导致本体混乱、难以复用。先想业务实体,再想技术存储。
## 一页带走
① 对象类型是模板 它定义"这类事物"的结构,对应数据集的 schema,本身不含具体数据。
② 三层对应 类型↔表结构、对象↔一行、对象集↔筛选后的一组行。
③ 必备部件 主键认人、标题好认、属性说清、数据源提供真实数据。
④ 颗粒度要对 建模真实实体/事件,别把属性或计算结果误当成对象类型。
### 常见问题速答 · FAQ
关于「对象类型(Object Type)入门」,读者最常问的几个问题。
对象类型就是现实事物的"模板"是什么? 在 Palantir Foundry 的本体里,对象类型(object type)是一个"真实世界实体或事件"的结构定义。它规定了"这一类东西"长什么样、有哪些特征,但不关心具体是哪一个。
它和数据集是同一套思维:三层类比是什么? 本体里的概念,和数据集的结构几乎一一对应。理解这张表,你就理解了一半的本体。
怎样挑一个好的对象类型:粒度与取舍是什么? 建模时最容易走偏。下面几条经验帮你判断"这个东西该不该是一个对象类型"。
---
## Ontologies 资源管理(Ontologies overview)
- 页面:https://www.hanzhongpin.xyz/ontology/ontologies-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/ontologies/ontologies-overview/
- 主题分组:资源管理篇
循序渐进 · 教学 · 资源管理篇
# Ontologies 资源管理(Ontologies overview)
前一篇认识了本体的"零件",这一篇认识装这些零件的"容器"——Ontology 本身。
它是私有还是共享?和 space 是什么关系?什么时候该开第二个?一篇讲清。
## 一句话速览
Ontologies 资源管理(Ontologies overview):前一篇认识了本体的"零件",这一篇认识装这些零件的"容器"——Ontology 本身。它是私有还是共享?和 space 是什么关系?什么时候该开第二个?一篇讲清。
1 一个 Ontology = 一个"本体资源容器" 原文定义:Ontology 是一个工件(artifact),用来存放本体的资源或实体,也就是我们前面讲的那几类—— 对象类型、链接类…
2 一生二、二合一 本体和 space(空间)是 1:1 映射的
3 以 Sky Industries 为例 Sky Industries 给自家客服团队做了一个"航班提醒收件箱"应用,用到 Flight、Flight Alert、Delay…
4 Sky × Sunrise 跨组织 Sunrise Airline 想减少由维护问题导致的航班延误,于是同意把自家的维护数据和 Sky 的航班延误数据合并分析
## 一个 Ontology = 一个"本体资源容器"
对象类型、链接类型、动作类型,都装在它里面。
原文定义:Ontology 是一个工件(artifact),用来存放本体的资源或实体,也就是我们前面讲的那几类——
对象类型、链接类型、动作类型等。我们统称它们为 Ontology resources(本体资源)。
一个本体可以是私有的(private),只属于单个组织(organization);也可以是共享的(shared),在多个组织之间共享。
把实体归到本体里,是为了保证只有指定组织的用户才能访问这些本体实体。
>
类比:如果对象类型像"文件",那 Ontology 就像"文件夹"——而且这个文件夹自带访问边界(组织边界)。
组织(organization)对不同用户和资源做了严格隔离,多数公司其实只有一个组织。
## 本体与 space:一生二、二合一
每建一个 space,就自动生成一个同名、同标记的 ontology。
本体和 space(空间)是 1:1 映射的。当你新建一个 space 时,
平台会同时创建一个同名的本体,并带上与该 space 相同的组织标记(markings)。
- 私有 space → 映射出私有本体;
- 共享 space → 映射出共享本体。
When a new space is created, a corresponding ontology with the same name is simultaneously created with the same organization markings as the space.
新建 space 时,会同时创建一个同名、且带有相同组织标记的本体。
所以"建本体"通常不是你手动点出来的,而是建 space 时自动生成的——你后续往里"装"对象类型等资源。
## 私有 vs 共享:一张决策表
选哪种,取决于"有几个组织要碰同一批对象"。
私有本体 Private ontology 共享本体 Shared ontology
选它当… 需要对象的人都在一个组织内 两个及以上组织需要同一批对象
应用的组织数 1 个 2 个及以上
谁能获得授权 该组织的成员与访客成员 任一应用组织的成员与访客成员
随什么一起创建 私有 space 共享 space
## 何时用私有本体:以 Sky Industries 为例
大多数工作流,一个私有本体就够了。
Sky Industries 给自家客服团队做了一个"航班提醒收件箱"应用,用到 Flight、Flight Alert、Delay、Aircraft
这些对象类型,以及把它们连起来的链接类型、用户执行的动作类型。这些只描述 Sky 自己的运营,只有 Sky 员工才该看到。
于是 Sky 在自己的私有 space里搭这套工作流,映射出来的私有本体就把这些资源全部限制在了 Sky 组织内。
>
重要提醒:几个团队共用同一个私有本体是完全正常的——用应用的人、搭应用的人、维护数据管道的人都在里面。
"要和其他团队协作"并不是另开一个本体的理由。想控制哪些团队能碰哪些资源,就在持有这些资源的项目上,给对应的组(group)授予角色(role)即可。
## 何时用共享本体:Sky × Sunrise 跨组织
当两家公司必须操作"同一批对象"时,私有就不够了。
Sunrise Airline 想减少由维护问题导致的航班延误,于是同意把自家的维护数据和 Sky 的航班延误数据合并分析。
两家公司需要同一套对象类型,横跨两边:来自 Sunrise 的维护问题,连到来自 Sky 数据的 Aircraft 和 Delay 对象;
两边分析师都要能打开这些对象、执行同样的动作类型。
私有本体做不到这件事——它被限制在单一组织,另一家公司的用户无法被授权访问其资源。
解决办法:管理员创建一个共享 space,同时应用 Sky 和 Sunrise 两个组织;随之生成的共享本体就带上双方的标记,
两边分析师都能被授权访问这批共有的对象/链接/动作类型。两家公司各自仍保留私有 space 与私有本体,装不共享的数据。
A private ontology cannot support this: it is restricted to a single organization, so users at the other company cannot be granted access to its resources.
私有本体不支持这种场景:它被限制在单一组织,另一家公司的用户无法被授权访问其资源。
## 别踩坑:共享本体≠自动暴露底层数据
标记(markings)的继承,需要开发者主动解除。
原文特别强调一个容易误解的点:创建共享本体,并不会自动让底层数据对每一个应用组织都可见。
如果一个数据集是从某个私有项目引用进共享项目的,它仍然保留来源组织的访问要求——
另一组织的用户在被放开前,依然看不到那份数据。
点我看"共享本体到底开放了什么" →
↑ 点击展开。换句话说:"共享"开放的是"对象定义能被多组织授权",而不是"数据自动人人可见"。
## 一页带走
① Ontology = 容器 装对象类型/链接类型/动作类型等资源,可私有或共享。
② 与 space 1:1 建 space 自动生成同名、同标记的本体。
③ 私有 vs 共享 看"几个组织要碰同一批对象":一个→私有,多个→共享。
④ 共享≠暴露数据 数据可见性仍由各自身标记决定,需主动解除继承。
### 常见问题速答 · FAQ
关于「Ontologies 资源管理(Ontologies overview)」,读者最常问的几个问题。
本体与 space:一生二、二合一是什么? 本体和 space(空间)是 1:1 映射的。当你新建一个 space 时,平台会同时创建一个同名的本体,并带上与该 space 相同的组织标记(markings)。
Sky × Sunrise 跨组织是什么? Sunrise Airline 想减少由维护问题导致的航班延误,于是同意把自家的维护数据和 Sky 的航班延误数据合并分析。两家公司需要同一套对象类型,横跨两边:来自 Sunrise 的维护问题,连到来自 Sky 数据的 Aircraft 和 Delay 对象…
别踩坑:共享本体≠自动暴露底层数据是什么? 原文特别强调一个容易误解的点:创建共享本体,并不会自动让底层数据对每一个应用组织都可见。如果一个数据集是从某个私有项目引用进共享项目的,它仍然保留来源组织的访问要求—— 另一组织的用户在被放开前,依然看不到那份数据。
---
## 本体设计最佳实践
- 页面:https://www.hanzhongpin.xyz/ontology/ontology-best-practices-tutorial.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/ontology-best-practices/
- 主题分组:教学
循序渐进 · 教学
# 本体设计最佳实践
这篇文章讲的是:如何把一个组织"建模"成一套人人(和 AI)都能看懂的数字结构。
下面用 10 个小步骤,把它拆开讲给完全没有基础的人听。
## 一句话速览
本体设计最佳实践:这篇文章讲的是:如何把一个组织"建模"成一套人人(和 AI)都能看懂的数字结构。下面用 10 个小步骤,把它拆开讲给完全没有基础的人听。
1 本体(Ontology)到底是什么 假设一家医院有挂号系统、检验系统、设备系统、财务系统
2 一张 CSV 引发的思考 数据团队拿到一张订单 CSV,很自然地想:建一个叫 OrderData 的对象类型,一列对一个属性,完事
## 先搞清楚:本体(Ontology)到底是什么?
一句话:本体是你所在组织的"语义层",不是又一个数据库。
假设一家医院有挂号系统、检验系统、设备系统、财务系统。每个系统都有自己的表、自己的字段名、自己的主键。
人和人之间要沟通,得先做一轮"翻译":dtLastInspMod 到底是啥?pat_id 和 patient_no 是不是同一个东西?
本体(Ontology)就是在这些系统之上再建一层:不去描述"数据在哪个表里",而是描述
"现实世界里有什么东西、它们之间是什么关系"。
>
打个比方:数据库是"仓库里的货架清单",本体是"这座城市的一张地图"。
地图不会告诉你数据存在哪个货架,但它会告诉你:这里有一家医院、一条路、一辆救护车,以及它们怎么连在一起。
The Ontology models the real world, not the source data.
本体建模的是现实世界,而不是源数据。
一个好的本体读起来应该是"顺"的——业务人员不用培训就能看懂,AI 智能体也能顺着它自己找答案。
判断标准很简单:如果看这张图的人需要反复问"这列是什么意思",那建模就失败了。
## 本体由五块积木拼成
先把名词认全,后面的原则才好理解。
Object type 对象类型
现实世界中的一类事物,不是一张表。比如 Patient(患者)、WorkOrder(工单)、Vessel(船舶)。
Property 属性
对象的特征。比如患者的姓名、出生日期。每个属性都应该讲得出用途,不是源表有什么就搬什么。
Link 链接
对象之间真实存在的关系:"这位患者去过这家医院"。注意:链接不是外键,外键是技术产物,链接是业务语义。
Action type 动作类型
人类或 AI 智能体做出的决策。比如"批准工单"。决策用 action,纯自动化的数据变换用 pipeline,别混用。
Interface 接口
一组"能力 / 角色"的抽象,可以被多个对象类型实现。比如 Inspectable(可被检查的)、Schedulable(可被预约的)。
接口是本体里避免造出一堆奇怪中间类型的关键工具——第 8 步会展开讲。
## 从一个反面例子讲起:一张 CSV 引发的思考
新手最常犯的错:把一张表原样搬成一个对象。
数据团队拿到一张订单 CSV,很自然地想:建一个叫 OrderData 的对象类型,一列对一个属性,完事。
这就是原文点名的反模式 「Kitchen Sink」(什么都往里塞)。
下面这张表其实描述了 3 个现实实体。请你试试:点击「归属」列的按钮,把它分到正确的实体里。
CSV 列名 示例值 归属
order_id A-10023
订单 客户 产品
customer_name 张三
订单 客户 产品
customer_email zhang@x.com
订单 客户 产品
product_sku SKU-8812
订单 客户 产品
quantity 3
订单 客户 产品
✗ 反模式:照抄表结构
OrderData
- order_id
- customer_name
- customer_email
- product_sku
- quantity
一个类型照抄一张 CSV
→
✓ 推荐:建模领域
Order
- order_id
- quantity
- 链接 → Customer、Product
Customer
- name
- email
Product
- sku
三个类型,建模真实领域
### 为什么差别这么大?
问题 后果
模型不直观 人和 AI 都无法自然地在其中导航,因为结构和他们对业务的认知对不上。
与源头硬耦合 源系统改一个字段,所有下游应用一起崩——因为本体在"镜像"源结构,而没有做抽象。
关系丢失 被塞进列里的实体(比如订单上的 customer_name)无法被单独链接、搜索和推理。
难以复用 被某一个系统形状塑造出来的对象类型,别的团队很难拿去用。
>
新手可执行的三步:
① 先别看数据,和业务专家一起列出"现实世界里有哪些东西";
② 再设计对象模型;
③ 最后才把源数据映射进去。
顺序反了(先看数据再定模型)几乎是必错。
## 八条速查清单(先混个眼熟)
这是原文的实用检查表,后面四条核心原则会逐一解释其中几条。
1 · 建模现实,而非系统 对象类型代表真实实体,而不是某个源系统或某个部门的一种表达方式。
2 · 有意策划 每个属性都要有清晰的业务或技术价值,没有就别放。
3 · 跨团队协作 设计要有多个团队的利益相关者参与。孤岛团队是重复造轮子的主要来源。
4 · 保持对象类型专注 一个对象类型只代表一个独立实体。
5 · 选对工具 人或智能体的决策用 action types;自动化数据变换用 pipelines。
6 · 用接口做抽象 实体共享特征时用接口,别去造一个又宽又稀疏的对象类型。
7 · 记录你的决策 在 Ontology Manager 里为对象类型、属性、链接写清楚说明。
8 · 对照真实业务问题验证 跑一遍基于任务的分析演练,确认人和智能体能真的用它支撑决策。
## 四条核心原则
按优先级排序,冲突时高优先级胜出。
优先级 原则 一句话
1 Domain-driven design 领域驱动设计 建模现实世界,而不是源数据。
2 Do not repeat yourself 不要重复自己 同样的东西造了三次,就该重构了。
3 Open for extension, closed for modification 开闭原则 保护核心模型,让其他人能扩展它。
4 Composition over deep hierarchies 组合优于深层继承 用接口做多重继承,保持可插拔。
1
### 领域驱动设计
Domain-driven design · Model the real world, not the source data.
要避开什么
- 对象类型在镜像源系统的数据表,而不是领域实体
- 属性从源列 1:1 照搬,没有任何筛选
- 命名沿用源系统习惯(dtLastInspMod),而不是业务语言(lastInspectionDate)
- 模型是"看着数据"设计出来的,而不是"理解了业务"设计出来的
- 一行源数据里其实包含多个实体,却被建模成单个对象类型
该怎么做
- 先看领域,再看表结构和业务方一起定义"哪些概念重要"。一个数据集往往描述多个实体。
- 区分「身份」与「观测」如果一行数据表示对某实体的一次测量或事件,那实体和观测很可能是两个不同的对象类型。
- 为人命名API 名要直观、自解释。用 person.children 而不是 person.linkedChildPersonObjects。
- 先建模,再映射数据理解领域 → 设计对象模型 → 把源数据映射进去。不要反过来。
- 非语义类型标记为 hidden纯技术用途的类型设为隐藏,保持默认视图干净,构建应用时仍可用。
2
### 不要重复自己(三法则)
Do not repeat yourself · If you built the same thing three times, refactor.
重复的对象类型、冗余的属性、复制粘贴的工作流,不仅是维护负担,更是上下文管理灾难——
无论是人还是 AI 智能体,面对三个长得几乎一样的 Customer,都无法判断哪个才是"正主"。
一次是巧合,两次是信号,三次就该重构了。
✗ 三个团队各造一个
Sales Customer
- name / email / phone
Support Customer
- name / email / phone
Billing Customer
- name / email / phone
三套类型 + 三套动作
= 三份维护负担
→
✓ 收敛成一个规范类型
Customer(唯一规范类型)
- name / email / phone
- salesStatus
- supportTier
- billingAccountId
— 或者,若形态确实不同 —
Interface: CustomerBase
由 SalesLead、SupportContact、
BillingAccount 实现
要避开什么
- 多个对象类型拥有相同的属性和相似的链接
- 同一段派生属性逻辑或动作逻辑散落在多个类型里
- 不同团队为略有差异的用途造出近乎相同的对象类型
- 存在只有细微差别、靠复制粘贴产生的工作流
该怎么做
- 做一次重复审计如果多个类型共享同一形态,评估:合并成一个类型 + 一个区分属性,还是共同实现一个接口。
- 收敛共享逻辑同一段派生属性或动作逻辑若能复用,抽成接口或共享函数。
- 统一团队私有副本合并为单一规范表示,用权限或过滤来满足各自诉求。
- 套用三法则一处重复可接受,两处是警告,三处就该动手重构。
3
### 对扩展开放,对修改关闭
Open for extension, closed for modification · Protect core models. Enable builders to extend them.
一个对象类型一旦上线、经过实战检验,它的核心结构就应该稳定下来。
别的团队要加新能力,应该是"在旁边加",而不是"进到里面改"。
✗ 直接改核心类型
Equipment
- serialNumber
- manufacturer
- certificationAuthority(新)
- certificationExpiry(新)
- certificationStatus(新)
- lastCertAudit(新)
四个新属性对大多数设备都是空的
现有消费者被迫跟着改
→
✓ 扩展而不修改
Equipment(原封不动)
- serialNumber
- manufacturer
- 链接 → Equipment Certification
Equipment Certification
- certificationAuthority
- certificationExpiry
- certificationStatus
Interface: Certifiable
核心类型不动,能力靠链接 + 接口加
要避开什么
- 频繁对已确立的对象类型做破坏性改动,波及所有下游应用
- 新需求靠改核心类型来满足,而不是扩展它
- 团队为了满足自己的特殊需求去编辑共享接口或动作
- 为某一团队做扩展时,安全边界意外扩大,影响到其他使用者
该怎么做
- 识别什么是本质确定哪些属性和链接真正属于这个实体的根本,把它们锁定。
- 为扩展而设计建核心类型时就预留空间:可链接的扩展类型、新的接口实现。
- 优先扩展而非修改新增内容先问一句:它该待在核心类型上,还是该放在扩展里(新链接类型 / 新接口实现 / 新属性命名空间)?
- 守住安全边界核心模型要有清晰的权限边界,确保扩展本体不会顺带扩大数据访问范围。
4
### 组合优于深层层次结构
Composition over deep hierarchies · Favor multiple inheritance via interfaces. Keep things pluggable.
Foundry 的本体支持通过接口实现多重继承。所以一个实体可以从多个"小而专"的抽象里各取所需,
而不必被塞进一条单一继承的链条里。
✗ 深层单继承
Asset
└── PhysicalAsset
└── Building
└── SchedulableBuilding
└── Arena
每出现一种新的能力组合
就要造一个新的中间类型。
再来个"可预约仓库"又要开新分支。
→
✓ 接口组合
Interface: Building
- address
- squareFootage
Interface: SchedulableResource
- schedulingCalendar
- bookingPolicy
Arena 同时实现两个接口
- arenaName / seatingCapacity
加"可预约仓库"只需再实现
同样两个接口,不动层次结构
要避开什么
- 深长的单继承链,子类型存在的唯一目的就是拼凑父类能力
- 出现 SchedulableBuilding、InspectableVehicle 这类把两个无关概念硬揉在一起的"组合类型"
- 工作流和具体对象类型紧耦合,明明可以面向共享接口来写
- 给实体加一种新能力,就得重构整条继承链
该怎么做
- 围绕"能力 / 角色"设计接口小而专: Inspectable、Schedulable、Billable、Depreciable。
- 用分类型接口做聚合比如 MilitaryAsset 由 Aircraft、Vessel、GroundVehicle 实现,特别适合下钻式调查。
- 工作流面向接口编程建在 SchedulableResource 上的工作流,对体育馆、会议室、车辆全都适用,无需改动。
- 能组合就别继承实体需要多种能力时,实现多个接口,而不是往继承链深处插一层。
## 务实与权衡:这些是指南,不是法律
现实里有 deadline、有遗留系统、有平台能力限制——理想设计往往不能一步到位。
别做路障 如果时间很紧必须上线,就先做一个合理的版本,并留出明确的改进路径。
把代价说出口 推荐走捷径时,讲清楚放弃了什么、什么时候会出问题。比如:现在这个规模下反范式没问题,但超过 1 万个对象就该回来重看。
小步快跑,别大爆炸重构 一个"略有瑕疵但已经在用、已经在产生价值"的本体,胜过"理论上完美但还在设计中"的本体。
守住关键不变量 命名质量、语义清晰度、安全设计——这三样事后极难补救。可以在实现细节上偷工,别在这三样上偷工。
The Ontology is the software that powers your organization.
本体是驱动整个组织运转的软件。像对待生产代码库一样对待它,但把业务价值排在完美之上。
## 一页带走
如果只记四句话:
① 建模现实 先看业务,再看数据;命名说人话。
② 不要重复 第三次出现同样的东西,就重构。
③ 只加不改 核心模型锁住,新能力靠扩展。
④ 组合优先 多重能力用接口拼,别堆继承树。
最后别忘了验证:拿真实的业务问题去跑一遍,看人和 AI 智能体能不能顺着本体找到答案。
能找到,设计才算成立。
### 常见问题速答 · FAQ
关于「本体设计最佳实践」,读者最常问的几个问题。
本体(Ontology)到底是什么? 假设一家医院有挂号系统、检验系统、设备系统、财务系统。每个系统都有自己的表、自己的字段名、自己的主键。人和人之间要沟通,得先做一轮"翻译":dtLastInspMod 到底是啥?pat_id 和 patient_no 是不是同一个东西?
一张 CSV 引发的思考是什么? 数据团队拿到一张订单 CSV,很自然地想:建一个叫 OrderData 的对象类型,一列对一个属性,完事。这就是原文点名的反模式 「Kitchen Sink」(什么都往里塞)。
---
## Ontology Manager:搭建与维护本体的工作台
- 页面:https://www.hanzhongpin.xyz/ontology/ontology-manager.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology-manager/overview/
- 主题分组:本体零件(十二)
循序渐进 · 教学 · 本体零件(十二)
# Ontology Manager:搭建与维护本体的工作台
前面学的对象类型、属性、链接、接口、动作、函数,都在哪里被创建和管理?答案是
Ontology Manager(OMA)。这一篇带你走一遍它的界面与一次完整的变更流程。
## 一句话速览
Ontology Manager:搭建与维护本体的工作台:前面学的对象类型、属性、链接、接口、动作、函数,都在哪里被创建和管理?答案是 Ontology Manager(OMA)。这一篇带你走一遍它的界面与一次完整的变更流程。
1 OMA 是"本体的工作台" Ontology Manager(有时也叫 Ontology Management Application,简称 OMA)是用来搭建…
2 进入 Ontology Manager 原文给出三种打开方式
3 导航 + 视图 Ontology Manager 的界面由两类常驻元素 + 一组视图构成
4 点进资源后,能看到什么 选中某个资源,OMA 会打开对应的视图
## 一句话:OMA 是"本体的工作台"
Ontology Manager enables you to build and maintain your organization's Ontology.
Ontology Manager(有时也叫 Ontology Management Application,简称 OMA)
是用来搭建与维护组织本体的应用。它能做的事覆盖面很广:
- 创建新的对象类型(object type)、定义新的动作类型(action type);
- 把数据连接到本体;
- 排查"数据有没有在用户应用里更新"之类的问题。
You can use Ontology Manager for a wide range of activities related to your Ontology, from creating a new object type and defining a new action type, to connecting data to the Ontology, and investigating whether data is updating in user applications.
从创建对象类型、定义动作类型,到连接数据、排查数据是否在用户应用中更新——OMA 都能做。
>
把它想成"工厂":前几篇讲的是本体的"零件"(对象、属性、接口、动作、函数);
OMA 是生产和管理这些零件的车间。
## 如何进入 Ontology Manager?
三种进入方式,挑顺手的。
原文给出三种打开方式:
侧边栏 Apps
在 Workspace 侧边栏的 Apps 区,点 Ontology Manager 图标。
右键对象类型
在 Data Lineage(数据血缘)里右键某个对象类型,选 Configure object type。
改 URL
在 Foundry 主页 URL 末尾加上 /workspace/ontology 直接访问。
## 界面骨架:导航 + 视图
顶栏、侧边栏,再加上一组"视图"。
Ontology Manager 的界面由两类常驻元素 + 一组视图构成:
顶栏(top bar)
三大功能:搜索本体资源、新建本体资源、在分支之间切换或新建分支(navigate / create branches)。
侧边栏(sidebar)
在 OMA 内部的各种资源、页面、应用之间快速跳转。
文档里会反复提到的"视图"包括:
七种视图
Discover(发现页) ·
Object type view(对象类型视图) ·
Property editor view(属性编辑器) ·
Link type view(链接类型视图) ·
Action type view(动作类型视图) ·
Function type view(函数类型视图) ·
以及贯穿它们的 Ontology Manager 导航。
>
记两个"常驻件":顶栏(搜索 / 新建 / 分支)和侧边栏(内部导航)永远在;
其余视图是点进不同资源后展开的工作区。
## 点进资源后,能看到什么?
每个本体零件都有专属视图与管理页面。
选中某个资源,OMA 会打开对应的视图。重点记这几个:
视图 打开方式 / 包含页面
Object type view 对象类型视图 选中对象类型。其 Overview 页含 7 块:① 元数据 ② 属性 ③ 动作类型 ④ 链接类型图 ⑤ 依赖方 ⑥ 数据 ⑦ 使用量。
Property editor view 属性编辑器 在对象类型 Overview 的 Properties 区里点某个属性即可打开。
Link type view 链接类型视图 在对象类型 Overview 的链接类型图里点链接类型打开,含 Overview 与 Datasources 页。
Action type view 动作类型视图 在对象类型的动作类型区点开,含 Overview / Logic / Observability 页。
Function type view 函数类型视图 在对象类型的函数区点开,含 Overview / Configuration / Observability 页。
>
对象类型的 Overview 七件套:元数据、属性、动作类型、链接类型图、依赖方、数据、使用量——
这是你检查"一个类型长什么样、被谁用、数据从哪来"的总入口。
## 上线之后:可观测与版本
看使用量、看监控、管版本、改代码的位置。
资源和应用跑起来后,OMA 还提供"回头看"的能力:
- Observability(可观测性):动作类型与函数类型视图都有该页,展示近 30 天的近实时使用量,以及相关监控规则(monitoring rules)及其状态。
- 函数版本:默认显示最新版本;可用左侧的版本下拉选择器查看其它版本。Usage History 面板记录用过某版本的应用,可直接跳过去升级版本。
- 改函数代码:修改函数只能在 Functions Code Repository(函数代码仓库)里进行;在实体视图右上角的 Open in Code Repository 按钮可跳转过去。
## 动手:一次变更,从草稿到发布
点开每一层,看一次完整流程。
在 OMA 里改本体,遵循"先在分支上改草稿、确认无误后再发布"的节奏。
下面用分层图走一遍:给某对象类型新增一个属性并接好数据的全过程。
(各平台具体按钮名称可能略有差异,这里讲的是通用流程。)
进入打开 Ontology Manager
App 图标 / 右键 Configure / URL 加 /workspace/ontology
先进入 OMA。在顶栏可以通过"切换或新建分支"进入一个分支(branch)——后续的改动会先落在分支上,不会立刻影响线上应用。
草稿在分支上编辑
在 Object type view 里改属性 / 链接 / 动作 / 函数,并接好数据
进入目标对象类型的视图,在 Overview 的 Properties 区新增属性,必要时在 Property editor 里配置;也可用 Link type / Action type / Function type 视图改其它零件。这一阶段的改动属于草稿,只在当前分支可见。
校验预览与排查
用 Discover / Object type view 确认改动正确、数据在更新
回到 Discover 或对象类型的 Data / Usage 区块,确认新属性已正确接入、数据在用户应用里正常更新。OMA 本就擅长"排查数据有没有更新"这类问题。
发布把分支发布出去
发布(publish)分支,使变更对所有用户应用生效
确认无误后,将分支发布(publish)。发布后,改动脱离草稿状态,对所有用户应用即时可见,逻辑与校验在所有前端应用保持一致。
观测上线后盯紧
Observability 看近 30 天使用量 + 监控规则
进入 Action type / Function type 视图的 Observability 页,查看近 30 天使用量与监控规则状态;函数还可用版本下拉查看历史版本、在 Usage History 里升级应用版本。
↑ 点击任意一层展开说明。分支 + 发布,是 OMA 把"改动"变成"线上真相"的标准节奏。
## 它和"应用"是什么关系?
OMA 管"本体",应用消费"本体"。
OMA 处在"建设侧":它负责把本体搭好、接好数据、验证改动。
而业务人员真正每天用的是应用(applications)——那些搭在本体之上、直接干活的工具。
✓ Ontology Manager(建设侧)
负责
· 创建 / 编辑对象类型、属性、链接
· 定义动作类型、函数
· 连接数据、排查更新
→ 供
✓ Applications(消费侧)
负责
· 用本体里的对象做分析、决策
· 执行动作类型、调用函数
· 把人的决策沉淀回本体
下一站就去看看 applications(应用)——它们才是本体价值最终落地的场所。
## 一页带走
① OMA = 本体工作台 建对象类型、定义动作/函数、接数据、排查更新。
② 进入与导航 Apps 图标 / 右键 Configure / URL 加 /workspace/ontology;顶栏搜索·新建·分支。
③ 资源视图 对象类型 Overview 七件套;属性/链接/动作/函数各有专属视图。
④ 草稿→发布→观测 分支上改草稿、发布生效、Observability 看使用量与监控。
### 常见问题速答 · FAQ
关于「Ontology Manager:搭建与维护本体的工作台」,读者最常问的几个问题。
一句话:OMA 是"本体的工作台"是什么? Ontology Manager(有时也叫 Ontology Management Application,简称 OMA)是用来搭建与维护组织本体的应用。它能做的事覆盖面很广。
界面骨架:导航 + 视图是什么? Ontology Manager 的界面由两类常驻元素 + 一组视图构成。
点进资源后,能看到什么? 选中某个资源,OMA 会打开对应的视图。重点记这几个。
上线之后:可观测与版本是什么? 资源和应用跑起来后,OMA 还提供"回头看"的能力。
---
## 本体总览:组织的运营层
- 页面:https://www.hanzhongpin.xyz/ontology/ontology-overview-tutorial.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/overview/
- 主题分组:入门篇
循序渐进 · 教学 · 入门篇
# 本体总览:组织的运营层
这是整个系列的第 0 课。它回答三个最基础的问题:
本体是什么、它由哪些零件组成、以及它最终用来干什么。
## 一句话速览
本体总览:组织的运营层:这是整个系列的第 0 课。它回答三个最基础的问题:本体是什么、它由哪些零件组成、以及它最终用来干什么。
1 本体是组织的"运营层" Palantir 平台里一开始有的,是各种数字资产:数据集、虚拟表、模型
2 定义组织"怎么变" 原文的用词很讲究:the kinetics of the organization——让组织动起来,同时又不违反组织自身的管控与治理…
3 让不同对象"长得一样" 接口(interface)描述的不是某个具体事物,而是一种形状:具备哪些属性、哪些链接、哪些能力
4 它怎么支撑决策 投入本体建设的最终目的,是让组织里的决策规模化地变好
## 一句话:本体是组织的"运营层"
Ontology = an operational layer for the organization.
Palantir 平台里一开始有的,是各种数字资产:数据集、虚拟表、模型。
它们是"原料",但业务人员看不懂,也没法直接拿来做决策。
本体就建在这些数字资产之上,把每一份数据连接到它在现实世界中对应的那个东西上——
可能是有形的(工厂、设备、产品),也可能是无形的(客户订单、金融交易)。
在很多场景里,本体就是整个组织的数字孪生(digital twin)。
…containing both the semantic elements (objects, properties, links) and kinetic elements (actions, functions, dynamic security) needed to enable use cases of all types.
>
记住这个二分法,它贯穿全部文档:
语义元素(semantic)= 世界"是什么";
动力元素(kinetic)= 世界"怎么变"。
本体必须同时具备两者,否则只能"看"不能"动"。
## 它坐在整个平台的哪一层?
点开每一层看看它负责什么。
上层面向用户的分析与运营工具
Object Views · Object Explorer · Quiver · Workshop
本体不是终点。它被深度集成进这些工具里:用户创建可复用的 Object Views、
在 Object Explorer 里搜索感兴趣的对象、在 Quiver 里做复杂分析、
在 Workshop 里搭出高质量的应用。第 8 步会展开。
本体层The Ontology
语义元素:objects / properties / links · 动力元素:actions / functions / dynamic security
这一层做的事情是:把数据映射成对象、属性和链接,并为所有字段提供丰富的元数据,
同时为所有变更提供细粒度的安全与治理。
原文特别强调:这远远超出了"数据编目"或"schema 设计"的范畴——
它是在为终端用户的工作流打地基。
下层已集成的数字资产
datasets · virtual tables · models
Datasets(数据集):从各个源系统接入后的数据。
Virtual tables(虚拟表):不落地、直接映射到外部系统的数据视图。
Models(模型):接入平台的分析或机器学习模型。
它们是本体的"燃料",本体把它们翻译成业务的现实对应物。
↑ 点击任意一层展开说明。
## 数字孪生到底长什么样?
左边是现实世界的一家医院,右边是它在本体里的样子。点任意一边。
现实世界
⇄
本体中的对象
← 点左边的一个事物,看看它在本体里对应什么。
>
注意每张卡片里的两种内容:属性(这个事物自身的特征)和链接(它和别的事物的关系)。
本体不只是把"东西"搬进来,更关键的是把"关系"也搬进来——这才是它能支撑决策的原因。
## 语义元素:定义组织"是什么"
把数据源映射成 objects、properties、links。
Object 对象
一个现实事物的实例。比如"呼吸机 V-204"这一台具体的机器。
对象类型(object type)则是它的类别: Ventilator。
Property 属性
对象的特征,比如 serialNumber、status。
本体允许为每个字段附加丰富的元数据。
Link 链接
对象与对象之间的关系,比如"这台呼吸机被写进了那张维修工单"。
链接类型(link type)定义关系的种类与两端。
本体远超数据编目或 schema 设计方案——它为终端用户的工作流定义了一套稳健的基础,
包括所有字段的丰富元数据,以及所有变更的细粒度安全与治理。
## 动力元素:定义组织"怎么变"
Action types 与 Functions。
原文的用词很讲究:the kinetics of the organization——让组织动起来,
同时又不违反组织自身的管控与治理。这就是动力元素的职责。
Action type 动作类型
用来采集业务人员的输入,或者编排决策流程并回写到既有系统。
例子:"批准这张采购订单""把这台设备标记为停用"。
每一次执行都会被记录、受权限与治理约束——这是"能动手但要合规"的关键。
Function 函数
用来编写和演进任意复杂度的业务逻辑。
例子:根据患者的全部病史与实时指标,计算一套风险评分。
逻辑可以被复用、被版本化演进,而不是散落各处。
>
一句话区分:Action type 是"人(或系统)做出的一次决策,会改变本体中的对象;
Function 是"一段计算逻辑",为决策提供依据。
## 练一练:语义还是动力?
这是全文最重要的心智模型,务必分清。
## Interface:让不同对象"长得一样"
一种描述"对象类型形状与能力"的本体类型,提供多态。
接口(interface)描述的不是某个具体事物,而是一种形状:
具备哪些属性、哪些链接、哪些能力。任何符合这个形状的对象类型都可以实现它。
好处是多态(polymorphism):工作流可以只针对接口来写,
于是对所有实现了它的对象类型都成立——不用为每个类型重写一遍。
### 动手试试:哪些类型实现了 Inspectable?
接口 Inspectable 要求具备 lastInspectionDate 与 inspectionStatus。点击你认为是实现者的卡片。
候选对象类型
判定结果
点击左边的卡片进行判定。
## 最后一步:它怎么支撑决策?
本体被深度集成进 Palantir 面向用户的工具里。
投入本体建设的最终目的,是让组织里的决策规模化地变好。
落到具体工具上,是这样四件事:
Object Views 创建可复用的对象视图——把一组对象和分析固化下来,别人可以直接接着用。
Object Explorer 搜索你感兴趣的对象,在本体里顺着链接自由导航。
Quiver 做复杂的时序与探索性分析。
Workshop 搭建高质量的、可直接投入使用的业务应用。
## 一页带走
① 本体 = 运营层 建在 datasets / virtual tables / models 之上,连接它们在现实世界的对应物。
② 语义:是什么 objects(事物)+ properties(特征)+ links(关系)。
③ 动力:怎么变 action types(受治理的决策)+ functions(业务逻辑)+ dynamic security。
④ 接口:共同的形状 提供多态,让工作流一次写成、处处适用。
学完这一篇,按顺序接着看
② 设计最佳实践(为什么)
和
③ 结构指南(怎么做)。
### 常见问题速答 · FAQ
关于「本体总览:组织的运营层」,读者最常问的几个问题。
一句话:本体是组织的"运营层"是什么? Palantir 平台里一开始有的,是各种数字资产:数据集、虚拟表、模型。它们是"原料",但业务人员看不懂,也没法直接拿来做决策。
动力元素:定义组织"怎么变"? 原文的用词很讲究:the kinetics of the organization——让组织动起来,同时又不违反组织自身的管控与治理。这就是动力元素的职责。
让不同对象"长得一样"是什么? 接口(interface)描述的不是某个具体事物,而是一种形状:具备哪些属性、哪些链接、哪些能力。任何符合这个形状的对象类型都可以实现它。
最后一步:它怎么支撑决策? 投入本体建设的最终目的,是让组织里的决策规模化地变好。落到具体工具上,是这样四件事。
---
## 场景示例(Ontology scenarios)
- 页面:https://www.hanzhongpin.xyz/ontology/ontology-scenario.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/overview-ontology-scenario/
- 主题分组:场景篇
循序渐进 · 教学 · 场景篇
# 场景示例(Ontology scenarios)
前面学了"对象、动作、本体容器"。这一篇看一个很实用的能力:场景(scenario)——
在本体之上开一个"沙盒",安全地做 what-if 推演,想清楚了再合并回生产。
## 一句话速览
场景示例(Ontology scenarios):前面学了"对象、动作、本体容器"。这一篇看一个很实用的能力:场景(scenario)—— 在本体之上开一个"沙盒",安全地做 what-if 推演,想清楚了再合并回生产。
1 Ontology scenario(场景) 场景(scenario)让你能用对象(objects)和本体里的模型(model)概念,创建并比较"what-if"分析
2 用执行上下文治理动作,再合并回主本体 动作提交标准(action submission criteria)里的执行上下文(execution context)能区分:一个…
3 函数与场景、以及要注意的限制 所有函数(AIP Logic 函数除外)都能原样在场景上运行:如果函数读本体,它读的是场景版本的本体的状态;
## 什么是 Ontology scenario(场景)
一个在本体之上、用动作生成编辑的"隔离沙盒"。
场景(scenario)让你能用对象(objects)和本体里的模型(model)概念,创建并比较"what-if"分析。
本质上,它就是一个沙盒(sandbox):在你在本体数据之上,通过应用一个或多个动作(actions)来叠加编辑。
>
注意阶段:原文标注场景功能目前处于 beta 阶段,并非所有 enrollment 都可用;功能在持续开发中。
关键区别:场景不是数据版本工具。它不能给你一份"历史某个时间点的本体快照",也不该被当成那个用途。
点我看"场景到底是什么、不是什么" →
## 四种常见用途
从假设分析到 agent 评估,都靠它。
① What-if 分析
对你的数据/系统做"假设改变"的模拟:开一个本体的隔离分叉,不影响真实数据。
② 业务逻辑仿真
应用动作与函数,模拟业务流程或评估运营改动的影响,提交前先看清后果。
③ Agent 评估与预测
用不同输入参数测试 agent,对比结果、打磨预测。
④ 对比分析
并排创建多个场景,找出最优决策或看清不同策略之间的权衡。
## 生命周期:30 天 TTL + 每 10 分钟自动 rebase
场景是"临时"的,要懂得它的保质期与同步机制。
Time to live(TTL)
为控制存储成本,场景默认寿命 30 天。到期后连同其上的编辑、以及底层的持久化场景对象,一并自动删除。
Auto-rebasing(自动变基)
场景每 10 分钟自动 rebase 到它的主分支/全局分支,把基础本体的最新变化同步进当前场景,保持与最新数据一致。
>
限制提醒:场景不能被"按需"rebase,也不能自定义 rebase 间隔——它就是固定每 10 分钟一次。
## 场景(scenario)vs 全局分支(Global Branching)
一个给构建者测流程,一个给用户试改动。
BUILDS
Global Branching(全局分支)
面向构建者,用于开发、测试端到端工作流——这些工作流若直接打生产环境会太有破坏性。
⇄
USES
Ontology scenario(场景)
给这些工作流的使用者(人和 agent)提供沙盒:在不动主本体数据的前提下叠加编辑,可比较多个场景,再合并回主数据。
一句话:分支是"开发者隔离环境",场景是"使用者试算环境"。两者互补,不是替代。
## 用执行上下文治理动作,再合并回主本体
在沙盒里可以更宽松,合并时依然收紧。
动作提交标准(action submission criteria)里的执行上下文(execution context)能区分:
一个动作是"在场景里执行",还是"对主本体执行"。这是个安全护栏——
规划者和 agent 在场景的隔离沙盒里测试动作时,可以用更宽松的提交标准;
而不会因此获得把动作应用到主本体的权限。
把审核通过的场景改动写回主本体,是单独通过"合并动作(merge action)"的提交标准来控制的。
也就是说:沙盒里随便试,合并那一步才需要真正的授权。
>
动手感受一下:下面这个沙盒模拟器,能让你直观看到"场景里的改动"和"主本体"是两条账——
只有点"合并",主本体才会变。
沙盒模拟器:场景里的改动,何时才真正影响主本体?
主本体 Main Ontology 已批准 0 生产环境,真实数据
场景 Scenario(沙盒) 已批准 0 隔离分支,可随意试错
在场景里批准一张订单
触发自动 rebase(主→场景)
把场景改动合并回主本体
## 函数与场景、以及要注意的限制
大多数函数能直接在场景上跑,但合并有上限。
所有函数(AIP Logic 函数除外)都能原样在场景上运行:如果函数读本体,它读的是场景版本的本体的状态;
如果函数改本体,它改的也是场景上的版本。想在场景上用 AIP Logic 函数,需要为它及其调用的所有嵌套 Logic 函数开启暂存写入(staged writes)。
限制清单:
- 合并场景用的是动作,因此同样受动作的规模/属性上限约束;
- 场景固定每 10 分钟自动 rebase 到基础分支;
- 场景不能按需 rebase,也不能自定义 rebase 间隔。
## 一页带走
① 场景 = 沙盒 在本体之上叠加动作编辑,做 what-if,不影响生产。
② 30 天 + 10 分钟 默认 30 天 TTL;每 10 分钟自动 rebase 到主分支。
③ 场景 ≠ 分支 分支给构建者,场景给使用者,互补。
④ 合并才落地 执行上下文管沙盒,merge action 管写回主本体。
### 常见问题速答 · FAQ
关于「场景示例(Ontology scenarios)」,读者最常问的几个问题。
用执行上下文治理动作,再合并回主本体是什么? 动作提交标准(action submission criteria)里的执行上下文(execution context)能区分:一个动作是"在场景里执行",还是"对主本体执行"。
函数与场景、以及要注意的限制是什么? 所有函数(AIP Logic 函数除外)都能原样在场景上运行:如果函数读本体,它读的是场景版本的本体的状态;如果函数改本体,它改的也是场景上的版本。
---
## 本体结构指南
- 页面:https://www.hanzhongpin.xyz/ontology/ontology-structural-guidance-tutorial.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/ontology-structural-guidance/
- 主题分组:教学
循序渐进 · 教学
# 本体结构指南
上一篇讲的是"原则",这一篇讲落地:属性怎么放、关系怎么连、权限怎么切、名字怎么起。
同样用 9 步拆开讲,配 4 个可以亲手点的互动演示。
## 一句话速览
本体结构指南:上一篇讲的是"原则",这一篇讲落地:属性怎么放、关系怎么连、权限怎么切、名字怎么起。同样用 9 步拆开讲,配 4 个可以亲手点的互动演示。
1 这一篇在讲什么 上一篇《最佳实践》给你的四条原则像是"宪法";这一篇是"施工规范",回答的是更具体的问题
2 一个事实只存一处 假设 Manager 想知道自己有多少个直属下属
3 那什么时候可以"抄一份" 不是所有计算都要放到查询时做
4 当"关系"本身也携带信息 每一条链接都应该回答一个清晰的领域问题
## 这一篇在讲什么?
原文一句话:如何在本体内部组织属性、关系和访问控制。
上一篇《最佳实践》给你的四条原则像是"宪法";这一篇是"施工规范",
回答的是更具体的问题:
同一个值要不要复制一份? → 规范化与派生属性
一个属性其实是一组字段怎么办? → Struct 结构体
多个类型长得一样怎么办? → Interface 接口
关系本身带信息怎么办? → 对象支撑链接
名字怎么起才不返工? → 命名规范
谁能看哪些格子? → 安全设计
>
先建立直觉:这六个话题其实在回答同一个问题——怎样让"现实世界的一个事实"在本体里只出现一次、出现在正确的位置、并且被恰当地保护起来。
## 核心铁律:一个事实只存一处
规范化(Normalization)与派生属性(Derived properties)。
假设 Manager 想知道自己有多少个直属下属。最直觉的做法是:在 Manager 上放一个
directReportCount 整数属性,有人入职就 +1,有人离职就 -1。
问题在于:这份"人数"其实不是 Manager 的属性,而是"有多少 Employee 链接到他"这个事实的结果。
你把它抄了一份,就得负责让这份副本永远不出错。
动手试试 · 点几下看看会发生什么
+ 有员工入职(通过 action)
- 有员工离职(通过 action)
手动同步那个计数器
重置
✗ 手动维护的整数属性
5
Manager.directReportCount
每次 action 都得记得改它
✓ 派生属性(查询时计算)
5
Manager.directReportCount
统计链接过来的 Employee 对象数
真实下属人数:5 人。点"入职/离职",看看哪一边会失准。
当某个值依赖于通过 action 发生的变更时,每一个可能影响它的 action 都必须同时更新它。只要有一个 action 忘了,这个值就会一直错下去,直到有人发现。
要避开什么
- 同一个值被存成多个对象类型上的属性
- 属性是别处维护的值的副本,因而逐渐过期
- 更新一个现实世界的事实,需要写多个对象
- 计数类属性靠人工维护,而不是从链接计算得出
## 那什么时候可以"抄一份"?
预计算(Pre-computed) vs 动态派生(Dynamically derived)。
不是所有计算都要放到查询时做。区分标准是:输入会不会被 Ontology 层的操作改变。
类型 特征 推荐工具 例子
预计算
由同一个对象上的属性算出;输入很少变,或只随 pipeline 摄入而变。
Pipeline transform
fullName = firstName + " " + lastName
输入稳定且在同一条 pipeline 里更新,预计算既安全又零运行时开销。
动态派生
依赖链接对象或会经 action、自动化等 Ontology 层操作改变的值。
Derived property
directReportCount
员工会通过 action 调岗、入职、离职。用派生属性在查询时统计,自动保持正确。
✗ 手动维护 + 复制字段
Manager
- directReportCount: 5
(人工维护的整数,
员工进出都要改)
Employee
- managerName: "Alice"
(从链接的 Manager 抄过来;
经理改名就失效)
→
✓ 查询时派生 + 只存一处
Manager
- directReportCount(派生):
在查询时统计链接的
Employee 对象
Employee
- manager(链接到 Manager)
该怎么做
- 每个事实只存一处放在它在语义上真正所属的那个对象上。
- 用派生属性在查询时从链接对象计算或聚合数值。
- 随着规模增长监控性能如果派生属性在大数据量下带来不可接受的延迟,再考虑 有选择地反范式化。
- 任何反范式化都要写清楚记录理由、事实来源(source of truth)、以及副本的同步更新策略。
## Struct:把语义相关的字段打包
一个"属性"如果天生就是多字段的,就别摊平成一堆属性。
S
### 结构体 Structs
Group semantically related fields into structs.
地址天然由街道、城市、州、邮编组成。摊平成 10 个平级属性后,
它们之间唯一的联系只剩下命名前缀——这是很脆弱的"约定"。
用 struct 则保留了语义分组,还能顺手把元数据一起带上。
什么时候该用 struct
场景 例子
多字段的值 地址(street / city / state / postalCode)、坐标(geopoint / altitude)
带元数据的值 AI 生成的输出,附带置信度、来源引用、推理过程
带选择逻辑的多值属性 多个电话号码,用 reducer 选出主号
✗ 摊平成十个属性
Facility
- addressStreet
- addressCity
- addressState
- addressPostalCode
- addressCountry
- addressGeopoint
- addressLastOccupied
- addressDatasource
- addressLlmConfidence
- addressLlmReasoning
十个互不相关的属性,
唯一的联系是命名约定
→
✓ 一个语义概念
Facility
- address(struct 数组)
- street(主字段)
- city(主字段)
- state(主字段)
- postalCode(主字段)
- country(主字段)
- geopoint
- lastOccupied(用于排序)
- datasource
- llmConfidence
- llmReasoning
一个语义概念:
主字段 + 结构化子字段
该怎么做
- 识别多字段属性字段之间语义相关,且总是被一起使用。
- 定义 struct字段名和类型都要清晰。
- 指定主字段(main field)让 struct 在大多数场景下表现得像一个简单属性。
- 用 reducer 处理多值 struct从多个候选中浮出最相关的那个值。
- 把元数据一起收进 struct来源、置信度、时间戳——尤其对 AI 生成的输出。
## Interface:把"重复的形状"抽出来
这是实现"不要重复自己"和"开闭原则"的主力工具。
I
### 接口 Interfaces
Use interfaces to build reusable, future-proof abstractions.
接口定义了一个共享形状(属性、链接、动作),多个对象类型都可以实现它。
这样工作流就可以面向接口而不是面向具体类型来写。
✗ 三份属性 + 三份动作
Vehicle
- lastInspectionDate
- inspectionStatus
(重复动作:安排车辆检查)
Equipment
- lastInspectionDate
- inspectionStatus
(重复动作:安排设备检查)
Facility
- lastInspectionDate
- inspectionStatus
(重复动作:安排设施检查)
三份副本,各自维护
→
✓ 一个接口 + 一个共享动作
Interface: Inspectable
- lastInspectionDate
- inspectionStatus
(共享动作:安排检查)
Vehicle implements Inspectable
- make, model, mileage, ...
Equipment implements Inspectable
- serialNumber, warrantyExpiry, ...
Facility implements Inspectable
- address, capacity, ...
一个接口,三个实现类型
该怎么做
- 识别共同的形状多个类型共享属性、链接或动作时,就抽一个接口出来。
- 围绕"能力"或"分类"设计接口能力型: Inspectable、Schedulable、Billable;分类型:MilitaryAsset、MedicalDevice。
- 工作流面向接口动作、函数、应用尽量建在接口上。
- 接口可以继承接口通过扩展构建分层的抽象。
- 先搭骨架,后收敛即使因平台能力暂时受限、某些工作流还得按类型复制一份,也先把接口定义出来。
## 链接:当"关系"本身也携带信息
直接链接 vs 对象支撑链接(Object-backed link)。
每一条链接都应该回答一个清晰的领域问题:
「这位患者去过哪家医疗机构?」
「这名员工属于哪个团队?」
「这张工单用了哪台设备?」
### 两种链接怎么选
链接类型 什么时候用 例子
直接链接 关系有意义,但本身不带元数据。 Employee → Department
对象支撑链接 关系自带元数据(日期、角色、状态、占比)。 Employee → VentureStaffing → Venture(带 role、startDate、allocation)
>
并不是每个"中间对象"都要在所有场景里露面。有些工作流关心这段关系的细节,有些只想要那条直达的连线。
对象支撑链接的好处是:两种视图你都能给。
✗ 直连,或塞进源对象
Employee → Venture(直接链接)
无法记录每次派驻的角色、
开始日期、投入占比
— 或者 —
Employee
- ventureRole
- ventureStartDate
(一人参与多个项目时
语义就含糊了)
→
✓ 中间对象承载关系
Employee → VentureStaffing → Venture
VentureStaffing
- role
- startDate
- allocationPercentage
- status
工作流可按需暴露:
- 简版:Employee → Venture
- 详版:Employee → Staffing
→ Venture
### 练一练:这三个场景该用哪种?
链接设计错了会怎样
问题 后果
元数据丢失 直接链接无法表达关系"何时、为何、以什么身份"存在。
多重链接含糊 像 ventureRole 这样放在源对象上的属性,一旦实体参与多重关系就说不清了。
无意义的链接 只因为两个数据集共享一个外键就建的链接,会往本体里加噪声,干扰导航。
该怎么做
- 先验证语义别只因为两个数据集共享外键就建链接,要问:这个关系在业务里说得通吗?
- 判断关系是否携带元数据如果带(日期、角色、状态),就用对象支撑链接把它记下来。
- 暴露合适的信息粒度按场景决定给"直达关系"还是"经过中间对象的详细关系"。
- 命名要让两个方向都读得通链接名要能从两端各自描述这段关系。
## 命名规范:最划算的一笔投资
为"人能读懂"和"AI 能导航"而优化。
一致且具描述性的命名,是你能为本体的质量做的最有价值的投资之一;而且一旦本体投入使用,它就极难纠正。
元素 约定 好例子 坏例子
对象类型 单数、具体的名词,领域专家一眼认得出 Patient, WorkOrder, FlightSegment Data, Item, Record
属性 简洁、自解释;不编码类型信息或实现细节 age, status, lastInspectionDate dtLastInspMod, nVAL01, fieldX
链接 从两个方向都读得自然 department(员工→部门)
employees(部门→员工) relatedItems, link1
日期 全本体统一遵循一种约定 createdDate, updatedDate, effectiveDate 混用 createdDate 和 dateOfCreation
含糊的词 加上限定,明确具体含义 monetaryValue, quantityOnHand, riskScore value, quantity, score
### 命名诊所:点开看看推荐怎么改
类型 ✗ 坏名字 ✓ 推荐名字(点击左侧「看推荐」)
对象类型 Item 看推荐 →
属性 dtLastInspMod 看推荐 →
属性 value 看推荐 →
属性 quantity 看推荐 →
链接 Item → Related Item 看推荐 →
链接 Employee → Related Employee 看推荐 →
该怎么做
- 动手前先定规范日期、状态、标识符、链接的命名模式先达成一致。
- 遵循本体已有的约定已经在用 createdDate,就别再引入 dateOfCreation。
- 给含糊的属性加限定用 monetaryValue、quantityOnHand、riskScore;别用 value、quantity、score。
- 按关系给链接命名Employee → Department 叫 department;反过来叫 employees。
- 和最终用户一起过一遍名字构建者觉得清楚的名字,使用者可能觉得含糊。用分析演练去观察用户会搜什么词、期待找到什么关系。
## 安全设计:按业务语义切权限
遵循最小权限原则,并且用"领域语言"而非"基础设施语言"来表达。
用户看一眼安全配置,就应该能明白"保护的是什么、为什么要保护"。
关键是:不要为了权限去复制对象类型——那正好撞上"不要重复自己"这条原则。
### 三层安全模型
层 控制什么 例子
行级 Row-level 用户能看到哪些对象 VIP 患者仅资深员工可见
列级 Column-level 对可见对象,用户能看到哪些属性 临床记录仅护理团队可见
单元格级(两者交叉) 行与列限制的交集 VIP 患者的临床记录仅资深护理团队可见
### 动手试试:切换身份,看哪些格子亮起来
行政人员
护理团队
精神科团队
资深护理团队
可见
被策略屏蔽
行级规则:VIP 患者仅资深员工可见 · 列级规则:diagnosis / clinicalNotes 仅护理团队;mentalHealthRecords 仅精神科团队
✗ 拆成两个对象类型来做权限
PublicPatient
- name
- dob
- diagnosis
RestrictedPatient
- name
- dob
- diagnosis
- clinicalNotes
- mentalHealthRecords
模式重复;靠拆类型实现安全。
给一个类型加属性时,
很容易忘了另一个
→
✓ 一个类型 + 策略
Patient(单一对象类型)
- name
- dob
- diagnosis(列级限制:护理团队)
- clinicalNotes(列级:护理团队)
- mentalHealthRecords(列级:精神科)
行级安全:
- VIP 患者:仅资深员工
一个类型;安全由策略实现。
领域边界驱动访问规则
安全设计错了会怎样
为安全而复制类型 模式逐渐不同步;加到一个类型上的属性很容易在另一个上被漏掉。违反"不要重复自己"。
默认过度宽松 先放开、日后收紧,意味着在收紧完成前敏感数据可能已经暴露。
用临时过滤代替策略 安全逻辑散落在应用代码里、而不是在本体层强制执行,既脆弱又难审计。
边界与领域不对齐 不跟随领域边界的安全边界更难推理,也更容易出现漏洞。
该怎么做
- 从严格开始,按需放开默认是最小访问权限;而不是先全开再慢慢收紧。
- 行级与列级组合使用两者交叉才能得到细粒度的单元格级访问控制。
- 让安全边界对齐领域边界区域经理看本区域数据、护理团队看自己的患者——用本体关系和安全策略来建模,而不是在应用层临时过滤。
- 不要为了安全复制对象类型一个类型配好策略,永远优于多个类型重复模式。
- 新增路径时复查权限一致性新加的链接、类型、属性都要确认没有绕过既有的保护。
## 一页带走
① 一个事实一处 能算出来的就别存;必须抄副本就写明来源与同步策略。
② 成组的用 struct 多字段 + 带元数据,指定主字段。
③ 同形状抽接口 工作流面向接口写,先搭骨架后收敛。
④ 关系带信息就加中间对象 对象支撑链接,两种视图都能给。
⑤ 命名先定规范 要具体、要一致、要让两端都读得通。
⑥ 安全按领域切 行 × 列 = 单元格级;绝不靠复制类型实现权限。
最后一句原文提醒:先确保安全边界对齐领域边界,再去查具体的配置文档。
边界对齐了,配置只是实现细节。
### 常见问题速答 · FAQ
关于「本体结构指南」,读者最常问的几个问题。
这一篇在讲什么? 上一篇《最佳实践》给你的四条原则像是"宪法";这一篇是"施工规范",回答的是更具体的问题。
核心铁律:一个事实只存一处是什么? 假设 Manager 想知道自己有多少个直属下属。最直觉的做法是:在 Manager 上放一个 directReportCount 整数属性,有人入职就 +1,有人离职就 -1。
那什么时候可以"抄一份"? 不是所有计算都要放到查询时做。区分标准是:输入会不会被 Ontology 层的操作改变。
链接:当"关系"本身也携带信息是什么? 每一条链接都应该回答一个清晰的领域问题。
---
## 参数(parameter)总览
- 页面:https://www.hanzhongpin.xyz/ontology/parameter-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/parameter-overview/
- 主题分组:动作类型详解
动作类型详解
# 参数(parameter)总览
参数是动作(action)的输入口,连接规则(rules)与 Workshop、Object Views 等界面。这一篇带你认识参数的本质、常见形态,以及它在提交时如何把值交给规则。
## 一句话速览
参数(parameter)总览:参数是动作(action)的输入口,连接规则(rules)与 Workshop、Object Views 等界面。
1 参数是动作的输入口 在 Foundry 里,动作类型(action type)定义的是"能做什么",而不是"对哪条数据做"
2 参数有哪些形态 官方文档没有给出一份"全部参数类型清单",但在讲解中多次出现以下形态
3 参数如何在动作里流动 文档用"修改工单状态"举了个完整例子:一个 Ticket 对象参数让用户选中要处理的工单,一个 Status 字符串参数承载期望的新…
4 每个参数都能单独配置 文档强调:每个参数都可以单独配置
## 参数是动作的输入口
一句话:动作本身不含数据,真正的数据来自参数。
在 Foundry 里,动作类型(action type)定义的是"能做什么",而不是"对哪条数据做"。真正要在提交时处理的数据,由参数(parameter)带进来。文档开篇就点明了这一点:
Parameters are the inputs of an action type.参数是动作类型的输入。
可以把参数理解成装"外部值"的变量。它的值来自三种地方:用户在表单里填写的内容、上游应用(如 Workshop)传进来的变量,或所选对象(object)的某些属性。参数是动作类型与 Foundry 其它应用(Workshop、Slate、Object Views)之间的接口。
> 关键直觉:参数不是写死在规则里的常量,而是在每次提交时被"带入"规则的值。换不同的参数值,同一个动作就能作用在不同的对象或状态上。
## 参数有哪些形态
文档没有固定枚举,但反复出现这几种常见形态。
官方文档没有给出一份"全部参数类型清单",但在讲解中多次出现以下形态。下面用可展开的分层卡帮你建立印象,点击每一层看说明:
对象对象类型 / 对象引用参数
让用户选择一个对象,参数值 = 被选中的那个对象。
例如一个 Ticket 对象参数,提交时取值为"用户当前选中的那张工单"。它可以是"单个对象引用",也可以配置成允许选择多个对象。
基础基础类型参数(string / number / boolean 等)
用户输入一段文字、一个数字,或从下拉里挑一个值。
例如 Status 参数定义为字符串,承载"工单期望变成的状态"。这类参数常被做成单选 / 多选下拉。
隐藏隐藏参数(hidden parameter)
不在表单里暴露给用户,专门用来携带上下文。
例如用 Previous Status 隐藏参数保存"改动前的状态",规则就能对比改动前后,而用户既看不到也不会误改它。
另外,参数还能接收来自宿主应用的局部变量(local variable),比如 Workshop 里的变量。文档还提到,你可以用值类型(value type)去约束动作参数,从而把同一套校验规则在 Foundry 内复用。
别硬记清单:记不住形态没关系,关键是想清楚"这个参数要装什么值、值从哪来"——下面几篇会逐个讲默认值、过滤、隐藏与覆盖。
## 参数如何在动作里流动
从"用户选择"到"规则执行",参数负责搬运值。
文档用"修改工单状态"举了个完整例子:一个 Ticket 对象参数让用户选中要处理的工单,一个 Status 字符串参数承载期望的新状态。提交动作时,这两个参数的值一起被交给规则(rules),规则据此去改对象。
进阶一点的玩法:用隐藏参数 Previous Status 保存"改动前的状态"。这样规则既能拿到新状态,也能对比旧状态,例如记录"谁把工单从 A 改成了 B"。
Parameters transport values across the action type and can be referenced in rules…参数在动作类型之间搬运值,并且可以被规则引用……
也就是说,参数的值可以在这些地方被引用:传给规则去改对象 / 链接 / 副作用、写进提交条件(submission criteria)判断动作能否提交、在覆盖(override)里改变后续参数的配置。下面的小实验让你直观感受"参数 → 规则"这条链路:
参数流向小实验
选择一张工单和目标状态,观察动作提交时参数如何把值交给规则。
工单对象:
T-101 登录故障
T-205 报表错误
T-318 权限申请
新状态:
处理中
已解决
已关闭
Ticket 参数(对象) — 提交时传给规则的对象
Status 参数(字符串) — 动作执行后的新状态
> 规则(rules)拿到这两个参数后,会把工单 — 的状态更新为选中的新状态。
## 每个参数都能单独配置
同一个动作里的不同参数,可以走完全不同的配置。
文档强调:每个参数都可以单独配置。常见的几个开关是——
- 是否暴露在表单里(exposed in form):暴露才让用户看到;不暴露就成隐藏参数。
- 是否允许用户修改(changeable by user):可改由用户填,不可改就是只读 / 由系统带值。
- 是否必填(required):必填则用户不填就不能提交。
下面用三道判断题练手(点选项看解析):
## 一页带走
① 参数是输入口 动作不含数据,参数在提交时把值带入规则。
② 形态看"装什么" 对象 / 基础类型 / 隐藏参数,区别在值从哪来、用户看不看得到。
③ 参数会流动 值可被规则、提交条件、覆盖引用,串起整个动作。
④ 逐参数配置 暴露、可改、必填三个开关各自独立,按需开关。
### 常见问题速答 · FAQ
关于「参数(parameter)总览」,读者最常问的几个问题。
参数是动作的输入口是什么? 在 Foundry 里,动作类型(action type)定义的是"能做什么",而不是"对哪条数据做"。真正要在提交时处理的数据,由参数(parameter)带进来。文档开篇就点明了这一点。
参数有哪些形态? 官方文档没有给出一份"全部参数类型清单",但在讲解中多次出现以下形态。下面用可展开的分层卡帮你建立印象,点击每一层看说明。
参数如何在动作里流动? 文档用"修改工单状态"举了个完整例子:一个 Ticket 对象参数让用户选中要处理的工单,一个 Status 字符串参数承载期望的新状态。提交动作时,这两个参数的值一起被交给规则(rules),规则据此去改对象。
每个参数都能单独配置是什么? 文档强调:每个参数都可以单独配置。常见的几个开关是——。
---
## 参数性能(performance)
- 页面:https://www.hanzhongpin.xyz/ontology/parameter-performance-considerations.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/parameter-performance-considerations/
- 主题分组:动作类型详解
动作类型详解
# 参数性能(performance)
参数之间一旦"层层依赖",表单加载就会变慢。这一篇用一个三参数例子讲清延迟从哪来,以及怎么把依赖层级压平来提速。
## 一句话速览
参数性能(performance):参数之间一旦"层层依赖",表单加载就会变慢。这一篇用一个三参数例子讲清延迟从哪来,以及怎么把依赖层级压平来提速。
1 参数也会影响性能 参数配置看似只是"填什么值",但文档提醒:参数之间的依赖(dependencies)——比如默认值和多选选项的定义——会直接影响动作…
2 链式依赖的例子 文档给了具体配置
3 扁平化建议 文档的核心建议是:配置参数时,尽量让依赖层级保持扁平(as flat as possible)
4 性能模拟器 下面的模拟器复现文档的建议
## 参数也会影响性能
一句话:参数之间的依赖,会拖慢表单加载。
参数配置看似只是"填什么值",但文档提醒:参数之间的依赖(dependencies)——比如默认值和多选选项的定义——会直接影响动作表单的加载耗时。
Dependencies between parameters … can impact the time that it takes for an action form to load.参数之间的依赖……会影响动作表单加载所需的时间。
原因在于:当一个参数的值要从"另一个参数的值"推导出来时,系统必须先把上游参数算出来,才能算下游的。依赖链越长、越串行,用户就要等越久表单才完全可用。
## 链式依赖的例子
三个参数,逐层推导,必须串行等待。
文档给了具体配置:
- 参数 1:对象引用,默认值是"对象集的单一结果(from single result of object set)"。
- 参数 2:字符串,默认值是"引用参数 1 的对象参数属性(object parameter property)"。
- 参数 3:字符串,无默认值,但配置成"从对象集取选项(get options from an object set)"的多选下拉,其对象集定义引用了参数 2。
用户一打开表单,系统就得迭代地做三步:
- 取参数 1 的默认值先从对象集算出参数 1 的值。
- 由参数 1 推导参数 2参数 2 的默认值依赖参数 1,必须等它算完。
- 由参数 2 推导参数 3 的选项参数 3 的对象集又依赖参数 2,再等一轮。
三步必须依次发生,因为每一步都在等上一步的结果。这就是加载变慢的来源。
## 扁平化建议
一句话:把依赖层级压平,让能并行的并行。
文档的核心建议是:配置参数时,尽量让依赖层级保持扁平(as flat as possible)。
回到上面的例子:如果参数 3 的对象集定义直接引用参数 1、而不是参数 2,那么参数 2 和参数 3 所需的信息就能并行推导——不用再等参数 2 算完才去算参数 3。
慢:链式 参数3 引用:参数 2顺序:1 → 2 → 3(串行)结果:总延迟更高
→
快:扁平 参数3 引用:参数 1顺序:1 之后 2、3 并行结果:总延迟更低
> 实操口诀:下游参数尽量引用"最上游、已确定的那个参数",而不是中间层;能不串的就别串。
## 性能模拟器
动手看:不同的引用方式,推导步骤差多少。
下面的模拟器复现文档的建议。第三个参数的对象集,应该引用"参数 2"还是"参数 1"?两种写法的总延迟不同:
依赖层级模拟器
参数 3 的对象集定义,引用哪一个上游参数?
引用参数 2(链式)
引用参数 1(扁平)
推导步骤 — —
> 点击上面按钮试一试。
> 小提醒:性能不是"功能对不对"的问题,而是"用户等多久"的体验问题。依赖设计得越扁平,表单越快变得可交互。
## 一页带走
① 依赖拖慢加载 默认值/选项相互依赖会影响表单耗时。
② 链式要串行 下游等上游,逐层推导变慢。
③ 压平层级 引用最上游参数,让能并行的并行。
④ 体验账 扁平化 = 表单更快变可交互。
### 常见问题速答 · FAQ
关于「参数性能(performance)」,读者最常问的几个问题。
参数也会影响性能是什么? 参数配置看似只是"填什么值",但文档提醒:参数之间的依赖(dependencies)——比如默认值和多选选项的定义——会直接影响动作表单的加载耗时。
扁平化建议是什么? 文档的核心建议是:配置参数时,尽量让依赖层级保持扁平(as flat as possible)。
性能模拟器是什么? 下面的模拟器复现文档的建议。第三个参数的对象集,应该引用"参数 2"还是"参数 1"?两种写法的总延迟不同。
---
## 参数默认值(default value)
- 页面:https://www.hanzhongpin.xyz/ontology/parameters-default-value.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/parameters-default-value/
- 主题分组:动作类型详解
动作类型详解
# 参数默认值(default value)
默认值用来"预先填好"动作表单里的参数。这一篇讲它有什么用、值从哪里来,以及当应用已经传了变量时,谁优先。
## 一句话速览
参数默认值(default value):默认值用来"预先填好"动作表单里的参数。这一篇讲它有什么用、值从哪里来,以及当应用已经传了变量时,谁优先。
1 默认值有什么用 动作的默认值(default value)用来在动作表单里预先填好(prefill)某个参数
2 默认值的三种来源 文档把默认值的来源分成几类,点击分层卡展开看
3 局部变量优先于全局默认 文档明确了一条优先级规则:局部默认值总是优先于全局默认值
4 默认值还是必填 很多初学者会混淆"给默认值"和"设为必填"
## 默认值有什么用
一句话:在表单里预填参数,让多个应用共用同一套逻辑。
动作的默认值(default value)用来在动作表单里预先填好(prefill)某个参数。它是在参数级别配置的,在 Workshop、Object Explorer、Object Views、Quiver、Slate 里都生效。
最大的好处是"一次配置,处处生效"。文档说:把默认值部署到动作上,就能在多个使用方应用之间统一动作逻辑,不必在每个应用里各自再写一遍默认值。
They can be deployed to standardize action logic across multiple consuming applications…可以把它们部署到多个使用方应用之间,统一动作逻辑……
> 对比一下:没有默认值的话,表单要填什么得在每个应用里分别配置;想改成别的行为(比如从 A320 改成 A380),可能要手动改好几个应用。有了默认值,只改动作一处即可。
## 默认值的三种来源
默认值可以是一个固定值、所选对象的某个属性,或特殊类型类生成的值。
文档把默认值的来源分成几类,点击分层卡展开看:
固定静态默认值(static default value)
参数永远预填同一个写死的值。
例如一个修改飞机 Type 属性的动作,把 Type 参数设成静态默认值 A320。点进该参数、添加静态默认值即可,用户打开表单就看到已填好。
属性对象属性默认值(object property default)
预填"当前所选对象的某个属性值"。
例如动作 Change Airplane Details:把每个参数预填为"当前选中飞机对象的当前属性值",用户只想改一项、其余保持原样。注意——只有排在输入列表该参数上方的对象引用参数,才能被用作默认值来源。
类型类类型类预填(type class prefill)
自动生成 UUID、当前用户 ID 等特殊值。
给参数标注"类型类(type class)"就能注入特殊值,如自动生成的 UUID 或当前用户 ID。这类值通常把参数可见性设为 hidden,避免用户手改。
## 局部变量优先于全局默认
一句话:应用传进来的变量,会盖过动作上的全局默认值。
文档明确了一条优先级规则:局部默认值总是优先于全局默认值。当任何 Workshop 变量带默认值传给动作时,表单会用 Workshop 变量的值来预填;Object Views 的环境变量、Slate 的默认值也是同样的道理——每次动作实例里提供的默认值优先。
Local default values (for example, Workshop variables) always take precedence over global default values.局部默认值(例如 Workshop 变量)总是优先于全局默认值。
迁移提醒:文档指出,凡是迁移到"用默认值"的方案,都要先移除各应用里的局部覆盖,否则那些局部值会继续盖过你在动作上设的全局默认。
下面这个小实验让你看到这条优先级:
默认值优先级小实验
全局默认值设的是"当前用户",但如果 Workshop 已经传了一个变量值,表单实际会预填哪个?
有 Workshop 变量传入
无变量,用全局默认
全局默认值(参数级) 当前用户 配置在动作上
表单实际预填 — —
> 点击上面按钮试一试。
## 默认值还是必填?
默认值不是必填的替代品,二者要解决不同的问题。
很多初学者会混淆"给默认值"和"设为必填"。简单说:默认值是"帮用户先填一个",用户仍可改或不改;必填是"用户不填就不能提交"。下面三道判断,点选项看解析:
## 一页带走
① 预填表单 默认值在参数级配置,跨应用统一逻辑。
② 三种来源 固定值、对象属性、类型类特殊值。
③ 局部盖全局 应用传的变量优先于动作上的全局默认。
④ 默认≠必填 默认值帮填,必填卡提交,作用不同。
### 常见问题速答 · FAQ
关于「参数默认值(default value)」,读者最常问的几个问题。
默认值有什么用? 动作的默认值(default value)用来在动作表单里预先填好(prefill)某个参数。它是在参数级别配置的,在 Workshop、Object Explorer、Object Views、Quiver、Slate 里都生效。
默认值的三种来源是什么? 文档把默认值的来源分成几类,点击分层卡展开看。
局部变量优先于全局默认是什么? 文档明确了一条优先级规则:局部默认值总是优先于全局默认值。当任何 Workshop 变量带默认值传给动作时,表单会用 Workshop 变量的值来预填;Object Views 的环境变量、Slate 的默认值也是同样的道理——每次动作实例里提供的默认值优先。
默认值还是必填?是什么? 很多初学者会混淆"给默认值"和"设为必填"。简单说:默认值是"帮用户先填一个",用户仍可改或不改;必填是"用户不填就不能提交"。下面三道判断,点选项看解析。
---
## 参数过滤(filter)
- 页面:https://www.hanzhongpin.xyz/ontology/parameters-filter.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/parameters-filter/
- 主题分组:动作类型详解
动作类型详解
# 参数过滤(filter)
过滤决定参数下拉里"能选哪些值"。这一篇讲多选参数怎么从对象集取选项、对象下拉怎么加过滤和 Search Around,以及这些过滤值从哪来。
## 一句话速览
参数过滤(filter):过滤决定参数下拉里"能选哪些值"。这一篇讲多选参数怎么从对象集取选项、对象下拉怎么加过滤和 Search Around,以及这些过滤值从哪来。
1 过滤是干嘛的 给参数加过滤(filter),本质上是限定下拉菜单里可选的值
2 从对象集取选项 对多选参数,你可以把允许的值收窄为某个对象集(object set)的属性
3 过滤与 Search Around 对对象引用参数的下拉,动作编辑者可以在配置视图里指定过滤(filters)和Search Around,从而在所有动作界面统一限制下…
4 来源与安全提示 文档特别警告了数据隐私含义(data privacy implications):当对象参数使用了新的校验时,所有能查看该动作类型的…
## 过滤是干嘛的
一句话:把下拉里"可选的值"收窄到允许的范围。
给参数加过滤(filter),本质上是限定下拉菜单里可选的值。文档原话:添加过滤会"决定参数下拉菜单中可选择的值"。过滤既可以用在多选(multiple choice)参数,也可以用在对象引用(object reference)参数的下拉里。
Adding filters … will determine the allowed values that are selectable in the parameter's dropdown menu.添加过滤……将决定参数下拉菜单中可选择的值。
关键在于:过滤后下拉里只会显示匹配的对象,而且选中值在动作执行前还会被再次校验。用户只能看到他们有权限查看的对象。
## 多选:从对象集取选项
把"允许的值"变成某个对象集的属性。
对多选参数,你可以把允许的值收窄为某个对象集(object set)的属性。做法:确保参数设为"显示多个选项",选择 Get options from an object set,配置好对象集,再选一个"包含所有允许值"的属性。
这样就能基于关联对象(linked object)的属性来显示或预填值。比如:只把"与当前工单关联的客户"的邮箱列出来当选项。
- 如果结果对象集里只有一个关联对象,且参数必填,下拉会自动预填那个属性值。
- 多选项来自用户有权查看的对象;看不到的对象,其属性也不会出现。
> 提示:这一机制天然受权限约束——用户不会看到自己无权访问的对象属性。
## 对象下拉:过滤与 Search Around
在参数配置里加过滤和 Search Around,跨所有界面统一生效。
对对象引用参数的下拉,动作编辑者可以在配置视图里指定过滤(filters)和Search Around,从而在所有动作界面统一限制下拉里出现的对象。配置后表单只渲染匹配过滤的对象。
反例 过滤值:写死 Name = "机密项目X"风险:该静态值本身可能被无权看对象的人看到
→
推荐 过滤值:来自参数 Name = {Name 参数}好处:值不直接暴露在界面,尊重对象可见性
### Supported operations
在属性上过滤(Filtering on a property):只显示"指定属性匹配任一提供值"的对象。过滤值可以是静态写死、从另一个参数推断,或某个对象引用参数的属性。如果提供多个比较值,结果是 OR 关系。
改变起始对象集(Changing the starting object set):默认起始集是"该对象类型的全部对象",可改成任意其它类型,或某个对象引用列表参数。Search Around 则对当前集里每个对象"沿一条链接遍历"生成新集——例如"当前员工的 Github Issue"会拿当前集的 Employees,生成与之关联的 Github Issues 集合。
> 显示哪些属性:下拉选项展示对象的标题和"突出属性(prominent properties)";匹配搜索词的排前面并高亮,无值的突出属性显示为 No value。具体显示哪些属性由 Ontology Manager 里的可见性决定,而不是动作类型。
## 来源与安全提示
不同来源不仅影响行为,还影响会不会"泄密"。
文档特别警告了数据隐私含义(data privacy implications):当对象参数使用了新的校验时,所有能查看该动作类型的人都可能看到数据。如果过滤里含有敏感的静态值,即便用户看不了被过滤的对象,也能看到这些静态值。下一页(下拉安全)会展开讲。先用小实验感受三种来源的差异:
过滤值来源小实验
点一种过滤值来源,看它对"可见性 / 安全"的影响。
静态写死的值
来自另一个参数
来自对象属性
> 点击上面按钮查看说明。
> 记住:用对象属性或参数来过滤对象集,值不会直接显示在界面里;只有静态值有泄露风险。下一篇专门讲怎么防范。
## 一页带走
① 过滤=收窄选项 决定下拉里能选什么,执行前再校验。
② 多选取对象集 Get options from an object set,受权限约束。
③ 来源分三类 静态值 / 来自参数 / 对象属性,决定行为与安全。
④ 静态值有风险 写死的值可能泄露,下篇讲防范。
### 常见问题速答 · FAQ
关于「参数过滤(filter)」,读者最常问的几个问题。
过滤是干嘛的是什么? 给参数加过滤(filter),本质上是限定下拉菜单里可选的值。文档原话:添加过滤会"决定参数下拉菜单中可选择的值"。过滤既可以用在多选(multiple choice)参数,也可以用在对象引用(object reference)参数的下拉里。
多选:从对象集取选项是什么? 对多选参数,你可以把允许的值收窄为某个对象集(object set)的属性。做法:确保参数设为"显示多个选项",选择 Get options from an object set,配置好对象集,再选一个"包含所有允许值"的属性。
过滤与 Search Around是什么? 对对象引用参数的下拉,动作编辑者可以在配置视图里指定过滤(filters)和Search Around,从而在所有动作界面统一限制下拉里出现的对象。配置后表单只渲染匹配过滤的对象。
来源与安全提示是什么? 文档特别警告了数据隐私含义(data privacy implications):当对象参数使用了新的校验时,所有能查看该动作类型的人都可能看到数据。如果过滤里含有敏感的静态值,即便用户看不了被过滤的对象,也能看到这些静态值。下一页(下拉安全)会展开讲。
---
## 参数覆盖(override)
- 页面:https://www.hanzhongpin.xyz/ontology/parameters-override.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/parameters-override/
- 主题分组:动作类型详解
动作类型详解
# 参数覆盖(override)
覆盖(override)让同一个参数在特定条件下"变行为"——不必为微小差异另建动作。这一篇讲它是什么、if/then 结构怎么写,并动手模拟一次。
## 一句话速览
参数覆盖(override):覆盖(override)让同一个参数在特定条件下"变行为"——不必为微小差异另建动作。这一篇讲它是什么、if/then 结构怎么写,并动手模拟一次。
1 覆盖 覆盖(override)用来在特定情形下改变参数的行为与配置
2 经理 vs 处理人 文档举了个经典例子:有个动作用来改"支持工单"的状态,且只允许经理(manager)和处理人(assignee)提交
3 覆盖块的 if / then 结构 覆盖以覆盖块(override block)为单位
4 覆盖模拟器 下面的模拟器复现了文档的例子
## 什么是覆盖
一句话:在特定情况下改变参数的行为与配置。
覆盖(override)用来在特定情形下改变参数的行为与配置。借助它,参数和表单能更灵活,不必为了"只有微小差别"的变体去单独配置一套动作类型。恰当使用覆盖还能引导用户完成提交,提升体验。
Overrides are used to change a parameter's behavior and configuration under specific circumstances.覆盖用于在特定情形下改变参数的行为与配置。
覆盖能改的东西,正是我们在总览篇讲过的那些配置开关:约束(constraints)、可见性(visibility)、必填性(requiredness)、默认值(default value)。
## 例子:经理 vs 处理人
同一个 Justification 参数,对两类人表现不同。
文档举了个经典例子:有个动作用来改"支持工单"的状态,且只允许经理(manager)和处理人(assignee)提交。
- 处理人可以改状态,但不需要理由。
- 经理改状态时,必须提供理由(justification)。
用覆盖就能做到:对经理,把 Justification reason 参数设为必填且可见;对处理人,则设为隐藏且可选。同一个动作、同一个参数,行为随身份而变。
处理人 Justification:隐藏(hidden)+ 可选体验:不必填理由,直接改状态
→
经理 Justification:可见(visible)+ 必填体验:必须填写理由才能提交
## 覆盖块的 if / then 结构
一个覆盖块 = 一组"如果…就…"规则。
覆盖以覆盖块(override block)为单位。每个块同时定义了"条件"(if 部分)和"覆盖"(then 部分),块头会给出一段逻辑摘要。点击分层卡看细节:
IF条件(conditions)
决定"什么时候"触发覆盖。
一个块可含一个或多个条件。注意:条件里只能引用排在"当前参数上方"的表单参数(与提交条件类似,但范围更受限)。
THEN覆盖(overrides)
决定"触发后改什么"。
满足条件时应用;一个块的 then 部分可含多个覆盖,一起生效。可改约束、可见性、必填、默认值。若覆盖值与参数已设的默认值相同,覆盖上会出现警告。
多块多个覆盖块的顺序
多个块都为 true 时,只执行第一个。
单个参数可挂多个覆盖块,但一旦有多个块的条件同时成立,只有最前面的一个会执行。配置顺序很重要。
> 在哪配置:最快的方式是在参数视图 General → Value 里点 Add override,弹窗会按所选选项自动配好;也可在 Overrides 标签页手动增删块与条件。General 区还会显示"已为某选项配了几个覆盖"。
## 覆盖模拟器
动手看:不同身份下,Justification 参数如何被覆盖。
下面的模拟器复现了文档的例子。选你的身份,看系统如何决定 Justification reason 参数的配置:
覆盖模拟器
你在"修改工单状态"动作里的身份是?
处理人(assignee)
经理(manager)
Justification 可见性 —
是否必填 — —
> 点击上面按钮试一试。
顺手检验两条规则(点选项看解析):
## 一页带走
① 覆盖=变行为 特定条件下改参数配置,省去另建动作。
② if / then 块含条件与覆盖,头显示逻辑摘要。
③ 只能引上方 条件只限引用当前参数上方的参数。
④ 多块只首个 多个块都成立时,只执行最前面的。
### 常见问题速答 · FAQ
关于「参数覆盖(override)」,读者最常问的几个问题。
什么是覆盖? 覆盖(override)用来在特定情形下改变参数的行为与配置。借助它,参数和表单能更灵活,不必为了"只有微小差别"的变体去单独配置一套动作类型。恰当使用覆盖还能引导用户完成提交,提升体验。
例子:经理 vs 处理人是什么? 文档举了个经典例子:有个动作用来改"支持工单"的状态,且只允许经理(manager)和处理人(assignee)提交。
覆盖块的 if / then 结构是什么? 覆盖以覆盖块(override block)为单位。每个块同时定义了"条件"(if 部分)和"覆盖"(then 部分),块头会给出一段逻辑摘要。点击分层卡看细节。
覆盖模拟器是什么? 下面的模拟器复现了文档的例子。选你的身份,看系统如何决定 Justification reason 参数的配置。
---
## 动作类型权限(Permissions):谁能看、谁能改、谁能运行
- 页面:https://www.hanzhongpin.xyz/ontology/permissions.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/permissions/
- 主题分组:动作类型详解
动作类型详解
# 动作类型权限(Permissions):谁能看、谁能改、谁能运行
动作类型涉及三类问题:谁能看这个动作、谁能改这个动作、谁能带着一组参数去运行它。运行权限尤其绕——它取决于被编辑对象的类型、数据源,以及提交条件。
## 一句话速览
动作类型权限(Permissions):谁能看、谁能改、谁能运行:动作类型涉及三类问题:谁能看这个动作、谁能改这个动作、谁能带着一组参数去运行它。运行权限尤其绕——它取决于被编辑对象的类型、数据源,以及提交条件。
1 权限作用在哪三个层面 权限对动作类型的作用方式有三问
2 Apply action(运行权限) 能否运行一个动作类型,取决于它编辑的对象类型与链接类型(object/link types)的配置
3 读取时强制(read-time enforcement) 行列访问控制(包括 restricted views、object security policies、property secur…
4 收紧还是放开 对象的编辑权限可以设为:锁定为只经动作编辑,或放开为允许动作、Foundry Forms、Object Explorer 直接编辑…
## 权限作用在哪三个层面
先把"看 / 改 / 运行"分开想。
权限对动作类型的作用方式有三问:
- 谁能查看(view)某个动作类型?
- 谁能编辑(edit)某个动作类型?
- 谁能带着一组参数运行(apply)某个动作类型?
本篇重点在第三问——运行权限,因为它最容易被误解。
## Apply action(运行权限)
运行一个动作,到底需要哪些权限?
能否运行一个动作类型,取决于它编辑的对象类型与链接类型(object/link types)的配置。任何情况下,提交动作的用户都必须:
- 能查看被编辑的对象类型、链接类型及其数据源(datasources);
- 通过 submission criteria(提交条件)。
进一步分情况:
- 若对象类型只允许通过动作编辑:用户对自己能查看的所有对象都能编辑;
- 若对象/链接类型还允许动作之外的编辑:用户还需对回写数据集(writeback dataset)有 Edit 权限(当其由数据集支撑时);
- 若由 Restricted View(受限视图)支撑:用户还需通过编辑策略(edit policy)。
## 读取时强制(read-time enforcement)
行列访问控制只管"读",不管"写"。
行列访问控制(包括 restricted views、object security policies、property security policies)过滤的是调用动作时用户能读取的数据。这些控制不会延伸到动作的写入(write)。
为了让数据在下游仍受保护,要把这些控制与 marking(标记)或 CABAC(基于分类的访问控制)搭配使用。这是"读"与"写"安全边界容易脱节的典型位置。
读取时的行列访问控制会作用于动作的写入吗?点击揭晓。
## 对象编辑权限:收紧还是放开
默认"仅经动作编辑"更安全,但有取舍。
对象的编辑权限可以设为:锁定为只经动作编辑,或放开为允许动作、Foundry Forms、Object Explorer 直接编辑、API 调用等多种方式。出于一致的安全范式,默认新对象类型只允许经动作编辑,其他方式不推荐用于新场景。
动手试:两种编辑设置下,运行动作要什么权限
仅经动作编辑
多种编辑方式
编辑设置 运行动作所需
仅经动作编辑 被编辑对象的 Read 即可(可能创建自己都看不到的对象)
多种编辑方式(含 dataset) 对所有被编辑对象的 writeback dataset 有 Edit
当前高亮场景
权衡:放开为多种编辑方式后,需要授予 Edit 权限——这可能让用户看到回写数据集中超出本体编辑所需的数据,因此一般不推荐。
## 副作用权限(side effect permissions)
谁能配副作用,通知发给谁。
任何能搭建动作的人,都可以配置副作用(side effects)。注意:
- Webhook 副作用默认不启用,要在 Data Connection 里额外授权才能用;
- 提交条件仍须照常通过,否则副作用不会被触发;
- 通知的收件人必须对通知内容里的对象数据有访问权——缺权限的人收不到;多人中部分缺权限,只有够权限的收到;
- 执行动作的用户必须能查看将要收到通知的用户/组。
谁能配置动作的副作用?点击揭晓。
## 一页带走
① 三层权限 谁能 view、谁能 edit、谁能 apply 一个动作类型,三者分开看。
② 运行靠对象权限 运行需查看数据源 + 过提交条件;仅经动作编辑时只需 Read。
③ 读控不控写 行列访问控制只过滤读取;写入安全要靠 marking / CABAC 补位。
④ 默认收紧 新对象默认只经动作编辑;放开多方式需 Edit,可能过度暴露数据。
### 常见问题速答 · FAQ
关于「动作类型权限(Permissions):谁能看、谁能改、谁能运行」,读者最常问的几个问题。
Apply action(运行权限)是什么? 能否运行一个动作类型,取决于它编辑的对象类型与链接类型(object/link types)的配置。任何情况下,提交动作的用户都必须。
对象编辑权限:收紧还是放开是什么? 对象的编辑权限可以设为:锁定为只经动作编辑,或放开为允许动作、Foundry Forms、Object Explorer 直接编辑、API 调用等多种方式。出于一致的安全范式,默认新对象类型只允许经动作编辑,其他方式不推荐用于新场景。
---
## 属性(Properties)入门
- 页面:https://www.hanzhongpin.xyz/ontology/properties.html
- 官方原文:https://www.palantir.com/docs/foundry/object-link-types/properties-overview/
- 主题分组:属性
循序渐进 · 教学 · 属性
# 属性(Properties)入门
对象类型规定了"这一类事物"长什么样,而真正填充内容的,是属性。这一篇带你认全常见的属性类型,搞懂主键与标题的取舍,并亲手做一次"命名诊所"。
## 一句话速览
属性(Properties)入门:对象类型规定了"这一类事物"长什么样,而真正填充内容的,是属性。这一篇带你认全常见的属性类型,搞懂主键与标题的取舍,并亲手做一次"命名诊所"。
1 对象的"列" 属性(property)是对象类型上某个"特征"的结构定义
2 具体那一个值 属性值(property value)指某个对象上、某个属性的具体取值
3 选才稳 标题(title)是界面上那行给人看的文字,可以是一到多个属性拼成,比如用"姓名"或"航班号"做标题
## 什么是属性:对象的"列"
属性描述对象的一个特征,就像表里的一列。
属性(property)是对象类型上某个"特征"的结构定义。比如 Employee 对象类型可以有 employee number(员工工号)、start date(入职日期)、role(岗位)这几个属性。
A property of an object type is the schema definition of a characteristic of a real-world entity or event.属性,是对象类型对某个真实世界特征的结构(schema)定义。
和数据集的类比再次成立:本体里的属性 ≈ 数据集里的一列(column),而下面要说到的属性值 ≈ 单元格(field)。
> 提示:属性是"结构",属性值是"填进去的具体内容"。定义对象类型时你在设计属性,导入或创建对象时才产生属性值。
## 属性值:具体那一个值
同一个属性,在不同对象身上是不同的数值。
属性值(property value)指某个对象上、某个属性的具体取值。比如员工 "Melissa Chang" 在 employee number 上的属性值是 11502,在 role 上是 software engineer。
对象 employee number start date role
Melissa Chang 11502 2016-10-09 software engineer
Akriti Patel 11877 2019-03-21 data analyst
对应到数据集:一列是 employee number,而 "Melissa Chang" 那一行里这个列的值 11502,就是属性值,对应一个单元格。
## 支持哪些属性类型(base types)
选对类型,后面才不会踩坑。下面是最常用的一批。
基础类型 可作标题 可作主键 说明 / 注意事项
String / Integer / Short Yes Yes 最通用,主键首选 String。
Date / Timestamp Yes Discouraged 时间值通常不适合做主键,存储与显示格式不同可能意外冲突,建议用 String。
Boolean Yes Discouraged 做主键会把对象类型限制成"只有两个实例"。
Byte / Long Yes Discouraged Byte 只能经 Integer 参数赋值;Long 在 JavaScript 中大于 1e15 有精度问题,多推荐 String。
Float / Double / Decimal Yes No 带小数点的数值,金额常用 Decimal。
Geopoint Yes No 以 纬度,经度 逗号分隔字符串存储,如 57.64911,10.40744。
Array Yes* No 内部类型须合法;不能含 null 元素;Object Storage v2 不支持嵌套数组。
Struct No No 不支持嵌套,字段也不能是数组。
Vector / Media Reference / Time Series / Attachment / Geoshape / Marking / Cipher 多数为 No No 专用于向量、媒体、时序、附件、地理形状、标记、加密等场景。
> 小记:打星号的 Array 仅在内部类型本身可作标题时,才能作标题属性。
## 主键与标题:怎么选才稳
这两个特殊属性决定了对象"怎样被认出、怎样被展示"。
标题(title)是界面上那行给人看的文字,可以是一到多个属性拼成,比如用"姓名"或"航班号"做标题。主键(primary key)则是系统用来唯一辨认每个对象的字段。
稳妥做法
用 String 做主键
稳定、无精度与格式歧义,是最常被推荐的默认选择。
⚠
要小心
用时间/布尔做主键
Date、Timestamp 因存储与显示格式差异可能冲突;Boolean 主键会把类型限制成仅两个对象。
> 提示:主键追求"唯一且稳定",标题追求"人能看懂"。两者职责不同,别用同一个字段硬扛两件事。
## 命名诊所与类型选择(动手)
好的属性名让人一眼读懂;好的类型让人少踩坑。
### 命名诊所:这些名字该不该改?
点击每行右侧的"为什么",看推荐命名的理由。
场景 不推荐 推荐
员工姓名 emp_nm employeeName
为什么 →
订单金额 amt orderAmount
为什么 →
是否完成 done_flag isCompleted
为什么 →
客户编号 cust_id customerId
为什么 →
### 类型选择:点选你的最佳答案
## 选择属性的最佳实践
把前面几条收拢成可执行的清单。
- 主键优先 String。除非有强理由,否则用稳定文本作主键,避开时间/布尔/长整型的坑。
- 金额用 Decimal。不要用 Integer 或 Float 存钱,避免截断与精度误差。
- 地理点用 Geopoint。记得它是 纬度,经度 字符串,别自己拼文本列。
- 数组不留空。Array 不能含 null 元素,设计前先确认数据质量。
- 命名用业务语言。驼峰、见名知意,少缩写、少下划线,方便在应用里直接展示。
> 一句话:属性类型选得对,后面过滤、排序、聚合才顺;命名取得好,业务人员才看得懂。
## 一页带走
① 属性是列 属性定义对象的一个特征,对应数据集的一列;属性值是具体的单元格。
② 类型要选对 主键优先 String,金额用 Decimal,地理点用 Geopoint,数组不容 null。
③ 主键稳、标题清 主键求唯一稳定,标题求人能读懂,别用同一字段硬扛两者。
④ 命名见名知意 用业务语言、驼峰、少缩写,方便在应用里直接展示给业务人员。
### 常见问题速答 · FAQ
关于「属性(Properties)入门」,读者最常问的几个问题。
什么是属性:对象的"列"? 属性(property)是对象类型上某个"特征"的结构定义。比如 Employee 对象类型可以有 employee number(员工工号)、start date(入职日期)、role(岗位)这几个属性。
属性值:具体那一个值是什么? 属性值(property value)指某个对象上、某个属性的具体取值。比如员工 "Melissa Chang" 在 employee number 上的属性值是 11502,在 role 上是 software engineer。
主键与标题:怎么选才稳? 标题(title)是界面上那行给人看的文字,可以是一到多个属性拼成,比如用"姓名"或"航班号"做标题。主键(primary key)则是系统用来唯一辨认每个对象的字段。
命名诊所与类型选择(动手)是什么? 点击每行右侧的"为什么",看推荐命名的理由。
---
## 读写授权(Read/Write authorizations):给动作加安全边界
- 页面:https://www.hanzhongpin.xyz/ontology/read-write-authorizations.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/read-write-authorizations/
- 主题分组:动作类型详解
动作类型详解
# 读写授权(Read/Write authorizations):给动作加安全边界
读写授权(处于 beta 阶段)给动作类型套上两道安全边界:读授权限制动作能直接读取或接收的带标记数据,写授权规定它创建/修改的数据必须满足的最低安全。它们只是"补充",不替代现有权限与提交条件。
## 一句话速览
读写授权(Read/Write authorizations):给动作加安全边界:读写授权(处于 beta 阶段)给动作类型套上两道安全边界:读授权限制动作能直接读取或接收的带标记数据,写授权规定它创建/修改的数据必须满足的最低安全。
1 read / write authorization 读写授权为动作类型增加安全边界(security boundaries)
2 读取的上限 读授权给动作能读取的数据设了一道额外的上限(upper bound)
3 写入的底线 写授权定义了动作创建或修改的数据必须满足的最低安全
4 强制标记保证与"降级"风险 强制标记(mandatory markings)本应沿数据依赖传播,让衍生数据保留输入的防护
## 什么是 read / write authorization
两道边界,一上一下。
读写授权为动作类型增加安全边界(security boundaries):
- Read authorization(读授权)限制动作在执行时能读取或直接接收的带标记(marked)数据的上限;
- Write authorization(写授权)为动作创建或修改的数据设定最低安全要求(minimum security)。
它们补充用户现有权限与动作的 submission criteria,但不授予访问、也不替代现有权限或提交条件。
注意:该功能是 beta 阶段,你的 enrollment 上可能尚未提供,平台支持也可能变化。
## Read authorization:读取的上限
即使你能看,动作也可能读不到。
读授权给动作能读取的数据设了一道额外的上限(upper bound)。它在 Foundry 把值载入参数时生效——包括另一段逻辑调用该动作时,以及 function-backed 动作执行读取时。
如果数据超出了配置的读授权,即使该用户本来能访问它,动作也无法载入那部分数据。当然,应用动作的用户仍须对数据本身有权限;若读授权未配置任何 marking,则除了用户现有访问外,不额外设读边界。
## Write authorization:写入的底线
低于最低安全,动作会被拦下。
写授权定义了动作创建或修改的数据必须满足的最低安全。Foundry 会校验结果数据的安全,若结果低于配置的最低要求,就阻断(block)该动作。
关键是:写授权不授予用户对 marking 的访问,也不会自动加上任何已配置的 marking,更不会让本就无效的编辑变得合法。用户仍须具备所需权限、在适用处提供有效的 marking 值、并通过 submission criteria。
另外,写授权不对平台托管的写入生效——例如 action log(动作日志)与 edit history(编辑历史)对象,因此它们的实际安全可能低于写授权。
写授权会授予用户对 marking 的访问、或替代现有权限吗?点击揭晓。
## 强制标记保证与"降级"风险
读写不一致,可能切断标记传播。
强制标记(mandatory markings)本应沿数据依赖传播,让衍生数据保留输入的防护。但动作的输出安全由动作逻辑决定——它可以比输入更高、相等,或更低。读/写授权分别设了动作的上界与下界。
若把写授权设得比读授权更宽松,动作就能写出低于其读取边界的数据——这会有意切断(sever)强制标记传播,可能导致数据降级(declassification)。编辑器在读写设置不一致时会显示警告。
当读写不一致时,Foundry 会检查保存/发布该动作类型的用户权限:他必须能降级(declassify)被切断的每一个强制标记。检查通过后,动作类型即可执行该降级;且运行时不再重复此检查。
风险:若根本没配置读授权,保存/发布时就不会做降级权限检查——动作可能读到高于写边界的数据并写出更宽松的数据,造成数据外泄(data spill)。因此"只要动作可能读取带标记数据,就配置读授权"。
## 如何配置,以及表单上的状态反馈
开启 Access constraints,分别配读写。
在动作类型编辑器里,启用 Access constraints(访问约束)即可配置授权:启用会初始化两套授权(无 marking),禁用则清空两者。用 Write security 与 Read security 标签页分别配置;设置不一致时编辑器会警告。若授权里含有你无权查看的值,会显示为已脱敏(redacted)且不可编辑。
提交前,动作表单可显示基于写授权的 Minimum required security(最低必需安全),状态有五种:
动手试:表单上的"最低必需安全"状态
下一项状态 »
状态
Security passed
目标安全预期满足配置的最低要求。
提示:这只是提前反馈;真正的权威校验在动作提交时由 Foundry 执行,不达标则失败。
## 一页带走
① 两道边界 读授权设读取上限,写授权设写入底线;只补充不替代。
② 读超限读不到 数据超出读授权,即使用户能看,动作也无法载入。
③ 写不达标就拦 结果低于最低安全则阻断;不对 action log / edit history 生效。
④ 读写别打架 写比读宽松会切断标记传播、致降级;不配读授权恐致数据外泄。
### 常见问题速答 · FAQ
关于「读写授权(Read/Write authorizations):给动作加安全边界」,读者最常问的几个问题。
读取的上限是什么? 读授权给动作能读取的数据设了一道额外的上限(upper bound)。它在 Foundry 把值载入参数时生效——包括另一段逻辑调用该动作时,以及 function-backed 动作执行读取时。
写入的底线是什么? 写授权定义了动作创建或修改的数据必须满足的最低安全。Foundry 会校验结果数据的安全,若结果低于配置的最低要求,就阻断(block)该动作。
强制标记保证与"降级"风险是什么? 强制标记(mandatory markings)本应沿数据依赖传播,让衍生数据保留输入的防护。但动作的输出安全由动作逻辑决定——它可以比输入更高、相等,或更低。读/写授权分别设了动作的上界与下界。
如何配置,以及表单上的状态反馈? 在动作类型编辑器里,启用 Access constraints(访问约束)即可配置授权:启用会初始化两套授权(无 marking),禁用则清空两者。用 Write security 与 Read security 标签页分别配置;设置不一致时编辑器会警告。
---
## 规则全解:动作类型背后的逻辑引擎
- 页面:https://www.hanzhongpin.xyz/ontology/rules.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/rules/
- 主题分组:动作类型详解
动作类型详解
# 规则全解:动作类型背后的逻辑引擎
规则(rules)把用户填的参数,翻译成对本体(Ontology)的编辑或平台里的其它效果。这一篇把规则的类型、取值与组合禁忌一次讲清。
## 一句话速览
规则全解:动作类型背后的逻辑引擎:规则(rules)把用户填的参数,翻译成对本体(Ontology)的编辑或平台里的其它效果。这一篇把规则的类型、取值与组合禁忌一次讲清。
1 两类效果 规则(rules)定义了动作类型的逻辑——它把参数(parameters)转换成本体编辑(Ontology edits)或其它效果
2 Ontology 规则清单 下面是一组常见的 Ontology 规则(编辑本体的规则)
3 属性从哪取值 当创建或修改对象与链接时,规则需要额外的"值"
4 组合与无效组合 动作类型可以组合多条 Ontology 规则
## 规则是什么:两类效果
规则(rules)定义了动作类型的逻辑。
规则(rules)定义了动作类型的逻辑——它把参数(parameters)转换成本体编辑(Ontology edits)或其它效果。规则大致分两类:
- 编辑本体的规则:创建、修改、删除对象与链接;
- 触发其它效果的规则:在 Foundry 里触发别的影响(通知、webhook、构建等)。
对"规则能搭出什么",可回看本系列《动作·浏览》;这一篇聚焦规则本身的语义、取值映射与组合限制。
## Ontology 规则清单
编辑本体的规则有哪些,各自做什么。
下面是一组常见的 Ontology 规则(编辑本体的规则):
规则 作用
Create object 创建预定义类型的对象(主键必填)
Modify object(s) 修改主键来自对象引用参数的已有对象(不能引用本动作新建的对象)
Create or modify object(s) 有对象就改,没提供就新建(自动 ID 或用户提交主键)
Delete object(s) 删除主键来自对象引用参数的已有对象
Create link(s) / Delete link 创建/删除多对多链接(外键型要用 Modify object)
Function rule 引用一个 Ontology edit function,输入来自参数;独占,不与其他 Ontology 规则组合
Interface 系列规则 针对"实现某接口"的任意对象类型做增改删/链接
记住:当存在 Function rule 时,不能再配置其它 Ontology 规则,因为函数代码本身就能表达其它规则的全部能力。
动手练:把左边的描述点选到右边正确的规则名上。
## 值映射:属性从哪取值
创建/修改对象与链接时,每个属性都要映射到一个值来源。
当创建或修改对象与链接时,规则需要额外的"值"。修改对象时,规则还定义了改哪些属性;而每个属性又被映射到一个值来源(链接规则只能取对象引用参数):
- From parameter(来自参数):一个与属性同类型的已有参数。默认每个新加的属性都会自动建一个同名参数并映射到它。
- Object parameter property(对象参数属性):某个已有对象引用参数的属性,其类型要与被映射的属性类型匹配。
- Static value(静态值):只存在于动作类型规则部分的固定值,用户在 Workshop、Slate、Object Views 里都改不了。
- Current User / Time(当前用户 / 时间):字符串属性可取"当前用户",时间戳属性可取"提交时间"这类上下文值;和静态值一样,提交时不可交互、也不能在动作其它地方复用。
你还可以在同一次动作里既创建对象又建好多对多链接:先配 Create object 规则(对象类型带多对多链接),再在 Add property 下方点 Add link 选链接类型并配置。而一对多 / 一对一链接,只需改对象上的外键即可。
## 组合与无效组合
多条规则会被编译成"每对象一次编辑",顺序很重要。
动作类型可以组合多条 Ontology 规则。当定义了多条规则时,动作后端会把它们编译成每个对象一次编辑(如 Add object、Modify object(s)、Delete object(s))。例如:一条规则把某属性更新为 "A",同动作另一条规则把它更新为 "B",最终编辑就只是更新为 "B"——规则顺序影响最终结果。
因此,以下对象编辑组合不被支持:
- 对象不能在"被新增或修之前"就被删除;
- 对象不能在"被新增之前"就被修改;
- 同一表单提交中,对象不能被创建两次。
> 一句话:顺序 = 结果。组合前先想清楚"先建后改还是先改后建"。
## 副作用规则与高级构建
除了编辑本体,还有两类触发"别的效果"的规则。
触发副作用(side effect)的规则
- Notification(通知):发一条关于该动作的通知。可用参数自定义内容与接收人;用户可自行选择接收方式(站内推送、邮件或两者)。通知在所有编辑应用后发送,但内容基于"编辑前"的本体状态生成。
- Webhooks:动作应用后向外部系统发请求,可把动作参数传进去。可配置为在编辑前或编辑后运行(对应 Writeback / 普通 webhook 的时机)。
触发构建(build)的高级规则
- Schedule(计划):触发一次计划构建。动作参数可传进计划,进而传给构建内的参数化转换(parameterized transforms)。Foundry 会在构建开始后应用本体编辑。
The order of rules affects the final object edit.规则的顺序会影响最终的对象编辑。(组合多条规则时务必留意)
## 一页带走
① 规则分两类 编辑本体的规则 + 触发其它效果(通知/webhook/构建)的规则。
② 属性要映射值来源 From parameter / 对象参数属性 / Static value / 当前用户·时间。
③ 顺序 = 结果 多条规则编译成每对象一次编辑;先删后建等组合不被支持。
④ function 独占 Function rule 不能与其它 Ontology 规则共存;通知内容用编辑前状态。
### 常见问题速答 · FAQ
关于「规则全解:动作类型背后的逻辑引擎」,读者最常问的几个问题。
规则是什么:两类效果? 规则(rules)定义了动作类型的逻辑——它把参数(parameters)转换成本体编辑(Ontology edits)或其它效果。规则大致分两类。
Ontology 规则清单是什么? 下面是一组常见的 Ontology 规则(编辑本体的规则)。
值映射:属性从哪取值是什么? 当创建或修改对象与链接时,规则需要额外的"值"。修改对象时,规则还定义了改哪些属性;而每个属性又被映射到一个值来源(链接规则只能取对象引用参数)。
组合与无效组合是什么? 动作类型可以组合多条 Ontology 规则。当定义了多条规则时,动作后端会把它们编译成每个对象一次编辑(如 Add object、Modify object(s)、Delete object(s))。
---
## 规模与属性限制(Scale & limits):守住性能边界
- 页面:https://www.hanzhongpin.xyz/ontology/scale-property-limits.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/scale-property-limits/
- 主题分组:动作类型详解
动作类型详解
# 规模与属性限制(Scale & limits):守住性能边界
动作不是"想改多少就改多少"。Foundry 在配置、编辑、批量调用三个层面设了上限,确保被编辑的对象类型能快速处理改动、不让线上应用变慢。超限的提交会直接报错。
## 一句话速览
规模与属性限制(Scale & limits):守住性能边界:动作不是"想改多少就改多少"。Foundry 在配置、编辑、批量调用三个层面设了上限,确保被编辑的对象类型能快速处理改动、不让线上应用变慢。超限的提交会直接报错。
1 为什么要有这些限制 这些上限存在的目的是:确保被编辑的对象类型能快速处理编辑(process edits quickly),并更新面向用户的数据,而不拖…
2 配置限制(configuration limits) Allow multiple values(允许多值)开关允许向一个参数传入值列表
3 批量调用限制(batch call limits) 一个动作在一次批量(batch)中最多可被调用 10,000 次
4 支持的属性类型与不可编辑项 文档列出了支持的单值与数组属性类型,其中不少仅 OSv2 支持(如 Media reference、Struct、Time seri…
## 为什么要有这些限制
限制是为了"快",不是故意为难你。
这些上限存在的目的是:确保被编辑的对象类型能快速处理编辑(process edits quickly),并更新面向用户的数据,而不拖慢实时应用。
"Actions submitted that exceed these limits will not succeed and will display an error message to the user."超过这些限制的提交不会成功,并向用户显示错误信息。
所以,设计动作时要把规模上限当成"红线"——尤其是要在表格里批量跑动作的场景。
## 配置限制(configuration limits)
与"允许多值"相关的列表长度上限。
Allow multiple values(允许多值)开关允许向一个参数传入值列表。列表能有多长,分三种情况:
列表类型 最大元素数
原始类型列表参数(primitive list) 10,000
对象引用列表参数(object reference list) 1,000
在 submission criteria 中使用的列表参数 1,000
上面三种列表的最大元素数分别是多少?点击揭晓。
## 编辑限制(edit limits)
单次提交能碰多少对象、每个对象改多大。
限制项 最大值
单次提交可编辑的对象类型(object types)数 50
单次提交可编辑的对象(objects)数 10,000
单个对象在一次提交中的编辑大小 32KB(OSv1)/ 3MB(OSv2)
动手试:单个对象的编辑大小上限(按存储版本)
Object Storage v1
Object Storage v2
OSv1 上限
32KB
Object Storage v2(OSv2)放宽到 3MB;许多高级属性类型也仅 OSv2 支持。
## 批量调用限制(batch call limits)
一个批量里能调多少次动作。
一个动作在一次批量(batch)中最多可被调用 10,000 次。但如果动作是 function-backed(函数支撑)、且函数没有配置 batched execution(批量执行),这个上限会被降到 20。
关键点:批量调用里产生的编辑,在套用"编辑限制"时会被当作一个整体(single group)来算,不管具体是哪一次请求造成的编辑。此外,视调用应用不同,还可能叠加其他限制。
## 支持的属性类型与不可编辑项
哪些属性能用、主键为什么不能改。
文档列出了支持的单值与数组属性类型,其中不少仅 OSv2 支持(如 Media reference、Struct、Time series reference、Vector 等)。多数常见类型(String、Integer、Boolean、Date、Timestamp…)两端都支持。
有一条尤其要记住:动作不能用来编辑对象的主键(primary key)。修改主键本质上等于"先删对象、再建新对象"。与其用动作改主键,不如通过 rules(规则)直接创建或删除对象。
另外,使用副作用通知(side effect notifications)时,单次动作最多通知 500 个收件人;若通知内容"来自函数(From a function)"渲染,则降到 50 个。
动作能否编辑对象的主键(primary key)?点击揭晓。
## 一页带走
① 限制为性能而生 超限提交直接失败并报错;设计动作要把上限当红线。
② 编辑上限 单次提交编辑对象类型 50、对象 10,000;单对象编辑 32KB(OSv1)/3MB(OSv2)。
③ 批量上限 普通批量 10,000 次;function-backed 未配批量执行时降为 20;编辑按整体计。
④ 不可编辑主键 动作不能改主键;应走 rules。通知收件人普通 500、函数渲染 50。
### 常见问题速答 · FAQ
关于「规模与属性限制(Scale & limits):守住性能边界」,读者最常问的几个问题。
为什么要有这些限制? 这些上限存在的目的是:确保被编辑的对象类型能快速处理编辑(process edits quickly),并更新面向用户的数据,而不拖慢实时应用。
支持的属性类型与不可编辑项是什么? 文档列出了支持的单值与数组属性类型,其中不少仅 OSv2 支持(如 Media reference、Struct、Time series reference、Vector 等)。
---
## 在本体里,怎么写才算「查得到」
- 页面:https://www.hanzhongpin.xyz/ontology/search-syntax.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/search-syntax/
- 主题分组:搜索语法 Search syntax
循序渐进 · 教学 · 搜索语法 Search syntax
# 在本体里,怎么写才算「查得到」
这一篇讲本体(Ontology)里搜索的语法,重点是正则(regex)查询:它能匹配什么、不能匹配什么、有哪些操作符。
学完你能写出既精确又不漏的查询串。
## 一句话速览
在本体里,怎么写才算「查得到」:这一篇讲本体(Ontology)里搜索的语法,重点是正则(regex)查询:它能匹配什么、不能匹配什么、有哪些操作符。学完你能写出既精确又不漏的查询串。
1 在哪搜,以及这篇讲什么 你可以在本体的两个地方发起搜索:Workshop 里的 filter list(筛选列表)组件,或 Object Explorer…
2 属性要先被索引 正则搜索不是默认就能用的,原文给了明确前提
3 查询命中判断练习器 下面每个练习都给出字段的真实值和一条查询串
## 在哪搜,以及这篇讲什么
在 Workshop 的 filter list 或 Object Explorer 的搜索框里搜。
你可以在本体的两个地方发起搜索:Workshop 里的 filter list(筛选列表)组件,
或 Object Explorer 里的搜索框(search bar)。
这一篇重点讲正则表达式(regex)搜索的语法。它的写法和常见的正则很像,但有几个关键差别——
下面几节会逐条讲清,并用一个练习器让你亲手验证「这个查询到底命不命中」。
## 正则搜索的前提:属性要先被索引
字符串属性必须在 Ontology Manager 开启 regex 索引。
正则搜索不是默认就能用的,原文给了明确前提:
- 字符串属性必须被索引以支持正则搜索。
- 开启方式:在本体管理器(Ontology Manager)里,进入该对象类型的 Properties 标签 → 选 Interaction 标签 → 勾选 Enable regex queries。
别忘了这步:如果属性没开 regex 索引,你写再多正则也不会生效。先去 Ontology Manager 把开关打开。
## 三条铁律:和你想的不一样
整值匹配、不是子串、没有 ^ 和 $。
① 匹配的是「整个值」,不是子串
因为索引把整串当作一个未分词的完整值,模式总是从头到尾去比整个字段。搜 cat 只会命中正好等于 cat 的值,不会命中 concatenate。要做子串匹配,前后加 .*,例如 .*cat.*。
② ^ 和 $ 锚点不支持
因为每次匹配都隐式从值开头到结尾,^ 与 $ 是多余的,不支持。
③ 想匹配字面量,用引号包起来
" 把一段变成「字面量分组」,里面的字符不再被当作正则操作符。例如 "v2.0" 只匹配字面的 v2.0;不加引号时 . 是通配符,可能误中 v2X0。
## 支持的操作符
从通配到分组、字符集、转义,一表收尽。
操作符 含义 例子
. 任意单个字符 c.t → cat, cot, cut
? 前一个字符可选(0 或 1 次) colou?r → color, colour
+ 前一个字符 1 次或多次 go+d → god, good, goood(不含 gd)
* 前一个字符 0 次或多次 go*d → gd, god, good, goood
{} 前一个字符重复次数区间 go{2}d→good;go{2,}→≥2;go{2,4}d→2~4
| 或(OR) cat|dog → cat 或 dog
() 分组,让操作符作用于整组 (un)?happy → happy, unhappy
[] 字符集(单字符);- 表范围;^ 开头表否定 gr[ae]y→gray,grey;[a-z];[^0-9]
" 字面量分组 "v2.0" → 仅字面 v2.0
\ 转义;并提供简写类 \d 数字;\s 空白;\w 词字符;\. 字面点
>
转义简写举例:\d{3}-\d{4} 会匹配 555-1234、800-5678 这种格式;
\w+\s\w+ 会匹配「两个被空格分开的词」,如 hello world。要搜字面点,用 \.,如 example\.com。
## 动手演示:查询命中判断练习器
给出字段真实值与查询串,先猜命中与否,再验证。
下面每个练习都给出字段的真实值和一条查询串。请先判断它能否命中
(记住三条铁律:整值匹配、^ $ 默认可省、"..." 表字面量),再点「会命中 / 不会命中」看结果。
动手试试 · 正则查询命中判断
说明:本练习器按原文规则实现了一个迷你正则引擎——模式默认按整值匹配,"..." 视为字面量,
其余采用标准正则语义。仅用于教学直观感受,不保证与平台内部实现逐字节一致。
## 常见示例速查
把高频写法直接抄走。
想匹配 查询串
包含 cat 的任意值 .*cat.*
color 或 colour colou?r
good / goood(2~4 个 o) go{2,4}d
cat 或 dog cat|dog
gray 或 grey gr[ae]y
字面 v2.0(点不通配) "v2.0"
形如 555-1234 的号码 \d{3}-\d{4}
example.com(点不误中) example\.com
## 一页带走
① 先开索引 属性须在 Ontology Manager 开启 regex 查询。
② 整值匹配 模式比的是整个值,不是子串;子串用 .*….*。
③ 引号做字面 "…" 内不转义;. 等变字面量,防误匹配。
④ 操作符记牢 . ? + * {} | () [] " \ 各司其职。
### 常见问题速答 · FAQ
关于「在本体里,怎么写才算「查得到」」,读者最常问的几个问题。
在哪搜,以及这篇讲什么? 你可以在本体的两个地方发起搜索:Workshop 里的 filter list(筛选列表)组件,或 Object Explorer 里的搜索框(search bar)。
正则搜索的前提:属性要先被索引是什么? 正则搜索不是默认就能用的,原文给了明确前提。
动手演示:查询命中判断练习器是什么? 下面每个练习都给出字段的真实值和一条查询串。请先判断它能否命中 (记住三条铁律:整值匹配、^ $ 默认可省、"..." 表字面量),再点「会命中 / 不会命中」看结果。
---
## 当你必须用「自己的」嵌入模型时
- 页面:https://www.hanzhongpin.xyz/ontology/semantic-search-custom-models.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/using-custom-models-to-create-a-semantic-search-workflow/
- 主题分组:用自定义模型做语义搜索 Custom models
循序渐进 · 教学 · 用自定义模型做语义搜索 Custom models
# 当你必须用「自己的」嵌入模型时
这一篇讲怎么把非 Palantir 提供的嵌入模型接进语义搜索:用 Foundry 模型生成向量、建对象类型、再写函数做 KNN 检索。
原文也直言——这已不是推荐做法,先看清何时才值得。
## 一句话速览
当你必须用「自己的」嵌入模型时:这一篇讲怎么把非 Palantir 提供的嵌入模型接进语义搜索:用 Foundry 模型生成向量、建对象类型、再写函数做 KNN 检索。
1 这是给「自带模型」的人看的 这篇教程面向使用非 Palantir 提供的嵌入模型的场景
2 用 Foundry 模型生成嵌入 从一份已解析好的数据集(含 Document_Content、Link 等元数据)出发,目标是给文本生成嵌入以便语义搜索
3 创建对象类型 有了含浮点向量列的数据集后,创建一个对象类型(文中名为 Document),并
4 写函数做 KNN 检索 最后一步是写一个函数:接收用户输入,用前面建好的 Live Modeling Deployment 生成查询向量,然后对该对象类型跑…
## 定位:这是给「自带模型」的人看的
原文开宗明义:自定义模型已不是推荐做法。
这篇教程面向使用非 Palantir 提供的嵌入模型的场景。原文第一句就给了一个重要提醒:
自定义模型这条路已经不再是推荐的工作流(no longer a recommended workflow),
建议优先看 Palantir 提供的模型清单与官方语义搜索教程。
先想清楚:除非你有「必须用自有模型」的硬理由(合规、数据不出域、已有自研模型),
否则上一页的官方模型方案更快、更省心。本篇的价值,在于让你知道「真要走自定义」时每一步做什么。
文中用一个「端到端的文档搜索服务」作例子:用 Foundry 的 modeling objective 把文档嵌入成向量、存入带 vector 属性的对象类型,
再写函数用自然语言查询它。
## 与官方模型方案:差异对照
同样的目标,不同的「模型从哪来」。
自定义模型
模型来源:你自己带入
需在 Foundry 导入/部署自有模型
要建 Live Modeling Deployment 供查询时嵌入
原文:已非推荐工作流
→
官方提供模型
模型来源:Palantir 提供
直接用 text-embedding-ada-002 等
Pipeline Builder 一键生成嵌入
更快起步、更省心
两条路最终都落到「带 vector 属性的对象类型 + KNN 检索」,差别主要在模型从哪来、谁部署。
## 步骤一:用 Foundry 模型生成嵌入
import 一个开源模型,用 transform 把文本列变成 embedding 列。
从一份已解析好的数据集(含 Document_Content、Link 等元数据)出发,目标是给文本生成嵌入以便语义搜索。
- 原文示例用开源模型 all-MiniLM-L6-v2:一个通用文本嵌入模型,产出维度 384 的向量。
- 这个模型可以被任何「输出与 Foundry Ontology vector 类型兼容的向量」的模型替换。
- 模型需暴露一个 API:表格输入含一个 text 字符串列;表格输出含一个 embedding 浮点数列。
- transform 跑完数据后返回 embedding,再把值转成 float 以匹配向量类型。
>
还要一个部署:除批量生成初始嵌入外,你还需要一个 Live Modeling Deployment,
用来针对「用户查询」实时生成嵌入去比对已有向量——且这个部署用的模型要和第一步一致。
## 步骤二:创建对象类型
把 embedding 建成 Vector 属性,并配好维度与相似度函数。
有了含浮点向量列的数据集后,创建一个对象类型(文中名为 Document),并:
- 把 embedding 属性设为 Vector 类型。
- 配置两个值:
Dimension(维度):即 embedding 列里数组的长度(如 384)。
- Similarity Function(相似度函数):两个对象的 embedding 之间计算距离的方法。
对象类型建好后,ObjectApiName(本例为 Document)会在配置页拿到,后续代码里用它指代该对象类型。
>
可替换项(value substitution):全流程里可一致替换的占位符还有 ModelApiName、OutputDatasetRid、
InputDatasetRid、ModelRid——保持每处一致即可。
## 步骤三:写函数做 KNN 检索
函数接收用户输入,用 live 部署生成向量,再跑 KNN。
最后一步是写一个函数:接收用户输入,用前面建好的 Live Modeling Deployment 生成查询向量,
然后对该对象类型跑 KNN 搜索(TSv1)。
- 函数把用户文本变成向量,再交给 nearestNeighbors 找最近邻对象。
- 文中强调:Python 函数也支持模型函数与语义搜索,但本教程未给出 Python 示例。
- 向量属性(vector properties)的修改,也可以由 Actions 和 Functions 来施加。
>
与官方方案的代码差异:官方方案里 TSv2 / Python 可把查询文本直接传给 nearestNeighbors;
自定义方案因为模型在你自己手里,通常要先调用你的 live 部署把文本转成向量,再去做近邻搜索。
## 动手演示:该用哪种方案?
给一个场景,判断该走「官方模型」还是「自定义模型」。
下面每个场景,点「用官方模型」或「用自定义模型」来作答。原文的核心立场是:自定义已非推荐,
只有「硬要用自有模型」时才值得——用这个标尺去判断。
重置分类
## 一页带走
① 非推荐路径 自定义模型已非推荐,先确认「必须自有模型」。
② 生成嵌入 导入模型(如 all-MiniLM,dim 384),transform 产 embedding 列。
③ 建 Vector 对象 配 Dimension 与 Similarity Function,拿到 ObjectApiName。
④ live 部署+函数 建 Live Deployment 实时嵌查询,函数跑 KNN。
### 常见问题速答 · FAQ
关于「当你必须用「自己的」嵌入模型时」,读者最常问的几个问题。
定位:这是给「自带模型」的人看的是什么? 这篇教程面向使用非 Palantir 提供的嵌入模型的场景。原文第一句就给了一个重要提醒:自定义模型这条路已经不再是推荐的工作流(no longer a recommended workflow),建议优先看 Palantir 提供的模型清单与官方语义搜索教程…
步骤一:用 Foundry 模型生成嵌入是什么? 从一份已解析好的数据集(含 Document_Content、Link 等元数据)出发,目标是给文本生成嵌入以便语义搜索。
步骤二:创建对象类型是什么? 有了含浮点向量列的数据集后,创建一个对象类型(文中名为 Document),并。
步骤三:写函数做 KNN 检索是什么? 最后一步是写一个函数:接收用户输入,用前面建好的 Live Modeling Deployment 生成查询向量,然后对该对象类型跑 KNN 搜索(TSv1)。
---
## 不自己部署模型,也能搭出语义搜索
- 页面:https://www.hanzhongpin.xyz/ontology/semantic-search-palantir-models.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/using-palantir-provided-models-to-create-a-semantic-search-workflow/
- 主题分组:用官方模型做语义搜索 Palantir-provided models
循序渐进 · 教学 · 用官方模型做语义搜索 Palantir-provided models
# 不自己部署模型,也能搭出语义搜索
这一篇用 Palantir 提供的嵌入模型,端到端搭一个语义搜索工作流。你会学到怎么生成嵌入、怎么用无码方案快速起步,
以及怎么写一个能按相关性排序的检索函数。
## 一句话速览
不自己部署模型,也能搭出语义搜索:这一篇用 Palantir 提供的嵌入模型,端到端搭一个语义搜索工作流。你会学到怎么生成嵌入、怎么用无码方案快速起步,以及怎么写一个能按相关性排序的检索函数。
1 前置条件与这篇讲什么 用 Palantir 提供的语言模型前,原文要求两件事:你的 enrollment 上必须已启用 AIP,并且你要有使用 AIP 开…
2 三条搭建路线 原文把所有路线归纳成「一个前置 + 三种选项」
3 生成嵌入并建对象类型 无论走哪条路线,第一步都一样:先有「带向量的对象」
4 两种无码方案 原文提醒:KNN 对象集无法按相关性排序
## 前置条件与这篇讲什么
先确认 AIP 已开启,再决定走官方模型还是自定义模型。
用 Palantir 提供的语言模型前,原文要求两件事:你的 enrollment 上必须已启用 AIP,
并且你要有使用 AIP 开发者能力(AIP developer capabilities)的权限。
先分清路线:如果你要用的是自己的模型,请直接看本系列下一篇《用自定义模型做语义搜索》。
这一篇只讲「用 Palantir 提供的嵌入模型」。
整篇目标很明确:用官方嵌入模型,搭建一个端到端的语义搜索工作流。
核心思路是先生成嵌入、存进带 vector 类型属性的对象类型,再在 Workshop / AIP Logic 里使用。
## 总览:三条搭建路线
先有嵌入与对象类型,再选「无码」或「写函数」路线。
原文把所有路线归纳成「一个前置 + 三种选项」:
前置:生成嵌入 + 建对象类型 用 Pipeline Builder 把文本转成向量,落到本体的 vector 属性上(三条路线共用)。
选项 A:Workshop KNN 对象集(无码) 在 Workshop 里配一个 KNN 对象集,零代码做语义搜索。
选项 B:AIP Chatbot(无码) 在 AIP Chatbot Studio 里加「本体语义搜索」工具,让机器人代你搜。
选项 C:写检索函数 写函数跨对象做语义搜索,可在 Workshop 与 AIP Logic 复用,且能按相关性排序。
## 步骤一:生成嵌入并建对象类型
用 Pipeline Builder 的「Text to Embeddings」把文本变成向量。
无论走哪条路线,第一步都一样:先有「带向量的对象」。
- 在 Pipeline Builder 里,用 Text to Embeddings 表达式把数据集里的文本转成向量。
- 该表达式接收一个字符串,用某个 Palantir 提供的模型把它变成向量;原文示例用的是 text-embedding-ada-002。
- 生成的嵌入要作为 vector 类型的属性加进本体(Ontology)。
>
想更可控:若需要对官方模型的嵌入生成有更多控制,原文指向「Python transforms 里的语言模型」用法,
可以在 Python transform 中调用 Palantir 提供的模型来生成嵌入。
## 步骤二:两种无码方案
Workshop KNN 对象集,或 AIP Chatbot——都不写代码。
### 方案 A:Workshop 里的 KNN 对象集
原文提醒:KNN 对象集无法按相关性排序。若你需要有序结果,要用后面的「函数方案」(TSv1 / TSv2,两者都支持相关性排序)。
配置步骤如下:
配置建对象集变量并选 embedding 属性
新建对象集变量 → 选含嵌入属性的对象类型 → 「+ On a property」选你的嵌入属性
选对属性后,KNN 配置面板会自动出现;若没出现,检查所选属性是否确为 embedding 类型。
参数K-value 与 Query
K-value:返回多少个对象;Query:用作查询的字符串变量
K-value 范围是 1–100。再建一个文本输入组件,把它的输出变量填进 KNN 的 Query。
展示对象表组件接 KNN 对象集
用户一输入,对象表就刷新出语义相关的结果
最后加一个 Object table 组件,输入变量选刚才的 KNN 对象集即可。
### 方案 B:AIP Chatbot(无码)
在 AIP Chatbot Studio 里建一个 Chatbot,添加 Ontology context,
或一个 Ontology semantic search 工具(tool)。这样用户就能直接让机器人对对象做语义搜索了。
## 步骤三:写检索函数(TSv1 / TSv2 / Python)
函数能按相关性排序,且可在 Workshop 与 AIP Logic 复用。
要「按相关性排序」或做更复杂逻辑,就得写函数,对对象类型跑 KNN 搜索。三种版本差别如下:
版本 查询嵌入怎么来 邻居数 k 相关性排序
TypeScript v1
用同款官方模型自己先嵌入查询,再把向量传给 nearestNeighbors
0 < K ≤ 100
额外调用 .orderByRelevance()
TypeScript v2
把用户文本直接传给 nearestNeighbors(它接受向量或文本)
numNeighbors 1–500
向 fetchPage() 传 $orderBy:"relevance"
Python
同样把查询文本传给 nearest_neighbors
由搜索范围约束
返回对象带 _score 字段
TSv1 专属配置:函数代码仓库的 functions.json 里必须有 "enableVectorProperties": true 这一项,
否则 KNN 搜不动。这是 TSv1 仓库的产物;TSv2 / Python 没有等价设置,文档未说明可直接沿用。
>
代码组织差异:TSv1 函数是导出类上的方法(通常在 functions-typescript/src/index.ts);
TSv2 是文件默认导出(位于 typescript-functions/src/functions,且文件名须与函数名一致);
Python 用 @function(beta=True) 声明(beta 特性)。
## 步骤四:发布并用于 Workshop / AIP Logic
发布函数后,在应用中调用;在 AIP Logic 里作为工具。
函数写好后,记得发布(publish)它,才能在 Foundry 各处使用。两种用法:
在 Workshop 用
加一个文本输入组件当函数入参;再加一个对象列表组件,输入选「函数生成的对象集」。邻居数(TSv1 的 kValue / Python 的 k_value)按上限填即可。
在 AIP Logic 用
把发布的函数作为工具(tool)加进 AIP Logic,用类似下面的提示让 LLM 调用它:
Use the findRelevantObjects tool with a kValue of 5...(注意查询加引号)。
## 动手演示:点开每步看完整配置流程
下面是把这一篇串起来的分层流程,点每层展开细节。
官方模型方案的完整路径就这五层。逐层点开,把每步该做什么记下来——它就是你在 Foundry 里真正要点的按钮。
全部展开
第 1 层确认 AIP 已启用 + 有权限
enrollment 开启 AIP,且你有 AIP developer capabilities 权限
这是所有后续步骤的前提;权限不够时函数与模型都调不动。
第 2 层Pipeline Builder 生成嵌入 + 建对象类型
Text to Embeddings 表达式(模型:text-embedding-ada-002)→ vector 属性
把文本的嵌入作为 vector 类型属性写进本体对象;这是三条路线共用的基础。
第 3 层选无码方案(可选)
Workshop KNN 对象集(K 1–100,不排序)或 AIP Chatbot 工具
零代码即可起步;若要相关性排序,跳过这层直接写函数。
第 4 层写检索函数(要排序就上这层)
TSv1 自嵌查询 / TSv2·Python 直传文本;KNN 搜索对象
TSv1 需 functions.json 里 enableVectorProperties:true;k 上限 100(TSv1)/500(TSv2)。
第 5 层发布并在 Workshop / AIP Logic 使用
发布函数 → Workshop 文本输入+对象列表;或 AIP Logic 加为工具
在 AIP Logic 里用提示让 LLM 调工具,例如 kValue of 5 找最相关对象。
## 一页带走
① 先开 AIP 启用 AIP + 开发者权限,是前提。
② 嵌入进本体 Pipeline Builder 生成向量,存为 vector 属性。
③ 无码或写函数 KNN/Chatbot 零代码;要排序就写函数。
④ 发布复用 函数发布后可在 Workshop 与 AIP Logic 使用。
### 常见问题速答 · FAQ
关于「不自己部署模型,也能搭出语义搜索」,读者最常问的几个问题。
前置条件与这篇讲什么? 用 Palantir 提供的语言模型前,原文要求两件事:你的 enrollment 上必须已启用 AIP,并且你要有使用 AIP 开发者能力(AIP developer capabilities)的权限。
总览:三条搭建路线是什么? 原文把所有路线归纳成「一个前置 + 三种选项」。
步骤一:生成嵌入并建对象类型是什么? 无论走哪条路线,第一步都一样:先有「带向量的对象」。
动手演示:点开每步看完整配置流程是什么? 官方模型方案的完整路径就这五层。逐层点开,把每步该做什么记下来——它就是你在 Foundry 里真正要点的按钮。
---
## 用"意思"来搜,而不是用"字"
- 页面:https://www.hanzhongpin.xyz/ontology/semantic-search.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/overview-semantic-search/
- 主题分组:语义搜索 Semantic search
循序渐进 · 教学 · 语义搜索 Semantic search
# 用"意思"来搜,而不是用"字"
语义搜索(semantic search)按文本的内在含义来检索,而不是只靠关键词匹配。这一篇讲它背后的嵌入(embedding)原理,
以及怎样把搜索结果和本体对象连起来,让运营工作流更聪明。
## 一句话速览
用"意思"来搜,而不是用"字":语义搜索(semantic search)按文本的内在含义来检索,而不是只靠关键词匹配。这一篇讲它背后的嵌入(embedding)原理,以及怎样把搜索结果和本体对象连起来,让运营工…
1 这一篇在讲什么 传统搜索靠"关键词匹配"——你输入什么字,系统就去找含这些字的文档
2 关键词搜索的局限 假设一份知识库里写着"面部遮挡物使用指南",而用户搜的是"口罩"
3 嵌入模型把文本变成向量 语义搜索靠 AI 模型把文本转换成向量(vector)——也就是一串数字组成的数组,也叫"嵌入(embedding)"
4 两条搭建路径(概览) 原文把后续学习资料分成两条线,本系列后面也会专门讲
## 这一篇在讲什么?
语义搜索:按含义检索,而非仅靠关键词或传统方法。
传统搜索靠"关键词匹配"——你输入什么字,系统就去找含这些字的文档。但用户的真实意图常常换了一种说法。
语义搜索(semantic search)要解决的正是这个问题:它根据文本的内在含义或上下文来检索,
而不只是依赖字面关键词。
Semantic search is a way to search for text based on the inherent meaning or context, rather than relying solely on keywords or other traditional search methods.
语义搜索是一种基于文本内在含义或上下文来检索的方式,而非仅仅依赖关键词或其他传统搜索方法。
这一篇是概览:先把"向量 / 嵌入"的直觉讲清楚,再告诉你怎么把搜索结果挂到本体对象上。
具体的搭建步骤(用官方模型、用自定义模型、做分块)留在本系列的后续几篇。
## 关键词搜索的局限
字面匹配会漏掉"同义但不同字"的相关内容。
假设一份知识库里写着"面部遮挡物使用指南",而用户搜的是"口罩"。关键词搜索只会找含"口罩"二字的文档,于是这篇指南被漏掉了——尽管它正是用户想要的。
✗ 关键词搜索
查询:口罩
命中:标题里出现"口罩"的文档
漏掉:面部遮挡物 / 呼吸防护
(同义,但字不一样 → 找不到)
→
✓ 语义搜索
查询:口罩
命中:意思相近的文档
包括:面部遮挡物 / 呼吸防护
(理解含义 → 找得到)
语义搜索不是要取代关键词搜索,而是补上"按意思找"这一层——尤其适合海量非结构化文本(PDF、工单、报告)。
## 核心原理:嵌入模型把文本变成向量
embedding model 输出一串数字(向量),意思越近、向量越近。
语义搜索靠 AI 模型把文本转换成向量(vector)——也就是一串数字组成的数组,也叫"嵌入(embedding)"。
如果模型够好,那么在一个 N 维空间里,彼此靠近的向量,就代表含义相近的文本。
输入一段文本
原始的句子 / 段落 / 文档
例如:"face mask"(口罩)、"face covering"(面部遮挡物)、"respirator"(呼吸器)。
模型嵌入模型 embedding model
把文本编码成一串数字
每个文本变成一个长度为 N 的向量。模型的质量决定了"近义文本是否真的向量相近"。
空间N 维空间里的最近邻
向量越近 = 含义越近
原文例子:"face mask" 的向量,比 "respirator" 更接近 "face covering"。检索 = 找最近的向量。
If the model is effective, the vectors, each of size N, that are close to each other in N-dimensional space are the ones that have similar underlying or semantic meaning. For example, the embedding vector of "face mask" will be closer to the embedding vector of "face covering" than it is to "respirator."
如果模型有效,那么在 N 维空间里彼此靠近的向量,正代表含义相近的文本。例如 "face mask" 的嵌入向量比 "respirator" 更接近 "face covering"。
## 把嵌入文本关联到本体对象
检索到的"近邻向量"一旦对应到对象,工作流就能直接用了。
光有向量还不够。原文强调:如果嵌入后的文本关联到本体(Ontology)里的某个对象,
你的"搜索驱动型运营工作流"会变得非常有用。
因为"找和某条查询相关的实体",本质上就变成了"在 N 维空间里找最近的向量"。
于是:
找相关实体 给定一段查询,返回向量最接近的本体对象列表。
找与某实体相关的 给定一个对象,返回和它语义相近的其他对象。
>
关键一步:嵌入向量必须和本体对象"绑"在一起(每个对象有自己的嵌入表示),语义搜索才能在 Workshop、Vertex 等应用里直接驱动检索与工作流。
## 两条搭建路径(概览)
用 Palantir 提供的模型,或用你自己的自定义模型。
原文把后续学习资料分成两条线,本系列后面也会专门讲:
路径 适合 本系列后续
用 Palantir 提供的模型
想快速起步、省去选模型与部署的麻烦
semantic-search-palantir-models.html
用自定义模型
已有自有嵌入模型、需要更可控
semantic-search-custom-models.html
### 练一练:该走哪条线?
>
配合 PDF 使用:原文还提到,做语义搜索时可以把长文档分块(chunking)再分别嵌入,效果更好——这正好衔接本系列下一篇《文档处理》。
## 动手演示:相似度排序
点一个查询,看结果按"向量距离 / 相似度"重新排序。
下面是一份知识库(8 篇)。点一个查询,右侧会按"与查询的相似度"从高到低排出结果,
并用横条显示相似度。越靠前 = 在向量空间里离查询越近 = 含义越相关。
动手试试 · 语义检索的相似度排序
查询:客户流失风险
查询:用户不再续费
查询:账户被异常登录
重置
点上方查询词,看结果如何按相似度排序
说明:这是教学用简化模型——真实语义搜索由嵌入模型算出查询与每篇文档的向量,再用余弦相似度排序。这里用预设的近似分数,只为你直观感受"意思越近排越前"。
## 一页带走
① 按意思找 语义搜索基于含义 / 上下文,不只靠关键词。
② 向量即含义 嵌入模型把文本编码成向量,近邻 = 近义。
③ 绑到对象 嵌入关联本体对象,检索直接驱动工作流。
④ 两条路径 官方模型快速起步;自定义模型更可控。
### 常见问题速答 · FAQ
关于「用"意思"来搜,而不是用"字"」,读者最常问的几个问题。
这一篇在讲什么? 传统搜索靠"关键词匹配"——你输入什么字,系统就去找含这些字的文档。但用户的真实意图常常换了一种说法。语义搜索(semantic search)要解决的正是这个问题:它根据文本的内在含义或上下文来检索,而不只是依赖字面关键词。
关键词搜索的局限是什么? 假设一份知识库里写着"面部遮挡物使用指南",而用户搜的是"口罩"。关键词搜索只会找含"口罩"二字的文档,于是这篇指南被漏掉了——尽管它正是用户想要的。
核心原理:嵌入模型把文本变成向量是什么? 语义搜索靠 AI 模型把文本转换成向量(vector)——也就是一串数字组成的数组,也叫"嵌入(embedding)"。如果模型够好,那么在一个 N 维空间里,彼此靠近的向量,就代表含义相近的文本。
把嵌入文本关联到本体对象是什么? 光有向量还不够。原文强调:如果嵌入后的文本关联到本体(Ontology)里的某个对象,你的"搜索驱动型运营工作流"会变得非常有用。
---
## 配置通知(Set up a notification)
- 页面:https://www.hanzhongpin.xyz/ontology/set-up-notification.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/set-up-notification/
- 主题分组:动作类型详解
动作类型详解
# 配置通知(Set up a notification)
跟着做一遍:给一个"修改工单优先级"的动作加上通知,自动提醒工单上的负责人。这是一篇手把手教程,从前提到发测试通知逐步来。
## 一句话速览
配置通知(Set up a notification):跟着做一遍:给一个"修改工单优先级"的动作加上通知,自动提醒工单上的负责人。这是一篇手把手教程,从前提到发测试通知逐步来。
1 前置条件 本教程假设你已经完成了动作的入门教程(Getting Started),并有一个这样的动作:它接收一个对象 + 一个新优先级参数,然…
2 添加一条通知规则 打开那个"修改工单优先级"的动作,在 Rules 区域点 Add new rule,然后选 Notification
3 配置接收人(recipients) 在 Recipients 下拉里,选 Recipient(s) from property of object parameter
4 配置内容(content) 在内容选项里选 Template——这是最直接、不需要写代码的方式
## 前置条件
开始前,你需要先有一个可编辑的对象和一个会改它的动作。
本教程假设你已经完成了动作的入门教程(Getting Started),并有一个这样的动作:它接收一个对象 + 一个新优先级参数,然后把该对象的 Priority 属性改掉。
此外,你的对象上需要有一个存"负责人"的属性——教程里叫 Case Managers,里面放的是该工单当前负责人的 Foundry 用户 ID。通常你会在应用里用"用户选择器"组件捕获并存储这个 ID,它在 Foundry 各处会显示成完整用户名。
> 提示:若你只想先验证逻辑,可暂时把接收人写成"固定的自己",等确认无误再换成来自对象属性的动态接收人。
## 添加一条通知规则
在动作的 Rules 区里,选择 Notification。
打开那个"修改工单优先级"的动作,在 Rules 区域点 Add new rule,然后选 Notification。这会打开通知的配置对话框。
1
### 入口位置where to click
- 动作编辑器 → Rules 区
- Add new rule → Notification
- 弹出的对话框里分别填接收人与内容
## 配置接收人(recipients)
本例:通知工单对象上"负责人"属性里存的那个用户。
在 Recipients 下拉里,选 Recipient(s) from property of object parameter。然后:
- 选择作为动作参数的那个 Alert 对象;
- 在弹出的提示里,选 Case managers 属性。
配置框里就会显示出"所选对象参数 + 属性"。关键点:接收人必须始终是 Foundry 用户 ID。如果该属性里放的是普通邮箱字符串之类,通知就发不出去。
点击揭晓:教程为什么建议测试时先用"固定接收人"?
## 配置内容(content)
用 Template 直接写,按名字称呼接收人,并带上新旧优先级。
在内容选项里选 Template——这是最直接、不需要写代码的方式。
- Subject(主题):输入你想说的话。要插入参数引用,打一个 / 再从下拉选参数;如果选的是对象参数,还会让你再选要引用的属性。
- Body(正文):写一段以接收人名字称呼、说明"谁做了改动"、并报告"之前/之后状态"的文字。
- 下拉里可选 Recipient、Current User 及任意参数,自动生成对应用户属性的引用。
这样通知就能"称呼对方名字 + 说明改动前后",比干巴巴一句"有更新"友好得多。
## 配置链接并发送测试
加一个"查看工单"按钮,然后真正跑一次验证。
最后,给通知加一个链接:选 Object View,再选你的工单对象参数,按钮文字填 View Ticket。这样接收人点一下就能跳到 Object Explorer 里那张工单。
保存后,就可以验证了:
- 建一张测试工单,把自己设为负责人 这样才能收到通知。
- 把动作暴露出来运行 通过 Object Explorer,或 Workshop 模块里的一个按钮来触发动作。
- 检查两种送达 你应该同时收到平台内推送和发到你 Foundry 用户资料的邮件。配置视图里也会显示两种预览。
- 没收到邮件? 可能你在 User Settings → Notifications 里关了邮件/平台通知,去那里确认。
## 一页带走
① 入口在 Rules Add new rule → Notification,打开配置对话框。
② 接收人取属性 Recipient(s) from property of object parameter,属性须是用户 ID。
③ 内容用 Template 打 / 插入参数,按名称呼接收人并带新旧值。
④ 加链接 + 测试 Object View 链接 + 自己建测试工单跑一次验证。
### 常见问题速答 · FAQ
关于「配置通知(Set up a notification)」,读者最常问的几个问题。
前置条件是什么? 本教程假设你已经完成了动作的入门教程(Getting Started),并有一个这样的动作:它接收一个对象 + 一个新优先级参数,然后把该对象的 Priority 属性改掉。
添加一条通知规则是什么? 打开那个"修改工单优先级"的动作,在 Rules 区域点 Add new rule,然后选 Notification。这会打开通知的配置对话框。
配置接收人(recipients)是什么? 在 Recipients 下拉里,选 Recipient(s) from property of object parameter。然后。
配置内容(content)是什么? 在内容选项里选 Template——这是最直接、不需要写代码的方式。
---
## 配置 Webhook(Set up a webhook)
- 页面:https://www.hanzhongpin.xyz/ontology/set-up-webhook.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/set-up-webhook/
- 主题分组:动作类型详解
动作类型详解
# 配置 Webhook(Set up a webhook)
跟着做一遍:给一个动作加上 Webhook,把数据发往外部系统。本篇是手把手教程,从前置条件到保存,重点讲清"副作用 / 写回"模式的取舍。
## 一句话速览
配置 Webhook(Set up a webhook):跟着做一遍:给一个动作加上 Webhook,把数据发往外部系统。本篇是手把手教程,从前置条件到保存,重点讲清"副作用 / 写回"模式的取舍。
1 前置条件 开始前需要两件事
2 添加一条 Webhook 规则 示例里我们假设已有一个叫 Modify ticket priority 的 Webhook,它接收一个 priority 字符串并发…
3 副作用 or 写回 新加的 Webhook 默认被配成 side effect——也就是在 Foundry 里的对象被改之后才运行
4 选择 Webhook 并配置输入 在下方菜单里选你要执行的 Webhook(示例选 Modify ticket priority),需要的话还可以选它的某个版本(ve…
## 前置条件
先有一个基础动作,且在 Data Connection 里先建好 Webhook。
开始前需要两件事:
- 已完成动作的入门教程(Getting Started),知道怎么建一个基础动作;
- 已在 Data Connection 里建好一个 Webhook(用于连接外部系统)。这一步可能需要有"连接源系统"权限的管理员协助。
点击揭晓:为什么"建 Webhook"这一步常需要管理员?
## 添加一条 Webhook 规则
在动作的 Logic 标签页里,Add new rule → Webhook。
示例里我们假设已有一个叫 Modify ticket priority 的 Webhook,它接收一个 priority 字符串并发往外部系统。
打开你的动作,切到 Logic 标签页,点 Add new rule,然后选 Webhook。这会新增一条 Webhook 规则。
## 选择模式:副作用 or 写回
默认是 side effect(改完再发);想"外部不成、本体不改"就选 Writeback。
新加的 Webhook 默认被配成 side effect——也就是在 Foundry 里的对象被改之后才运行。如果你要它先在外部系统执行、再改本体,就选 Writeback。
默认 SIDE EFFECT
对象改完 → 再发请求。用户先看到成功,失败不阻塞本体改动。
or
可选 WRITEBACK
先发请求 → 再改对象。外部失败则动作停下、本体不改。
## 选择 Webhook 并配置输入
选中具体的 Webhook(可指定版本),再把输入映射到动作参数。
在下方菜单里选你要执行的 Webhook(示例选 Modify ticket priority),需要的话还可以选它的某个版本(version)。
接着配置输入参数:
- 默认会为每个 Webhook 输入生成一个新动作参数;
- 若已存在同名的动作参数,则自动复用、直接配好;
- 本例把 Webhook 输入 priority 映射到已有的动作参数 Ticket Priority。
配好后点 Add webhook 把这条规则加进动作。Rules 区会显示:写回会在对象被修改之前发生。
## 收尾并保存
清理无用参数,点保存,动作就能触发外部请求了。
- 删除多余的自动生成参数 如果加 Webhook 时生成了现在用不到的参数,顺手清掉。
- 点右上角 Save 保存对动作的修改。
- 生效 之后动作被应用时,向外部系统的请求会在本体改动之前发出(Writeback 模式)。
> 下一步:想了解 Webhook 的全部选项,回看 Webhooks 总览;要用函数配置输入,可查 Input parameters 一节。
## 一页带走
① 先有连接 Data Connection 里先建 Webhook(常需管理员),动作里才能引用。
② Logic 里加 Logic → Add new rule → Webhook,新增一条规则。
③ 默认副作用 默认 side effect(改后发);要"外部先成"就改 Writeback。
④ 映射输入 输入映射到动作参数,清理无用参数后 Save 生效。
### 常见问题速答 · FAQ
关于「配置 Webhook(Set up a webhook)」,读者最常问的几个问题。
添加一条 Webhook 规则是什么? 示例里我们假设已有一个叫 Modify ticket priority 的 Webhook,它接收一个 priority 字符串并发往外部系统。
选择模式:副作用 or 写回是什么? 新加的 Webhook 默认被配成 side effect——也就是在 Foundry 里的对象被改之后才运行。如果你要它先在外部系统执行、再改本体,就选 Writeback。
选择 Webhook 并配置输入是什么? 在下方菜单里选你要执行的 Webhook(示例选 Modify ticket priority),需要的话还可以选它的某个版本(version)。
---
## 副作用(Side Effects)总览
- 页面:https://www.hanzhongpin.xyz/ontology/side-effects-overview.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/side-effects-overview/
- 主题分组:动作类型详解
动作类型详解
# 副作用(Side Effects)总览
动作类型(action types)不只是修改本体(Ontology)里的对象,还能把数据"送出去",去接入你组织里既有的业务流程。这一篇先建立整体心智模型:副作用是什么、有哪两种、分别解决什么问题。
## 一句话速览
副作用(Side Effects)总览:动作类型(action types)不只是修改本体(Ontology)里的对象,还能把数据"送出去",去接入你组织里既有的业务流程。
1 "副作用(side effect)" 在 Foundry 里,动作类型(action types)的核心职责是:用 规则(rules)来定义对本体对象的修改(增、删、改)…
2 通知 vs Webhook 官方文档明确指出,动作类型的副作用主要有两种
3 通知(notification)能做什么 通知允许你灵活地配置:当某个动作被应用时,该如何通知用户
4 Webhook 能做什么 Webhook 让你能以极高的灵活度连接 Foundry 之外的系统,包括向一个 REST API 或 ERP 系统发送请求
## 什么是"副作用(side effect)"
当本体成为某个决策流程的"记录系统"时,动作除了改数据,还需要向外通报或联动。
在 Foundry 里,动作类型(action types)的核心职责是:用 规则(rules) 来定义对本体对象的修改(增、删、改)。但一个组织真实的决策流程,往往不止"改个字段"这么简单——你常常需要:
- 在系统里发生变动时,通知(notify)相关的人,让他们能及时响应;
- 当"真相来源"在 Foundry 之外的系统时,去集成(integrate)那个外部系统,这种把决策"编排"出去的模式有时被称为 decision orchestration(决策编排)。
Side effects in action types enable you to send data out of Foundry to integrate with existing organizational processes.动作类型中的副作用,让你能够把数据送出 Foundry,从而接入组织既有的业务流程。
简单说:副作用就是把数据"送出 Foundry"——它不是改本体本身,而是动作执行后顺带发生的、对外部世界的影响。下面这张分层图帮你理解它在本体流程里的位置。
本体规则(rules)修改本体对象
动作被应用时,先按规则对 Ontology 中的对象做增删改。
规则是动作类型的"主菜":例如"把这张工单的优先级改为高""新建一个任务对象"。这些修改通常发生在副作用之前(side effect 模式)或之后(writeback 模式,详见 Webhook 篇)。
副作用把变化"送出去"
在对象改动之上,顺带通知人或调用外部系统。
副作用有两种:通知(notification)和 Webhook。它们让动作不再"孤芳自赏",而是真正融入组织的工作流。
外部人或系统收到并响应
用户收到提醒去处理;ERP / REST API 收到请求去写回数据。
这一步发生在 Foundry 之外。副作用通常是"尽力而为(best-effort)"的:即使它失败,本体改动一般也已经发生(side effect 模式)。
> 提示:副作用是"附加项"。即使没有配置任何副作用,一个动作依然可以正常修改本体对象。
## 两种副作用类型:通知 vs Webhook
两者都"把数据送出去",但送的对象和灵活度差别很大。
官方文档明确指出,动作类型的副作用主要有两种:
通知 NOTIFICATION
对象:Foundry 平台内的用户
方式:平台内弹窗 / 邮件
灵活度:可配置"谁、在什么内容下"收到提醒
适合:让人知道"发生了什么",并附上链接快速跳转处理。
vs
WEBHOOK
对象:Foundry 之外的系统
方式:发起 HTTP 请求(REST API / ERP)
灵活度:极高,可写回外部源系统
适合:把决策结果真正"写回"外部系统,或接入消息系统做更灵活的提醒。
一句话区分:通知是对"人"说话,Webhook 是对"系统"说话。下两节分别展开它们各自能做什么。后面几篇(notifications / webhooks 及其配置教程)会手把手带你把它们配起来。
## 通知(notification)能做什么
实时流程里,让人第一时间知道系统里发生了什么变化。
通知允许你灵活地配置:当某个动作被应用时,该如何通知用户。它最典型的用途,是向平台上的用户发送一封邮件或一条平台内提醒。
- 可以指定接收人(recipients):固定的人/组、动作参数里的用户、对象属性里的用户、甚至用函数动态算出来;
- 可以配置内容(content):主题、正文、可选链接(指向对象、Workshop 应用、新建对象等);
- 可以支持邮件的自定义 HTML,做更高级的排版。
通知非常适合实时流程:当系统里"工单被改派""风险被标记"这类事件发生时,立刻让人去响应。
## Webhook 能做什么
当"真相来源"在 Foundry 之外时,把决策结果写回外部系统。
Webhook 让你能以极高的灵活度连接 Foundry 之外的系统,包括向一个 REST API 或 ERP 系统发送请求。这意味着你可以:
- 把决策结果写回(write back)到组织里的其他源系统;
- 通过接入消息系统,更灵活地给用户发通知(相比平台内建的通知)。
Webhooks allow you to connect to systems outside Foundry in a highly flexible way, including sending requests to a REST API or an ERP system.Webhook 让你以极高灵活度连接 Foundry 之外的系统,包括向 REST API 或 ERP 系统发送请求。
这就是前面提到的 decision orchestration(决策编排):本体里做出的决定,顺着 Webhook 流回外部系统,让两套系统保持一致。
点击揭晓:Webhook 相比通知,独特的能力是什么?
## 何时用哪一个
先判断"接收方是人还是系统",再决定。
把前两节合起来,决策其实很简单:
流
### 选择决策树how to choose
问自己两个问题
- 接收方是人吗? 是 → 用通知(让人知道并响应)。
- 接收方是 Foundry 之外的系统吗? 是 → 用 Webhook(把数据/决策写回去)。
- 既要通知人、又要联动系统? 可以两者都配:用 Webhook 接消息系统发提醒,或用通知 + Webhook 双管齐下。
记住:通知只"说给人听",Webhook 才"写给系统看"。需要修改外部系统的数据时,通知做不到,必须用 Webhook。
下一篇我们先深入通知:它能发给谁、内容怎么配、有哪些限制。之后再讲 Webhook 与各自的配置教程,以及定时触发构建。
## 一页带走
① 副作用 = 送出数据 动作执行后把数据送出 Foundry,接入外部业务流程,是规则的附加项。
② 通知对人说话 通知面向平台用户,可发平台内提醒和邮件,让人及时响应。
③ Webhook 对系统说话 Webhook 向外部系统发 HTTP 请求,能把决策写回 ERP / REST API。
④ 先判接收方 接收方是人→通知;是外部系统→Webhook;两者都要就都配。
### 常见问题速答 · FAQ
关于「副作用(Side Effects)总览」,读者最常问的几个问题。
通知(notification)能做什么? 通知允许你灵活地配置:当某个动作被应用时,该如何通知用户。它最典型的用途,是向平台上的用户发送一封邮件或一条平台内提醒。
Webhook 能做什么? Webhook 让你能以极高的灵活度连接 Foundry 之外的系统,包括向一个 REST API 或 ERP 系统发送请求。这意味着你可以。
---
## 动作·提交条件(Submission Criteria)
- 页面:https://www.hanzhongpin.xyz/ontology/submission-criteria.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/submission-criteria/
- 主题分组:动作类型详解
动作类型详解
# 动作·提交条件(Submission Criteria)
提交条件决定一个动作能不能被提交。它把业务规则"焊"进数据编辑权限里,
保证本体数据质量与编辑治理。这一篇讲清它是什么、由什么组成、怎么配置。
## 一句话速览
动作·提交条件(Submission Criteria):提交条件决定一个动作能不能被提交。它把业务规则"焊"进数据编辑权限里,保证本体数据质量与编辑治理。这一篇讲清它是什么、由什么组成、怎么配置。
1 提交条件 = "这条动作现在能不能交" 提交条件(submission criteria)是判断一个动作能否被提交的一组条件
2 条件 + 运算符 条件(condition)是单一的比较检查:在中间用一个运算符,比较两个值
3 比、比什么 运算符定义两个值之间的比较
4 失败消息与测试运行 失败消息(failure message)定义当动作无法提交时,向用户展示什么错误
## 一句话:提交条件 = "这条动作现在能不能交"
Submission criteria(原名 validations)决定动作是否可提交。
提交条件(submission criteria)是判断一个动作能否被提交的一组条件。它把业务规则编码进
数据编辑权限里,从而保证本体(Ontology)的数据质量与编辑治理。
Submission criteria are the conditions that determine whether an action can be submitted.
提交条件是决定一个动作能否被提交的那些条件。
提交条件由条件(conditions)和运算符(operators)组合而成:把"基于上下文的值"
(比如当前用户、某个参数)与"静态信息"拼成一条逻辑判断。它可以纳入对象、关系、甚至用户信息来做判断。
>
两个关键点:① 只有当所有提交条件都满足时,动作才允许提交;
② 提交条件独立于"用户能否编辑这个动作类型本身"的权限——它是提交那一刻的额外校验。
同一个对象类型可以有多个动作类型(增/改/删),每个动作类型有自己独立的提交条件。
## 它由什么组成:条件 + 运算符
一个条件是比较两个值;运算符把多个条件拼起来。
条件(condition)是单一的比较检查:在中间用一个运算符,比较两个值。每个条件要么通过、要么失败。
运算符(operator)则用来把不同的条件组合、嵌套,写出贴近真实业务流程的复杂逻辑。
条件 Condition
一条"值 A 运算符 值 B"的判断。例如:当前用户是否属于某组、某参数值是否等于预期。
运算符 Operator
把多个条件用"全部满足 / 任一满足 / 都不满足"等逻辑组合、甚至嵌套,构成完整规则。
举个航空业的例子:航司想修改某航班(Flight)关联的飞机(Aircraft)。动作本身允许用户改链接,
但航司只希望特定的用户(如飞行调度员)能这么改,并且只允许使用仍在运营状态的飞机。
用提交条件就能把"用户属于某组"和"飞机状态为运营中"这两条绑在一起,缺一不可。
## 三种条件模板:从哪拿要比较的值
Current user / Parameter / Execution context。
条件模板 拿什么值来比较 典型用途
Current user 当前用户 提交动作的人:用户 ID、所属组(group IDs)、MultiPass 属性(如组织)。 限制"只有某角色的人能提交"。
Parameter 参数 动作参数区里定义的参数(由用户或其他应用传入)。 把业务规则嵌进参数,挡掉不合规的数据。
Execution context 执行上下文 动作是在什么上下文被评估的,例如是否在某个本体场景(Ontology Scenario)内提交。 场景内允许规划者试算,正式环境只允调度者。
>
Current user 细节:用户 ID 被当作字符串,可与静态 ID 列表或存放 ID 的字符串参数比较。组(group)选项可基于
用户直接或继承的组成员身份判断。MultiPass 属性被当成字符串列表处理。
坑:别对组/标记/组织成员用 NOT。 平台支持"作用域令牌(scoped token)"——它只携带用户权限的子集,
可能缺少 NOT 要检查的那条属性,于是条件反而通过、发给了不该有的权限。这是典型的误配置。
>
支持范围:提交条件不支持附件(attachment)与对象集(object set)参数,这两类会从选择面板里被移除。
## 运算符与取值:怎么比、比什么
运算符会按参数类型预筛;值可以是参数、静态值或"空"。
运算符定义两个值之间的比较。为简化配置,系统会按参数类型预筛只显示合法的运算符;一旦改了参数,用到它的条件都要重配。
单值参数常用运算符
运算符 含义
is 左值完全等于右值。
is not 左值与右值不相等。
matches 左值匹配某个正则(如 ^[AEI])。
is less than / is greater than or equals 数值比较(小于 / 大于等于)。
多值参数常用运算符
运算符 含义
includes 左值中至少有一个等于右值。
includes any 左值中至少有一个等于右值列表中的某一个。
is included in 左值等于右值列表中的某一个。
each is / each is not 左值全部等于 / 全都不等于右值。
值(value)是比较的另一侧:可以基于某个已有参数、一个静态值,或"无值(no value)"——
后者用来判断第一个值是否为空(null)。在航班例子里:调度员的组用静态值选定(每次都一样);
飞机"在运营"则要求状态属性等于静态值 Yes。最后用逻辑运算符把多个条件串起来,可嵌套、可要求"全部/任一/都不"。
点我看航班例子的完整配置思路 →
## 失败消息与测试运行
不满足条件时,告诉用户"为什么被拦"。
失败消息(failure message)定义当动作无法提交时,向用户展示什么错误。根层级上的每个条件与逻辑运算符都有自己的失败消息;
底层条件不通过时,显示的是其对应父级的失败消息。
>
哪都能看到:只要条件不满足,这条消息会在 Foundry 各处(Object Explorer、Workshop、Quiver)对用户显示,
明确告诉他们"为什么被拦下"。
另外,你可以用本体管理器(Ontology Manager)里的测试运行(test run),
针对一组给定的参数值,验证你的提交条件到底会如何评估。这在正式上线前很有用。
## 动手:该用哪种条件模板?
逐个场景判断。点选项看解析。
## 一页带走
① 提交条件 = 能否提交 决定动作此刻能不能交;所有条件都满足才放行,独立于编辑权限。
② 组成:条件 + 运算符 条件比较两个值;运算符组合、嵌套多个条件成业务规则。
③ 三模板取值 Current user(谁提交)/ Parameter(带什么参数)/ Execution context(在哪提交)。
④ 消息 + 测试 失败消息说明被拦原因;用 test run 验证条件评估。别对组用 NOT。
### 常见问题速答 · FAQ
关于「动作·提交条件(Submission Criteria)」,读者最常问的几个问题。
提交条件 = "这条动作现在能不能交"是什么? 提交条件(submission criteria)是判断一个动作能否被提交的一组条件。它把业务规则编码进 数据编辑权限里,从而保证本体(Ontology)的数据质量与编辑治理。
它由什么组成:条件 + 运算符? 条件(condition)是单一的比较检查:在中间用一个运算符,比较两个值。每个条件要么通过、要么失败。运算符(operator)则用来把不同的条件组合、嵌套,写出贴近真实业务流程的复杂逻辑。
运算符与取值:怎么比、比什么? 运算符定义两个值之间的比较。为简化配置,系统会按参数类型预筛只显示合法的运算符;一旦改了参数,用到它的条件都要重配。
失败消息与测试运行是什么? 失败消息(failure message)定义当动作无法提交时,向用户展示什么错误。根层级上的每个条件与逻辑运算符都有自己的失败消息;底层条件不通过时,显示的是其对应父级的失败消息。
---
## 上线前先试跑:安全地验证动作会改什么
- 页面:https://www.hanzhongpin.xyz/ontology/test-run.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/test-run/
- 主题分组:动作类型详解
动作类型详解
# 上线前先试跑:安全地验证动作会改什么
test run(试跑)让你在正式发布前,用真实权限模拟一次动作,看清它"会改什么、怎么执行",却不动真数据。
## 一句话速览
上线前先试跑:安全地验证动作会改什么:test run(试跑)让你在正式发布前,用真实权限模拟一次动作,看清它"会改什么、怎么执行",却不动真数据。
1 模拟,而非真的改 Test run 让你在 Ontology Manager 里模拟一个动作类型,在终端用户能应用它之前就验证逻辑
2 Proposed changes 一次完成的试跑,结果分布在两个标签里
3 Details Details 标签说明动作是如何被评估的、在直接编辑之外还会发生什么
4 会被跳过的部分 & 外部调用 试跑只执行"确定动作结果"所需的工作,那些在动作应用之后才生效的副作用会被跳过
## 什么是试跑:模拟,而非真的改
试跑(test run)在动笔生产数据之前,先看清后果。
Test run 让你在 Ontology Manager 里模拟一个动作类型,在终端用户能应用它之前就验证逻辑。提交一次试跑时,Foundry 会用你提供的参数值去评估这个动作,并返回它本将产生的编辑,以及一份详细的执行分解(execution breakdown)。
关键点:试跑产生的编辑不会应用到你的本体(Ontology)上。它是一种安全地"预览"动作会做什么、会怎么执行的方式,不改动任何数据。
试跑在动作类型编辑器里、动作表单预览(action form preview)的 Test run 标签下可用。它会以你的权限在当前本体分支上执行,并强制实施与普通动作提交相同的对象安全(object security)和提交条件(submission criteria)。只要你能查看该动作类型的配置,就能跑试跑。
## 运行一次试跑:五步走
流程很简单,但有两个前提要注意。
步骤 1打开动作类型
在 Ontology Manager 里打开一个动作类型,并打开它的动作表单预览
进入动作类型编辑器后,找到动作表单预览(action form preview)区域。
步骤 2确认是表单布局
试跑只在 form layout 可用
确认预览处于表单(form)布局。试跑在表单布局下可用,表格(table)布局下不可用。
步骤 3切到 Test run 标签
在表单预览里点 Test run
在动作表单预览中选中 Test run 标签。
步骤 4填入参数值
用你想测试的参数值把表单填好
在表单中填入你希望测试的参数值。
步骤 5点 Submit 运行
等待运行完成后查看结果
选 Submit 运行测试;结果会显示在动作表单预览中。
> 注意:当动作类型还有未保存的修改时,试跑不可用——先保存,确保试跑评估的是已保存的配置。
试跑(test run)在哪种表单布局下可用?点我看推荐 →
## 解读结果(一):Proposed changes
这一页列出"动作会改动哪些对象"。
一次完成的试跑,结果分布在两个标签里。先看 Proposed changes(提议的改动):
- 列出动作会对本体做出的编辑,包括创建、修改、删除的对象与链接;
- 属性变更以"当前值 vs 提议值"的对比方式呈现;
- 如果动作不会产生任何编辑,该标签会显示 No proposed changes。
这一页回答的核心问题是:"这个动作到底会动哪些数据?"
## 解读结果(二):Details
这一页解释"动作是怎么被评估的"。
Details 标签说明动作是如何被评估的、在直接编辑之外还会发生什么:
- Execution log(执行日志):分步记录这次运行——元数据加载、依赖校验、提交条件、参数校验、编辑计算。用它理解动作为何成功、或卡在哪一步。
- Side effects(副作用):预览动作会触发的副作用,如通知(notification)。可展开通知预览,查看将生成的内容与接收人。
- Referred entities(引用的实体):运行期间动作引用的对象类型、链接类型、接口类型与函数(functions)。
如果动作失败,Details 会把错误分成两类:Admin-facing errors(给管理员排查的技术细节)和 End-user-facing errors(展示给触发动作的用户的消息)。
## 会被跳过的部分 & 外部调用
试跑只做"算出结果所必需"的工作。
试跑只执行"确定动作结果"所需的工作,那些在动作应用之后才生效的副作用会被跳过。若你的动作类型包含以下任何一项,表单预览会提示它们将被跳过:
- 副作用 webhook(side effect webhooks)不会被调用;
- 通知(notifications)不会被发送,但结果里会显示"本将被触发"的通知分解;
- 计划构建(schedule builds)不会被触发。
但要注意:为了得出准确结果,试跑会执行动作达成结果所需的函数与调用——包括规则里的函数、生成通知正文/接收人的函数、生成 webhook 载荷的函数、writeback webhooks,以及访问外部资源的函数。也就是说,只有"算出结果所必须"的调用才会发出。
外部调用可能真的产生影响:因为外部调用会被执行,它们可能真的动到外部系统。当动作类型包含这类调用时,Foundry 会列出执行来源,并提示你先 Confirm the external call(确认外部调用),试跑才会继续;调用只在你确认后执行。
## 一页带走
① 模拟不改数据 test run 用你的权限预览编辑,结果不写入本体。
② 表单布局 + 先保存 仅 form layout 可用;有未保存修改时不可用,先保存。
③ 两页结果 Proposed changes 看改了啥;Details 看日志/副作用/引用实体。
④ 外部调用要确认 通知/webhook/构建会被跳过,但必要的外部调用需确认才执行。
### 常见问题速答 · FAQ
关于「上线前先试跑:安全地验证动作会改什么」,读者最常问的几个问题。
什么是试跑:模拟,而非真的改? Test run 让你在 Ontology Manager 里模拟一个动作类型,在终端用户能应用它之前就验证逻辑。提交一次试跑时,Foundry 会用你提供的参数值去评估这个动作,并返回它本将产生的编辑,以及一份详细的执行分解(execution breakd…
Proposed changes是什么? 一次完成的试跑,结果分布在两个标签里。先看 Proposed changes(提议的改动)。
解读结果(二):Details是什么? Details 标签说明动作是如何被评估的、在直接编辑之外还会发生什么。
会被跳过的部分 & 外部调用是什么? 试跑只执行"确定动作结果"所需的工作,那些在动作应用之后才生效的副作用会被跳过。若你的动作类型包含以下任何一项,表单预览会提示它们将被跳过。
---
## 定时触发构建(Trigger a scheduled build)
- 页面:https://www.hanzhongpin.xyz/ontology/trigger-schedule-build.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/trigger-schedule-build/
- 主题分组:动作类型详解
动作类型详解
# 定时触发构建(Trigger a scheduled build)
让本体里的工作流"顺手"重新计算数据集:给动作配一条调度规则(schedule rule),动作一执行就触发一次构建(build),用户不必再跑到 Data Lineage 或 Builds 应用去手动跑。
## 一句话速览
定时触发构建(Trigger a scheduled build):让本体里的工作流"顺手"重新计算数据集:给动作配一条调度规则(schedule rule),动作一执行就触发一次构建(build),用户不必再跑到 Data Lineage 或 B…
1 它是什么 Schedule(调度)定义了一组 Foundry 会在一次 build(构建)里重新计算的数据资源
2 配置调度规则(schedule rule) 给动作类型加一条 schedule rule,并选择一个调度
3 从调度"委派"给动作 动作类型的 submission criteria(提交条件)管理着"通过动作触发调度"所需的权限
4 跟踪构建进度 调度规则触发后,这次调度运行由一个 schedule run RID 标识
## 它是什么
一条 schedule rule,让动作应用时自动触发一次构建。
Schedule(调度)定义了一组 Foundry 会在一次 build(构建) 里重新计算的数据资源。给一个动作类型加上 schedule rule(调度规则),就能在动作被应用时,触发该调度的构建。
By configuring a schedule rule on an action type, you can trigger a build of that schedule whenever the action is applied.给动作类型配置一条调度规则,就能在动作被应用时触发该调度的构建。
价值在于:本体里的最终用户工作流,可以直接重新计算数据集,而不用让用户切去 Data Lineage 或 Builds 应用手动触发。
## 编辑与构建的顺序
构建一开始,本体编辑就"之后"应用——动作不等待构建完成。
关键点:当一个动作类型含 schedule rule 时,它的本体编辑会在构建开始之后才应用,而且不会等构建跑完。动作的行为是:
①触发构建(trigger the build)
动作应用 → 启动调度构建,并捕获 schedule run RID。
调度运行一旦启动,动作就拿到这次运行的 RID(schedule run RID),用于后续追踪。
②立即应用其余规则(含本体编辑)
不等待构建完成,马上把本体改动等规则应用掉。
也就是说:用户几乎立刻看到动作成功,而底层数据集的重新计算在后台异步进行。
## 配置调度规则(schedule rule)
加一条规则、选一个调度;参数化调度要填参数值。
给动作类型加一条 schedule rule,并选择一个调度。注意两点:
- 所选调度必须处于 project-scoped mode(项目作用域模式);
- 如果选中的调度是参数化(parameterized)的,必须为每个调度参数提供一个值;动作应用时会把解析出的参数值传给调度,并转发给构建里底层的参数化转换(transform)。
> 进阶:调度规则尤其适合搭配并行化参数化调度(parallelized parameterized schedules),用本体里的动作来实现并行调度。详情见参数化文档。
## 权限:从调度"委派"给动作
满足动作的提交条件,就能跑调度,无需调度本身的直接权限。
动作类型的 submission criteria(提交条件) 管理着"通过动作触发调度"所需的权限。只要用户满足动作提交条件,就能运行该调度,无需在调度上有任何直接权限。
Foundry 会在首次引用该调度时、以及每次编辑 schedule rule 时,检查用户是否有运行该调度的权限。从动作类型引用一个调度,等于把"运行它的控制权"从调度委派给了动作类型——任何能管理该动作类型上动作的人,就掌控了"谁能触发这个调度"。
点击揭晓:为什么"被动作引用"后,用户常无需调度的直接权限?
## 跟踪构建进度
把 schedule run RID 写进对象属性,并格式化成实时状态。
调度规则触发后,这次调度运行由一个 schedule run RID 标识。这个 RID 会作为一个值暴露出来,可供动作类型的本体编辑规则引用——你可以把它写进某个被编辑对象的字符串属性里,作为"这条对象触发了哪次构建"的记录。
- 在同动作类型上配 Modify/Create object 规则 把目标对象的某个字符串属性,映射到 schedule rule 提供的 schedule run RID 值。
- 对该属性应用 resource RID 格式化 启用后,Foundry 会把 RID 显示成一个带图标的链接,文字反映构建当前状态。
- 状态会实时更新 显示 Running / Ignored / Failed / Succeeded 之一。
> 提示:这样你就能在对象上直接看到一个"活的"构建状态指示,而不必去 Builds 应用里翻。
## 一页带走
① 一触即建 schedule rule 让动作应用即触发构建,省去手动去 Builds。
② 不等待 编辑在构建开始之后应用,动作不阻塞等构建完成。
③ 权限委派 满足动作提交条件即可触发;调度须 project-scoped。
④ 可见状态 把 schedule run RID 写进属性并格式化,看到实时构建状态。
### 常见问题速答 · FAQ
关于「定时触发构建(Trigger a scheduled build)」,读者最常问的几个问题。
它是什么? Schedule(调度)定义了一组 Foundry 会在一次 build(构建)里重新计算的数据资源。给一个动作类型加上 schedule rule(调度规则),就能在动作被应用时,触发该调度的构建。
权限:从调度"委派"给动作是什么? 动作类型的 submission criteria(提交条件)管理着"通过动作触发调度"所需的权限。只要用户满足动作提交条件,就能运行该调度,无需在调度上有任何直接权限。
跟踪构建进度是什么? 调度规则触发后,这次调度运行由一个 schedule run RID 标识。这个 RID 会作为一个值暴露出来,可供动作类型的本体编辑规则引用——你可以把它写进某个被编辑对象的字符串属性里,作为"这条对象触发了哪次构建"的记录。
---
## 上传附件(Attachment):把文件挂到对象上
- 页面:https://www.hanzhongpin.xyz/ontology/upload-attachments.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/upload-attachments/
- 主题分组:动作类型详解
动作类型详解
# 上传附件(Attachment):把文件挂到对象上
附件(attachment)是把文件"挂"在某个对象上的轻量方式。它从 Workshop、Object Explorer 等多处都能上传,权限跟随对象本身,但有明确的类型与大小限制。
## 一句话速览
上传附件(Attachment):把文件挂到对象上:附件(attachment)是把文件"挂"在某个对象上的轻量方式。它从 Workshop、Object Explorer 等多处都能上传,权限跟随对象本身,但有明确的类型与大小限制…
1 附件(attachment) 动作支持从 Workshop、Object Explorer、Object Views、Quiver、Slate 上传附件(atta…
2 参数类型选 Attachment 在参数配置视图(parameter configuration view)里,把参数类型选为 Attachment
3 属性类型选 Attachment 在对象详情视图里,把属性类型选为 Attachment
4 上传时机与自动清理 附件一旦被加入动作表单,就会立即上传到 Foundry
## 什么是附件(attachment)
先理解它的"身份"与"权限来源"。
动作支持从 Workshop、Object Explorer、Object Views、Quiver、Slate 上传附件(attachment)。对附件的查看、编辑、删除权限,与该附件所上传到的对象(object)保持一致。
例如:若用户对某对象有查看(view)权限,就能查看并下载挂在该对象上的附件;若要替换已有附件,则需要对对象有编辑(edit)权限。
> 提示:你可以上传单个附件,也可以上传一个附件列表(list of attachments)。一次传多份文件时,需要在动作与对象两侧都打开"允许多值"。
## 配置动作类型:参数类型选 Attachment
动作侧的两条硬约束。
在参数配置视图(parameter configuration view)里,把参数类型选为 Attachment。附件只能通过 attachment 参数类型上传。
同时有两个底层约束:
- 对象底层数据集(backing dataset)里对应的列必须是 String;
- 被编辑的对象属性必须是 Attachment 类型。
若要一次上传多份媒体文件,需勾选 Allow multiple values(允许多值)。不过仅此还不够——对象类型侧也要打开允许多值,下一步会讲。
## 配置对象类型:属性类型选 Attachment
对象侧也要打开"允许多值"。
在对象详情视图里,把属性类型选为 Attachment。附件只能上传到 attachment 属性类型。
如果想把多份文件传到一个属性上,需勾选 Allow multiple(允许多值)。此时,对象底层数据集里的该属性必须是 Array(数组)。
注意:"动作侧 Allow multiple values" 与 "对象侧 Allow multiple" 要两边同时打开,一次传多份文件才会真正生效。
## 上传时机与自动清理
附件是"先传后提交",取消会怎样?
附件一旦被加入动作表单,就会立即上传到 Foundry。在表单提交(submit)时,对附件的查看/编辑/删除权限,会从用户对底层对象类型的权限推断(inferred)出来。
如果表单提交失败或取消,那份"已上传但尚未真正挂上对象"的附件就不再可直接访问,并在一段时间后被自动永久删除。同理,属于已删除对象的附件、或因属性被删而不再映射到对象的附件,也会最终被自动永久删除。
提交失败/取消时,已上传但未关联的附件会怎样?点击揭晓。
## 规模限制:大小与关联数
两个硬上限要记牢。
附件同时支持 logic-backed 与 function-backed 动作。存在一条全局固定的文件大小上限:200MB。
此外,每个附件在其"生命周期"内最多可关联到 10 个对象。一旦关联到 10 个对象,即便其中某些原对象被删,也无法再关联其他对象;达到这个上限后,若想关联到更多对象,只能把文件重新上传为新的附件。
动手试:这两条限制分别管什么
单文件大小
关联对象数
单文件大小上限
200MB
全局固定上限;无论逻辑型还是函数型动作都受此约束。
单个附件最多关联对象
10 个
达上限后不可再关联;需重新上传为新的附件。
## 一页带走
① 权限随对象 附件的查看/编辑/删除权限与所属对象一致;替换需对象编辑权。
② 两侧都选 Attachment 动作参数与对象属性都须为 Attachment;底层列是 String(多值为 Array)。
③ 先传后提交 加入表单即上传;提交失败/取消则附件不再可达并最终自动删除。
④ 两个硬上限 单文件 200MB;单个附件最多关联 10 个对象,超限需重新上传。
### 常见问题速答 · FAQ
关于「上传附件(Attachment):把文件挂到对象上」,读者最常问的几个问题。
什么是附件(attachment)? 动作支持从 Workshop、Object Explorer、Object Views、Quiver、Slate 上传附件(attachment)。对附件的查看、编辑、删除权限,与该附件所上传到的对象(object)保持一致。
参数类型选 Attachment是什么? 在参数配置视图(parameter configuration view)里,把参数类型选为 Attachment。附件只能通过 attachment 参数类型上传。
属性类型选 Attachment是什么? 在对象详情视图里,把属性类型选为 Attachment。附件只能上传到 attachment 属性类型。
上传时机与自动清理是什么? 附件一旦被加入动作表单,就会立即上传到 Foundry。在表单提交(submit)时,对附件的查看/编辑/删除权限,会从用户对底层对象类型的权限推断(inferred)出来。
---
## 上传媒体(Media):用媒体集承载海量文件
- 页面:https://www.hanzhongpin.xyz/ontology/upload-media.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/upload-media/
- 主题分组:动作类型详解
动作类型详解
# 上传媒体(Media):用媒体集承载海量文件
上传图片、影像、文档这类"媒体"时,Foundry 推荐用媒体引用属性(media reference property)。它背后是媒体集(media set),能撑住数十亿文件,还自带转换与预览能力。
## 一句话速览
上传媒体(Media):用媒体集承载海量文件:上传图片、影像、文档这类"媒体"时,Foundry 推荐用媒体引用属性(media reference property)。
1 媒体引用属性(media reference property) 动作支持通过动作表单或表格上传媒体文件
2 文件选择器 → 媒体集 用户通过文件选择器(file-picker)界面上传媒体文件;在动作成功提交(submit)后,文件会被持久化(persist)到对…
3 配置上传媒体的动作 详细的配置步骤分两头
4 靠 submission criteria 管,而不是媒体集权限 通过动作上传媒体的权限,由 action submission criteria(动作提交条件)管理
## 什么是媒体引用属性(media reference property)
先弄清"媒体"和"附件"不是一回事。
动作支持通过动作表单或表格上传媒体文件。在 Foundry 大多数场景里,上传到 media reference(媒体引用)属性是推荐方法。
媒体引用属性由 media set(媒体集)支撑。它和附件属性(attachment property)相比有几个关键优势,我们下一步展开。简单说:附件适合"挂在对象上的小文件",媒体集适合"海量、需转换与预览的媒体"。
## 为什么推荐 media reference 而不是 attachment
四个理由,每一条都对应真实痛点。
可扩展Scalability
支持数十亿(billions)文件,存取都高效。
媒体集为大规模媒体存储与检索而生,远超附件通常的承载量级。
内置转换Built-in transformations
开箱即用地支持多种媒体转换与 LLM 能力。
不用自己搭管道,就能做格式转换、AI 处理等。
高级预览Advanced previews
对支持的格式提供内置渲染与富预览。
用户在界面里就能直接看内容,不用先下载。
格式支持Format support
兼顾标准格式与专业格式,如 NITF、GeoTIFF、DICOM。
对遥感、地理、医疗影像等专业场景很友好。
动手试:看清两种上传方式的定位
看 media reference
看 attachment
media reference
海量
背后是 media set;几十亿文件、内置转换与富预览,适合专业媒体。
attachment
轻量
挂在对象上的小文件;从 Workshop / Object Explorer 等多处上传,权限随对象。
## 上传流程:文件选择器 → 媒体集
用户怎么传,系统怎么存。
用户通过文件选择器(file-picker)界面上传媒体文件;在动作成功提交(submit)后,文件会被持久化(persist)到对应的 media set 中。
"Format conversions only happen after the action completes and the media file has been uploaded to the media set."格式转换只在动作完成、文件已上传到媒体集之后才会发生。
格式转换(format conversion)发生在什么时机?点击揭晓。
## 如何配置上传媒体的动作
配置落到两处:属性与动作。
详细的配置步骤分两头:
- 配置 media reference property(媒体引用属性)本身;
- 设置 upload media(上传媒体)动作。
也就是说,既要在对象类型侧把属性定义为媒体引用,也要在动作侧把上传媒体的能力接上。两者配齐,用户才能在表单里选文件、提交后落进媒体集。
> 提示:若你只想先理解概念,记住"属性侧定义 + 动作侧启用"这个两步结构即可;具体点击项随 Foundry 版本可能略有差异,以你实例里的配置向导为准。
## 权限:靠 submission criteria 管,而不是媒体集权限
一个反直觉但重要的点。
通过动作上传媒体的权限,由 action submission criteria(动作提交条件)管理。若用户满足了提交条件,即使对底层 media set 没有权限,也能上传媒体。
不过有个边界:当媒体集第一次被加到对象类型、或被动作类型引用时,会检查媒体集上的 Edit(编辑)权限。把媒体集加入本体(ontology)后,访问控制会从媒体集委派(delegate)给本体——这意味着任何能管理该对象类型动作的人,就能控制"谁可以往这个媒体集上传媒体"。
通过动作上传媒体的权限主要靠什么控制?点击揭晓。
## 一页带走
① 媒体引用是推荐项 media reference 背后是 media set,适合海量、需转换与预览的媒体。
② 四大优势 可扩展(数十亿)、内置转换、高级预览、专业格式(NITF/GeoTIFF/DICOM)。
③ 提交后才落库 文件在动作成功提交后持久化到 media set,格式转换也在之后。
④ 权限靠提交条件 满足 submission criteria 即可上传,无需 media set 权限;首次加入本体时检查 Edit。
### 常见问题速答 · FAQ
关于「上传媒体(Media):用媒体集承载海量文件」,读者最常问的几个问题。
一句话速览是什么? 上传媒体(Media):用媒体集承载海量文件:上传图片、影像、文档这类"媒体"时,Foundry 推荐用媒体引用属性(media reference property)。
上传流程:文件选择器 → 媒体集是什么? 用户通过文件选择器(file-picker)界面上传媒体文件;在动作成功提交(submit)后,文件会被持久化(persist)到对应的 media set 中。
---
## 把动作用起来:在 Object Explorer 与 Workshop 中触发
- 页面:https://www.hanzhongpin.xyz/ontology/use-actions.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/use-actions/
- 主题分组:动作类型详解
动作类型详解
# 把动作用起来:在 Object Explorer 与 Workshop 中触发
动作类型(action type)建好之后,要去哪里、怎么让用户真正点下那个按钮?这一篇讲配置与应用的位置。
## 一句话速览
把动作用起来:在 Object Explorer 与 Workshop 中触发:动作类型(action type)建好之后,要去哪里、怎么让用户真正点下那个按钮?这一篇讲配置与应用的位置。
1 single 与 bulk 文档用两个术语区分动作的范围
2 在 Object View 的 Actions 区块配置 在 Object View 里用 Actions section(动作区块)添加动作时,你可以
3 Object Explorer 的三个入口 在 Object Explorer 中,动作会自动出现在三处
4 在 Workshop 用 Button group 触发 在 Workshop 里,动作通过 Button group widget(按钮组组件)来配置和触发
## 动作如何出现在各处:single 与 bulk
同一个动作类型,会按"当前选了什么"自动出现在合适的位置。
文档用两个术语区分动作的范围:
- single action type(单对象动作):使用对象引用参数(object reference parameter),一次针对一个对象。
- bulk action type(批量动作):使用对象引用列表参数(object reference list parameter),一次针对一组对象。
下面每个位置都只列出"对当前选择适用"的动作类型。在批量上下文(比如列表视图里多选了对象)中,就只会出现"对象列表参数匹配所选对象类型"的批量动作。
> 提示:理解 single / bulk 的区别,是后面看 Object Explorer、Workshop 入口的前提。
## 在 Object View 的 Actions 区块配置
把动作加进对象视图,它就成了页面上的一个按钮。
在 Object View 里用 Actions section(动作区块)添加动作时,你可以:
- 把任意动作作为区块里的一个按钮(button);
- 给每个按钮设置自己的标签(label)和颜色(color);
- 把默认的"点击就弹表单"改成"用默认值立即应用(apply immediately)"——前提默认值合法;
- 指定:当某个不可见参数不合法时,按钮是隐藏还是禁用(思路是:可见参数还能在打开表单后修正);
- 给每个参数提供默认值:可以是当前对象的某个属性值,也可以是"本地值"(当前用户、当前时间戳、当前对象,或手动输入的值);
- 覆盖每个参数的可见性。
正因为能覆盖默认值与标签,你可以用同一个"通用动作"做出多个结构化版本——比如"延迟 10 分钟""延迟 30 分钟"等按钮。
## Object Explorer 的三个入口
动作会自动出现在 Object Explorer 的几个下拉里。
在 Object Explorer 中,动作会自动出现在三处:
- Exploration View 的 Actions 下拉在右上角。基于"当前这组对象",自动填入适用的批量(bulk)动作。
- Object View 的 Object Actions 下拉在右上角。基于"当前对象",自动填入适用的单对象与批量动作类型。
- Object View 的 Linked objects view section在顶部。基于"所选对象",自动填入适用的单对象 / 批量动作类型。
也就是说,你不用手动登记——只要动作类型的参数范围与当前选择匹配,下拉里就会出现它。
## 在 Workshop 用 Button group 触发
Workshop 的 Button group 组件配置项与 Object View 类似,但更灵活。
在 Workshop 里,动作通过 Button group widget(按钮组组件)来配置和触发。它的配置项和 Object View 的 Actions 区块基本相同,还有几个扩展:
- 有三种布局(layout)可选;
- 按钮有更多显示选项:左/右图标、极简样式(minimal)、标签样式(tag);
- 除了触发动作,单个按钮还能触发 Workshop 事件、打开 URL,或导出对象集(object set)。
还有一个区别:Workshop 里按钮的默认值除了"当前用户 / 当前时间戳",还可以是一个 变量(variable)。这让动作能直接接到 Workshop 应用的状态上。
Workshop 的 Button group 比 Object View 的 Actions 区块"多"出的能力之一是什么?点我看推荐 →
Each location below lists only the action types applicable to the current selection.下面每个位置都只列出对当前选择适用的动作类型。
## 一页带走
① single vs bulk 单对象用对象引用参数,批量用对象引用列表参数,按选择自动出现。
② Object View 配按钮 Actions 区块可设标签/颜色/默认值/可见性,一个动作变多个版本。
③ Explorer 三入口 Exploration View、Object View 的 Object Actions、Linked objects 三处下拉。
④ Workshop 更灵活 Button group 还能触发事件/URL/导出,默认值可为变量。
---
## Webhook
- 页面:https://www.hanzhongpin.xyz/ontology/webhooks.html
- 官方原文:https://www.palantir.com/docs/foundry/action-types/webhooks/
- 主题分组:动作类型详解
动作类型详解
# Webhook
Webhook 是动作"对外部系统说话"的通道:当有人在 Foundry 里执行动作,就向外部系统(如 Salesforce、SAP 或任意 HTTP 服务)发一个请求,把决策写回去。这一篇讲清两种配置模式与参数机制。
## 一句话速览
Webhook:Webhook 是动作"对外部系统说话"的通道:当有人在 Foundry 里执行动作,就向外部系统(如 Salesforce、SAP 或任意 HTTP 服务)发一个请求,把决策写回…
1 Webhook 是什么 Webhook 本是属于 Data Connection 的一个概念:向外部系统(如 Salesforce、SAP 或任意配置好的…
2 输入参数(input parameters) 在动作里配 Webhook,必须填完它所有必填输入参数
3 输出参数(output parameters) 当一个 Webhook 配成 writeback 时,它的输出参数可以在后续规则里使用——比如外部系统返回的数据,你想立刻写进某个…
4 OAuth 2.0 鉴权 当 Webhook 配置在一个使用出站应用(outbound application)做鉴权的 REST API 源上时,Found…
## Webhook 是什么
一个把请求"发到 Foundry 之外"的概念,让本体工作流直接连上源系统。
Webhook 本是属于 Data Connection 的一个概念:向外部系统(如 Salesforce、SAP 或任意配置好的 HTTP 服务器)发送请求,通常是为了修改那个外部系统的数据。
By setting up a webhook and then configuring it for use in an action, you can send data to an external system when end users apply an action in Foundry.配置好一个 Webhook 并把它用在动作里,就能在最终用户于 Foundry 中执行动作时,把数据发往外部系统。
在动作里用 Webhook,有两种配置方式:作为 writeback(写回),或作为 side effect(副作用)。它们的关键区别在于执行时机与失败是否暴露给用户。下节细说。
## 写回(writeback)vs 副作用(side effect)
核心差异:在对象改动之前还是之后执行,失败是否给用户看。
类型 执行时机 失败会显示给用户吗?
Writeback 对象改动之前 会(用户看到错误)
Side effect 对象改动之后 不会(可能成功提示后才跑)
把每行描述归到正确的模式(点击右侧):
SIDESide effect:先改本体 → 再发请求
用户先看到成功,Webhook 之后尽力执行。
适合"尽力而为"的通知、或写回多个外部系统。可配多个,顺序不保证。若想一次调用多次,可让函数返回一个 payload 列表,按列表逐个触发(顺序也不保证)。
WRITEWriteback:先发请求 → 再改本体
外部失败则本体不改,带一点"事务感"。
因为失败就停,所以一个动作里只能配一个 writeback。它带来 Foundry 与外部系统之间一定程度的事务性:外部请求失败则本体不被改动(但仍有"外部成功、本体失败"的可能)。
> 提示:想要"best-effort 通知 / 写回多个系统"→ side effect;想要"外部不成、本体不改"→ writeback。
## 输入参数(input parameters)
必填输入要么映射到动作参数,要么用一个函数算出来。
在动作里配 Webhook,必须填完它所有必填输入参数。两种方式:
- 映射到动作参数:每个必填输入可设为"同类型的动作参数""静态值"或"对象参数的属性"。
- 用函数(Function):选一个返回自定义类型、且强匹配 Webhook 输入结构的函数;否则会报 OntologyMetadata:ActionWebhookInputsDoNotHaveExpectedType 错误。
函数方式特别适合"用逻辑填输入",尤其是基于本体对象取值——比如取关联对象、拉它的属性来预填 Webhook 输入。函数还能返回一个payload 列表,让一个 side effect Webhook 被触发多次。
## 输出参数(output parameters)
只有 writeback 才有;把外部返回的数据接回本体。
当一个 Webhook 配成 writeback 时,它的输出参数可以在后续规则里使用——比如外部系统返回的数据,你想立刻写进某个 Foundry 对象,或用在随后的通知 / 另一个 side effect Webhook 中。
> 用法:在填某个逻辑规则的值时,选 Writeback response,再挑你要用的那个具体输出即可。
Side effect 模式没有"输出参数可被后续规则使用"这一说,因为它在对象改动之后才跑。
## OAuth 2.0 鉴权
用出站应用(outbound application)时,Foundry 帮你管 token。
当 Webhook 配置在一个使用出站应用(outbound application)做鉴权的 REST API 源上时,Foundry 会代你完成 OAuth 2.0 授权流程:开发者无需自己获取或刷新 token,Foundry 在每次 Webhook 调用时自动带上正确的访问令牌(access token)。
点击揭晓:配置在 REST API 源、用出站应用鉴权的 Webhook,token 谁来管理?
## 一页带走
① 两种模式 Writeback 先外后内、失败可见;Side effect 先内后外、尽力而为。
② 输入两法 映射动作参数,或函数强匹配返回;函数可返回 payload 列表。
③ 输出仅写回 只有 writeback 的输出参数可在后续规则里用(Writeback response)。
④ 鉴权托管 出站应用下 Foundry 自动完成 OAuth 2.0,调用自带 token。
### 常见问题速答 · FAQ
关于「Webhook」,读者最常问的几个问题。
Webhook 是什么? Webhook 本是属于 Data Connection 的一个概念:向外部系统(如 Salesforce、SAP 或任意配置好的 HTTP 服务器)发送请求,通常是为了修改那个外部系统的数据。
OAuth 2.0 鉴权是什么? 当 Webhook 配置在一个使用出站应用(outbound application)做鉴权的 REST API 源上时,Foundry 会代你完成 OAuth 2.0 授权流程:开发者无需自己获取或刷新 token,Foundry 在每次 Webhook 调…
---
## 为什么需要本体(Why create an Ontology)
- 页面:https://www.hanzhongpin.xyz/ontology/why-ontology.html
- 官方原文:https://www.palantir.com/docs/foundry/ontology/why-ontology/
- 主题分组:理念篇
循序渐进 · 教学 · 理念篇
# 为什么需要本体(Why create an Ontology)
这一篇不教你怎么建,只讲清楚"为什么要有本体"——它和普通数据仓库、报表系统到底差在哪,
又如何用数据、逻辑、行动、安全四件套,把人和 AI 一起连到真正的运营现场。
## 一句话速览
为什么需要本体(Why create an Ontology):这一篇不教你怎么建,只讲清楚"为什么要有本体"——它和普通数据仓库、报表系统到底差在哪,又如何用数据、逻辑、行动、安全四件套,把人和 AI 一起连到真正的运营现场。
1 传统数据架构"看得到,动不了" 设想一家工厂:ERP 里有订单,传感器里有温度,邮件里有客户抱怨
2 以"决策"为中心 Palantir 给本体的定位非常清楚:它是一个以决策为中心(decision-centric)的系统,而不是又一个以数据为中心的仓…
3 名词 + 动词 = 完整句子 原文给了一个极好懂的比喻:本体里的数据元素是企业里的"名词"(那些有语义的、现实世界的对象和链接);
4 让 AI "能动手",但绝不越界 把"行动"交给 AI 是最让人担心的一步
## 先说痛点:传统数据架构"看得到,动不了"
为什么几十年了,企业的数据还是没能直接变成决策?
设想一家工厂:ERP 里有订单,传感器里有温度,邮件里有客户抱怨。这些数据散落在各处,
而且即便被汇总进数据仓库,它们也只是"静止的数字"——记录过去发生了什么,却没说"接下来该做什么、由谁做、做完了会怎样"。
原文直白地点出了传统架构的两个短板:它没有记录做决策时的推理过程,也没有记录决策之后的行动。
于是组织没法从过去的决策里学习,AI 也很难真正参与进来。
Traditional data architectures do not capture the reasoning that goes into decision-making or the actions that follow, and therefore limit learning and the incorporation of AI.
传统数据架构没有捕捉"做决策时的推理"和"决策之后的行动",因此限制了学习和 AI 的融入。
>
一句话记住:报表告诉你"昨天发生了什么",但本体要回答的是"现在该怎么办、由谁去办"。
## 本体的核心主张:以"决策"为中心
不是"数据层",而是"决策层"。
Palantir 给本体的定位非常清楚:它是一个以决策为中心(decision-centric)的系统,
而不是又一个以数据为中心的仓库。它代表的不是一个企业的"数据",而是企业里每天都在做的"决策"。
The Ontology represents the decisions in an enterprise, not simply the data.
本体代表的是企业里的"决策",而不只是"数据"。
这意味着:当一个人或一台 AI 要下决定时,本体把相关信息、推理方法、可执行动作、以及合规约束
全都摆在同一个地方,让人和 AI 直接面对运营现实,去对抗组织最棘手的挑战。
>
为什么这对初学者重要:你后面看到的每一个概念(对象、属性、链接、动作、函数、接口)都是为"支持决策"服务的,
而不是为了"把数据存整齐"。带着这个视角读下去,全系列会好懂很多。
## 决策四件套:Data · Logic · Action · Security
Palantir 把"一次决策"拆成四块,本体把它们整合成一个可扩展、可协作的资源。
① Data 数据
做决策所依据的信息:既包含企业各类数据源(结构化的、流式的、非结构化的、图像等),也包含人和 AI 在决策过程中新产生的"决策数据"——谁在什么版本的数据上、通过哪个应用做了决定。
② Logic 逻辑
评估一个决策时依靠的推理与计算过程:启发式规则、模型、优化器……本体用"逻辑绑定"把它们统一成一个一致的接口,让人和 AI 都能调用。
③ Action 行动
所选决策的编排与执行:把决定真正落到业务系统里。原文说,能实时"关闭行动回路"的,才是运营系统,而非分析系统。
④ Security 安全
保证决策符合运营策略:基于标记、用途、角色的细粒度权限,并贯穿数据、逻辑、行动、应用全链路。
### 动手搭一遍:四件套少了谁,决策就转不起来?
下面是个小实验室。点开关,亲手感受"缺哪一块,闭环就断在哪"。
决策四件套开关
Data 数据
Logic 逻辑
Action 行动
Security 安全
已连接 4 / 4
决策中心成立:人和 AI 都能在安全边界内做决策。
尚缺 ✓
四件套齐备。
## 四件套怎么协同:名词 + 动词 = 完整句子
用"名词 / 动词"这个类比,一下子就通了。
原文给了一个极好懂的比喻:本体里的数据元素是企业里的"名词"(那些有语义的、现实世界的对象和链接);
而行动就是"动词"(真正发生、会改变世界的执行)。
If the data elements in the Ontology are 'the nouns' of the enterprise, then the actions can be considered 'the verbs'. With every Ontology-driven workflow, the nouns and the verbs are brought together into complete sentences.
数据是企业的"名词",行动是"动词";每个本体驱动的工作流,都把名词和动词连成完整的句子。
光有名词(数据),你只能"描述"世界;加上动词(行动),世界才"改变"。而逻辑决定动词怎么发,
安全决定动词能不能发。四件套合起来,就是一次次"看得清、想得明、动得了、不出格"的决策。
>
一个关键动作:把决策暂存为场景(scenario)、用和数椐、逻辑同样的细粒度权限来治理,
再安全地写回到各个业务系统(交易系统、边缘设备、定制应用……)。这就把"分析与运营"连成了一条闭环。
场景(scenario)我们会在第 5 篇专门展开。
## Security:让 AI "能动手",但绝不越界
这是本体敢把动作交给 AI 的底气。
把"行动"交给 AI 是最让人担心的一步。本体的安全模型专门解决这个问题:它把标记(marking)、用途(purpose)、角色(role)策略
和贯穿数据/逻辑/行动/应用全链路的动态血缘结合起来,再配上一整套变更与发布管理工具。
- 细粒度策略可以同时约束人和 AI:谁能看什么敏感信息,运行时实时计算。
- 工具(tool)的使用,也由同一套安全架构动态管控——和管数据访问是同一把锁。
- 每一次 AI 或人的动作,都依赖明确的授权,只开放"被允许的那些操作",防止被意外调用。
The Ontology brings together data, logic, action, and security into a decision-centric model of the enterprise, which can be jointly leveraged by both humans and agents.
本体把数据、逻辑、行动、安全汇成一个以决策为中心的企业模型,人和 AI 可以共同使用它。
## 一个具体故事:Onyx 医疗器械厂的断供危机
虚构但典型。点开每一阶段,看四件套是怎么被用上的。
Onyx 是一家医疗器械厂,生产注射器、外科口罩等。某天,主力供应商突然断供口罩原料,
而生产线排期紧、客户催得急。运营团队用 Palantir 把一堆数据源、逻辑、行动系统接进了企业本体来应对。
阶段一看清问题
先评估断供的即时影响,再用 AI 评估各产线重新调配的方案
本体提供端到端的实时可见性:供应商信息、库存、实时生产指标、发货清单、客户反馈都在一个地方。
敏感的财务数据按细粒度安全模型默认隐藏。引入 AI 代理后,相当于多了"新队友"——而且它的权限和人是同一套策略管的。
阶段二建模拟、想方案
"看清"只是冰山一角,更要快速找出"解法"
预测模型、调配模型、生产优化器都已接进本体。模拟结果被暂存为 ontology scenario(沙盒)。
Onyx 造了个调好的代理 "Disruption Bot",它能用一组本体工具扫描全网数据、过往行动报告、可复用模型,
提出了一个分析师还没想到的调配方案——但方案先交人工分析师终审。
阶段三执行与行动
把方案写回各个业务系统,并守住边界
执行调配计划时,自动编排一组回写例程:仓库系统走 API、三个 ERP 走本体连接器、生产计划系统收一个扁平文件。
默认情况下,AI 只能把动作暂存,交给人终审;随着日志与监控积累信任,才可谨慎放开"自动闭环"。
阶段四从决策中学习
每一次决策都成为下一次决策的养料
数据、逻辑、行动、安全都被连进本体,形成端到端的决策血缘——这正是训练和优化 AI 的丰富燃料。
过去卡在"流程缝隙"里的隐性经验,被 AI 照亮,整个企业一起变好。
## 一页带走
① 以决策为中心 本体代表企业的"决策",而不只是"数据"。
② 决策四件套 Data 数据 + Logic 逻辑 + Action 行动 + Security 安全,缺一不可。
③ 名词 + 动词 数据是名词、行动是动词;合起来世界才既"被看清"又"被改变"。
④ 安全兜底 同一套策略约束人和 AI,让 AI 敢动手、不出格。
### 常见问题速答 · FAQ
关于「为什么需要本体(Why create an Ontology)」,读者最常问的几个问题。
先说痛点:传统数据架构"看得到,动不了"是什么? 设想一家工厂:ERP 里有订单,传感器里有温度,邮件里有客户抱怨。这些数据散落在各处,而且即便被汇总进数据仓库,它们也只是"静止的数字"——记录过去发生了什么,却没说"接下来该做什么、由谁做、做完了会怎样"。
本体的核心主张:以"决策"为中心是什么? Palantir 给本体的定位非常清楚:它是一个以决策为中心(decision-centric)的系统,而不是又一个以数据为中心的仓库。它代表的不是一个企业的"数据",而是企业里每天都在做的"决策"。
名词 + 动词 = 完整句子是什么? 原文给了一个极好懂的比喻:本体里的数据元素是企业里的"名词"(那些有语义的、现实世界的对象和链接);而行动就是"动词"(真正发生、会改变世界的执行)。
让 AI "能动手",但绝不越界是什么? 把"行动"交给 AI 是最让人担心的一步。本体的安全模型专门解决这个问题:它把标记(marking)、用途(purpose)、角色(role)策略 和贯穿数据/逻辑/行动/应用全链路的动态血缘结合起来,再配上一整套变更与发布管理工具。
---