本文档描述了如何使用流式生成月度总结API调用AI生成会员的月度体适能评估总结,并以流式方式实时返回生成的内容。
流式生成月度总结API提供了调用AI生成会员月度体适能评估总结的功能,并以流式方式实时返回生成的内容,可以用于教练或会员在月度评估后自动生成训练效果的总结报告,并提供更好的用户体验。
调用AI生成指定体适能评估记录的月度总结内容,并以流式方式实时返回生成的内容。
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| assessment_id | Integer | 是 | 体适能评估ID |
API返回Server-Sent Events (SSE)格式的流式数据,每个事件包含以下JSON数据:
{
"text": "生成的文本块", // 生成的文本块,如果为空字符串且done为true,表示生成完成
"done": true/false // 可选,如果为true,表示生成完成
}
| 错误码 | 描述 |
|---|---|
| 400 | 请求参数错误,如缺少必要参数或没有上一次评估记录 |
| 404 | 未找到指定体适能评估记录 |
| 500 | 服务器内部错误 |
POST /gym/member/stream_monthly_summary
Content-Type: application/x-www-form-urlencoded
assessment_id=123
调用此API后,服务器会以流式方式实时返回AI生成的内容,客户端可以逐块显示这些内容,提供更好的用户体验。
注意:要使用此API,体适能评估记录必须有上一次评估记录,否则将返回错误。
生成完成后,客户端可以调用update_monthly_summary API将完整的总结内容保存到体适能评估记录中。
// 使用EventSource接收流式数据
function streamMonthlySummary(assessmentId, accessToken) {
// 创建结果容器
const resultContainer = document.getElementById('result-container');
resultContainer.innerHTML = '';
// 完整的总结内容
let fullSummary = '';
// 创建EventSource
const url = `/gym/member/stream_monthly_summary?assessment_id=${assessmentId}&access_token=${accessToken}`;
const eventSource = new EventSource(url);
// 处理消息
eventSource.onmessage = function(event) {
try {
const data = JSON.parse(event.data);
// 检查是否完成
if (data.done === true) {
console.log('生成完成');
eventSource.close();
// 可以在这里调用update_monthly_summary API保存总结
saveMonthlySummary(assessmentId, fullSummary);
return;
}
// 检查是否有错误
if (data.error) {
console.error('生成错误:', data.error);
resultContainer.innerHTML += `${data.error}
`;
eventSource.close();
return;
}
// 显示文本块
if (data.text) {
fullSummary += data.text;
resultContainer.innerHTML = fullSummary;
// 滚动到底部
resultContainer.scrollTop = resultContainer.scrollHeight;
}
} catch (e) {
console.error('解析事件数据出错:', e);
}
};
// 处理错误
eventSource.onerror = function(error) {
console.error('EventSource错误:', error);
resultContainer.innerHTML += '连接错误,请重试
';
eventSource.close();
};
}
// 保存总结内容
async function saveMonthlySummary(assessmentId, summary) {
try {
const response = await fetch('/gym/member/update_monthly_summary', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + accessToken
},
body: JSON.stringify({
assessment_id: assessmentId,
summary: summary
})
});
const data = await response.json();
if (data.error === 0) {
console.log('月度总结保存成功:', data.message);
} else {
console.error('保存失败:', data.message);
}
} catch (error) {
console.error('保存请求出错:', error);
}
}
// 使用fetch API接收流式数据
async function streamMonthlySummaryWithFetch(assessmentId, accessToken) {
// 创建结果容器
const resultContainer = document.getElementById('result-container');
resultContainer.innerHTML = '';
// 完整的总结内容
let fullSummary = '';
try {
// 发送请求
const response = await fetch(`/gym/member/stream_monthly_summary?assessment_id=${assessmentId}&access_token=${accessToken}`, {
method: 'POST'
});
// 获取reader
const reader = response.body.getReader();
const decoder = new TextDecoder();
// 读取数据
while (true) {
const { value, done } = await reader.read();
if (done) {
console.log('流读取完成');
break;
}
// 解码数据
const chunk = decoder.decode(value, { stream: true });
// 处理SSE格式的数据
const lines = chunk.split('\n\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.substring(6));
// 检查是否有错误
if (data.error) {
console.error('生成错误:', data.error);
resultContainer.innerHTML += `${data.error}
`;
return;
}
// 检查是否完成
if (data.done === true) {
console.log('生成完成');
// 可以在这里调用update_monthly_summary API保存总结
saveMonthlySummary(assessmentId, fullSummary);
return;
}
// 显示文本块
if (data.text) {
fullSummary += data.text;
resultContainer.innerHTML = fullSummary;
// 滚动到底部
resultContainer.scrollTop = resultContainer.scrollHeight;
}
} catch (e) {
console.error('解析事件数据出错:', e);
}
}
}
}
} catch (error) {
console.error('请求出错:', error);
resultContainer.innerHTML += '连接错误,请重试
';
}
}
import requests
import json
import sseclient # 需要安装 sseclient-py 包
def stream_monthly_summary(assessment_id, access_token):
"""
流式生成月度总结
Args:
assessment_id: 体适能评估ID
access_token: 访问令牌
"""
url = f'http://your-domain.com/gym/member/stream_monthly_summary?assessment_id={assessment_id}'
headers = {
'Accept': 'text/event-stream',
'Authorization': f'Bearer {access_token}'
}
# 发送请求
response = requests.post(url, headers=headers, stream=True)
# 创建SSE客户端
client = sseclient.SSEClient(response)
# 完整的总结内容
full_summary = ''
# 处理事件
try:
for event in client.events():
try:
data = json.loads(event.data)
# 检查是否有错误
if 'error' in data:
print(f"生成错误: {data['error']}")
break
# 检查是否完成
if data.get('done', False):
print("生成完成")
# 可以在这里调用update_monthly_summary API保存总结
save_monthly_summary(assessment_id, full_summary, access_token)
break
# 显示文本块
if 'text' in data and data['text']:
full_summary += data['text']
print(data['text'], end='', flush=True)
except json.JSONDecodeError:
print(f"解析事件数据出错: {event.data}")
except Exception as e:
print(f"流处理错误: {str(e)}")
return full_summary
def save_monthly_summary(assessment_id, summary, access_token):
"""
保存月度总结
Args:
assessment_id: 体适能评估ID
summary: 总结内容
access_token: 访问令牌
"""
url = 'http://your-domain.com/gym/member/update_monthly_summary'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {access_token}'
}
data = {
'assessment_id': assessment_id,
'summary': summary
}
response = requests.post(url, json=data, headers=headers)
if response.status_code == 200:
result = response.json()
if result['error'] == 0:
print(f"月度总结保存成功: {result['message']}")
return result
else:
print(f"保存失败: {result['message']}")
raise Exception(result['message'])
else:
print(f"请求失败,状态码: {response.status_code}")
raise Exception(f"请求失败,状态码: {response.status_code}")
# 调用示例
try:
summary = stream_monthly_summary(
assessment_id=123,
access_token='your-access-token'
)
print(f"\n完整总结:\n{summary}")
except Exception as e:
print(f"流式生成月度总结失败: {str(e)}")