通过分析源码,为 Apify Actor 生成输出 Schema(dataset_schema.json、output_schema.json、key_value_store_schema.json)。适用于创建或更新 Actor 输出 Schema 的场景。
生成 Actor 输出 Schema
你正在为 Apify Actor 生成输出 Schema 文件。输出 Schema 用于告诉 Apify Console 如何展示运行结果。你需要分析 Actor 的源代码,创建 dataset_schema.json、output_schema.json 以及 key_value_store_schema.json(若 Actor 使用了键值存储/key-value store),并更新 actor.json。
核心原则
- 代码优先,拒绝凭空臆测:先阅读 Actor 的源码,搞清楚它到底向数据集(dataset)写入了哪些数据,绝不要主观猜想
- 所有字段均设为可空(nullable):API 和网页响应往往不可控——务必统一设置
"nullable": true - 示例数据必须脱敏/匿名化:示例中切勿包含真实的用户 ID、用户名或个人敏感信息
- 与代码交叉验证:如果存在 TypeScript 类型定义,请结合类型定义和实际生成数据的代码双重校验 Schema
- 复用现有规范:生成 Schema 前,先检查同一仓库下的其他 Actor 是否已有输出 Schema,保持结构、命名规范、描述风格和格式一致
- 避免重复造轮子:直接复用代码库中现有的类型定义、接口和工具函数,不要重复定义
阶段 1:探明 Actor 结构
目标:定位 Actor 并理清其输出数据
初始请求:$ARGUMENTS
操作步骤:
- 创建包含所有阶段的任务清单(todo list)
- 找到包含
actor.json的.actor/目录 - 阅读
actor.json以了解 Actor 的配置 - 检查
dataset_schema.json、output_schema.json和key_value_store_schema.json是否已存在 - 在仓库中检索已有 Schema:查找其他
.actor/目录或 Schema 文件(例如**/dataset_schema.json、**/output_schema.json、**/key_value_store_schema.json),学习仓库内部规范——保持描述风格、字段命名、示例格式和总体结构的一致性 - 找出所有向数据集写入数据的位置:
- JavaScript/TypeScript:搜索
Actor.pushData(、dataset.pushData(、Dataset.pushData( - Python:搜索
Actor.push_data(、dataset.push_data(、Dataset.push_data(
- JavaScript/TypeScript:搜索
- 找出所有向键值存储写入数据的位置:
- JavaScript/TypeScript:搜索
Actor.setValue(、keyValueStore.setValue(、KeyValueStore.setValue( - Python:搜索
Actor.set_value(、key_value_store.set_value(、KeyValueStore.set_value(
- JavaScript/TypeScript:搜索
- 找到输出类型定义——直接复用,无需从零搭建:
- TypeScript:查找输出相关的接口/类型(例如在
src/types/、src/types/output.ts中)。如果已有接口或类型定义了输出结构,直接据此推导 Schema 字段——不要新建一套并行定义 - Python:查找 TypedDict、dataclass 或 Pydantic 模型定义。以现有的字段名、类型和文档注释(docstrings)作为单一事实来源(source of truth)
- TypeScript:查找输出相关的接口/类型(例如在
- 检查代码库中是否有现成的用于 Schema 生成或校验的共享工具函数/辅助函数——尽量复用,避免新建重复逻辑
- 如果
actor.json中存在内联的storages.dataset或storages.keyValueStore配置,记录下来以便后续迁移
将排查结果呈报给用户:列出探明的所有数据集输出字段、键值存储的键(key)、对应类型以及来源位置。
阶段 2:生成 dataset_schema.json
目标:创建完整的数据集 Schema,包含字段定义与视图展示配置
文件结构
{
"actorSpecification": 1,
"fields": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
// 此处列出所有输出字段——包含 Actor 可能产生的所有字段,
// 绝不仅限于 overview 视图中展示的部分
},
"required": [],
"additionalProperties": true
},
"views": {
"overview": {
"title": "Overview",
"description": "Most important fields at a glance",
"transformation": {
"fields": [
// 8-12 个最重要的字段名称
]
},
"display": {
"component": "table",
"properties": {
// 每个概览字段的展示配置
}
}
}
}
}
保持与已有 Schema 的一致性
如果在阶段 1(步骤 5)中在仓库中找到了已有的输出 Schema,请遵循其规范:
- 统一描述书写风格(首字母大写 vs 小写、末尾加句号 vs 不加句号等)
- 统一字段命名约定(camelCase 驼峰命名 vs snake_case 蛇形命名)——这也必须与 Actor 代码实际生成的键名相匹配
- 统一示例值风格(例如日期格式、URL 模式、占位符名称)
- 统一视图结构(概览中包含的字段数量、展示格式的选择)
- 统一 JSON 格式化风格(缩进格数、属性排序、空格)——同一仓库中的所有 Schema(包括独立的 Actor)必须使用完全一致的格式
当 Actor 代码中已包含定义清晰的 TypeScript 接口或 Python 类型类时,直接从这些类型推导字段,而不是重新逐行分析 pushData/push_data 调用。类型定义就是权威来源。
硬性规则(绝无例外)
| 规则 | 细则 |
|---|---|
所有字段均放入 properties |
fields.properties 对象必须包含 Actor 可以输出的每一个字段,不能只写概览视图中显示的字段。views 部分只是筛选子集进行展示,properties 部分必须是完整全集 |
"nullable": true |
作用于每个字段——因为外部 API 充满不确定性 |
"additionalProperties": true |
必须同时加在顶层 fields 对象以及 properties 内的每个嵌套对象上。这是最常被遗漏的规则——两个层级缺一不可 |
"required": [] |
始终为空数组——必须同时加在顶层 fields 对象以及 properties 内的每个嵌套对象上 |
| 示例值必须脱敏 | 禁止出现真实用户 ID、用户名或真实内容 |
"nullable" 必须配合 "type" 使用 |
校验器 AJV 如果看到 nullable 但同级缺少 "type" 会直接报错 |
警告——最常见错误:
- 只包含在概览视图中出现的字段。
fields.properties必须列出所有输出字段,即使它们不在views部分中。- 只在嵌套的对象类型属性上添加
"required": []和"additionalProperties": true,却忘记在顶层fields对象上添加。两个层级都必须配备。
注意:
nullable是 Apify 针对 JSON Schema draft-07 的自定义扩展属性。这是符合预期且完全正确的。
字段类型常见模式
字符串字段(String):
"title": {
"type": "string",
"description": "Title of the scraped item",
"nullable": true,
"example": "Example Item Title"
}
数值字段(Number):
"viewCount": {
"type": "number",
"description": "Number of views",
"nullable": true,
"example": 15000
}
布尔字段(Boolean):
"isVerified": {
"type": "boolean",
"description": "Whether the account is verified",
"nullable": true,
"example": true
}
数组字段(Array):
"hashtags": {
"type": "array",
"description": "Hashtags associated with the item",
"items": { "type": "string" },
"nullable": true,
"example": ["#example", "#demo"]
}
嵌套对象字段(Object):
"authorInfo": {
"type": "object",
"description": "Information about the author",
"properties": {
"name": { "type": "string", "nullable": true },
"url": { "type": "string", "nullable": true }
},
"required": [],
"additionalProperties": true,
"nullable": true,
"example": { "name": "Example Author", "url": "https://example.com/author" }
}
枚举字段(Enum):
"contentType": {
"type": "string",
"description": "Type of content",
"enum": ["article", "video", "image"],
"nullable": true,
"example": "article"
}
联合类型(Union type,例如 TypeScript 中的 ObjectType | string):
"metadata": {
"type": ["object", "string"],
"description": "Structured metadata object, or error string if unavailable",
"nullable": true,
"example": { "key": "value" }
}
脱敏示例值
使用真实合理但通用的假数据。遵循对应平台的 ID 格式约定:
| 字段类型 | 示例处理方式 |
|---|---|
| ID | 匹配对应平台的格式与长度(例如 YouTube 视频 ID 固定为 11 位) |
| 用户名 | "exampleuser"、"sampleuser123" |
| 展示名称 | "Example Channel"、"Sample Author" |
| URL | 使用平台的标准 URL 格式搭配伪造 ID |
| 日期 | "2025-01-15T12:00:00.000Z"(ISO 8601 格式) |
| 文本内容 | 通用描述性文本,例如 "This is an example description." |
视图(Views)配置
transformation.fields:挑选 8–12 个最重要的字段名称(列表中的顺序即为 UI 中表格列的顺序)display.properties:概览视图中的每个字段对应一个配置条目,包含label(标签名称)和format(展示格式)- 可选展示格式:
"text"、"number"、"date"、"link"、"boolean"、"image"、"array"、"object"
挑选能够为用户提供最直观、最有价值数据概览的字段。
阶段 3:生成 key_value_store_schema.json(若适用)
目标:如果 Actor 在键值存储(key-value store)中存有数据,请定义对应的键值存储集合
跳过此阶段:如果在阶段 1 中未发现
Actor.setValue()/Actor.set_value()调用(默认的INPUT键除外)。
文件结构
{
"actorKeyValueStoreSchemaVersion": 1,
"title": "<描述性标题——表明键值存储包含的内容>",
"description": "<单句描述存储的数据>",
"collections": {
"<collectionName>": {
"title": "<易读的标题>",
"description": "<此集合包含的内容>",
"keyPrefix": "<prefix->"
}
}
}
如何识别集合(Collections)
按键名(Key)模式归类排查出的 setValue / set_value 调用:
- 固定键名(例如
"RESULTS"、"summary")——使用"key"(精准匹配) - 带前缀的动态键名(例如
"screenshot-${id}"、f"image-{name}")——使用"keyPrefix"
每个分组归为一个集合(collection)。
集合属性说明
| 属性 | 是否必填 | 描述 |
|---|---|---|
title |
是 | 在 UI 标签页中显示 |
description |
否 | 在 UI 提示框(tooltip)中显示 |
key |
条件必填 | 单文件集合的精准键名(key 和 keyPrefix 二选一,不可同时设置) |
keyPrefix |
条件必填 | 多文件集合的前缀(key 和 keyPrefix 二选一,不可同时设置) |
contentTypes |
否 | 限制允许的 MIME 类型(例如 ["image/jpeg"]、["application/json"]) |
jsonSchema |
否 | 用于校验 application/json 内容的 JSON Schema draft-07 规范 |
示例
单文件输出(例如分析报告):
{
"actorKeyValueStoreSchemaVersion": 1,
"title": "Analysis Results",
"description": "Key-value store containing analysis output",
"collections": {
"report": {
"title": "Report",
"description": "Final analysis report",
"key": "REPORT",
"contentTypes": ["application/json"]
}
}
}
多文件前缀输出(例如网页截图):
{
"actorKeyValueStoreSchemaVersion": 1,
"title": "Scraped Files",
"description": "Key-value store containing downloaded files and screenshots",
"collections": {
"screenshots": {
"title": "Screenshots",
"description": "Page screenshots captured during scraping",
"keyPrefix": "screenshot-",
"contentTyp
<!-- truncated for translation batch; full body continues in source -->






