简介
Keq 是什么?
Keq 是一个为 AI 编程时代设计的 TypeScript HTTP 客户端。它基于 Fetch API 构建,融合了 Koa 的中间件设计和 SuperAgent 的链式调用体验。
与传统 HTTP 客户端不同,Keq 把 OpenAPI 文档变成 AI 可直接检索的结构化知识,并让请求代码由工具生成,而不是由 AI 手写——你的 AI 助手既能精确定位接口,也能拿到与接口定义完全一致的类型。
为 AI 编程而生
告诉 AI 你要什么,代码自己就写好了
当你的 AI 编程助手接入 Keq 后,开发体验会变成这样:
👤 开发者:帮我写一个猫咪领养页面,展示可领养的猫咪列表,支持按品种筛选
🤖 AI 助手:
→ 搜索 API:"猫咪"、"品种"
→ 找到:GET /cats (catService#getCats)
→ 找到:GET /breeds (catService#getBreeds)
→ 生成请求代码并构建页面...import { getCats, getBreeds } from "./apis/cat_service"
export function AdoptionPage() {
const [breed, setBreed] = useState("")
const breeds = await getBreeds()
const cats = await getCats({ breed, status: "adoptable" })
// ^^^^^ 参数类型由 OpenAPI 文档推断,拼错字段编译器直接报错
return (/* 渲染猫咪列表... */)
}这段代码里没有手写 URL、参数类型或响应结构:getCats / getBreeds 的签名来自 OpenAPI 文档,AI 只负责把它们组合进页面。请求层的类型由生成器维护,页面代码专注业务逻辑。
为 AI 助手安装 Keq Skills
在项目根目录执行:
npx skills add keq-request/skills安装后,AI 助手会在需要时加载 Keq 的编码规范,获得以下能力:
- 🔍 自然语言搜索 — 用中文或英文描述你想要的接口,AI 通过
keq search语义匹配 - 🏗️ 按需生成代码 — AI 根据
.keqrc执行keq build,生成类型安全的 TypeScript 请求函数 - 📋 过滤规则管理 — AI 维护
.keqfilter,只生成项目实际用到的接口代码 - 🔄 实时感知变更 — OpenAPI 文档更新后重新生成,AI 始终基于最新接口信息工作
完整用法见 Vibing Code。
为什么 AI 编程需要 Keq?
AI 写 HTTP 请求,难点通常不是把请求发出去,而是让代码在后续迭代中始终和接口定义保持一致。AI 很容易写出“看起来能跑”的代码,但 API 上下文、类型约束和接口变更这三件事,往往没有处理好。
上下文浪费:AI 不知道有哪些接口,只能翻原始文档
AI 缺少 API 上下文时,只能读取大段 Swagger/OpenAPI JSON,或者到后端代码里搜索路由。这会消耗大量上下文,还容易找错接口。
Keq 把 OpenAPI 文档变成 AI 可以直接检索的结构化知识:
keq search "猫咪 品种":用自然语言定位接口keq apis:列出模块、接口和数据结构keq describe operation:查看单个接口的完整参数与响应 Schema
AI 只读取当前任务需要的接口信息,不必把整份 API 文档或后端代码塞进上下文。
类型漂移:为了让代码通过,类型被改成 any
手写类型的问题在于,它是对接口定义的一次性拷贝。接口字段一变,这份拷贝就失效;为了让编译继续通过,AI 往往会放宽类型,而不是逐一修正调用点。
Keq 的请求函数由 @keq-request/cli 从 OpenAPI 文档编译生成。参数、返回值、请求体类型都来自接口定义,AI 只调用生成好的函数,不需要手写类型,也不应该修改生成文件。
变更可追踪:不兼容改动会让所有调用点一起报错
接口不会一成不变:字段重命名、类型收紧、必填参数增加,都会影响已有调用。手写请求时,这些影响散落在各个文件里,AI 可能只改了眼前的代码,漏掉其他调用点。
Keq 的请求函数由接口定义生成。接口发生不兼容变更后,重新生成代码,所有受影响的调用点都会在 TypeScript 编译时暴露出来:参数少传、类型不匹配、返回值用法错误,都会变成具体文件里的具体报错。编译错误就是一份完整的待修清单,AI 沿着它逐个修正即可。
一个让 AI 不必翻原始文档,一个让 AI 不必手写类型,一个让不兼容改动无处可藏——这就是 Keq 为 AI 编程准备的三项基础能力。
核心特性
⚡ 链式调用
流畅的 API 设计,让手写和 AI 生成的代码都直观易读:
await request
.post("/cats")
.send({ name: "mimi", age: 3 })
.set("Content-Type", "application/json")
.timeout(5000)
.retry(2);🧩 洋葱模型中间件
通过中间件组合复杂功能,官方提供开箱即用:
- 超时控制 - 防止请求长时间挂起
- 失败重试 - 灵活的重试策略
- 并发控制 - 管理并发请求数量
- 智能序列化 - 根据 Content-Type 自动处理响应
- 异常处理 - 统一的错误处理机制
- 请求缓存 - 减少不必要的网络请求
拦截器的能力上限有限——它将请求和响应割裂为独立钩子,无法共享上下文,一些场景(如条件重试、请求计时、基于响应的二次请求)根本无法实现。中间件虽然编写更复杂,但它提供了一个能力上限极高的架构模型。在 AI 编程时代,编写复杂度已不再是瓶颈——让架构本身具备足够的灵活性,比降低手写门槛更重要。
📘 TypeScript 全链路类型推断
从请求参数到响应体,类型一路贯通:
// 自动推断响应体类型
const cat = await request.get<Cat>("/cats/1");
// ^? Cat
// @keq-request/cli 生成的函数,参数类型严格校验
await getCats({ breed: "siamese" });
// ^^^^^^ 未定义的参数会在编译时报错🎨 灵活的路由系统
精准控制中间件的应用范围:
request
.apply(authMiddleware()).forRoutes({ host: "api.example.com" })
.apply(adminAuth()).forRoutes({ pathname: "/admin/**" })
.apply(logMiddleware()).forRoutes({ method: "POST" });🌐 跨平台
基于标准 Fetch API,在浏览器和 Node.js (≥20) 中使用同一套代码。
设计哲学
- AI 协作优先 — 让 AI 助手能精确理解和操作项目的 API 层
- 优雅的 API — 链式调用让代码更易读易写
- 可组合性 — 通过中间件组合复杂功能,而非臃肿的配置
- 类型安全 — 充分利用 TypeScript,在编译期发现问题
- 开发效率 — 通过 CLI 工具和 AI 集成减少重复劳动
- 灵活可控 — 提供足够的扩展点,满足各种定制需求