Use when wiring up or switching between China-domestic LLM providers (DeepSeek, Doubao/Volc Ark, Qwen/DashScope, MiniMax). Provides OpenAI-compatible adapter pattern, env-var contracts, fallback strategy, cost guardrails, and minimum verifications before declaring integration done.
npx skills add https://github.com/pcliangx/AppGenesisForge --skill agf-wiring-multi-llm-sdk
Use this skill when:
backend/app/agents/ or any backend moduleAll four providers expose OpenAI-compatible endpoints. Default to the openai Python SDK with a custom base_url rather than each vendor's bespoke SDK — fewer dependencies, easier to swap, less drift.
Bespoke SDK exceptions:
volcengine-python-sdk for Ark image APIminimax official SDKBefore wiring any SDK, pull its current docs via Context7 (resolve-library-id → query-docs) — all four vendors iterate fast and training-data memory of their APIs is likely stale. Context7 coverage of domestic SDKs varies; if a library isn't indexed, fall back to WebFetch on official docs.
All providers follow the same pattern. Never hardcode keys. Each is read from environment at module init; a missing key raises early.
| Provider | Endpoint env | Key env | Default model env |
|---|---|---|---|
| DeepSeek | DEEPSEEK_BASE_URL (default https://api.deepseek.com/v1) | DEEPSEEK_API_KEY | DEEPSEEK_MODEL (e.g. deepseek-chat) |
| Doubao (Volc Ark) | ARK_BASE_URL (default https://ark.cn-beijing.volces.com/api/v3) | ARK_API_KEY | ARK_MODEL_ENDPOINT_ID (vendor-specific endpoint id, NOT model name) |
| Qwen (DashScope) | DASHSCOPE_BASE_URL (default https://dashscope.aliyuncs.com/compatible-mode/v1) | DASHSCOPE_API_KEY | QWEN_MODEL (e.g. qwen-plus) |
| MiniMax | MINIMAX_BASE_URL (default https://api.minimaxi.com/v1) | MINIMAX_API_KEY | MINIMAX_MODEL (e.g. abab6.5s-chat) |
> Doubao gotcha: the "model name" in OAI-compat call is actually the Ark endpoint id (ep-2024xxxx), not a public model id like doubao-pro-32k. Get the endpoint id from Volc Ark console.
# backend/app/agents/llm_clients.py
import os
from openai import OpenAI
def get_client(provider: str) -> tuple[OpenAI, str]:
if provider == "deepseek":
return OpenAI(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url=os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com/v1"),
), os.getenv("DEEPSEEK_MODEL", "deepseek-chat")
if provider == "doubao":
return OpenAI(
api_key=os.environ["ARK_API_KEY"],
base_url=os.getenv("ARK_BASE_URL", "https://ark.cn-beijing.volces.com/api/v3"),
), os.environ["ARK_MODEL_ENDPOINT_ID"]
if provider == "qwen":
return OpenAI(
api_key=os.environ["DASHSCOPE_API_KEY"],
base_url=os.getenv("DASHSCOPE_BASE_URL", "https://dashscope.aliyuncs.com/compatible-mode/v1"),
), os.getenv("QWEN_MODEL", "qwen-plus")
if provider == "minimax":
return OpenAI(
api_key=os.environ["MINIMAX_API_KEY"],
base_url=os.getenv("MINIMAX_BASE_URL", "https://api.minimaxi.com/v1"),
), os.getenv("MINIMAX_MODEL", "abab6.5s-chat")
raise ValueError(f"unknown provider: {provider}")
Default order (tunable in CLAUDE.md per project): DeepSeek → Doubao → Qwen → MiniMax.
Implement with tenacity retry + a thin orchestrator that walks the list. Never silently swap models without telemetry — every failover emits a structured log line per observability.md.
Every call must record the LLM fields mandated by observability.md:17 plus provider. DeepSeek + Doubao support prompt caching — read cache_hit_ratio off the response usage object.
Before claiming the integration works, run this checklist explicitly. Verify outputs match expectations — do not assume.
localhost:1) and confirm auto-fallback + log linegit diff | grep -iE 'api[_-]?key|secret|token' before commit)base_url strings — always read from envusage shape — validate and normalize.env (gitignored) or secret managerConvert PyTorch AT_DISPATCH macros to AT_DISPATCH_V2 format in ATen C++ code. Use when porting AT_DISPATCH_ALL_TYPES_AND*, AT_DISPATCH_FLOATING_TYPES*, or other dispatch macros to the new v2 API. For ATen kernel files, CUDA kernels, and native operator implementations.
Write docstrings for PyTorch functions and methods following PyTorch conventions. Use when writing or updating docstrings in PyTorch code.
Statistical models library for Python. Use when you need specific model classes (OLS, GLM, mixed models, ARIMA) with detailed diagnostics, residuals, and inference. Best for econometrics, time series, rigorous inference with coefficient tables. For guided statistical test selection with APA reporting use statistical-analysis.
Answer questions about the AI SDK and help build AI-powered features. Use when developers: (1) Ask about AI SDK functions like generateText, streamText, ToolLoopAgent, embed, or tools, (2) Want to build AI agents, chatbots, RAG systems, or text generation features, (3) Have questions about AI providers (OpenAI, Anthropic, Google, etc.), streaming, tool calling, structured output, or embeddings, (4) Use React hooks like useChat or useCompletion. Triggers on: "AI SDK", "Vercel AI SDK", "generateText", "streamText", "add AI to my app", "build an agent", "tool calling", "structured output", "useChat".
Create an llms.txt file from scratch based on repository structure following the llms.txt specification at https://llmstxt.org/
Use when working directly with the `esm` Python SDK, ESM3 or ESMC model IDs, Forge/Biohub inference clients, or ESMFold2 folding workflows.
Modal is a serverless cloud platform for running Python on demand, including on-demand GPUs. Use when deploying or serving AI/ML models, running GPU-accelerated workloads (training, fine-tuning, inference), serving web endpoints, scheduling batch jobs, or scaling Python code to cloud containers with the Modal SDK.
Use Therapeutics Data Commons through the PyTDC Python package for registry discovery, approved dataset access, task-aware splits, evaluator metrics, benchmark groups, and bounded molecular-oracle workflows.
Take pcliangx/agf-wiring-multi-llm-sdk from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.