Understanding the Difference Between Skills, Agents, and Commands in OpenAI Plugins
Skills define high-level capabilities, agents provide the LLM reasoning engine, and commands execute deterministic function calls that interface with external APIs.
The OpenAI plugins repository establishes a three-tier architecture that separates user-facing capabilities from implementation details. Understanding the difference between skills, agents, and commands in OpenAI plugins enables developers to build maintainable integrations where prompt engineering, business logic, and API calls remain decoupled. This modular design allows teams to update AI behavior without modifying underlying infrastructure, or change API implementations without affecting the conversational interface.
What Are Skills, Agents, and Commands?
The OpenAI plugins framework organizes code into three distinct layers, each with specific responsibilities and file locations.
Skills: High-Level Capabilities
A skill represents a user-facing capability such as "search a Zotero library" or "create a Figma frame." Skills group together the agents that drive LLM reasoning and the commands that expose concrete functions. According to the repository structure, skills live in plugins/<plugin-name>/skills/<skill-name>/SKILL.md and are referenced in the plugin manifest at .codex-plugin/plugin.json.
When a user asks the model to perform a task, the runtime first identifies the relevant skill from the catalog. The skill definition declares which agents and commands are available for fulfilling that specific type of request.
Agents: LLM-Driven Reasoning Engines
An agent is an LLM-driven assistant configured through YAML files that define the system prompt, temperature, tool-use policies, and function schemas. Agents reside in plugins/<plugin-name>/agents/<agent-name>/openai.yaml (or within the skill subdirectory as shown in the Zotero implementation).
The runtime creates an OpenAI chat completion using the agent's configuration. The agent interprets user intent, maintains chain-of-thought reasoning, and decides when to invoke commands. By encapsulating prompt engineering in agent files, developers can modify LLM behavior without touching business logic or API integrations.
Commands: Stateless Function Execution
A command is a single, stateless function that maps to the OpenAI "function-calling" API. Commands define concrete HTTP calls, SDK methods, CLI invocations, or other deterministic operations. They are stored in plugins/<plugin-name>/commands/<command-name>/openai.yaml (for example, plugins/zoom/skills/rest-api/commands/listAgents/openai.yaml).
When an agent determines that data retrieval or action execution is required, it emits a function-call payload. The Codex runtime executes the associated command and feeds the structured result back to the agent for inclusion in the final response.
How the Three Components Interact
The architectural flow demonstrates how skills, agents, and commands collaborate to process user requests:
- User request → The model evaluates available skills in
.codex-plugin/plugin.jsonand selects the relevant capability. - Agent loading → The runtime loads the YAML configuration from
agents/openai.yaml, initializing the system prompt and temperature settings. - Reasoning → The agent processes the request using its configured model (e.g.,
gpt-4) and determines which commands are necessary. - Command execution → The runtime invokes the command defined in
commands/<name>/openai.yaml, executing HTTP requests or other operations. - Response synthesis → The agent incorporates command results into its final output and returns the answer to the user.
This separation ensures that skills remain stable user interfaces, agents can be tuned for different reasoning strategies, and commands serve as reusable, testable units of API integration.
Code Examples from the OpenAI Plugins Repository
Defining a Skill
The Zotero search skill demonstrates how capabilities are declared in plugins/zotero/skills/zotero/SKILL.md:
name: zotero-search
description: Search items in a Zotero library.
agents:
- openai.yaml # points to the agent that drives the skill
commands:
- searchItems.yaml # a command that calls Zotero's REST API
Configuring an Agent
The agent configuration in plugins/zotero/skills/zotero/agents/openai.yaml specifies the LLM parameters and available functions:
model: gpt-4
temperature: 0.2
system: |
You are a Zotero assistant. When asked to look up items, call the `searchItems` function with the
relevant query. Use the result to answer the user concisely.
functions:
- name: searchItems
description: Search Zotero library items.
parameters:
type: object
properties:
query:
type: string
description: The search string.
required: [query]
Implementing a Command
The actual API wrapper lives in plugins/zotero/skills/zotero/commands/searchItems/openai.yaml:
name: searchItems
type: http
method: GET
url: https://api.zotero.org/users/{{USER_ID}}/items
query:
q: "{{query}}"
headers:
ZOTERO-API-KEY: "{{API_KEY}}"
When a user asks, "Find all papers about transformer quantization," the model loads the zotero-search skill, initializes the agent defined in openai.yaml, which decides to call the searchItems command. The runtime executes the HTTP GET request, and the agent formats the returned bibliography into a conversational response.
Summary
- Skills serve as the user-facing entry points that declare available capabilities and map them to specific agents and commands.
- Agents encapsulate LLM configuration, system prompts, and reasoning logic, determining when and how to invoke commands.
- Commands provide deterministic, stateless function implementations that execute HTTP requests, CLI calls, or SDK operations.
- This three-tier architecture enables modular development where teams can update prompts, swap models, or modify APIs independently.
Frequently Asked Questions
Can a single skill use multiple agents?
Yes. A skill can reference multiple agent configurations in its SKILL.md file, allowing different reasoning strategies for different subtasks. The runtime selects the appropriate agent based on the specific intent detected in the user's request, or agents can be chained together for complex multi-step workflows.
Are commands reusable across different skills?
Yes. Commands are designed as standalone, stateless functions that can be referenced by any skill within the same plugin. Since commands live in plugins/<plugin>/commands/<command>/openai.yaml and are referenced by name, multiple skills can invoke the same command implementation without duplication, promoting code reuse across the codebase.
How does the agent decide which command to call?
The agent uses the function schema defined in its YAML configuration to determine when a command is relevant. When processing a user request, the LLM evaluates whether the required data or action matches a declared function's parameters. If so, the agent outputs a function-call payload specifying the command name and arguments, which the runtime translates into the actual HTTP request or operation defined in the command's YAML file.
What is the relationship between the plugin manifest and skills?
The .codex-plugin/plugin.json manifest registers the plugin with the marketplace and catalogs available skills. When a user installs a plugin, the system reads this manifest to discover what skills are available. Each skill listed in the manifest points to its respective SKILL.md file, creating the bridge between the plugin's public interface and its internal implementation of agents and commands.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →