智慧體技能為智慧體提供執行任務所需的可重複使用指示與輔助檔案。您可以搭配 Responses API Shell 工具使用技能,也可以在 Agents API 沙盒中提供技能。
以下上傳、附加與版本管理指示適用於 Responses API Shell 工具。Agents API 工作階段會從其沙盒中的目錄探索技能。
Responses API 支援兩種技能執行方式:本機執行,以及
以容器為基礎的託管執行。若要在自己的電腦上執行程式碼,請使用
Shell 工具的本機執行模式。
技能是一個檔案目錄,其中包含 SKILL.md 資訊清單(前置中繼資料與指示)。技能將指示模組化,讓您能將流程與慣例編寫成明確規範,涵蓋公司風格指南到多步驟工作流程等內容。上傳的技能採用具版本管理的套件。
技能相容於開放的智慧體技能標準。
1
2
3
4
5
6---
name: basic-math
description: Add or multiply numbers.
---
Use this skill when you need a quick sum or product of numbers.
探索技能時,模型會看到技能的名稱與描述。撰寫描述時,請同時說明技能的功能與適用時機。例如,相較於「協助處理法律事務」,「使用備用條款審查供應商合約並標示修訂」能為模型提供更有用的上下文。
將主要指示放在 SKILL.md 中,並視需要加入輔助檔案的連結:
review-pr/
├── SKILL.md
├── references/
│ └── review-guidelines.md
├── scripts/
│ └── check-changes.sh
└── assets/
└── review-template.md
使用 references/ 存放背景資料、scripts/ 存放可重複執行的動作,以及 assets/ 存放可重複使用的範本。
你可以使用多部分表單資料上傳目錄,或上傳僅包含一個最上層資料夾的 .zip 檔案。
上傳多個 files[] 部分。每個部分都包含同一個最上層資料夾內的路徑。
1
2
3
4curl -X POST 'https://api.openai.com/v1/skills' \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F 'files[]=@./basic_math/SKILL.md;filename=basic_math/SKILL.md;type=text/markdown' \
-F 'files[]=@./basic_math/calculate.py;filename=basic_math/calculate.py;type=text/plain'
將最上層資料夾壓縮成 zip 檔案,然後上傳。
1
2
3curl -X POST 'https://api.openai.com/v1/skills' \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F 'files=@./basic_math.zip;type=application/zip'
若要將技能掛載至託管 Shell 環境,請在呼叫 Shell 工具時,透過 tools[].environment.skills 附加技能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19curl -L 'https://api.openai.com/v1/responses' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-6-astra",
"tools": [
{
"type": "shell",
"environment": {
"type": "container_auto",
"skills": [
{ "type": "skill_reference", "skill_id": "<skill_id>" },
{ "type": "skill_reference", "skill_id": "<skill_id>", "version": 2 }
]
}
}
],
"input": "Use the skills to add 144 and 377, then compute triangle area with base 9 height 13."
}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-6-astra",
tools: [
{
type: "shell",
environment: {
type: "container_auto",
skills: [
{ type: "skill_reference", skill_id: "<skill_id>" },
{ type: "skill_reference", skill_id: "<skill_id>", version: "2" },
],
},
},
],
input:
"Use the skills to add 144 and 377, then compute triangle area with base 9 height 13.",
});
console.log(response.output_text);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22response = client.responses.create(
model="gpt-6-astra",
tools=[
{
"type": "shell",
"environment": {
"type": "container_auto",
"skills": [
{"type": "skill_reference", "skill_id": "<skill_id>"},
{
"type": "skill_reference",
"skill_id": "<skill_id>",
"version": 2,
},
],
},
}
],
input="Use the skills to add 144 and 377, then compute triangle area with base 9 height 13.",
)
print(response.output_text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
tool := responses.ToolUnionParam{OfShell: &responses.FunctionShellToolParam{
Environment: responses.FunctionShellToolEnvironmentUnionParam{OfContainerAuto: &responses.ContainerAutoParam{
Skills: []responses.ContainerAutoSkillUnionParam{
{OfSkillReference: &responses.SkillReferenceParam{SkillID: "<skill_id>"}},
{OfSkillReference: &responses.SkillReferenceParam{SkillID: "<skill_id>", Version: openai.String("2")}},
},
}},
}}
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Tools: []responses.ToolUnionParam{tool},
Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Use the skills to add 144 and 377, then compute triangle area with base 9 height 13.")},
})
if err != nil {
panic(err)
}
fmt.Println(response.OutputText())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.responses.ResponseCreateParams;
import java.util.List;
import java.util.Map;
String skillId = "<skill_id>";
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input(
"Use the skills to add 144 and 377, then compute a triangle area with base 9 and height 13.")
.putAdditionalBodyProperty(
"tools",
JsonValue.from(
List.of(
Map.of(
"type",
"shell",
"environment",
Map.of(
"type",
"container_auto",
"skills",
List.of(
Map.of("type", "skill_reference", "skill_id", skillId),
Map.of(
"type", "skill_reference",
"skill_id", skillId,
"version", "2")))))))
.build();
client.responses().create(params).output().stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.text()));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28require "openai"
client = OpenAI::Client.new
response = client.responses.create(
model: "gpt-6-astra",
input: "Use the skills to add 144 and 377, then compute a triangle area with base 9 and height 13.",
tools: [
{
type: :shell,
environment: {
type: :container_auto,
skills: [
{
type: :skill_reference,
skill_id: "<skill_id>"
},
{
type: :skill_reference,
skill_id: "<skill_id>",
version: "2"
}
]
}
}
]
)
puts(response.output_text)
技能掛載後,模型可自行決定何時使用。如果你希望模型的行為更明確可控,可在適當時明確指示模型「使用 <skill name> 技能」。
技能也適用於本機 Shell 模式,但本機 Shell 與託管 Shell 環境接受的技能附件格式不同。
- 託管 Shell 環境支援已上傳的
skill_reference 附件,包括精選技能及明確指定的版本。
- 本機 Shell 不支援
skill_reference 附件。請改為透過你所控制的執行環境中的本機檔案路徑,提供技能檔案。
如需本機 Shell 執行的詳細資訊,請參閱 Shell 指南。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22curl -L 'https://api.openai.com/v1/responses' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-6-astra",
"tools": [
{
"type": "shell",
"environment": {
"type": "local",
"skills": [
{
"name": "csv-insights",
"description": "Summarize CSV files and produce a markdown report.",
"path": "<path-to-skill-folder>"
}
]
}
}
],
"input": "Use the csv-insights skill and run locally to summarize today\'s CSV reports in this repo."
}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-6-astra",
tools: [
{
type: "shell",
environment: {
type: "local",
skills: [
{
name: "csv-insights",
description: "Summarize CSV files and produce a markdown report.",
path: "<path-to-skill-folder>",
},
],
},
},
],
input:
"Use the csv-insights skill and run locally to summarize today's CSV reports in this repo.",
});
console.log(response.output_text);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21response = client.responses.create(
model="gpt-6-astra",
tools=[
{
"type": "shell",
"environment": {
"type": "local",
"skills": [
{
"name": "csv-insights",
"description": "Summarize CSV files and produce a markdown report.",
"path": "<path-to-skill-folder>",
}
],
},
}
],
input="Use the csv-insights skill and run locally to summarize today's CSV reports in this repo.",
)
print(response.output_text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
tool := responses.ToolUnionParam{OfShell: &responses.FunctionShellToolParam{
Environment: responses.FunctionShellToolEnvironmentUnionParam{OfLocal: &responses.LocalEnvironmentParam{
Skills: []responses.LocalSkillParam{{
Name: "csv-insights",
Description: "Summarize CSV files and produce a markdown report.",
Path: "<path-to-skill-folder>",
}},
}},
}}
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Tools: []responses.ToolUnionParam{tool},
Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Use the csv-insights skill and run locally to summarize today's CSV reports in this repo.")},
})
if err != nil {
panic(err)
}
fmt.Println(response.OutputText())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.responses.ResponseCreateParams;
import java.util.List;
import java.util.Map;
String skillPath = "<path-to-skill-folder>";
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input("Use the csv-insights skill to summarize today's CSV reports.")
.putAdditionalBodyProperty(
"tools",
JsonValue.from(
List.of(
Map.of(
"type",
"shell",
"environment",
Map.of(
"type",
"local",
"skills",
List.of(
Map.of(
"name", "csv-insights",
"description",
"Summarize CSV files and produce a Markdown report.",
"path", skillPath)))))))
.build();
client.responses().create(params).output().stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.text()));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24require "openai"
client = OpenAI::Client.new
response = client.responses.create(
model: "gpt-6-astra",
input: "Use the csv-insights skill to summarize today's CSV reports.",
tools: [
{
type: :shell,
environment: {
type: :local,
skills: [
{
name: "csv-insights",
description: "Summarize CSV files and produce a Markdown report.",
path: "<path-to-skill-folder>"
}
]
}
}
]
)
puts(response.output_text)
若要在 Agents API 中使用技能,請將技能目錄放入沙盒,並在建立工作階段時,於 environment.capability_directories 中註冊這些目錄的父目錄。這些父目錄稱為 能力目錄。任務執行框架會透過這些目錄探索技能;此設定不使用託管 Shell 環境的 skill_reference 附加格式。
例如,在沙盒中放入合約審查技能與 Pull Request 審查技能:
/workspace/capabilities/
├── legal/
│ └── contract-redline/
│ ├── SKILL.md
│ └── references/
│ └── fallback-clauses.md
└── engineering/
└── review-pr/
├── SKILL.md
└── references/
└── review-guidelines.md
在建立工作階段的請求中使用以下環境組態:
12345678910{
"environment": {
"type": "self_hosted",
"workspace_directory": "/workspace",
"capability_directories": [
"/workspace/capabilities/legal",
"/workspace/capabilities/engineering"
]
}
}
能力目錄必須符合以下要求:
- 路徑必須指向沙盒內的目錄。
- 路徑必須是絕對路徑且不得重複,也不能包含
. 或 .. 路徑區段。
- 每個工作階段最多可註冊 32 個能力目錄。
- 目錄必須已存在於環境中。
沙盒可用後,任務執行框架會在這些目錄中搜尋 SKILL.md 檔案,並將找到的每個技能的名稱與描述加入上下文。模型可以選擇相關技能,並讀取其完整指示與輔助檔案。
如需工作階段的設定方式,請參閱智慧體組態;如需執行環境的資訊,請參閱連接沙盒。將技能提供給智慧體之前,請先審查技能及其輔助檔案,並遵循沙盒安全性指南。
使用 Responses API Shell 工具時,平台會將每個可用技能的 name、description 與 path 加入使用者提示詞的上下文,讓模型知道該技能存在。
模型會根據這些中繼資料,決定是否呼叫技能。如果模型呼叫技能,就會依據 path,從 SKILL.md 讀取完整的 Markdown 指示。
技能指示屬於使用者提示詞輸入(而非系統提示詞輸入),因此其處理優先順序與其他使用者提供的指示相同。若要明確控制行為,你仍可指示模型「使用 <skill name> 技能」。
- 比對
SKILL.md 檔案時不區分大小寫。
- 技能套件中必須且只能包含一個
skill.md/SKILL.md 檔案。
- 技能的前置中繼資料依照智慧體技能規格進行驗證。
- 上傳的 zip 檔案大小上限為
50 MB。
- 每個技能版本的檔案數量上限為
500。
- 未壓縮的檔案大小上限為
25 MB。
檢查所有搭配 Responses API 使用的技能非常重要。技能
會帶來安全風險,例如由提示注入引發的資料外洩。
使用此工具前,請仔細閱讀下方的風險與安全
一節。
- 未提供版本時,會使用
default_version。
latest_version 會追蹤最新上傳的版本。
skill_reference.version 接受整數或 "latest"。
1
2
3curl -X POST 'https://api.openai.com/v1/skills/<skill_id>/versions' \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F 'files=@./geometry.zip;type=application/zip'
1
2
3
4curl -X POST 'https://api.openai.com/v1/skills/<skill_id>' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{"default_version": 2}'
- 無法刪除預設版本;請先將其他版本設為預設。
- 刪除最後一個剩餘版本時,也會刪除該技能。
- 刪除技能時,會一併移除所有版本。
OpenAI 維護了一組第一方技能,可透過 ID 引用(例如 openai-spreadsheets)。
{ "type": "skill_reference", "skill_id": "openai-spreadsheets", "version": "latest" }
如果不想建立託管技能,可以將以 base64 編碼的 zip 套件內嵌至環境的 skills 陣列中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20INLINE_ZIP=$(base64 -i ./basic_math.zip)
curl -L 'https://api.openai.com/v1/containers' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"name": "inline-skill-container",
"skills": [
{
"type": "inline",
"name": "basic_math",
"description": "Add or multiply numbers.",
"source": {
"type": "base64",
"media_type": "application/zip",
"data": "'"$INLINE_ZIP"'"
}
}
]
}'
務必檢查所有搭配 Responses API 使用的技能。技能會帶來安全風險,例如提示注入導致的資料竊取。
若技能搭配網路存取功能使用,請仔細閱讀網路功能的風險與安全章節。
技能內容可能影響規劃、工具使用及指令執行。在開發人員驗證之前,應將所有技能視為可能不受信任的輸入並加以審查。
避免讓一般消費者型終端使用者在產品中自由瀏覽開放目錄,並任意選取或附加技能。這類設計會大幅增加下列風險:
- 透過惡意 SKILL.md 指示進行提示注入及繞過政策。
- 未經審查的自動化觸發資料竊取或破壞性動作。
技能應由開發人員檢查並整合,再透過範圍受限的產品功能提供給終端使用者。具體做法如下:
- 將技能對應至特定的產品工作流程或使用案例。
- 防止終端使用者任意選取技能。
- 寫入或影響重大的動作必須取得明確核准並通過政策檢查,才能執行。
對於能執行寫入或影響重大動作的工作流程,應要求在執行前取得明確核准。
Responses API 支援兩種技能執行方式:本機執行,以及以容器為基礎的託管執行。託管技能遵循與託管 Shell 環境相同的容器生命週期:容器處於作用中狀態時,掛載的技能與容器檔案會持續可用;容器到期或遭刪除時,這些技能與檔案也會一併移除。若希望執行作業完全在您管理的基礎架構上進行,請使用本機 Shell 模式。如需 Agents API 沙盒的相關資訊,請參閱沙盒生命週期。進一步瞭解我們的資料控管措施。