SPB Git

Repository Public

tools-skills.md 20.7 KB 640 lines markdown

1# Skills23> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.45Agent Skills give an agent reusable instructions and supporting files for a task. Use them with Responses API shell tools or make them available in an [Agents API sandbox](#agents-api).67The upload, attachment, and versioning instructions below describe Responses API shell tools. Agents API sessions discover skills from directories in their sandbox.89The Responses API supports Skills in two form factors: local execution and10  hosted, container-based execution. To run code on your own machine, use the11  local execution mode of the [shell tool](https://developers.openai.com/api/docs/guides/tools-shell).1213## What's a skill1415A skill is a directory of files with a `SKILL.md` manifest (front matter + instructions). Skills are modular instructions you can use to codify processes and conventions, from company style guides to multi-step workflows. Uploaded skills use versioned bundles.1617Skills are compatible with the open [Agent Skills standard](https://agentskills.io/home).1819Example SKILL.md2021```markdown22---23name: basic-math24description: Add or multiply numbers.25---2627Use this skill when you need a quick sum or product of numbers.28```293031During skill discovery, the model sees the skill's name and description. Write a description that explains both what the skill does and when to use it. For example, "Review and redline vendor agreements using the fallback clauses" gives the model more useful context than "Helps with legal work."3233Keep the main instructions in `SKILL.md` and link to supporting files as needed:3435```text36review-pr/37├── SKILL.md38├── references/39│   └── review-guidelines.md40├── scripts/41│   └── check-changes.sh42└── assets/43    └── review-template.md44```4546Use `references/` for background material, `scripts/` for repeatable actions, and `assets/` for reusable templates.4748## Create a skill4950You can upload a directory as multipart form data or upload a `.zip` that contains a single top-level folder.5152### Option 1: Directory upload (multipart)5354Upload multiple `files[]` parts. Each part includes the path inside a single top-level folder.5556Create a skill (multipart)5758```bash59curl -X POST 'https://api.openai.com/v1/skills' \60  -H "Authorization: Bearer $OPENAI_API_KEY" \61  -F 'files[]=@./basic_math/SKILL.md;filename=basic_math/SKILL.md;type=text/markdown' \62  -F 'files[]=@./basic_math/calculate.py;filename=basic_math/calculate.py;type=text/plain'63```646566### Option 2: Zip upload6768Zip the top-level folder and upload the zip file.6970Create a skill (zip)7172```bash73curl -X POST 'https://api.openai.com/v1/skills' \74  -H "Authorization: Bearer $OPENAI_API_KEY" \75  -F 'files=@./basic_math.zip;type=application/zip'76```777879## Use skills with hosted shell8081To mount skills in a hosted shell environment, attach them via `tools[].environment.skills` when calling the shell tool.8283Use skills in hosted shell8485```bash86curl -L 'https://api.openai.com/v1/responses' \87  -H "Content-Type: application/json" \88  -H "Authorization: Bearer $OPENAI_API_KEY" \89  -d '{90    "model": "gpt-6-astra",91    "tools": [92      {93        "type": "shell",94        "environment": {95          "type": "container_auto",96          "skills": [97            { "type": "skill_reference", "skill_id": "<skill_id>" },98            { "type": "skill_reference", "skill_id": "<skill_id>", "version": 2 }99          ]100        }101      }102    ],103    "input": "Use the skills to add 144 and 377, then compute triangle area with base 9 height 13."104  }'105```106107```javascript108import OpenAI from "openai";109110const client = new OpenAI();111112const response = await client.responses.create({113  model: "gpt-6-astra",114  tools: [115    {116      type: "shell",117      environment: {118        type: "container_auto",119        skills: [120          { type: "skill_reference", skill_id: "<skill_id>" },121          { type: "skill_reference", skill_id: "<skill_id>", version: "2" },122        ],123      },124    },125  ],126  input:127    "Use the skills to add 144 and 377, then compute triangle area with base 9 height 13.",128});129130console.log(response.output_text);131```132133```python134response = client.responses.create(135    model="gpt-6-astra",136    tools=[137        {138            "type": "shell",139            "environment": {140                "type": "container_auto",141                "skills": [142                    {"type": "skill_reference", "skill_id": "<skill_id>"},143                    {144                        "type": "skill_reference",145                        "skill_id": "<skill_id>",146                        "version": 2,147                    },148                ],149            },150        }151    ],152    input="Use the skills to add 144 and 377, then compute triangle area with base 9 height 13.",153)154155print(response.output_text)156```157158```go159package main160161import (162	"context"163	"fmt"164165	"github.com/openai/openai-go/v3"166	"github.com/openai/openai-go/v3/responses"167)168169func main() {170	client := openai.NewClient()171	tool := responses.ToolUnionParam{OfShell: &responses.FunctionShellToolParam{172		Environment: responses.FunctionShellToolEnvironmentUnionParam{OfContainerAuto: &responses.ContainerAutoParam{173			Skills: []responses.ContainerAutoSkillUnionParam{174				{OfSkillReference: &responses.SkillReferenceParam{SkillID: "<skill_id>"}},175				{OfSkillReference: &responses.SkillReferenceParam{SkillID: "<skill_id>", Version: openai.String("2")}},176			},177		}},178	}}179	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{180		Model: "gpt-6-astra",181		Tools: []responses.ToolUnionParam{tool},182		Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Use the skills to add 144 and 377, then compute triangle area with base 9 height 13.")},183	})184	if err != nil {185		panic(err)186	}187	fmt.Println(response.OutputText())188}189```190191```java192import com.openai.client.OpenAIClient;193import com.openai.client.okhttp.OpenAIOkHttpClient;194import com.openai.core.JsonValue;195import com.openai.models.responses.ResponseCreateParams;196import java.util.List;197import java.util.Map;198199String skillId = "<skill_id>";200201ResponseCreateParams params =202    ResponseCreateParams.builder()203        .model("gpt-6-astra")204        .input(205            "Use the skills to add 144 and 377, then compute a triangle area with base 9 and height 13.")206        .putAdditionalBodyProperty(207            "tools",208            JsonValue.from(209                List.of(210                    Map.of(211                        "type",212                        "shell",213                        "environment",214                        Map.of(215                            "type",216                            "container_auto",217                            "skills",218                            List.of(219                                Map.of("type", "skill_reference", "skill_id", skillId),220                                Map.of(221                                    "type", "skill_reference",222                                    "skill_id", skillId,223                                    "version", "2")))))))224        .build();225226client.responses().create(params).output().stream()227    .flatMap(item -> item.message().stream())228    .flatMap(message -> message.content().stream())229    .flatMap(content -> content.outputText().stream())230    .forEach(text -> System.out.println(text.text()));231```232233```ruby234require "openai"235236client = OpenAI::Client.new237response = client.responses.create(238  model: "gpt-6-astra",239  input: "Use the skills to add 144 and 377, then compute a triangle area with base 9 and height 13.",240  tools: [241    {242      type: :shell,243      environment: {244        type: :container_auto,245        skills: [246          {247            type: :skill_reference,248            skill_id: "<skill_id>"249          },250          {251            type: :skill_reference,252            skill_id: "<skill_id>",253            version: "2"254          }255        ]256      }257    }258  ]259)260261puts(response.output_text)262```263264265### Prompting behavior266267Once a skill is mounted, the model can decide when to use it. If you want more deterministic behavior, explicitly instruct the model to "use the `<skill name>` skill" when appropriate.268269## Use skills with local shell mode270271Skills also work with local shell mode, but local shell and hosted shell do not accept the same skill attachment formats.272273- Hosted shell supports uploaded `skill_reference` attachments, including curated skills and explicit versions.274- Local shell does not support `skill_reference` attachments. Instead, provide skill files from local file paths in the runtime you control.275276Use the [Shell guide](https://developers.openai.com/api/docs/guides/tools-shell) for local shell execution details.277278Use skills in local shell mode279280```bash281curl -L 'https://api.openai.com/v1/responses' \282  -H "Content-Type: application/json" \283  -H "Authorization: Bearer $OPENAI_API_KEY" \284  -d '{285    "model": "gpt-6-astra",286    "tools": [287      {288        "type": "shell",289        "environment": {290          "type": "local",291          "skills": [292            {293              "name": "csv-insights",294              "description": "Summarize CSV files and produce a markdown report.",295              "path": "<path-to-skill-folder>"296            }297          ]298        }299      }300    ],301    "input": "Use the csv-insights skill and run locally to summarize today\'s CSV reports in this repo."302  }'303```304305```javascript306import OpenAI from "openai";307308const client = new OpenAI();309310const response = await client.responses.create({311  model: "gpt-6-astra",312  tools: [313    {314      type: "shell",315      environment: {316        type: "local",317        skills: [318          {319            name: "csv-insights",320            description: "Summarize CSV files and produce a markdown report.",321            path: "<path-to-skill-folder>",322          },323        ],324      },325    },326  ],327  input:328    "Use the csv-insights skill and run locally to summarize today's CSV reports in this repo.",329});330331console.log(response.output_text);332```333334```python335response = client.responses.create(336    model="gpt-6-astra",337    tools=[338        {339            "type": "shell",340            "environment": {341                "type": "local",342                "skills": [343                    {344                        "name": "csv-insights",345                        "description": "Summarize CSV files and produce a markdown report.",346                        "path": "<path-to-skill-folder>",347                    }348                ],349            },350        }351    ],352    input="Use the csv-insights skill and run locally to summarize today's CSV reports in this repo.",353)354355print(response.output_text)356```357358```go359package main360361import (362	"context"363	"fmt"364365	"github.com/openai/openai-go/v3"366	"github.com/openai/openai-go/v3/responses"367)368369func main() {370	client := openai.NewClient()371	tool := responses.ToolUnionParam{OfShell: &responses.FunctionShellToolParam{372		Environment: responses.FunctionShellToolEnvironmentUnionParam{OfLocal: &responses.LocalEnvironmentParam{373			Skills: []responses.LocalSkillParam{{374				Name:        "csv-insights",375				Description: "Summarize CSV files and produce a markdown report.",376				Path:        "<path-to-skill-folder>",377			}},378		}},379	}}380	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{381		Model: "gpt-6-astra",382		Tools: []responses.ToolUnionParam{tool},383		Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Use the csv-insights skill and run locally to summarize today's CSV reports in this repo.")},384	})385	if err != nil {386		panic(err)387	}388	fmt.Println(response.OutputText())389}390```391392```java393import com.openai.client.OpenAIClient;394import com.openai.client.okhttp.OpenAIOkHttpClient;395import com.openai.core.JsonValue;396import com.openai.models.responses.ResponseCreateParams;397import java.util.List;398import java.util.Map;399400String skillPath = "<path-to-skill-folder>";401402ResponseCreateParams params =403    ResponseCreateParams.builder()404        .model("gpt-6-astra")405        .input("Use the csv-insights skill to summarize today's CSV reports.")406        .putAdditionalBodyProperty(407            "tools",408            JsonValue.from(409                List.of(410                    Map.of(411                        "type",412                        "shell",413                        "environment",414                        Map.of(415                            "type",416                            "local",417                            "skills",418                            List.of(419                                Map.of(420                                    "name", "csv-insights",421                                    "description",422                                        "Summarize CSV files and produce a Markdown report.",423                                    "path", skillPath)))))))424        .build();425426client.responses().create(params).output().stream()427    .flatMap(item -> item.message().stream())428    .flatMap(message -> message.content().stream())429    .flatMap(content -> content.outputText().stream())430    .forEach(text -> System.out.println(text.text()));431```432433```ruby434require "openai"435436client = OpenAI::Client.new437response = client.responses.create(438  model: "gpt-6-astra",439  input: "Use the csv-insights skill to summarize today's CSV reports.",440  tools: [441    {442      type: :shell,443      environment: {444        type: :local,445        skills: [446          {447            name: "csv-insights",448            description: "Summarize CSV files and produce a Markdown report.",449            path: "<path-to-skill-folder>"450          }451        ]452      }453    }454  ]455)456457puts(response.output_text)458```459460461## Agents API462463To use skills in the [Agents API](https://developers.openai.com/api/docs/guides/agents-api/overview), put the skill directories in the sandbox and register their parent directories in `environment.capability_directories` when creating the session. These are called **capability directories**. The harness uses them to discover skills; this setup doesn't use the hosted shell's `skill_reference` attachment format.464465For example, place a contract-review skill and a pull-request-review skill in the sandbox:466467```text468/workspace/capabilities/469├── legal/470│   └── contract-redline/471│       ├── SKILL.md472│       └── references/473│           └── fallback-clauses.md474└── engineering/475    └── review-pr/476        ├── SKILL.md477        └── references/478            └── review-guidelines.md479```480481Use this environment configuration in the session-creation request:482483```json484{485  "environment": {486    "type": "self_hosted",487    "workspace_directory": "/workspace",488    "capability_directories": [489      "/workspace/capabilities/legal",490      "/workspace/capabilities/engineering"491    ]492  }493}494```495496Capability directories have these requirements:497498- Paths must point to directories inside the sandbox.499- Paths must be absolute and unique, and cannot contain `.` or `..` path segments.500- A session can register up to 32 capability directories.501- Directories must already exist in the environment.502503Once the sandbox becomes available, the harness searches these directories for `SKILL.md` files and adds each discovered skill's name and description to context. The model can select relevant skills and read their full instructions and supporting files.504505See [Agent configuration](https://developers.openai.com/api/docs/guides/agents-api/configuration) for session setup and [Connect a sandbox](https://developers.openai.com/api/docs/guides/agents-api/environments/self-hosted) for the execution environment. Review the skills and their supporting files before making them available to the agent, and follow the [sandbox security guidance](https://developers.openai.com/api/docs/guides/agents-api/environments/security).506507## Skills in the user prompt508509For Responses API shell tools, the platform adds each available skill's `name`, `description`, and `path` to user prompt context so the model knows the skill exists.510511The model decides whether to invoke a skill based on this metadata. If the model invokes a skill, it uses the `path` to read the full Markdown instructions from `SKILL.md`.512513Skill instructions are user prompt input (not system prompt input), so they're handled with the same priority as other user-provided instructions. For explicit control, you can still instruct the model to "use the `<skill name>` skill."514515## Limits and validation516517- `SKILL.md` file matching is case-insensitive.518- Exactly one `skill.md`/`SKILL.md` file is allowed in a skill bundle.519- Skill front matter validation follows the [agent skills specification](https://agentskills.io/specification#name-field).520- Maximum zip upload size is `50 MB`.521- Maximum file count per skill version is `500`.522- Maximum uncompressed file size is `25 MB`.523524## Safety with network access525526It is very important to inspect any Skill used with the Responses API. Skills527  introduce security risks such as prompt injection-driven data exfiltration.528  Carefully review the [Risks and safety](#risks-and-safety) section below529  before using this tool.530531## Versioning and management532533### Version pointers534535- `default_version` is used when a version isn't provided.536- `latest_version` tracks the newest upload.537- `skill_reference.version` accepts an integer or `"latest"`.538539### Create a new version540541Create a new skill version542543```bash544curl -X POST 'https://api.openai.com/v1/skills/<skill_id>/versions' \545  -H "Authorization: Bearer $OPENAI_API_KEY" \546  -F 'files=@./geometry.zip;type=application/zip'547```548549550### Set default version551552Set a skill's default version553554```bash555curl -X POST 'https://api.openai.com/v1/skills/<skill_id>' \556  -H "Content-Type: application/json" \557  -H "Authorization: Bearer $OPENAI_API_KEY" \558  -d '{"default_version": 2}'559```560561562### Delete rules563564- You can't delete the default version; set another default first.565- Deleting the last remaining version deletes the skill.566- Deleting a skill cascades to remove all versions.567568## Curated skills569570OpenAI maintains a set of first-party skills that can be referenced by id (for example, `openai-spreadsheets`).571572Reference a curated skill573574```json575{ "type": "skill_reference", "skill_id": "openai-spreadsheets", "version": "latest" }576```577578579## Inline skills580581If you don't want to create a hosted skill, you can inline a zip bundle (base64) in the environment's `skills` array.582583Inline a skill bundle584585```bash586INLINE_ZIP=$(base64 -i ./basic_math.zip)587588curl -L 'https://api.openai.com/v1/containers' \589  -H "Content-Type: application/json" \590  -H "Authorization: Bearer $OPENAI_API_KEY" \591  -d '{592    "name": "inline-skill-container",593    "skills": [594      {595        "type": "inline",596        "name": "basic_math",597        "description": "Add or multiply numbers.",598        "source": {599          "type": "base64",600          "media_type": "application/zip",601          "data": "'"$INLINE_ZIP"'"602        }603      }604    ]605  }'606```607608609## Risks and safety610611It's important to inspect any Skill used with the Responses API. Skills introduce security risks such as prompt injection-driven data exfiltration.612613For Skills used in conjunction with network access, carefully review the [Risks and safety section for networking](https://developers.openai.com/api/docs/guides/tools-shell#risks-and-safety).614615#### Treat Skills as privileged code and instructions616617Skill content can influence planning, tool usage, and command execution. Any Skill should be reviewed as potentially untrusted input until validated by the developer.618619### Don't expose an open Skills repository to end-users620621Avoid product designs where consumer end-users can freely browse, select, or attach arbitrary Skills from an open catalog. This materially increases risk from:622623- Prompt-injection and policy bypass via malicious SKILL.md instructions.624- Data exfiltration or destructive actions triggered by unvetted automation.625626#### Integrate Skills at the developer level627628Skills should be inspected and integrated by the developer, then exposed to end-users only through bounded product experiences. In practice:629630- Map Skills to specific product workflows/use cases.631- Prevent end-user control over arbitrary Skill selection.632- Gate write or high-impact actions behind explicit approval and policy checks.633634#### Require approval for sensitive actions635636For workflows that can perform write or high-impact actions, require explicit approval before execution.637638#### Validate data residency and retention requirements639640The Responses API supports Skills in two form factors: local execution and hosted container-based execution. Hosted skills follow the same container lifecycle as hosted shell: mounted skills and container files remain available while the container is active and are discarded when the container expires or is deleted. If you want execution to stay entirely on infrastructure you manage, use local shell mode. For Agents API sandboxes, see [Sandbox lifecycle](https://developers.openai.com/api/docs/guides/agents-api/environments/lifecycle). Read more about our [data controls](https://developers.openai.com/api/docs/guides/your-data).
Files main
Menu

Theme