objectstack-ai
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAI Agent Design — ObjectStack AI Protocol
AI Agent设计 — ObjectStack AI协议
Expert instructions for designing AI skills, tools, and knowledge sources —
and the platform agents they plug into — using the ObjectStack specification.
This skill covers the Agent → Skill → Tool three-tier architecture aligned with
Salesforce Agentforce, Microsoft Copilot Studio, and ServiceNow Now Assist
patterns.
Edition boundary (→ cloud; open = MCP-only). The in-UI AI runtime — theservice-ai/askagents, in-product chat, and thebuildroutes (/api/v1/ai/*) — ships in the cloud / Enterprise distribution, not the open framework. The agent / skill / tool schemas in@objectstack/service-aistay open, so you author@objectstack/spec/ai/*.skill.tsas source either way (*.tool.tsis platform-internal) — but they only execute in a cloud / EE host. On the open edition there is no in-product agent: expose the app to your own AI via*.agent.ts(BYO-AI) for data query, and author metadata in source mode with an AI coding agent (Claude Code, Cursor).@objectstack/mcp
关于使用ObjectStack规范设计AI技能、工具、知识源及其所接入的平台Agent的专业指导说明。本内容涵盖与Salesforce Agentforce、Microsoft Copilot Studio和ServiceNow Now Assist模式对齐的Agent→Skill→Tool三层架构。
版本边界(→云版本;开源版仅支持MCP) 界面内AI 运行时——service-ai/askAgent、产品内聊天以及build路由(/api/v1/ai/*)——仅在云/企业发行版中提供,开源框架不包含该内容。@objectstack/service-ai中的Agent/技能/工具** schema 保持开源,因此无论哪种版本,您都可以编写@objectstack/spec/ai/*.skill.ts作为源文件(*.tool.ts为平台内部文件)——但它们仅能在云/企业版宿主环境中执行。在开源版中没有内置产品Agent:需通过*.agent.ts(BYO-AI)将应用接入您自己的AI以进行数据查询,并借助AI编码Agent(如Claude Code、Cursor)以源模式**编写元数据。@objectstack/mcp
When to Use This Skill
何时使用本内容
- You need to define skills — bundles of related tools bound to the
/
asksurfaces.build - You are configuring tools for data queries, actions, or integrations.
- You want to index ObjectStack data as a knowledge source for RAG retrieval.
- You are choosing and configuring LLM models (model registry).
- You need to read or review agent configuration — platform-internal; third parties extend agents via skills, not by authoring them.
- 您需要定义技能——绑定到/
ask界面的相关工具集合。build - 您正在配置用于数据查询、操作或集成的工具。
- 您希望将ObjectStack数据索引为RAG检索的知识源。
- 您正在选择和配置LLM模型(模型注册表)。
- 您需要读取或审核Agent配置——平台内部组件;第三方通过技能扩展Agent,而非编写Agent文件。
Three-Tier Architecture
三层架构
Agent → Skill → Tool
│ │ │
│ │ └─ Atomic operation (query, action, flow, API call)
│ └─ Capability bundle with instructions & trigger phrases
└─ Autonomous actor with role, instructions, and guardrailsAgent → Skill → Tool
│ │ │
│ │ └─ 原子操作(查询、动作、流程、API调用)
│ └─ 包含指令和触发短语的能力集合
└─ 具备角色、指令和防护规则的自主执行主体Why Three Tiers?
为何采用三层架构?
| Tier | Analogy | Reuse Level |
|---|---|---|
| Agent | Job role (e.g., "Help Desk Agent") | Per use-case |
| Skill | Competency (e.g., "Case Management") | Across agents |
| Tool | Specific operation (e.g., "create_record") | Across skills |
Best practice: Always model via Skills first. Direct tool assignment to agents is supported but considered legacy. Skills provide better discoverability, instruction scoping, and reuse.
| 层级 | 类比 | 复用级别 |
|---|---|---|
| Agent | 职位角色(如“客服台Agent”) | 按用例划分 |
| Skill | 能力资质(如“案例管理”) | 跨Agent复用 |
| Tool | 具体操作(如“create_record”) | 跨技能复用 |
最佳实践: 始终优先通过Skill进行建模。直接为Agent分配工具的方式虽被支持,但已被视为遗留方案。Skill具备更好的可发现性、指令范围控制和复用性。
Built-in agents: ask
& build
(ADR-0063 / ADR-0064)
askbuild内置Agent:ask
& build
(ADR-0063 / ADR-0064)
askbuildThe runtime ships exactly two platform agents, bound by surface — the user
never picks from a roster; the surface they are in selects the agent:
- — the data product (≈ Claude Chat). Conversational read / query / explore over records, plus running the business actions the app already exposes. End-user audience, RLS-bounded. Canonical id
ask(ask). Cloud / Enterprise — theASK_AGENT_NAMEruntime ships in the closed cloud AI runtime (ask); it is the implicit copilot for any cloud / EE app that does not pin@objectstack/service-ai. (Open editions have no in-productapp.defaultAgent; use MCP.)ask - — the authoring product (≈ Claude Code). Agentic authoring of metadata (objects, fields, views, flows) through plan → draft → verify → publish. Builder audience, governance-gated. Canonical id
build. Cloud-only · paid — ships in the cloud AI Studio plugin; Studio pins it viabuild.app.defaultAgent
There is no per-turn intent classifier: a -shaped request arriving at
is declined and redirected to the Builder, never silently re-routed into
authoring (ADR-0063 §1/§5).
buildaskLegacy names are aliases only.→data_chatandask→metadata_assistantresolve through the alias table for old bookmarks and persistedbuilds; they are not vocabulary — always writeagent_id/ask.buildis closed to third parties (*.agent.tstype isagent): you extend the platform with skills, never by authoring an agent (ADR-0063 §2).allowRuntimeCreate:false, allowOrgOverride:false
运行时仅提供两个平台Agent,按界面绑定——用户无需从列表中选择,而是由当前所在界面自动选择对应的Agent:
- —— 数据产品(类似Claude Chat)。支持对记录进行对话式读取/查询/探索,以及执行应用已暴露的业务动作。面向终端用户,受RLS权限限制。标准ID为
ask(ask)。云/企业版专属——ASK_AGENT_NAME运行时包含在闭源云AI运行时(ask)中;对于未设置@objectstack/service-ai的云/企业版应用,它是默认的副驾驶助手。(开源版无内置app.defaultAgentAgent;需使用MCP。)ask - —— 创作产品(类似Claude Code)。通过计划→起草→验证→发布的流程,以Agent方式创作元数据(对象、字段、视图、流程)。面向构建者,受治理规则管控。标准ID为
build。仅云付费版提供——包含在云AI Studio插件中;Studio通过build指定使用该Agent。app.defaultAgent
系统无逐轮意图分类器:发送到的类请求会被拒绝并引导至Builder界面,绝不会静默路由到创作流程(ADR-0063 §1/§5)。
askbuild旧名称仅为别名。→data_chat和ask→metadata_assistant仅用于兼容旧书签和持久化的build;它们不属于标准词汇——请始终使用agent_id/ask。build对第三方关闭(*.agent.ts类型设置agent):您需通过技能扩展平台,而非编写Agent(ADR-0063 §2)。allowRuntimeCreate:false, allowOrgOverride:false
Skill → agent affinity: the surface
field (ADR-0063 §3)
surface技能→Agent关联性:surface
字段(ADR-0063 §3)
surfaceEvery skill declares which surface it binds to via
(defaults to ). A skill may bind only
to an agent whose surface it matches; binds to either. The runtime
enforces this in at load time — an incompatible binding is a
fast load error, not a silent mis-scope. An agent's tool set is the union of
its surface-compatible skills' tools — there is no global fall-through
(ADR-0064), so cannot author by construction.
surface: 'ask' | 'build' | 'both''ask''both'resolveActiveSkillsaskThe built-in skills and their affinities:
| Skill | | Owns | Edition |
|---|---|---|---|
| | | OSS |
| | | OSS |
| | | OSS |
| | metadata draft / verify / publish + blueprint propose / apply | cloud only |
To grant data exploration to your own (platform-internal) agent, add
/ to its ; deactivating a skill
() revokes that capability for every agent that references it.
data_explorerschema_readerskills[]active: falseskills are inert on OSS — by design, not a bug. The open single-env framework ships only thesurface:'build'agent;ask/metadata_authoring(and any third-partysolution_designskill) are supplied by the cloud AI Studio plugin and simply do not resolve in OSS. Asurface:'build'-intent turn on OSS degrades gracefully ("authoring lives in the cloud Build assistant") instead of dead-ending — this is intentional tiering. Do not assume authoring tools resolve in the open framework.build
: the only built-in tool that draws a chart — it aggregates an object and emits an inlinevisualize_datapart. Auto-registered only when an analytics service (data-chart) is wired;IAnalyticsService/query_datareturn numbers, not charts.aggregate_data
Ops: setto cap user turns per user per day (backed by theAI_DAILY_USER_MESSAGES=<N>object; no-op if unset). Adapter health is observable atai_usage_daily; invalidGET /api/v1/ai/statussettings are rejected at save time.ai
每个技能通过(默认值为)声明其绑定的界面。技能仅能绑定与之界面匹配的Agent;表示可绑定任意界面。运行时在加载时通过强制执行此规则——不兼容的绑定会触发快速加载错误,而非静默失效。Agent的工具集是其所有兼容界面技能的工具的并集——不存在全局回退机制(ADR-0064),因此Agent本质上无法执行创作操作。
surface: 'ask' | 'build' | 'both''ask''both'resolveActiveSkillsask内置技能及其关联性:
| 技能 | | 包含工具 | 版本 |
|---|---|---|---|
| | | 开源版 |
| | | 开源版 |
| | | 开源版 |
| | 元数据起草/验证/发布 + 蓝图提议/应用 | 仅云版本 |
若要为您的(平台内部)Agent授予数据探索能力,需将/添加到其中;停用技能()会撤销所有引用该技能的Agent的对应能力。
data_explorerschema_readerskills[]active: false技能在开源版中无效——这是设计使然,而非Bug。 开源单环境框架仅提供surface:'build'Agent;ask/metadata_authoring(以及任何第三方solution_design技能)由云AI Studio插件提供,在开源版中无法解析。开源版中收到surface:'build'意图请求时会优雅降级(“创作功能位于云Build助手中”),而非直接失败——这是有意的分层设计。请勿假设创作工具在开源框架中可用。build
: 唯一内置的绘图工具——它聚合对象并输出内嵌的visualize_data部分。仅在接入分析服务(data-chart)时自动注册;IAnalyticsService/query_data仅返回数值,不生成图表。aggregate_data
运维配置: 设置可限制每个用户每日的交互轮次(由AI_DAILY_USER_MESSAGES=<N>对象支持;未设置时无限制)。适配器健康状态可通过ai_usage_daily查看;无效的GET /api/v1/ai/status设置会在保存时被拒绝。ai
Agent Configuration
Agent配置
Reference only — third parties do not author agents. Thetype is closed (agent; ADR-0063 §2): the platform ships exactlyallowRuntimeCreate:falseandask, maintained by platform / cloud plugin authors. You extend the platform with skills + tools (and knowledge sources) — never by adding an agent. This section documentsbuildfor reading existing agents and for platform-internal work.AgentSchema
仅供参考——第三方无需编写Agent。类型为闭源(agent;ADR-0063 §2):平台仅提供allowRuntimeCreate:false和ask两个Agent,由平台/云插件维护者负责维护。您需通过技能+工具(以及知识源)扩展平台——绝不能通过添加Agent的方式。本节记录build用于读取现有Agent配置及平台内部开发。AgentSchema
Required Properties
必填属性
| Property | Type | Description |
|---|---|---|
| | Unique agent identifier |
| string | Human-readable name |
| string | Agent's persona/role description |
| string | System prompt — detailed behavioural guidance |
| 属性 | 类型 | 描述 |
|---|---|---|
| | 唯一Agent标识符 |
| string | 人类可读名称 |
| string | Agent的角色/人设描述 |
| string | 系统提示词——详细的行为指导 |
Important Optional Properties
重要可选属性
| Property | Purpose |
|---|---|
| Array of skill names — primary capability model |
| Direct tool references — legacy fallback |
| |
| LLM model configuration — |
| REMOVED in protocol 17 (#3896 close-out) — declaring sources/indexes on an agent never scoped retrieval ( |
| |
| Output format (JSON schema, regex, etc.) |
| Autonomous reasoning — |
| |
| Permission-set capabilities required to use the agent |
| Enable/disable the agent |
There is no top-level / on an agent — sampling
parameters live under ().
temperaturemaxTokensmodelAIModelConfigSchema| 属性 | 用途 |
|---|---|
| 技能名称数组——核心能力模型 |
| 直接工具引用——遗留回退方案 |
| |
| LLM模型配置—— |
| 协议17版本中移除(#3896收尾工作)——在Agent上声明源/索引无法限定检索范围( |
| |
| 输出格式(JSON schema、正则表达式等) |
| 自主推理—— |
| |
| 使用Agent所需的权限集能力 |
| 启用/禁用Agent |
Agent**无顶层/**参数——采样参数位于()下。
temperaturemaxTokensmodelAIModelConfigSchemaAgent Example
Agent示例
<!-- os:check -->
typescript
import { defineAgent } from '@objectstack/spec';
export default defineAgent({
name: 'support_tier_1',
label: 'First Line Support',
role: 'Help Desk Assistant for customer support cases',
instructions: `
You are a friendly and professional help desk assistant.
RULES:
- Always greet the customer by name if available.
- Search the knowledge base before creating a new case.
- Escalate to a human agent if the issue is critical or security-related.
- Never share internal system details with customers.
- Respond in the customer's preferred language.
`,
skills: ['case_management', 'knowledge_search'],
model: {
provider: 'openai',
model: 'gpt-4o',
temperature: 0.3,
},
guardrails: {
blockedTopics: ['internal_pricing', 'employee_data'], // forbidden topics / action names
maxTokensPerInvocation: 8000, // token budget per invocation
maxExecutionTimeSec: 60, // wall-clock cap per invocation
},
});<!-- os:check -->
typescript
import { defineAgent } from '@objectstack/spec';
export default defineAgent({
name: 'support_tier_1',
label: '一线客服',
role: '客户支持案例的客服台助手',
instructions: `
您是一位友好且专业的客服台助手。
规则:
- 若可用,请始终称呼客户姓名。
- 创建新案例前先搜索知识库。
- 若问题严重或涉及安全,请升级给人工Agent。
- 绝不能向客户透露内部系统细节。
- 使用客户偏好的语言回复。
`,
skills: ['case_management', 'knowledge_search'],
model: {
provider: 'openai',
model: 'gpt-4o',
temperature: 0.3,
},
guardrails: {
blockedTopics: ['internal_pricing', 'employee_data'], // 禁止的主题/动作名称
maxTokensPerInvocation: 8000, // 每次调用的token预算
maxExecutionTimeSec: 60, // 每次调用的最长执行时间(秒)
},
});Skill Configuration
技能配置
A Skill is a named bundle of tools with dedicated instructions and
trigger conditions.
Skill是包含专用指令和触发条件的命名工具集合。
Required Properties
必填属性
| Property | Type | Description |
|---|---|---|
| | Unique skill identifier ( |
| string | Human-readable name |
| | Tool names this skill grants access to (trailing wildcard allowed, e.g. |
| 属性 | 类型 | 描述 |
|---|---|---|
| | 唯一技能标识符( |
| string | 人类可读名称 |
| | 该技能授予访问权限的工具名称(支持后缀通配符,如 |
Important Optional Properties
重要可选属性
| Property | Purpose |
|---|---|
| |
| What the skill does — helps the agent decide when to use it |
| LLM prompt guidance specific to this skill's context |
| Natural language phrases that activate the skill |
| Programmatic activation rules |
| Is the skill enabled (default: |
A skill has nokey — it was removed in 16.x. Skill invocation was never gated by it (the registry reads onlypermissions/active/triggerConditions), and a security-shaped field that enforces nothing is worse than no field at all. Gate access at the agent instead —tools/accessonpermissionsare enforced at the chat route — or on the underlying actions the skill's tools call (permission sets, ADR-0066).defineAgent
| 属性 | 用途 |
|---|---|
| |
| 技能功能描述——帮助Agent判断何时使用该技能 |
| 针对该技能场景的LLM提示指导 |
| 触发技能的自然语言短语 |
| 程序化激活规则 |
| 技能是否启用(默认: |
技能无字段——该字段在16.x版本中移除。技能调用从未受此字段限制(注册表仅读取permissions/active/triggerConditions),一个无实际作用的安全相关字段比没有字段更糟。请在Agent层面控制访问权限——tools中的defineAgent/access会在聊天路由层面强制执行——或在技能工具调用的底层动作上进行控制(权限集,ADR-0066)。permissions
Skill Example
技能示例
<!-- os:check -->
typescript
import { defineSkill } from '@objectstack/spec';
export default defineSkill({
name: 'case_management',
label: 'Case Management',
description: 'Create, update, query, and escalate support cases.',
instructions: `
When managing cases:
- Always check for duplicate cases before creating a new one.
- Set priority based on customer tier: Enterprise → High, Pro → Medium, Free → Low.
- Escalated cases must include a summary of actions already taken.
`,
tools: [
'query_support_case',
'create_support_case',
'update_support_case',
'escalate_case',
],
triggerConditions: [
{ field: 'objectName', operator: 'eq', value: 'support_case' },
],
active: true,
});<!-- os:check -->
typescript
import { defineSkill } from '@objectstack/spec';
export default defineSkill({
name: 'case_management',
label: '案例管理',
description: '创建、更新、查询和升级支持案例。',
instructions: `
管理案例时:
- 创建新案例前务必检查是否存在重复案例。
- 根据客户等级设置优先级:企业版→高,专业版→中,免费版→低。
- 升级的案例必须包含已执行操作的摘要。
`,
tools: [
'query_support_case',
'create_support_case',
'update_support_case',
'escalate_case',
],
triggerConditions: [
{ field: 'objectName', operator: 'eq', value: 'support_case' },
],
active: true,
});Trigger Conditions
触发条件
| Operator | Meaning |
|---|---|
| Equals |
| Not equals |
| Value is in array |
| Value is not in array |
| String contains substring |
| 操作符 | 含义 |
|---|---|
| 等于 |
| 不等于 |
| 值在数组中 |
| 值不在数组中 |
| 字符串包含子串 |
Tool Configuration
工具配置
Tools are the atomic operations that skills expose to agents.
工具是技能向Agent暴露的原子操作。
First-Class Tool Metadata (defineTool
)
defineTool一等工具元数据(defineTool
)
defineToolA tool authored as metadata (, ) is validated by
: required / / , a JSON Schema
object, plus optional and .
is strict — an unknown key (a typo, or a retired key) is a parse error, not
a silent strip. Retired in the #3896 close-out: , ,
and (all were authorable and inert; gated
nothing and withdrew nothing — the rejection message carries
each key's replacement), joining (#3715).
<!-- os:check -->
type: 'tool'*.tool.tsToolSchemanamelabeldescriptionparametersobjectNameoutputSchemaToolSchemacategorypermissionsactivebuiltInpermissionsactive: falserequiresConfirmationtypescript
import { defineTool } from '@objectstack/spec';
export default defineTool({
name: 'create_case',
label: 'Create Support Case',
description: 'Creates a new support case record',
parameters: {
type: 'object',
properties: {
subject: { type: 'string', description: 'Case subject' },
priority: { type: 'string', enum: ['low', 'medium', 'high'] },
},
required: ['subject'],
},
objectName: 'support_case',
});To gate what a tool can do, gate the underlying action
(, ADR-0066) or the objects it touches; to withdraw
a tool, remove it from the skills/agents that reference it. Categorization, if
you need it, belongs on the action side ( — a live,
enforced surface).
action.requiredPermissionsaction.ai.categoryTool metadata is a read-only projection — not an execution entry point.has noToolSchema/handlerfield, and no framework executor loads a metadata-authored tool. The runtime executes a separately-registeredimplementation(cloudAIToolDefinition); tool metadata is a one-way projection for Studio / discovery. Do not expect a hand-authored tool to run in the open edition (liveness audit #1878/#1892).@objectstack/service-ai
以元数据方式编写的工具(,)会被验证:必填//,一个JSON Schema格式的对象,以及可选的和。是严格模式——未知键(如拼写错误或已废弃的键)会导致解析错误,而非静默忽略。#3896收尾工作中已废弃的字段:, , 和(这些字段均可编写但无实际作用;无限制作用,无法禁用工具——错误信息会包含每个字段的替代方案),同时废弃的还有(#3715)。
<!-- os:check -->
type: 'tool'*.tool.tsToolSchemanamelabeldescriptionparametersobjectNameoutputSchemaToolSchemacategorypermissionsactivebuiltInpermissionsactive: falserequiresConfirmationtypescript
import { defineTool } from '@objectstack/spec';
export default defineTool({
name: 'create_case',
label: '创建支持案例',
description: '创建新的支持案例记录',
parameters: {
type: 'object',
properties: {
subject: { type: 'string', description: '案例主题' },
priority: { type: 'string', enum: ['low', 'medium', 'high'] },
},
required: ['subject'],
},
objectName: 'support_case',
});若要限制工具的操作范围,请在底层动作(,ADR-0066)或其涉及的对象上进行控制;若要停用工具,请从引用它的技能/Agent中移除。如需分类,请在动作层面设置(——一个有效的、受强制执行的字段)。
action.requiredPermissionsaction.ai.category工具元数据是只读投影——而非执行入口。无ToolSchema/handler字段,框架执行器不会加载以元数据编写的工具。运行时执行的是单独注册的implementation(云版本AIToolDefinition);工具元数据仅用于Studio/发现功能的单向投影。请勿期望手动编写的工具能在开源版中运行(活性审计#1878/#1892)。@objectstack/service-ai
Inline Agent tools[]
(legacy)
tools[]Agent内联tools[]
(遗留方案)
tools[]Entries in an agent's inline array are a different, legacy shape
(): — references to existing actions / flows / queries, not
tool definitions. Prefer skills + first-class tool names.
tools[]AIToolSchema{ type: 'action' | 'flow' | 'query' | 'vector_search', name, description? }Agent内联数组中的条目是不同的遗留格式():——引用现有动作/流程/查询,而非工具定义。优先使用技能+一等工具名称的方式。
tools[]AIToolSchema{ type: 'action' | 'flow' | 'query' | 'vector_search', name, description? }Auto-Exposed Actions
自动暴露的动作
Cloud / EE runtime.,registerActionsAsTools(), and the HITL approval queue below ship inAIServicePlugin— the closed cloud / Enterprise runtime, not an open package. On the open edition, expose actions to your own AI via@objectstack/service-aiinstead.@objectstack/mcp
You usually don't author tool definitions by hand for action invocation. Every you attach to an object via is auto-exposed as a tool named by (invoked from ).
ActiondefineObject({ actions: [...] })action_<actionName>registerActionsAsTools()AIServicePluginThree action types dispatch headlessly:
| Dispatch | Wiring |
|---|---|---|
| | none |
| HTTP call to | |
| | |
Skipped automatically:
- UI-only types (,
url,modal).form - Dangerous variants (set,
confirmText,mode: 'delete') — unless the plugin is started withvariant: 'danger', in which case they route through the HITL approval queue (see below).enableActionApproval: true - Owner opt-outs ().
aiExposed: false
type:'api'recordIdParamrecordIdField'id'bodyExtrabodyShape: { wrap: 'data' }datarecordIdParamUse (exported from — cloud-only, not importable on the open edition) when authoring an action and you want to know why it isn't surfacing in chat. Studio's "AI exposure" diagnostics use the same predicate. Pair with to know whether a registered action will be routed through HITL.
actionSkipReason(action, ctx)@objectstack/service-aiactionRequiresApproval(action)云/企业版运行时专属。、registerActionsAsTools()以及下文的人工审核队列均包含在AIServicePlugin中——闭源云/企业版运行时,而非开源包。在开源版中,请通过@objectstack/service-ai将动作暴露给您自己的AI。@objectstack/mcp
通常,您无需手动编写工具定义来调用动作。通过附加到对象的每个都会被(由调用)自动暴露为名为的工具。
defineObject({ actions: [...] })ActionregisterActionsAsTools()AIServicePluginaction_<actionName>三种动作类型支持无头调度:
| 调度方式 | 配置 |
|---|---|---|
| | 无需额外配置 |
| 向 | |
| | 内核已注册 |
自动跳过的动作:
- 仅UI类型(,
url,modal)。form - 危险变体(设置了、
confirmText、mode: 'delete')——除非插件启动时设置variant: 'danger',此时这些动作会进入人工审核队列(详见下文)。enableActionApproval: true - 所有者选择不暴露的动作()。
aiExposed: false
type:'api'recordIdParamrecordIdField'id'bodyExtrabodyShape: { wrap: 'data' }datarecordIdParam编写动作时,若想了解动作未在聊天中显示的原因,可使用(从导出——仅云版本可用,开源版无法导入)。Studio的“AI暴露”诊断功能使用相同的判断逻辑。可搭配判断已注册动作是否需要进入人工审核流程。
actionSkipReason(action, ctx)@objectstack/service-aiactionRequiresApproval(action)Human-In-The-Loop approval
人工审核(Human-In-The-Loop)
Cloud / EE runtime. The HITL approval queue is part ofand is not available in the open framework.@objectstack/service-ai
ts
kernel.use(new AIServicePlugin({
enableActionApproval: true, // opt in; default is false
apiActionBaseUrl: process.env.OS_AI_ACTION_API_BASE_URL,
}));Flow:
- LLM picks → runtime persists an
action_delete_taskrow and returnsai_pending_actions.{ status: 'pending_approval', pendingActionId } - Operator triages via Studio's AI Pending Actions inbox (or the REST endpoints: ).
GET/POST /api/v1/ai/pending-actions/... - Approve → service re-runs the action via the pre-registered bypass-approval dispatcher; row transitions to /
executed.failed - Reject → row transitions to with an optional reason.
rejected
Programmatic API on : , , , . All are optional (returns clear error when no is wired).
IAIServiceproposePendingActionapprovePendingActionrejectPendingActionlistPendingActionsIDataEngine云/企业版运行时专属。 人工审核队列是的一部分,开源框架不提供此功能。@objectstack/service-ai
ts
kernel.use(new AIServicePlugin({
enableActionApproval: true, // 选择启用;默认false
apiActionBaseUrl: process.env.OS_AI_ACTION_API_BASE_URL,
}));流程:
- LLM选择→运行时创建
action_delete_task记录并返回ai_pending_actions。{ status: 'pending_approval', pendingActionId } - 操作员通过Studio的AI待处理动作收件箱(或REST端点:)进行分类处理。
GET/POST /api/v1/ai/pending-actions/... - 批准→服务通过预注册的绕过审核调度器重新执行动作;记录状态变为/
executed。failed - 拒绝→记录状态变为并可附带拒绝原因。
rejected
IAIServiceproposePendingActionapprovePendingActionrejectPendingActionlistPendingActionsIDataEngineKnowledge Sources (RAG)
知识源(RAG)
The platform's RAG primitive is the KnowledgeSource
( in ): declarative metadata
pairing what to index with the id of an that does the
work. Sources are registered at runtime via
(there is no collection for
them), and the tool exposes registered sources to agents.
KnowledgeSourceSchema@objectstack/spec/aiIKnowledgeAdapterIKnowledgeService.registerSource()defineStacksearch_knowledge平台的RAG基础组件是KnowledgeSource(中的):声明式元数据,将待索引内容与执行索引工作的的ID配对。源在运行时通过注册(无集合用于存储),工具将已注册的源暴露给Agent。
@objectstack/spec/aiKnowledgeSourceSchemaIKnowledgeAdapterIKnowledgeService.registerSource()defineStacksearch_knowledgeKnowledgeSource Structure
KnowledgeSource结构
| Property | Purpose |
|---|---|
| Snake_case source id |
| Display metadata |
| Adapter id (e.g. |
| Adapter-specific configuration (opaque to the service) |
| What gets indexed — discriminated on |
| Optional |
| Optional |
| |
| Whether |
Source kinds:
| Fields |
|---|---|
| |
| |
| |
| 属性 | 用途 |
|---|---|
| 蛇形命名的源ID |
| 显示元数据 |
| 适配器ID(如 |
| 适配器专属配置(服务无需理解其内容) |
| 待索引内容——按 |
| 可选的 |
| 可选的 |
| |
| |
源类型:
| 字段 |
|---|---|
| |
| |
| |
Knowledge Source Example
知识源示例
<!-- os:check -->
typescript
import { KnowledgeSourceSchema, type KnowledgeSource } from '@objectstack/spec/ai';
export const supportKb: KnowledgeSource = KnowledgeSourceSchema.parse({
id: 'support_kb',
label: 'Support Knowledge Base',
adapter: 'ragflow', // or 'memory' for dev/test
source: {
kind: 'object',
object: 'kb_article',
contentFields: ['title', 'body'], // concatenated into document content
metadataFields: ['category', 'owner_id'], // projected for search-time filtering
where: { published: true }, // index published articles only
},
refresh: { onRecordChange: true }, // re-index on record.* events
});Chunking, top-K, score thresholds, and rerankers are NOT platform metadata. The spec deliberately scopes them out (): chunking strategies, retrieval pipelines, and RAG orchestration belong to the adapter (embedding.zod.ts) or application code. The platform only carries the embed + vector primitives so any RAG strategy can be built on top.adapterConfig
<!-- os:check -->
typescript
import { KnowledgeSourceSchema, type KnowledgeSource } from '@objectstack/spec/ai';
export const supportKb: KnowledgeSource = KnowledgeSourceSchema.parse({
id: 'support_kb',
label: '支持知识库',
adapter: 'ragflow', // 开发/测试时可使用'memory'
source: {
kind: 'object',
object: 'kb_article',
contentFields: ['title', 'body'], // 拼接为文档内容
metadataFields: ['category', 'owner_id'], // 投影供搜索时过滤使用
where: { published: true }, // 仅索引已发布的文章
},
refresh: { onRecordChange: true }, // 记录变更时重新索引
});分块、Top-K、分数阈值和重排序器不属于平台元数据。 规范有意将这些内容排除在外():分块策略、检索管道和RAG编排属于适配器(embedding.zod.ts)或应用代码的范畴。平台仅提供嵌入和向量基础组件,以便在其上构建任意RAG策略。adapterConfig
Knowledge Source Best Practices
知识源最佳实践
- Filter with . Index only published/active records (
where) so draft or archived content never enters the index.where: { published: true } - Index only meaningful text via . Do not include system fields or IDs; use
contentFields(all readable text fields) sparingly.* - Project filter fields into (e.g.
metadataFields,status,owner_id) so searches can be narrowed at query time.tags - Hide with when a source should be indexed but not agent-searchable.
aiExposed: false - Tune relevance in the adapter, not the metadata. Top-K, thresholds, and
reranking are configured in your RAG backend (via ), not in ObjectStack metadata.
adapterConfig
- 使用过滤。 仅索引已发布/激活的记录(
where),确保草稿或归档内容不会进入索引。where: { published: true } - 通过仅索引有意义的文本。 不要包含系统字段或ID;谨慎使用
contentFields(所有可读文本字段)。* - 将过滤字段投影到(如
metadataFields,status,owner_id),以便在查询时缩小搜索范围。tags - 设置隐藏源,当需要索引但不希望Agent可搜索时使用。
aiExposed: false - 在适配器中调整相关性,而非元数据。 Top-K、阈值和重排序需在RAG后端配置(通过),而非ObjectStack元数据。
adapterConfig
Model Configuration
模型配置
Supported Providers
支持的提供商
| Provider | Models | Use Case |
|---|---|---|
| GPT-4o, GPT-4o-mini, o1, o3-mini | General purpose, reasoning |
| Claude Sonnet 4, Claude Haiku | Long context, safety |
| Same as OpenAI, enterprise managed | Compliance, data residency |
| Ollama, vLLM, llama.cpp | On-premise, air-gapped |
The inline agentenum is the narrow set above (model.provider/openai/azure_openai/anthropic). Model-registry entries (local) accept a wider set: alsoModelProviderSchema,,cohere,huggingface.custom
| 提供商 | 模型 | 使用场景 |
|---|---|---|
| GPT-4o, GPT-4o-mini, o1, o3-mini | 通用场景、推理 |
| Claude Sonnet 4, Claude Haiku | 长上下文、安全性 |
| 与OpenAI相同,企业托管 | 合规性、数据驻留 |
| Ollama, vLLM, llama.cpp | 本地部署、离线环境 |
Agent内联的枚举仅包含上述窄范围选项(model.provider/openai/azure_openai/anthropic)。模型注册表条目(local)支持更广泛的提供商:还包括ModelProviderSchema,,cohere,huggingface。custom
Model Selection Guidelines
模型选择指南
| Scenario | Recommended |
|---|---|
| Complex reasoning, multi-step planning | GPT-4o / Claude Sonnet 4 |
| High-volume, low-latency | GPT-4o-mini / Claude Haiku |
| Sensitive data, on-premise | Local models via Ollama |
| Structured data extraction | Any model + |
| 场景 | 推荐模型 |
|---|---|
| 复杂推理、多步骤规划 | GPT-4o / Claude Sonnet 4 |
| 高并发、低延迟 | GPT-4o-mini / Claude Haiku |
| 敏感数据、本地部署 | 通过Ollama使用本地模型 |
| 结构化数据提取 | 任意模型 + |
Temperature Guidelines
Temperature参数指南
| Value | Use Case |
|---|---|
| Factual Q&A, data extraction, code generation |
| Conversational agents, customer support |
| Creative writing, brainstorming |
| Experimental / highly creative (use with caution) |
| 值 | 使用场景 |
|---|---|
| 事实问答、数据提取、代码生成 |
| 对话式Agent、客户支持 |
| 创意写作、头脑风暴 |
| 实验性/高创意场景(谨慎使用) |
Structured Output
结构化输出
Force the agent to respond in a specific format:
typescript
structuredOutput: {
format: 'json_schema',
schema: {
type: 'object',
properties: {
summary: { type: 'string' },
priority: { type: 'string', enum: ['low', 'medium', 'high'] },
action_items: { type: 'array', items: { type: 'string' } },
},
required: ['summary', 'priority'],
},
strict: true, // enforce exact schema compliance (default: false)
maxRetries: 3, // max retries on validation failure (default: 3)
}On validation failure the runtime retries by default
(). Optional extras: and a
of post-processing steps (, ,
, ). There is no object — the knobs are
+ .
retryOnValidationFailure: truefallbackFormattransformPipelinetrimparse_jsonvalidatecoerce_typesretryretryOnValidationFailuremaxRetries强制Agent以特定格式响应:
typescript
structuredOutput: {
format: 'json_schema',
schema: {
type: 'object',
properties: {
summary: { type: 'string' },
priority: { type: 'string', enum: ['low', 'medium', 'high'] },
action_items: { type: 'array', items: { type: 'string' } },
},
required: ['summary', 'priority'],
},
strict: true, // 强制严格符合schema(默认:false)
maxRetries: 3, // 验证失败时的最大重试次数(默认:3)
}验证失败时,运行时默认会重试()。可选扩展:和后处理步骤的(, , , )。无单独的对象——相关配置为 + 。
retryOnValidationFailure: truefallbackFormattransformPipelinetrimparse_jsonvalidatecoerce_typesretryretryOnValidationFailuremaxRetriesCommon Pitfalls
常见陷阱
- Overly broad instructions. Agents with vague instructions hallucinate more. Be specific about what the agent should and should not do.
- Too many tools per skill. Keep skills focused (3–8 tools). If a skill has 15+ tools, split it.
- Missing guardrails and approval gates. Define (plus the token / time budgets) in agent
blockedTopics; for destructive operations put a human in the loop with a gate that is actually enforced —guardrails(HITL queue, cloud) for auto-exposed actions,enableActionApproval: trueon the action, orai.requiresConfirmationon an MCP tool binding. AI metadata edits are already gated: they land as drafts a human must publish (ADR-0033). ⚠️approval: 'always'on the tool was REMOVED (#3715, ADR-0033 §2) — it was read by no execution path, so it produced no pause.requiresConfirmationis strict, so authoring it now fails the parse with the migration attached. There is noToolSchemafield.requireApprovalFor - Ignoring tool descriptions. The LLM uses tool to decide when to call it. Poor descriptions = wrong tool selection.
description - Not testing trigger phrases. Ambiguous trigger phrases cause skill conflicts. Test with edge-case inputs.
- Indexing everything. A knowledge source without a filter and curated
wherefills the index with drafts and boilerplate that pollute retrieval. Source hygiene is the metadata's job; relevance tuning (top-K, thresholds, reranking) belongs to the adapter.contentFields
- 指令过于宽泛。 指令模糊的Agent更容易产生幻觉。请明确说明Agent应该做什么和不应该做什么。
- 单个技能包含过多工具。 保持技能聚焦(3–8个工具)。若技能包含15个以上工具,请拆分。
- 缺少防护规则和审核 gate。 在Agent的中定义
guardrails(以及token/时间预算);对于破坏性操作,设置实际生效的人工审核 gate——自动暴露的动作设置blockedTopics(云版本人工审核队列),动作上设置enableActionApproval: true,或MCP工具绑定上设置ai.requiresConfirmation。AI元数据编辑已默认受管控:它们会作为草稿保存,需人工发布(ADR-0033)。 ⚠️ 工具上的approval: 'always'已被移除(#3715,ADR-0033 §2)——没有执行路径读取此字段,因此无法产生暂停效果。requiresConfirmation为严格模式,编写此字段会导致解析失败并附带迁移说明。无ToolSchema字段。requireApprovalFor - 忽略工具描述。 LLM会根据工具的判断何时调用它。描述不佳会导致工具选择错误。
description - 未测试触发短语。 模糊的触发短语会导致技能冲突。请使用边缘案例输入进行测试。
- 索引所有内容。 未设置过滤和精心选择
where的知识源会将草稿和模板内容填充到索引中,污染检索结果。源清理是元数据的职责;相关性调整(Top-K、阈值、重排序)属于适配器的工作。contentFields
App AI Blueprint (Skills + Tools + Knowledge)
应用AI蓝图(技能+工具+知识)
Reference layout for a scaffolded app:
| Layer | File | Pattern |
|---|---|---|
| Reusable skill | | |
| Tool metadata | | |
| Knowledge source | | |
| Central registration | | |
Default for metadata apps: push business capability logic into skills, keep
tools atomic, and wire domain knowledge through knowledge sources.
脚手架应用的参考布局:
| 层级 | 文件 | 模式 |
|---|---|---|
| 可复用技能 | | |
| 工具元数据 | | |
| 知识源 | | |
| 集中注册 | | |
元数据应用的默认方案:将业务能力逻辑放入技能,保持工具原子化,并通过知识源连接领域知识。
Verify your work
验证您的工作
After authoring a / (or platform-internal
) or a model-registry entry, run the author-time gate before
reporting done:
*.skill.ts*.tool.ts*.agent.tsbash
os validate # Zod schema + CEL predicate validation + bindings (no artifact)编写完/(或平台内部的)或模型注册表条目后,在完成前运行创作时验证:
*.skill.ts*.tool.ts*.agent.tsbash
os validate # Zod schema + CEL断言验证 + 绑定检查(不生成产物)or: os build # the same gates, plus emits dist/
或:os build # 相同的检查,同时生成dist/
It confirms the agent/tool/model metadata conforms to the protocol and that any
CEL predicate (e.g. a tool's availability condition) parses and resolves. In a
scaffolded project the gate is `npm run validate`. See objectstack-platform →
**Verify your work**.
---
它会验证Agent/工具/模型元数据是否符合协议,以及任何CEL断言(如工具的可用条件)是否可解析和生效。在脚手架项目中,验证命令为`npm run validate`。详见objectstack-platform → **验证您的工作**章节。
---References
参考资料
See references/_index.md for the full list of Zod
schemas (with one-line descriptions) — pointers into
. Always the source for exact field
shapes; do not rely on memory of property names.
node_modules/@objectstack/spec/src/Read请查看references/_index.md获取完整的Zod schema列表(含单行描述)——指向中的代码。请始终查阅源代码以获取准确的字段结构;不要依赖对属性名称的记忆。
node_modules/@objectstack/spec/src/