Ai
聊天机器人
使用 Nebutra 的聊天补全 API 构建聊天机器人——系统提示、对话历史和限流配置。
概述
聊天补全接口接收一组消息并返回模型响应。支持流式(SSE)和非流式响应、自定义系统提示,以及存储在 @nebutra/db 中的持久对话历史。
配置步骤
在 .env 中添加模型供应商密钥:
OPENAI_API_KEY=""
AI_DEFAULT_MODEL="gpt-5.4-mini"
# 可选:启用多模型路由
OPENROUTER_API_KEY=""AI 聊天默认关闭,需为租户启用:
import { setFeatureFlag } from "@nebutra/preset";
await setFeatureFlag("org_123", "ai.chat", true);也可在控制台 → 组织 → 功能 → AI 聊天中切换。
在 Authorization 请求头中携带 API Key,向 /api/v1/ai/chat 发送 POST 请求:
curl -X POST https://api.yourdomain.com/api/v1/ai/chat \
-H "Authorization: Bearer nbk_live_org123_xxx" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "user", "content": "你好,你能帮我做什么?" }
]
}'请求格式
POST /api/v1/ai/chat
interface ChatRequest {
messages: Array<{
role: "system" | "user" | "assistant";
content: string;
}>;
model?: string; // 默认为 AI_DEFAULT_MODEL
stream?: boolean; // 默认为 true
conversationId?: string; // 在 @nebutra/db 中持久化对话历史
systemPrompt?: string; // 覆盖默认系统提示
maxTokens?: number; // 默认:2048
temperature?: number; // 0–2,默认:0.7
}响应格式
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"model": "gpt-5.4-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "我可以帮您……"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 42,
"completion_tokens": 87,
"total_tokens": 129
}
}响应为 Server-Sent Events(SSE)流。完整的客户端处理方式请参阅流式传输页面。
data: {"choices":[{"delta":{"role":"assistant"},"index":0}]}
data: {"choices":[{"delta":{"content":"我可以"},"index":0}]}
data: {"choices":[{"delta":{"content":"帮您"},"index":0}]}
data: [DONE]自定义系统提示
可以在每次请求中覆盖系统提示,也可以为租户全局设置默认值。
单次请求覆盖:
const response = await fetch("/api/v1/ai/chat", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
messages: [{ role: "user", content: userMessage }],
systemPrompt: "你是 Acme Corp 的客户支持专员。请简洁、专业地回答问题。",
}),
});租户全局默认值(存储在租户设置中):
import { updateTenantAiSettings } from "@nebutra/tenant";
await updateTenantAiSettings("org_123", {
systemPrompt: "你是 Acme Corp 的智能助手。",
defaultModel: "gpt-5.5",
});对话历史
传入 conversationId 可自动持久化和读取消息历史。对话按租户隔离,存储在 Nebutra 数据库中。
// 第一条消息——创建新对话
const res1 = await fetch("/api/v1/ai/chat", {
method: "POST",
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
body: JSON.stringify({
messages: [{ role: "user", content: "法国的首都是哪里?" }],
conversationId: "conv_abc123",
}),
});
// 后续消息——自动读取历史上下文
const res2 = await fetch("/api/v1/ai/chat", {
method: "POST",
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
body: JSON.stringify({
messages: [{ role: "user", content: "那里的人说什么语言?" }],
conversationId: "conv_abc123", // 相同 ID——自动加载之前的上下文
}),
});对话历史会占用模型的上下文窗口。对于非常长的对话,旧消息会被自动摘要以保持在上下文限制内。
上下文窗口管理
API 网关在对话历史接近模型上下文限制时自动进行裁剪:
- 摘要 — 最早的消息被压缩为一条摘要消息
- 滑动窗口 — 最近的 N 条消息始终保留原文
- 系统提示保护 — 系统提示永远不会被裁剪
可以通过响应头查看实际发送给模型的上下文信息:
X-Nebutra-Prompt-Tokens: 1842
X-Nebutra-Context-Window: 128000
X-Nebutra-Messages-Trimmed: 4在服务端代码中调用
在服务端代码(API 路由、后台任务)中直接使用 @nebutra/agents:
import { generateText, streamText } from "@nebutra/agents";
import { getCurrentTenant } from "@nebutra/tenant";
const { tenantId } = getCurrentTenant();
// 非流式——适合后台处理
const { text } = await generateText({
model: "gpt-5.4-mini",
prompt: "总结以下文档:" + document.content,
tenantId,
});
// 流式——适合实时 UI
const stream = await streamText({
model: "gpt-5.5",
messages: conversation.messages,
tenantId,
});限流
AI 接口按租户进行限流,防止 Token 消耗失控:
| 套餐 | 请求数/分钟 | Token 数/分钟 |
|---|---|---|
| FREE | 10 | 40,000 |
| PRO | 60 | 300,000 |
| ENTERPRISE | 自定义 | 自定义 |
触发限流时,API 返回 429 Too Many Requests,并在响应头中携带 Retry-After。
{
"error": "rate_limit_exceeded",
"message": "AI 请求频率超限,请在 12 秒后重试。",
"retryAfter": 12
}错误码
| 错误码 | HTTP 状态 | 含义 |
|---|---|---|
feature_disabled | 403 | 该租户的 ai.chat 标志已关闭 |
quota_exceeded | 402 | 月度 AI Token 配额已耗尽 |
rate_limit_exceeded | 429 | 触发每分钟限流 |
invalid_model | 400 | 模型标识符无法识别 |
upstream_error | 502 | OpenAI / OpenRouter 返回错误 |
相关文档
How is this guide?
在 GitHub 上编辑此页面
最后更新于