乐于分享
好东西不私藏

少查文档、少踩坑:我把 LLM 原生 API 接入做了一个Skill

少查文档、少踩坑:我把 LLM 原生 API 接入做了一个Skill

项目地址 https://github.com/v2ish1yan/llm-apis


故事是这样的。

我这两年写代码的时候,越来越怕一件事。

不是怕写不出来。

是怕你以为写出来了,结果一跑就炸,炸的还特别刁钻。

比如你看着某个平台写着 OpenAI compatible,你心想这不就是换个 base URL 的事儿嘛。

然后你就真的只换了 base URL。

接下来就是 401。

你又把 key 检查了三遍。

还是 401。

你开始怀疑人生,怀疑是不是自己昨晚没睡好,连 Authorization 这种东西都能写错。

结果最后发现是 header 名字不一样,或者空格不对,或者这个平台要求你把 key 放到另一个字段里。

我当时就一声叹息。

这种坑最折磨人的点在于,它永远发生在最关键也最烦的地方,而且它看起来又特别像你自己的锅。

所以我干了件比较朴素的事儿。

我把自己踩过的这些坑,和我能确认的那些差异,整理成了一个 Claude Code skill,名字叫 llm-apis。

项目在这儿

https://github.com/v2ish1yan/llm-apis

你可以把它理解成一个写给编码助手看的原生接口速查参考。

不是 SDK。

也不是那种大而全的统一抽象层。

就是很实在的那种,你要接某家厂商的原生 LLM API,我帮你把最容易出错的那一截路铺平一点点。

磨平一些信息差这种事儿,说起来很虚。

但你真的在凌晨两点被 422 折磨到开始怀疑自己是不是 JSON 写错了一个括号的时候,你就会知道,能少折腾一次都是功德无量。


回到 llm-apis 这块。

它主要解决的其实就一个矛盾。

兼容不等于一致。

路径兼容也不等于行为兼容。

你以为大家都长得差不多。

但真正接入的时候,每家都在最关键的一两个字段上,偷偷长了刺。

鉴权是刺。

流式输出是刺。

tool calling 是刺。

结构化输出也是刺。

同样是 401,它可能是在告诉你 key 错了,也可能是在告诉你你写对了 key 但写错了格式,也可能是在告诉你你压根没权限,或者你被风控了。

你敢信???

这玩意儿最气人的地方还在于,你一旦换了第二家第三家,就会发现这些刺的位置每次都不一样。

你不是在写业务。

你是在玩一个叫做 对齐厂商细节 的大型拼图游戏。

然后 llm-apis 想做的事就是,把这个拼图游戏里最常见的那几块拼图,按厂商按场景放好。

你不用翻一整套文档,也不用在 issue 里找别人踩过的坑。

你直接跟 Claude 说你要干啥就行。


你可以这样用

你直接把需求扔给 Claude 就行,比如下面这些。

我要接入 DeepSeek API
把我现在的 OpenAI 请求改成 Gemini 原生格式
给 Anthropic 的请求加 streaming,用 TypeScript
这个请求一直 401,你帮我按步骤排一下

你把任务抛出来,Claude 读 skill 的参考文件,然后给你一套更接近真实可跑的答案。

说真的,这比我自己每次开新项目都重新去翻一遍 docs 要爽太多了。


顺着上面的再聊聊它到底覆盖了啥。

我自己也没想到会做到这么大。

目前是 38+ provider

里面既有 OpenAI Anthropic Gemini DeepSeek 这种大家天天听到的。

也有 Azure OpenAI AWS Bedrock NVIDIA NIM 这种你在公司里很容易遇到的。

还有 OpenRouter SiliconFlow 这种网关和聚合层。

甚至还有一堆中转和代理服务。

你可能平时根本不会主动去研究它们,但当你真的要接的时候,它们就会以一种很魔幻的方式闯进你的生活。

比如你打开一个页面,看到它写着 全网最低价,支持 OpenAI 接口。

然后你心动了。

然后你就开始踩坑了。

所以我在 llm-apis 里做了一个分级。

我不想假装每个 provider 我都验证到端到端。

那样不真诚。

我把内容分成了 gold usable partial 三档。

gold 就是你可以相对放心地拿来做完整接入的那种。

usable 是大部分实际开发够用,但你边写边核对会更稳。

partial 就是线索入口,你别拿它当生产契约。

我宁愿你一开始就知道它的边界。

这样你踩坑的时候也不会觉得是 skill 在骗你。


回到最核心的使用体验。

llm-apis 不是让你少写代码。

而是让你少干那些特别浪费生命的事。

比如反复确认 base URL。

比如对 header 名字。

比如猜 request body 的结构。

比如 streaming 的 SSE 到底应该怎么 parse。

比如 tool calling 到底叫 tools 还是 tool_config。

这些事儿你做一次就够了。

做第二次第三次你就会觉得自己像个在生产线上拧螺丝的人。

但我们写代码的人,明明应该把时间花在更有创造力的地方。

你想想看,我们花了一整个时代去追求更高层的抽象,更好的框架,更少的样板代码。

结果在 LLM API 这块,又突然回到了一个非常原始的阶段。

每家都在发自己的协议。

每家都在说自己兼容。

每家都在关键字段上长得不一样。

我有时候觉得,这像不像早期互联网,各种浏览器各种标准,一堆人苦哈哈地写兼容性。

历史就是这么爱开玩笑。


当然了,讲人话,我也得把它的局限说清楚。

它不是统一 SDK。

它不会把所有东西封装成一个 llm.chat.completions.create 然后天下太平。

如果你追求的是完全一致的开发体验,那你还是得上抽象层。

llm-apis 更适合那种时刻。

就是你发现抽象层不够用了。

你要迁移。

你要调试。

你要用 provider native 的特性。

你要搞清楚为什么同样一段代码在这家能跑在那家就爆炸。

这时候你就得面对细节。

而 llm-apis 就是给你一点点面对细节的底气。


安装方式

在 Claude Code 里直接装。

/plugin install llm-apis@github:v2ish1yan/llm-apis

你也可以 clone 下来放到 skills 目录里。

记得目录名要叫 llm-apis。

然后重启。

就这么朴素。


写到这儿,屏幕前的你可能会想。

这东西到底适合谁。

我自己的判断是。

如果你一年只接一家厂商,而且永远不迁移,永远不用 streaming,永远不碰 tool calling。

那你可能不太需要它。

但如果你稍微做点真实项目。

你就会发现,迁移是常态,调试是常态,跨厂商对齐更是常态。

然后你会越来越想要一个东西,能把这些坑写明白。

写得像个活人踩过一样。

因为确实踩过。


以上。

既然看到这里了,如果觉得对你有一点点帮助,随手点个赞,在看,转发三连吧。

如果你想第一时间收到推送,也可以给我个星标。

谢谢你看我的文章,我们,下次再见。

项目地址

https://github.com/v2ish1yan/llm-apis