본문으로 건너뛰기

이식 가능한 에이전트 스킬

SKILL.md 파일 모음이 있습니다. 이는 모델이 한 가지 작업을 잘 수행하도록 가르치는 재사용 가능한 지침입니다(슬라이드 덱 만들기, 브랜드 보이스 따르기, PDF 작성 등). 모든 스킬을 시스템 프롬프트에 붙여 넣지 않고도, 사용하는 provider에서 모델이 스스로 적절한 스킬을 선택하게 하려는 경우에 사용합니다.

@tanstack/ai-skillswithSkills가 이를 수행합니다. 제공하는 스킬의 간단한 카탈로그를 렌더링하고 모델에 load_skill 도구를 제공합니다. 모델은 카탈로그를 읽고 스킬을 선택한 다음 load_skill을 호출하여 필요한 경우에만 전체 지침을 받습니다. 모든 도구 호출 모델에서 작동합니다.

이는 이식 가능한 경로입니다. 이미 사용하는 모델에서 실행되며 서버 샌드박스가 필요하지 않습니다. provider의 샌드박스에서 실행되는 호스팅 스킬은 Provider Skills를 참조하세요. 두 방식은 하나의 호출에서 함께 사용할 수 없습니다. Portable vs hosted를 참조하세요.

설치

npm install @tanstack/ai-skills

채팅에 스킬 추가

스킬을 인라인으로 정의한 다음 middleware 배열에서 withSkills에 전달합니다. 미들웨어가 카탈로그와 load_skill 도구를 처리합니다.

import { chat, toServerSentEventsResponse } from '@tanstack/ai'
import { anthropicText } from '@tanstack/ai-anthropic'
import { inlineSkill, withSkills } from '@tanstack/ai-skills'

const pptx = inlineSkill({
name: 'pptx-builder',
description: 'Build and edit PowerPoint decks with python-pptx.',
instructions: `
# Building a deck
Use python-pptx. Open or create the presentation, edit slides, then save.
Keep one idea per slide.
`,
})

export async function POST(request: Request) {
const { messages } = await request.json()

const stream = chat({
adapter: anthropicText('claude-sonnet-4-5'),
messages,
middleware: [withSkills(pptx)],
})

return toServerSentEventsResponse(stream)
}

설정은 이것으로 끝입니다. 이제 모델은 카탈로그에서 pptx-builder를 보고, 덱 작성 작업이 생기면 load_skill을 호출하여 지침을 가져올 수 있습니다.

모델에 표시되는 내용

withSkills는 요청에 두 가지를 추가합니다.

  • 시스템 프롬프트의 카탈로그: 스킬마다 이름과 설명을 한 줄에 표시합니다. load_skillname은 스킬 이름으로 제한되므로 모델이 임의의 이름을 만들 수 없습니다.
  • load_skill 도구: 모델이 호출하면 미들웨어가 스킬 본문(frontmatter 제거)과 번들 리소스 목록을 반환합니다.

한 대화에서 같은 스킬을 두 번 로드하면 본문을 반복하는 대신 짧은 "already loaded" 표시를 반환하여 컨텍스트를 간결하게 유지합니다.

여러 스킬 제공

배열을 전달합니다. 스킬은 이름순으로 정렬되고 중복이 제거됩니다.

import { chat, toServerSentEventsResponse } from '@tanstack/ai'
import { anthropicText } from '@tanstack/ai-anthropic'
import { inlineSkill, withSkills } from '@tanstack/ai-skills'

const pptx = inlineSkill({
name: 'pptx-builder',
description: 'Build and edit PowerPoint decks with python-pptx.',
instructions: '# Building a deck\nUse python-pptx. Edit slides, then save.',
})

const brand = inlineSkill({
name: 'brand-voice',
description: 'Write in the company brand voice.',
instructions: '# Brand voice\nWarm, direct, no jargon.',
})

export async function POST(request: Request) {
const { messages } = await request.json()

const stream = chat({
adapter: anthropicText('claude-sonnet-4-5'),
messages,
middleware: [withSkills([pptx, brand])],
})

return toServerSentEventsResponse(stream)
}

인라인 스킬은 가장 빠르게 시작하는 방법이지만, 스킬을 코드에 보관하는 경우는 드뭅니다. 폴더, 빌드 타임 번들 또는 자체 데이터베이스에서 읽을 수 있습니다. Skill sources를 참조하세요.

카탈로그 조정

withSkills는 일반적인 경우를 위한 옵션을 받습니다.

withSkills(sources, {
// Cap the catalog so a big skill library doesn't tax every request.
// Default 4000 tokens; throws if exceeded unless you supply a reducer.
maxCatalogTokens: 4000,

// Require a human approval before load_skill runs. Default false.
requireApproval: true,
})

