用 Deno 构建 AI 应用
设计流式响应、密钥权限、工具调用、RAG 与可观测性边界
最小安全边界
AI 服务通常需要监听端口、读取一个供应商密钥并访问指定 API:
deno run \
--allow-net=0.0.0.0:8000,api.example.com:443 \
--allow-env=MODEL_API_KEY \
--no-prompt main.ts
模型名、API 路径和 SDK 方法变化很快;实现前查询对应供应商当前官方文档,不在共享代码里猜默认模型。
流式代理
Deno.serve(async (request) => {
const upstream = await fetch("https://api.example.com/v1/responses", {
method: "POST",
headers: {
authorization: `Bearer ${Deno.env.get("MODEL_API_KEY")}`,
"content-type": "application/json",
},
body: await request.text(),
signal: request.signal,
});
return new Response(upstream.body, {
status: upstream.status,
headers: { "content-type": upstream.headers.get("content-type") ?? "text/event-stream" },
});
});
生产代码还要限制请求体、校验结构、设置超时、映射错误,并在客户端断开时取消上游请求。
工具调用
- 工具名映射到固定函数,不把模型文本拼进 shell。
- 用 schema 校验参数,并在授权前显示影响范围。
- 文件工具限制到工作目录;网络工具限制 host allowlist。
- 读操作与写操作分级;删除、发布、付款和生产变更需人类确认。
- 日志记录工具名、耗时、结果类型和 request ID,但不记录密钥或完整敏感输入。
RAG 与评测
文档分块保留来源 URL、版本、更新时间与权限标签。检索结果是上下文,不是授权。发布前固定评测集,覆盖拒答、提示注入、超时、供应商 429/5xx 与敏感信息泄露。