http://localhost:8000/api/llm{
"code": 200,
"message": "success",
"data": {}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| code | int | 状态码:200成功,400参数错误,401未授权,404资源不存在,500服务器错误,502上游错误,504超时 |
| message | string | 响应消息 |
| data | object | 响应数据 |
POST /api/llm/chat
统一对话API端点,支持流式和非流式两种输出模式。可调用所有类型为语言模型(type=0)的Qwen系列模型。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| Content-Type | string | 是 | application/json |
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| model | string | 是 | - | 模型名称,必须是type=0的语言模型,如 qwen-turbo、qwen-plus、qwen-max |
| messages | array | 是 | - | 对话消息列表,至少包含一条消息 |
| stream | boolean | 否 | false | 是否使用流式输出,true时返回SSE格式流式响应 |
| temperature | number | 否 | - | 采样温度,范围 [0, 2),值越高输出越随机,值越低输出越确定 |
| top_p | number | 否 | - | 核采样概率,范围 (0, 1.0],与temperature二选一使用 |
| max_tokens | integer | 否 | - | 最大输出token数,控制响应长度 |
messages 数组中的每个对象包含以下字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| role | string | 是 | 消息角色,可选值:system(系统设定)、user(用户)、assistant(助手) |
| content | string | 是 | 消息内容 |
{
"code": 200,
"message": "success",
"data": {
"content": "你好!我是AI助手,很高兴为你服务。",
"finish_reason": "stop",
"usage": {
"input_tokens": 10,
"output_tokens": 15,
"total_tokens": 25
}
}
}
流式响应使用 Server-Sent Events (SSE) 格式:
data: {"content": "你好", "finish_reason": null}
data: {"content": "!", "finish_reason": null}
data: {"content": "我是AI助手", "finish_reason": null}
data: {"content": "。", "finish_reason": "stop", "usage": {"input_tokens": 10, "output_tokens": 15, "total_tokens": 25}}
data: [DONE]
无效模型:
{
"code": 400,
"message": "无效的模型名称或模型类型不匹配",
"data": null
}
消息列表为空:
{
"code": 400,
"message": "消息列表不能为空",
"data": null
}
API Key无效或缺失:
{
"code": 401,
"message": "未授权:API Key缺失或无效",
"data": null
}
百炼平台返回错误:
{
"code": 502,
"message": "百炼平台返回错误:[原始错误信息]",
"data": null
}
GET /api/llm/models
获取所有可用的语言模型列表,仅返回 type=0 的语言模型。
无参数
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"title": "qwen-turbo",
"img": "https://example.com/qwen-turbo.png",
"name": "通义千问-Turbo",
"description": "通义千问超大规模语言模型,加速响应版本",
"keyword": "文本生成",
"time": "2025-01-01",
"tag1": "高速",
"tag2": "Qwen",
"type": 0,
"is_featured": true,
"created_at": "2025-01-01T00:00:00",
"updated_at": "2025-01-01T00:00:00"
},
{
"id": 2,
"title": "qwen-plus",
"img": "https://example.com/qwen-plus.png",
"name": "通义千问-Plus",
"description": "通义千问超大规模语言模型,均衡性能版本",
"keyword": "文本生成",
"time": "2025-01-01",
"tag1": "均衡",
"tag2": "Qwen",
"type": 0,
"is_featured": false,
"created_at": "2025-01-01T00:00:00",
"updated_at": "2025-01-01T00:00:00"
}
]
}
| 字段 | 类型 | 说明 |
|---|---|---|
| content | string | 模型生成的响应内容 |
| finish_reason | string | 结束原因,可选值:stop(正常结束)、length(达到最大长度)、content_filter(内容过滤) |
| usage | object | Token使用统计 |
| 字段 | 类型 | 说明 |
|---|---|---|
| input_tokens | int | 输入token数 |
| output_tokens | int | 输出token数 |
| total_tokens | int | 总token数 |
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 模型ID |
| title | string | 模型标识(唯一),用于API调用 |
| img | string | 图标URL |
| name | string | 显示名称 |
| description | string | 模型描述 |
| keyword | string | 关键词 |
| time | string | 发布时间 |
| tag1 | string | 主标签 |
| tag2 | string | 次要标签 |
| type | int | 模型类型,0=语言模型 |
| is_featured | boolean | 是否为推荐模型 |
| created_at | datetime | 创建时间 |
| updated_at | datetime | 更新时间 |
| 错误码 | HTTP状态码 | 说明 |
|---|---|---|
| INVALID_MODEL | 400 | 无效的模型名称或模型类型不匹配(非type=0) |
| INVALID_MESSAGES | 400 | 消息格式错误或消息列表为空 |
| INVALID_PARAMS | 400 | 参数值超出有效范围 |
| UNAUTHORIZED | 401 | API Key缺失或无效 |
| RATE_LIMITED | 429 | 请求频率超限 |
| UPSTREAM_ERROR | 502 | 百炼平台返回错误 |
| TIMEOUT | 504 | 请求超时 |
启动服务后访问:
http://localhost:8000/docshttp://localhost:8000/redocconst response = await fetch('http://localhost:8000/api/llm/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'qwen-turbo',
messages: [
{ role: 'user', content: '你好' }
],
stream: false,
temperature: 0.7
})
});
const data = await response.json();
console.log(data.data.content); // 模型响应内容
const response = await fetch('http://localhost:8000/api/llm/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'qwen-turbo',
messages: [
{ role: 'user', content: '你好' }
],
stream: true
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') {
console.log('流式响应结束');
return;
}
const parsed = JSON.parse(data);
console.log(parsed.content); // 逐步输出内容
}
}
}