카탈로그는 모델 family별로 렌더링됩니다. Anthropic 모델에는 해당 모델에 맞춘 <available_skills> XML이 제공되고, 그 외 모델에는 일반 Markdown 목록이 제공됩니다. renderCatalog 함수 또는 {skills} placeholder가 있는 instructionTemplate 문자열로 이를 재정의할 수 있습니다.

스킬 파일 읽기

일부 스킬은 참조 파일(스타일 가이드, 스키마, 예시)을 번들로 포함합니다. 모델이 이를 읽게 하려면 toolscreateResourceTool을 추가합니다. withSkills가 이를 감지하고 모델에 read_skill_resource를 호출할 수 있다고 알립니다.

import { chat, toServerSentEventsResponse } from '@tanstack/ai'
import { anthropicText } from '@tanstack/ai-anthropic'
import { createResourceTool, inlineSkill, withSkills } from '@tanstack/ai-skills'

const pdf = inlineSkill({
name: 'pdf-filler',
description: 'Fill a PDF form from a data object.',
instructions: '# Fill a PDF\nSee references/fields.md for the field map.',
resources: { 'references/fields.md': 'name -> field_1\nemail -> field_2' },
})

export async function POST(request: Request) {
const { messages } = await request.json()

const stream = chat({
adapter: anthropicText('claude-sonnet-4-5'),
messages,
tools: [createResourceTool(pdf)],
middleware: [withSkills(pdf)],
})

return toServerSentEventsResponse(stream)
}

리소스 도구가 없어도 load_skill 결과에는 리소스가 계속 나열되지만, 이 설정에서는 로드할 수 없다고 모델에 알립니다.

코드가 포함된 스킬

일부 스킬은 스크립트를 포함하거나 지침에 "python3 extract.py를 실행하세요"라고 적습니다. withSkillsload_skill 결과에 해당 스크립트를 나열하지만 실행하지는 않습니다. 코드 실행은 앱의 역할이며, 자체 도구를 전달하여 연결합니다.

withSkillschat()에 제공하는 모든 도구와 조합됩니다. 따라서 실행 도구를 추가하고 모델이 해당 도구를 호출하도록 스킬을 작성합니다. 스킬은 "방법"(명령)을 제공하고, 도구는 이를 실행하는 기능을 제공합니다.

import { chat, toServerSentEventsResponse, toolDefinition } from '@tanstack/ai'
import { anthropicText } from '@tanstack/ai-anthropic'
import { inlineSkill, withSkills } from '@tanstack/ai-skills'
import { z } from 'zod'

// Your own execution tool. Run the command wherever you want: a provider
// sandbox, a local isolate, a serverless worker. Guard it in production.
const executeShell = toolDefinition({
name: 'execute_shell',
description: 'Run a shell command and return its stdout.',
inputSchema: z.object({ command: z.string() }),
outputSchema: z.object({ stdout: z.string() }),
}).server(async ({ command }) => {
const { stdout } = await runInYourSandbox(command)
return { stdout }
})

const extractPdf = inlineSkill({
name: 'pdf-extract',
description: 'Extract text from a PDF with a small Python script.',
instructions: `
# Extract PDF text
Run this with the execute_shell tool, then return the text it prints:
python3 -c "import sys, pypdf; ..."
`,
})

export async function POST(request: Request) {
const { messages } = await request.json()

const stream = chat({
adapter: anthropicText('claude-sonnet-4-5'),
messages,
tools: [executeShell],
middleware: [withSkills(extractPdf)],
})

return toServerSentEventsResponse(stream)
}

execute_shell을 컨테이너 실행기, Code Mode 샌드박스 또는 원격 worker 등 어떤 도구로든 바꿀 수 있습니다. 스킬은 변하지 않고 이를 뒷받침하는 도구만 바뀝니다. provider 자체 샌드박스에서 실행되는 호스팅 스킬은 Provider Skills.

다음 단계

  • Skill sources — 폴더, 빌드 타임 번들 또는 자체 저장소에서 스킬을 로드하고 여러 소스를 결합합니다. 번들 또는 자체 저장소에서 스킬을 로드하고 여러 소스를 결합합니다.
  • 스킬 소스 작성 — S3, 데이터베이스 또는 registry를 사용해 스킬을 제공하고 conformance suite로 검증합니다. 또는 registry를 사용해 스킬을 제공하고 conformance suite로 검증합니다.
  • Provider Skills — provider 샌드박스에서 실행되는 호스팅 스킬과 이를 대신 사용해야 하는 경우를 설명합니다. provider 샌드박스에서 실행되며 이를 대신 사용해야 하는 경우를 설명합니다.