[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F7004FZ8S8KMDDNGJST2CX":3,"skill-same:01M6F7004FZ8S8KMDDNGJST2CX":81},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":58,"commitSha":59,"skillDirectory":60,"forksCount":61,"repositoryHtmlUrl":62,"repositoryHomepageUrl":63,"ownerHtmlUrl":64,"ownerBlogUrl":6,"ownerDescription":65,"updatedAt":66,"install":67,"resources":80},"01M6F7004FZ8S8KMDDNGJST2CX","anth-sdk-patterns",null,"Apply production-ready Anthropic SDK patterns for TypeScript and Python.\nUse when implementing Claude integrations, building reusable wrappers,\nor establishing team coding standards for the Messages API.\nTrigger with phrases like \"anthropic SDK patterns\", \"claude best practices\",\n\"anthropic code patterns\", \"production claude code\".","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fanth-sdk-patterns\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"sdk","anth sdk patterns","patterns","edit","typescript","code patterns","anthropic sdk","trigger","io","code","standards","ready","coding standards","write","read","coding","integrations","team","api","messages","2026-11-10 10:12:30",false,"---\nname: anth-sdk-patterns\ndescription: |\n  Apply production-ready Anthropic SDK patterns for TypeScript and Python.\n  Use when implementing Claude integrations, building reusable wrappers,\n  or establishing team coding standards for the Messages API.\n  Trigger with phrases like \"anthropic SDK patterns\", \"claude best practices\",\n  \"anthropic code patterns\", \"production claude code\".\nallowed-tools: Read, Write, Edit\nversion: 1.0.0\nlicense: MIT\nauthor: Jeremy Longshore \u003Cjeremy@intentsolutions.io>\ntags: [saas, ai, anthropic]\ncompatible-with: claude-code\n---\n\n# Anthropic SDK Patterns\n\n## Overview\n\nProduction-ready patterns for the Anthropic SDK covering client management, error handling, type safety, and multi-tenant configurations.\n\n## Prerequisites\n\n- Completed `anth-install-auth` setup\n- Familiarity with async\u002Fawait patterns\n- TypeScript 5+ or Python 3.10+\n\n## Pattern 1: Typed Wrapper with Retry\n\n```typescript\nimport Anthropic from '@anthropic-ai\u002Fsdk';\nimport type { Message, MessageCreateParams } from '@anthropic-ai\u002Fsdk\u002Fresources\u002Fmessages';\n\nclass ClaudeService {\n  private client: Anthropic;\n\n  constructor(apiKey?: string) {\n    this.client = new Anthropic({\n      apiKey: apiKey || process.env.ANTHROPIC_API_KEY,\n      maxRetries: 3,      \u002F\u002F SDK handles 429 + 5xx automatically\n      timeout: 60_000,\n    });\n  }\n\n  async complete(\n    prompt: string,\n    options: Partial\u003CMessageCreateParams> = {}\n  ): Promise\u003Cstring> {\n    const message = await this.client.messages.create({\n      model: options.model || 'claude-sonnet-4-20250514',\n      max_tokens: options.max_tokens || 1024,\n      messages: [{ role: 'user', content: prompt }],\n      ...options,\n    });\n\n    const textBlock = message.content.find((b) => b.type === 'text');\n    if (!textBlock || textBlock.type !== 'text') {\n      throw new Error(`No text in response: ${message.stop_reason}`);\n    }\n    return textBlock.text;\n  }\n\n  async *stream(prompt: string, model = 'claude-sonnet-4-20250514'): AsyncGenerator\u003Cstring> {\n    const stream = this.client.messages.stream({\n      model,\n      max_tokens: 4096,\n      messages: [{ role: 'user', content: prompt }],\n    });\n\n    for await (const event of stream) {\n      if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {\n        yield event.delta.text;\n      }\n    }\n  }\n}\n```\n\n## Pattern 2: Multi-Turn Conversation Manager\n\n```python\nimport anthropic\nfrom dataclasses import dataclass, field\n\n@dataclass\nclass Conversation:\n    client: anthropic.Anthropic = field(default_factory=anthropic.Anthropic)\n    model: str = \"claude-sonnet-4-20250514\"\n    system: str = \"\"\n    messages: list = field(default_factory=list)\n    max_tokens: int = 4096\n\n    def say(self, user_message: str) -> str:\n        self.messages.append({\"role\": \"user\", \"content\": user_message})\n\n        response = self.client.messages.create(\n            model=self.model,\n            max_tokens=self.max_tokens,\n            system=self.system,\n            messages=self.messages,\n        )\n\n        assistant_text = response.content[0].text\n        self.messages.append({\"role\": \"assistant\", \"content\": assistant_text})\n        return assistant_text\n\n    @property\n    def token_count(self) -> int:\n        \"\"\"Estimate total tokens in conversation.\"\"\"\n        return sum(len(str(m[\"content\"])) \u002F\u002F 4 for m in self.messages)\n\n# Usage\nconv = Conversation(system=\"You are a helpful coding assistant.\")\nprint(conv.say(\"What is a closure in JavaScript?\"))\nprint(conv.say(\"Can you show me an example?\"))  # Has full context\n```\n\n## Pattern 3: Structured Output with Prefill\n\n```python\nimport json\nimport anthropic\n\nclient = anthropic.Anthropic()\n\ndef extract_structured(text: str, schema_description: str) -> dict:\n    \"\"\"Force JSON output using assistant prefill technique.\"\"\"\n    message = client.messages.create(\n        model=\"claude-sonnet-4-20250514\",\n        max_tokens=1024,\n        messages=[\n            {\"role\": \"user\", \"content\": f\"Extract data from this text as JSON.\\n\\nSchema: {schema_description}\\n\\nText: {text}\"},\n            {\"role\": \"assistant\", \"content\": \"{\"}  # Prefill forces JSON output\n        ]\n    )\n    json_str = \"{\" + message.content[0].text\n    return json.loads(json_str)\n\n# Usage\ndata = extract_structured(\n    \"John Smith, 35, lives in NYC and works at Google as a PM.\",\n    '{\"name\": str, \"age\": int, \"city\": str, \"company\": str, \"role\": str}'\n)\n# {\"name\": \"John Smith\", \"age\": 35, \"city\": \"NYC\", \"company\": \"Google\", \"role\": \"PM\"}\n```\n\n## Pattern 4: Multi-Tenant Client Factory\n\n```typescript\nconst clients = new Map\u003Cstring, Anthropic>();\n\nexport function getClientForTenant(tenantId: string): Anthropic {\n  if (!clients.has(tenantId)) {\n    const apiKey = getApiKeyForTenant(tenantId);  \u002F\u002F From your secret store\n    clients.set(tenantId, new Anthropic({ apiKey }));\n  }\n  return clients.get(tenantId)!;\n}\n```\n\n## Pattern 5: Token-Aware Request Sizing\n\n```python\n# Use the Token Counting API to pre-check request size\ncount = client.messages.count_tokens(\n    model=\"claude-sonnet-4-20250514\",\n    messages=[{\"role\": \"user\", \"content\": long_document}],\n    system=\"You are a summarizer.\"\n)\nprint(f\"Input will use {count.input_tokens} tokens\")\n\n# Adjust max_tokens to stay within budget\nremaining_budget = 200_000 - count.input_tokens\nmax_tokens = min(4096, remaining_budget)\n```\n\n## Error Handling\n\n| Pattern | Use Case | Benefit |\n|---------|----------|---------|\n| SDK `maxRetries` | 429 \u002F 5xx errors | Built-in exponential backoff |\n| Prefill technique | Force JSON output | No regex parsing needed |\n| Token counting | Long documents | Prevent context overflow |\n| Client factory | Multi-tenant SaaS | Key isolation per customer |\n\n## Resources\n\n- [Client SDKs](https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fapi\u002Fclient-sdks)\n- [Token Counting API](https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fdocs\u002Fbuild-with-claude\u002Ftoken-counting)\n- [Prompt Caching](https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fdocs\u002Fbuild-with-claude\u002Fprompt-caching)\n\n## Next Steps\n\nApply patterns in `anth-core-workflow-a` for tool use workflows.\n\n","# Anthropic SDK Patterns\n\n## Overview\n\nProduction-ready patterns for the Anthropic SDK covering client management, error handling, type safety, and multi-tenant configurations.\n\n## Prerequisites\n\n- Completed `anth-install-auth` setup\n- Familiarity with async\u002Fawait patterns\n- TypeScript 5+ or Python 3.10+\n\n## Pattern 1: Typed Wrapper with Retry\n\n```typescript\nimport Anthropic from '@anthropic-ai\u002Fsdk';\nimport type { Message, MessageCreateParams } from '@anthropic-ai\u002Fsdk\u002Fresources\u002Fmessages';\n\nclass ClaudeService {\n  private client: Anthropic;\n\n  constructor(apiKey?: string) {\n    this.client = new Anthropic({\n      apiKey: apiKey || process.env.ANTHROPIC_API_KEY,\n      maxRetries: 3,      \u002F\u002F SDK handles 429 + 5xx automatically\n      timeout: 60_000,\n    });\n  }\n\n  async complete(\n    prompt: string,\n    options: Partial\u003CMessageCreateParams> = {}\n  ): Promise\u003Cstring> {\n    const message = await this.client.messages.create({\n      model: options.model || 'claude-sonnet-4-20250514',\n      max_tokens: options.max_tokens || 1024,\n      messages: [{ role: 'user', content: prompt }],\n      ...options,\n    });\n\n    const textBlock = message.content.find((b) => b.type === 'text');\n    if (!textBlock || textBlock.type !== 'text') {\n      throw new Error(`No text in response: ${message.stop_reason}`);\n    }\n    return textBlock.text;\n  }\n\n  async *stream(prompt: string, model = 'claude-sonnet-4-20250514'): AsyncGenerator\u003Cstring> {\n    const stream = this.client.messages.stream({\n      model,\n      max_tokens: 4096,\n      messages: [{ role: 'user', content: prompt }],\n    });\n\n    for await (const event of stream) {\n      if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {\n        yield event.delta.text;\n      }\n    }\n  }\n}\n```\n\n## Pattern 2: Multi-Turn Conversation Manager\n\n```python\nimport anthropic\nfrom dataclasses import dataclass, field\n\n@dataclass\nclass Conversation:\n    client: anthropic.Anthropic = field(default_factory=anthropic.Anthropic)\n    model: str = \"claude-sonnet-4-20250514\"\n    system: str = \"\"\n    messages: list = field(default_factory=list)\n    max_tokens: int = 4096\n\n    def say(self, user_message: str) -> str:\n        self.messages.append({\"role\": \"user\", \"content\": user_message})\n\n        response = self.client.messages.create(\n            model=self.model,\n            max_tokens=self.max_tokens,\n            system=self.system,\n            messages=self.messages,\n        )\n\n        assistant_text = response.content[0].text\n        self.messages.append({\"role\": \"assistant\", \"content\": assistant_text})\n        return assistant_text\n\n    @property\n    def token_count(self) -> int:\n        \"\"\"Estimate total tokens in conversation.\"\"\"\n        return sum(len(str(m[\"content\"])) \u002F\u002F 4 for m in self.messages)\n\n# Usage\nconv = Conversation(system=\"You are a helpful coding assistant.\")\nprint(conv.say(\"What is a closure in JavaScript?\"))\nprint(conv.say(\"Can you show me an example?\"))  # Has full context\n```\n\n## Pattern 3: Structured Output with Prefill\n\n```python\nimport json\nimport anthropic\n\nclient = anthropic.Anthropic()\n\ndef extract_structured(text: str, schema_description: str) -> dict:\n    \"\"\"Force JSON output using assistant prefill technique.\"\"\"\n    message = client.messages.create(\n        model=\"claude-sonnet-4-20250514\",\n        max_tokens=1024,\n        messages=[\n            {\"role\": \"user\", \"content\": f\"Extract data from this text as JSON.\\n\\nSchema: {schema_description}\\n\\nText: {text}\"},\n            {\"role\": \"assistant\", \"content\": \"{\"}  # Prefill forces JSON output\n        ]\n    )\n    json_str = \"{\" + message.content[0].text\n    return json.loads(json_str)\n\n# Usage\ndata = extract_structured(\n    \"John Smith, 35, lives in NYC and works at Google as a PM.\",\n    '{\"name\": str, \"age\": int, \"city\": str, \"company\": str, \"role\": str}'\n)\n# {\"name\": \"John Smith\", \"age\": 35, \"city\": \"NYC\", \"company\": \"Google\", \"role\": \"PM\"}\n```\n\n## Pattern 4: Multi-Tenant Client Factory\n\n```typescript\nconst clients = new Map\u003Cstring, Anthropic>();\n\nexport function getClientForTenant(tenantId: string): Anthropic {\n  if (!clients.has(tenantId)) {\n    const apiKey = getApiKeyForTenant(tenantId);  \u002F\u002F From your secret store\n    clients.set(tenantId, new Anthropic({ apiKey }));\n  }\n  return clients.get(tenantId)!;\n}\n```\n\n## Pattern 5: Token-Aware Request Sizing\n\n```python\n# Use the Token Counting API to pre-check request size\ncount = client.messages.count_tokens(\n    model=\"claude-sonnet-4-20250514\",\n    messages=[{\"role\": \"user\", \"content\": long_document}],\n    system=\"You are a summarizer.\"\n)\nprint(f\"Input will use {count.input_tokens} tokens\")\n\n# Adjust max_tokens to stay within budget\nremaining_budget = 200_000 - count.input_tokens\nmax_tokens = min(4096, remaining_budget)\n```\n\n## Error Handling\n\n| Pattern | Use Case | Benefit |\n|---------|----------|---------|\n| SDK `maxRetries` | 429 \u002F 5xx errors | Built-in exponential backoff |\n| Prefill technique | Force JSON output | No regex parsing needed |\n| Token counting | Long documents | Prevent context overflow |\n| Client factory | Multi-tenant SaaS | Key isolation per customer |\n\n## Resources\n\n- [Client SDKs](https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fapi\u002Fclient-sdks)\n- [Token Counting API](https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fdocs\u002Fbuild-with-claude\u002Ftoken-counting)\n- [Prompt Caching](https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fdocs\u002Fbuild-with-claude\u002Fprompt-caching)\n\n## Next Steps\n\nApply patterns in `anth-core-workflow-a` for tool use workflows.\n\n",{"name":5,"tags":49,"author":53,"license":15,"version":54,"description":55,"allowed-tools":56,"compatible-with":57},[50,51,52],"saas","ai","anthropic","Jeremy Longshore \u003Cjeremy@intentsolutions.io>","1.0.0","Apply production-ready Anthropic SDK patterns for TypeScript and Python.\nUse when implementing Claude integrations, building reusable wrappers,\nor establishing team coding standards for the Messages API.\nTrigger with phrases like \"anthropic SDK patterns\", \"claude best practices\",\n\"anthropic code patterns\", \"production claude code\".\n","Read, Write, Edit","claude-code","main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fanth-sdk-patterns",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":68,"prompt":78,"zipAvailable":79},[69,72,75],{"tool":70,"command":71},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill anth-sdk-patterns",{"tool":73,"command":74},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill anth-sdk-patterns",{"tool":76,"command":77},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill anth-sdk-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fanth-sdk-patterns\u002FSKILL.md",true,[],[82,96,106,114,120,127],{"skillNo":83,"name":84,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":92,"publishedAt":44},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[87],{"categoryNo":88,"categoryName":89,"taxonomyType":90,"taxonomyTypeDesc":91},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[93,94,95],"model","model hierarchy","model hierarchy skill",{"skillNo":97,"name":98,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":102,"publishedAt":44},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[101],{"categoryNo":88,"categoryName":89,"taxonomyType":90,"taxonomyTypeDesc":91},[103,104,105],"MCP","zoom","zoom mcp",{"skillNo":107,"name":108,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":111,"publishedAt":44},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[24,112,113,104],"zoom apps sdk","apps",{"skillNo":115,"name":116,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":44},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[116],{"skillNo":121,"name":122,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":126,"publishedAt":44},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[125],{"categoryNo":88,"categoryName":89,"taxonomyType":90,"taxonomyTypeDesc":91},[122],{"skillNo":128,"name":129,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":132,"publishedAt":44},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[129]]