GuidesAgent configuration and extensions

Create and attach a Skill

Use a Skill to package reusable instructions and supporting files that an Agent loads progressively. Tenant Skills are reusable across that Tenant's Agents; platform Skills are curated and read-only.

Outcome

You will build a minimal three-file archive, upload it, preserve the Agent's existing Skill IDs while attaching it, and verify activation in a Turn.

Before you begin

You need ZIP tooling, an Agent ID, a backend SDK client, and the archive bytes available as a Blob or Uint8Array. Review the Skills capability and Agents.

Build the Skill archive

Create this directory, then ZIP its contents so SKILL.md is at the archive root:

SKILL.md
style-guide.md
release.md

Use this complete minimal SKILL.md; names use lowercase letters, numbers, and hyphens:

---
name: release-notes
description: Draft release notes from a list of changes.
---
# Release notes
When activated, begin the response with exactly RELEASE NOTES READY.

Supporting paths are relative to the archive root. Put Use sentence case. in references/style-guide.md and # Release notes in templates/release.md for reproducible placeholder content; expand them when the instructions depend on those files.

Upload the Skill

skills.create() uploads one ZIP as multipart form data. The returned detail includes the generated Skill ID, ownership kind, parsed metadata, and live file listing.

Attach it to the Agent

The Agent's skills field is a complete replacement array. Read it first, merge the new ID, and avoid adding a duplicate.

Verify activation

import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
const skill = await client.skills.create({
  file: await readFile("./release-notes.zip"),
  filename: "release-notes.zip",
  metadata: { team: "developer-experience" },
});
const agent = await client.agents.get(agentId);
const skills = [...new Set([...agent.skills, skill.id])];
const updated = await client.agents.update(agentId, { skills });
assert.ok(updated.skills.includes(skill.id));
const turn = await client.chat({
  agentId,
  message: {
    id: crypto.randomUUID(),
    role: "user",
    parts: [{ type: "text", text: "Use release-notes to draft one heading." }],
  },
});
let activated = false, reply = "";
for await (const chunk of turn.toUIMessageStream()) {
  if (chunk.type === "tool-input-available") {
    activated ||= chunk.toolName === "activate_skill";
  }
  if (chunk.type === "text-delta") reply += chunk.delta;
}
assert.ok(activated, "The Turn should activate release-notes");
assert.match(reply, /RELEASE NOTES READY/);

The stream should show the activate_skill Tool call before the model applies the Skill instructions to its response.

Update or remove the Skill

skills.update() uploads a complete replacement ZIP for a Tenant Skill. Each stored object version is immutable, while the Skill record points future Turns at the current version; an Agent Version records only the Skill ID. Updating the same Skill ID therefore changes what historical Pins load. Platform Skills cannot be updated or deleted.

Detach a Skill by sending a replacement skills array without its ID. Deleting a Tenant Skill is rejected while a current Agent still references it, so detach it from every Agent first. Before replacement or deletion, audit Pins: deleted Skills disappear from pinned execution, and restoring a Version that names a deleted Skill fails current attachment validation.

Production notes

  • Keep SKILL.md focused and load larger references progressively instead of placing all guidance in the entry file.
  • ZIP uploads must contain a root SKILL.md; unsafe paths, invalid frontmatter, and oversized archives are rejected.
  • Skill content is private platform-managed storage. Agents select Skills by ID; the instructions are not copied into the Agent record.

See Skills, Agents, Versions and lifecycle, and Security and credentials.

SDK and REST reference

The example uses skills.create(), agents.get(), agents.update(), and chat(). Lifecycle work uses skills.update() and skills.delete().

The matching operations are create Skill, update Skill, delete Skill, get Agent, update Agent, and create a Session Turn.

On this page