透過分析 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 的資料——絕不盲目猜測
- 所有欄位皆可為 null: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),學習該專案的慣例——維持相同的描述風格、欄位命名、範例格式與整體結構 - 找出所有將資料推送到 Dataset 的位置:
- JavaScript/TypeScript:搜尋
Actor.pushData(、dataset.pushData(、Dataset.pushData( - Python:搜尋
Actor.push_data(、dataset.push_data(、Dataset.push_data(
- JavaScript/TypeScript:搜尋
- 找出所有將資料儲存至 Key-Value Store 的位置:
- 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 模型定義。使用既有的欄位名稱、型別與 docstring 作為權威資料來源
- TypeScript:尋找輸出型別介面/型別(例如在
- 檢查程式碼庫中是否有處理 Schema 生成或驗證的既有共用 Schema 工具或輔助函式——進行複用而非撰寫新邏輯
- 若
actor.json中存在行內的storages.dataset或storages.keyValueStore設定,請標記以供後續遷移
向使用者呈現探索結果:列出所有發現的 Dataset 輸出欄位、Key-Value Store 鍵值、其型別以及來源位置。
階段 2:生成 dataset_schema.json
目標:建立包含欄位定義與顯示檢視(views)的完整 Dataset 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、使用者名稱或內容 |
"type" 需搭配 "nullable" |
若未在同一欄位指定 type,AJV 會拒絕 nullable |
警告——最常見的錯誤:
- 僅包含顯示在概覽檢視中的欄位。即使未出現在
views區段中,fields.properties也必須列出所有輸出欄位。- 僅在巢狀物件型別的屬性中添加
"required": []與"additionalProperties": true,卻忘記在最外層的fields物件上添加。兩個層級都需要。
附註:
nullable是 JSON Schema draft-07 的 Apify 特定擴充。這是刻意設計且正確的。
欄位型別模式
字串欄位:
"title": {
"type": "string",
"description": "Title of the scraped item",
"nullable": true,
"example": "Example Item Title"
}
數字欄位:
"viewCount": {
"type": "number",
"description": "Number of views",
"nullable": true,
"example": 15000
}
布林值欄位:
"isVerified": {
"type": "boolean",
"description": "Whether the account is verified",
"nullable": true,
"example": true
}
陣列欄位:
"hashtags": {
"type": "array",
"description": "Hashtags associated with the item",
"items": { "type": "string" },
"nullable": true,
"example": ["#example", "#demo"]
}
巢狀物件欄位:
"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"
}
聯合型別(例如 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 中儲存資料,請定義 Key-Value Store 集合(collections)
跳過此階段:如果在階段 1 未找到任何
Actor.setValue()/Actor.set_value()呼叫(預設的INPUT鍵除外)。
檔案結構
{
"actorKeyValueStoreSchemaVersion": 1,
"title": "<描述性標題——Key-Value Store 包含的內容>",
"description": "<單句描述儲存的資料>",
"collections": {
"<collectionName>": {
"title": "<易於閱讀的標題>",
"description": "<此集合包含的內容>",
"keyPrefix": "<prefix->"
}
}
}
如何識別集合
將發現的 setValue / set_value 呼叫按 Key 模式進行分組:
- 固定 Key(例如
"RESULTS"、"summary")——使用"key"(完全比對) - 具前綴的動態 Key(例如
"screenshot-${id}"、f"image-{name}")——使用"keyPrefix"
每個分組各自成為一個集合。
集合屬性
| 屬性 | 必填 | 描述 |
|---|---|---|
title |
是 | 顯示於 UI 分頁中 |
description |
否 | 顯示於 UI 提示文字中 |
key |
視情況 | 單一 Key 集合的精確 Key(key 或 keyPrefix 擇一使用,不可同時使用) |
keyPrefix |
視情況 | 多 Key 集合的前綴(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






