SpringCloud+原生LangChain双栈改造Vol.4 AI评价总结
前言
上篇文章已经在Python端搭建好了Langchain+Langgraph,以及完善了tools、websocket等基础设施。这篇文章将新增:评价总结功能。
新增的小功能
在新增评价总结前先开发了一些小功能:这些是基于上篇文章的基础开发的,属于小增量更新,就不单独开文章说明。当然这些功能中有些只是开发过程中搞的小玩具,若要正式部署到生产环境只会保留必要tools
查你自己的最近订单(我的订单)
查指定订单的详细信息(订单状态、金额、服务人员等)
企业/服务人员可查自己负责的服务单
联网搜索:帮你查找最新的新闻、资讯、实时信息
数学计算:加减乘除、幂运算等都能算
获取当前时间:问我现在几点,马上告诉你
服务人员查自己负责的订单:


联网搜索:


数学运算和获取当前时间:


评级总结
设计产品需求文档
1.背景与目标
- 背景
当前对服务人员的评价多且杂,用户想查看不同服务人员的服务质量时,需要手动翻看大量评论并自行总结,无法快速横向对比不同的服务人员;运营端也需要人工阅读评价来评估服务人员的服务质量,耗时费力。因此需要引入AI自动总结评论的功能,提高决策效率 - 目标
支持用户、运营端查看对不同服务人员的评论总结,运营端可一键生成评价或者定时生成评价。在服务人员平均评价50条的情况下,不同端获取核心结论的时间从平均2分钟缩短至10秒内,节省90%以上的阅读时间
2.需求范围
-
范围内
- 生成总结时,采用首次全量 + 后续增量策略:
- 若该服务人员从未生成过总结 → 读取其所有评价,生成全量总结。
- 若已有总结记录 → 只读取上次总结之后的新增评价,结合旧摘要生成增量总结。
- 总结表中必须记录
last_evaluation_id(最后一次处理的评论ID),用于增量判断。
- 生成总结时,采用首次全量 + 后续增量策略:
-
范围外
不修改评论表、不对用户端提供主动总结入口(防止恶意刷token)、不对总结结果做个性化定制
3.流程
- 生成总结
- 运营端:点击总结按钮→查询是否有总结记录→有→增量生成总结→存入数据库;没有→全量生成总结→更新数据库
- 自动触发:定时任务触发总结→后端生成总结(同样判断是否增量)→存入数据库
- 查询总结
- 直接查询:前端进入评价界面→后端读取数据库→返回评价总结
- AI对话查询:前端询问AI→AI调用工具查询数据库→返回评价总结
- 异常流程
- 生成失败:触发总结→模型超时、评论为空、Token限额等→前端返回友好提示,记录错误日志
- 查询失败:查询→无记录、模型超时等→前端返回友好提示,记录错误日志
4.功能性需求
- FR-1:运营在评价总结页面点击“生成总结”按钮,系统应触发总结生成(全量或增量),并将结果存入数据库
- FR-2:系统每周凌晨 1:00 触发定时任务,扫描所有有新增评价的服务人员,自动生成或更新总结
- FR-3:用户查询评价总结时,系统应从数据库返回已有的总结内容
- FR-4:用户在聊天界面询问 AI 评价总结时,AI 应通过工具查询数据库并返回已有总结
- FR-5:系统必须支持“首次全量 + 后续增量”的生成策略。
- FR-6:增量生成时,不得重新分析历史评论,只能基于旧摘要和新增评价生成新摘要。
- FR-7:运营端可强制触发全量重新生成(忽略已有总结和增量逻辑)
5.非功能需求
- NFR-1:
- 查询总结接口:P99 ≤ 1s,支持 500 QPS
- 聊天界面查询总结:P99 < 10s
- 首次全量生成:P95 ≤ 60s(取决于历史评价数量)。
- 增量生成:P95 ≤ 10s(因为只处理少量新评价)。
- NFR-2:可靠性:当总结功能、读取总结功能不可用时返回友好提示
- NFR-3:安全性:网关不暴露inner路由
- NFR-4:可观测性:日志需包括调用的详情,包括:调用的工具、接口、返回的值等
- NFR-5:兼容性:API变更是否向后兼容,不得删除或修改已有字段的类型/含义
- NFR-6: 成本控制:采用增量策略后,每次生成(除首次和强制全量外)的 token 消耗应比全量减少 75% 以上。
6.影响面分析
后端项目
| 服务 | 影响 |
|---|---|
| AI engine(Python) | 新增远程工具 |
| api(Java) | 新增Feign客户端接口 |
| customer(Java) | 新增总结表CRUD接口 |
| customer(Java) | 新增定时任务 |
| ai(Java) | 新增总结表查询接口 |
| ai(Java) | 新增查询工具 |
决策:评价总结的对外接口放在 customer 服务,而非 ai 服务。
理由:评价总结属于评价领域功能,由 customer 作为门面(Facade)统一对外提供,内部调用 ai 服务的能力接口。这样保持前端调用语义清晰、鉴权统一,并便于未来扩展业务编排。
前端项目
| 项目 | 影响 |
|---|---|
| PC端运营端 | 新增总结页面 |
为了方便开发,这里暂时只开发运营端功能
数据库
| 库 | 影响 |
|---|---|
| ai | 新增evaluation_summary表 |
8. 数据模型定义
8.1.业务实体与关键属性
- 服务人员ID:关联到对应服务人员
- 摘要:对应服务人员的摘要,200字以内
- 总结时间
- 最后评价ID:本次总结覆盖的最后一条评价 ID
9.接口定义
接口 1:查询已有 AI 评价总结(前端直接调用)
| 项 | 值 |
|---|---|
| URL | /customer/agency/evaluation/summarize |
| 方法 | GET |
| 鉴权 | 需登录(机构端 token) |
| 说明 | 纯查库,不触发 AI 生成。无记录时返回 { "summary": "" } |
请求字段(Query String)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
targetTypeId |
Integer | ✅ | 评价目标类型:6=服务项,7=服务人员 |
targetId |
Long | ✅ | 目标 ID(服务人员 ID 或服务项 ID) |
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
summary |
String | AI 总结文本,无记录时为空字符串 "" |
成功示例
{
"summary": "该服务人员在过去30天内共收到25条评价,整体满意度为96%。用户普遍反映其服务态度热情、专业技能扎实,尤其在家电维修方面表现突出。待改进点:部分用户反馈预约时间不够灵活。"
}
无记录时
{
"summary": ""
}
接口 2:触发 AI 评价总结生成(前端直接调用)
| 项 | 值 |
|---|---|
| URL | /customer/agency/evaluation/summarize |
| 方法 | POST |
| 鉴权 | 需登录(机构端 token) |
| 说明 | 增量模式:只处理上次总结之后的新评价。 |
请求字段(Query String)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
targetTypeId |
Integer | ✅ | 6=服务项,7=服务人员 |
targetId |
Long | ✅ | 目标 ID |
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
summary |
String | 最新 AI 总结文本 |
status |
String | SUCCESS = 成功 |
msg |
String | 当 status=PROCESSING 时,返回提示信息 |
成功示例
{
"summary": "该服务人员在过去30天内共收到28条评价,整体满意度为97%。新增3条评价均给予5星好评...",
"status": "SUCCESS"
}
接口 3:内部 Feign — 触发 AI 总结(AiApi.summarizeEvaluation)
| 项 | 值 |
|---|---|
| 调用方 | jzo2o-customer-dev_01 → jzo2o-ai |
| URL | /ai/inner/ai/evaluation/summarize |
| 方法 | POST |
| 注解 | @FeignClient(contextId = "jzo2o-ai", value = "jzo2o-ai", path = "/ai/inner/ai") |
请求/响应字段同接口 2。
接口 4:内部 Feign — 查询总结(AiApi.getEvaluationSummary)
| 项 | 值 |
|---|---|
| 调用方 | jzo2o-customer-dev_01 → jzo2o-ai |
| URL | /ai/inner/ai/evaluation/summarize |
| 方法 | GET |
请求/响应字段同接口 1。
接口 5:内部 Feign — 查询新增评价(EvaluationApi.queryByTargetIdAndTime)
| 项 | 值 |
|---|---|
| 调用方 | jzo2o-ai → jzo2o-customer |
| URL | /customer/inner/evaluation/queryByTargetIdAndTime |
| 方法 | GET |
| 说明 | 供 AI 模块查询指定时间之后的新增评价,用于增量总结 |
请求字段(Query String)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
targetTypeId |
Integer | ✅ | 6=服务项,7=服务人员 |
targetId |
Long | ❌ | 目标 ID;为 null 时查该类型下所有目标 |
afterTime |
String | ❌ | 时间游标(ISO 格式),只查此时间之后的评价 |
响应
直接返回 JSON 字符串(List<Evaluation> 的 JSON 序列化结果)。
接口 6:前端 — 分页查询评价列表
| 项 | 值 |
|---|---|
| URL | /customer/agency/evaluation/pageByTarget |
| 方法 | GET |
| 前端函数 | getEvaluationList(params) |
接口 7:前端 — 查询评价详情
| 项 | 值 |
|---|---|
| URL | /customer/agency/evaluation/{id} |
| 方法 | GET |
| 前端函数 | getEvaluationDetail(id) |
接口 8:前端 — 删除评价
| 项 | 值 |
|---|---|
| URL | /customer/agency/evaluation/{id} |
| 方法 | DELETE |
| 前端函数 | deleteEvaluation(id) |
关键错误码
| HTTP 状态码 | 说明 | 触发场景 |
|---|---|---|
| 400 Bad Request | 请求参数缺失或格式错误 | targetTypeId 或 targetId 未传;前端 params 被误转为 body 导致后端 @RequestParam 收不到 |
| 503 Service Unavailable | AI 引擎不可用 | AiEngineWebSocketClient 连接失败或 AI 引擎服务宕机 |
| 504 Gateway Timeout | AI 生成超时 | AI 总结超过 180s 未返回(前端 timeout 和后端 future.get(180, ...) 双重保护) |
数据库表 evaluation_summary
| 字段 | 类型 | 说明 |
|---|---|---|
id |
BIGINT AUTO_INCREMENT | 主键 |
target_type_id |
INT | 目标类型:6=服务项,7=服务人员 |
target_id |
BIGINT | 目标 ID |
summary_content |
TEXT | AI 生成的总结文本 |
last_evaluation_id |
BIGINT | 增量游标:本次总结覆盖的最后一条评价 ID |
last_evaluation_time |
DATETIME | 增量游标:本次总结覆盖的最后一条评价时间 |
create_time |
DATETIME | 创建时间 |
update_time |
DATETIME | 更新时间 |
开发
由CC完成
验收
FR-1
运营在评价总结页面点击“生成总结”按钮,系统应触发总结生成(全量或增量),并将结果存入数据库
点击总结


落库成功
FR-1验收通过
FR-2
系统每周凌晨 1:00 触发定时任务,扫描所有有新增评价的服务人员,自动生成或更新总结
这里直接触发一次xxl-job来模拟
2026-06-02 11:11:46.544 DEBUG 28452 --- [io-11511-exec-6] c.j.a.m.E.selectList : ==> Preparing: SELECT id,target_type_id,target_id,summary_content,last_evaluation_id,last_evaluation_time,create_time,update_time FROM evaluation_summary WHERE (target_type_id = ? AND target_id = ?)
2026-06-02 11:11:46.544 DEBUG 28452 --- [io-11511-exec-6] c.j.a.m.E.selectList : ==> Parameters: 7(Integer), 1695007144950132737(Long)
2026-06-02 11:11:46.554 DEBUG 28452 --- [io-11511-exec-6] c.j.a.m.E.selectList : <== Total: 1
2026-06-02 11:11:46.554 INFO 28452 --- [io-11511-exec-6] c.j.a.s.i.EvaluationSummaryServiceImpl : 增量总结: targetTypeId=7, targetId=1695007144950132737, 上次总结时间=2026-05-16T13:44:08
2026-06-02 11:11:46.554 INFO 28452 --- [io-11511-exec-6] c.j.a.s.i.EvaluationSummaryServiceImpl : 查询新评价: targetTypeId=7, targetId=1695007144950132737, afterTime=2026-05-16T13:44:08
2026-06-02 11:11:46.631 INFO 28452 --- [oundedElastic-1] com.alibaba.nacos.client.naming : [SUBSCRIBE-SERVICE] service:jzo2o-customer, group:DEFAULT_GROUP, clusters:
2026-06-02 11:11:46.631 INFO 28452 --- [oundedElastic-1] com.alibaba.nacos.client.naming : [GRPC-SUBSCRIBE] service:jzo2o-customer, group:DEFAULT_GROUP, cluster:
2026-06-02 11:11:46.636 INFO 28452 --- [oundedElastic-1] com.alibaba.nacos.client.naming : init new ips(1) service: DEFAULT_GROUP@@jzo2o-customer -> [{"instanceId":"192.168.101.1#11502#DEFAULT#DEFAULT_GROUP@@jzo2o-customer","ip":"192.168.101.1","port":11502,"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"DEFAULT","serviceName":"DEFAULT_GROUP@@jzo2o-customer","metadata":{"preserved.register.source":"SPRING_CLOUD"},"ipDeleteTimeout":30000,"instanceHeartBeatTimeOut":15000,"instanceHeartBeatInterval":5000}]
2026-06-02 11:11:46.637 INFO 28452 --- [oundedElastic-1] com.alibaba.nacos.client.naming : current ips:(1) service: DEFAULT_GROUP@@jzo2o-customer -> [{"instanceId":"192.168.101.1#11502#DEFAULT#DEFAULT_GROUP@@jzo2o-customer","ip":"192.168.101.1","port":11502,"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"DEFAULT","serviceName":"DEFAULT_GROUP@@jzo2o-customer","metadata":{"preserved.register.source":"SPRING_CLOUD"},"ipDeleteTimeout":30000,"instanceHeartBeatTimeOut":15000,"instanceHeartBeatInterval":5000}]
2026-06-02 11:11:46.692 INFO 28452 --- [io-11511-exec-6] c.j.a.s.i.EvaluationSummaryServiceImpl : 评价查询返回: length=8044, preview=[{"id":42,"targetTypeId":7,"targetId":1695007144950132737,"targetName":"服务人员01","relationId":2026051516579888,"evaluatorId":1695071373085589504,"evaluatorNickname":"信11","evaluatorAvatar":"11","isAnonymous":0,"content":"墙面置物架松动下坠,更换加固膨胀螺丝,承重稳固不用担心掉落。","totalScore":3.8,"scoreLevel":3,"scoreItems":"[{\"score\": 4.8, \"itemId\": \"1\", \"itemName\": \"专业能力\"}, {\"score\": 3.2, \"itemId\": \"2\", \"itemName\": \"服务态度\"}, {\"score\": 3.5, \"itemId\": \"3\", \"itemName\": \"准时到达\"}]","pictureArray":"[
2026-06-02 11:11:46.696 INFO 28452 --- [io-11511-exec-6] c.j.a.s.i.EvaluationSummaryServiceImpl : 发现 14 条新评价: targetTypeId=7, targetId=1695007144950132737
2026-06-02 11:11:46.697 INFO 28452 --- [io-11511-exec-6] c.j.a.s.i.EvaluationSummaryServiceImpl : 发送 AI 请求: sessionId=eval-summary-64c79d89, prompt 长度=10450, prompt 末尾(300字符)=mName\": \"专业能力\"}, {\"score\": 3.7, \"itemId\": \"2\", \"itemName\": \"服务态度\"}, {\"score\": 4.0, \"itemId\": \"3\", \"itemName\": \"准时到达\"}]","pictureArray":"[]","status":0,"createTime":1780331438000,"updateTime":1780331438000}]
......
2026-06-02 11:14:47.236 INFO 28452 --- [io-11511-exec-6] c.j.a.s.i.EvaluationSummaryServiceImpl : 增量总结: targetTypeId=7, targetId=1695628302246506498, 上次总结时间=2026-06-02T00:27:58
2026-06-02 11:14:47.236 INFO 28452 --- [io-11511-exec-6] c.j.a.s.i.EvaluationSummaryServiceImpl : 查询新评价: targetTypeId=7, targetId=1695628302246506498, afterTime=2026-06-02T00:27:58
2026-06-02 11:14:47.256 INFO 28452 --- [io-11511-exec-6] c.j.a.s.i.EvaluationSummaryServiceImpl : 评价查询返回: length=2, preview=[]
2026-06-02 11:14:47.256 INFO 28452 --- [io-11511-exec-6] c.j.a.s.i.EvaluationSummaryServiceImpl : 无新评价, 返回旧总结: targetTypeId=7, targetId=1695628302246506498
从第一条日志到最后一条耗时3分钟
FR-2验收通过
FR-3
用户查询评价总结时,系统应从数据库返回已有的总结内容
FR-3验收通过
FR-4
用户在聊天界面询问 AI 评价总结时,AI 应通过工具查询数据库并返回已有总结
Python服务日志:
Java服务日志(UPDATE ai_chat_record SET content=? WHERE id=?是将AI回复的信息定时落库的日志):
2026-05-30 23:28:04.057 INFO 14304 --- [io-11511-exec-1] c.j.a.c.consumer.ChatController : 收到聊天请求, sessionId: 1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:28:04.059 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Preparing: INSERT INTO ai_chat_record ( user_id, user_type, session_id, role, content, status, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
2026-05-30 23:28:04.059 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Parameters: 1696706462195150849(Long), 3(Integer), 1a038089-035c-4256-ba0b-e88b419c5743(String), user(String), 查看mm的评价总结(String), 1(Integer), 2026-05-30T23:28:04.057678600(LocalDateTime)
2026-05-30 23:28:04.062 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : <== Updates: 1
2026-05-30 23:28:04.063 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Preparing: INSERT INTO ai_chat_record ( user_id, user_type, session_id, role, content, status, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
2026-05-30 23:28:04.063 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Parameters: 1696706462195150849(Long), 3(Integer), 1a038089-035c-4256-ba0b-e88b419c5743(String), assistant(String), (String), 0(Integer), 2026-05-30T23:28:04.062410400(LocalDateTime)
2026-05-30 23:28:04.066 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : <== Updates: 1
2026-05-30 23:28:04.066 DEBUG 14304 --- [io-11511-exec-1] com.jzo2o.ai.service.impl.AsyncFlusher : AsyncFlusher 创建, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, recordId=484
2026-05-30 23:28:04.066 INFO 14304 --- [io-11511-exec-1] c.j.ai.client.AiEngineWebSocketClient : 建立 WebSocket, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, reconnectable=false, attempt=0
2026-05-30 23:28:06.093 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : ==> Preparing: UPDATE ai_chat_record SET content=? WHERE id=?
2026-05-30 23:28:06.094 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : ==> Parameters: 以下是 **mm** 的服务评价总结 📋---**📝 当前总结内容:**> 服务细致到位,维修保洁都做得好,主动验收有礼貌,客户强烈推荐。(String), 484(Long)
2026-05-30 23:28:06.097 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : <== Updates: 1
2026-05-30 23:28:07.111 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : ==> Preparing: UPDATE ai_chat_record SET content=? WHERE id=?
2026-05-30 23:28:07.111 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : ==> Parameters: 以下是 **mm** 的服务评价总结 📋---**📝 当前总结内容:**> 服务细致到位,维修保洁都做得好,主动验收有礼貌,客户强烈推荐。**⏰ 上次总结时间:** 2026年5月30日 19:37---**mm 的服务评价概览:**- 共收到 **5条** 客户评价- 涉及 **日常保洁、家电维修、燃气安检** 等服务- 客户普遍反馈:**服务认真细致、沟通温和有礼貌、主动邀请验收**- 评分在 **3.7 ~ 4.7分** 之间,整体表现不错(String), 484(Long)
2026-05-30 23:28:07.114 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : <== Updates: 1
2026-05-30 23:28:07.121 DEBUG 14304 --- [ctor-http-nio-8] c.j.a.m.AiChatRecordMapper.updateById : ==> Preparing: UPDATE ai_chat_record SET content=?, status=? WHERE id=?
2026-05-30 23:28:07.122 DEBUG 14304 --- [ctor-http-nio-8] c.j.a.m.AiChatRecordMapper.updateById : ==> Parameters: 以下是 **mm** 的服务评价总结 📋---**📝 当前总结内容:**> 服务细致到位,维修保洁都做得好,主动验收有礼貌,客户强烈推荐。**⏰ 上次总结时间:** 2026年5月30日 19:37---**mm 的服务评价概览:**- 共收到 **5条** 客户评价- 涉及 **日常保洁、家电维修、燃气安检** 等服务- 客户普遍反馈:**服务认真细致、沟通温和有礼貌、主动邀请验收**- 评分在 **3.7 ~ 4.7分** 之间,整体表现不错如需更新/合并最新评价生成新的总结,也可以随时告诉我!😊(String), 1(Integer), 484(Long)
2026-05-30 23:28:07.126 DEBUG 14304 --- [ctor-http-nio-8] c.j.a.m.AiChatRecordMapper.updateById : <== Updates: 1
2026-05-30 23:28:07.126 INFO 14304 --- [ctor-http-nio-8] com.jzo2o.ai.service.impl.AsyncFlusher : AsyncFlusher 最终落盘, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, recordId=484, status=1, contentLen=256
2026-05-30 23:28:07.126 INFO 14304 --- [ctor-http-nio-8] c.jzo2o.ai.service.impl.ChatServiceImpl : 聊天会话完成(WS), sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:28:07.128 INFO 14304 --- [io-11511-exec-2] c.j.ai.client.AiEngineWebSocketClient : SSE 完成, 取消 WebSocket, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:28:07.128 INFO 14304 --- [io-11511-exec-2] c.j.ai.client.AiEngineWebSocketClient : 取消会话: 找到上下文, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, state=ACTIVE, cancelReason=user_cancel, wsOpen=true
2026-05-30 23:28:07.128 INFO 14304 --- [ctor-http-nio-8] c.j.ai.client.AiEngineWebSocketClient : cancel 帧已发送, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:28:07.128 INFO 14304 --- [ctor-http-nio-8] c.j.ai.client.AiEngineWebSocketClient : cancel 帧发送完成, 清理会话, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:28:07.128 INFO 14304 --- [ctor-http-nio-8] c.jzo2o.ai.service.impl.ChatServiceImpl : 用户取消会话(WS), sessionId=1a038089-035c-4256-ba0b-e88b419c5743, reason=user_cancel
FR-4验收通过
FR-5 + FR-6
系统必须支持“首次全量 + 后续增量”的生成策略。
增量生成时,不得重新分析历史评论,只能基于旧摘要和新增评价生成新摘要。
首先是无增量时触发增量:
2026-05-30 23:39:32.224 INFO 14304 --- [io-11511-exec-9] c.j.a.s.i.EvaluationSummaryServiceImpl : 增量总结: targetTypeId=7, targetId=1696706462195150849, 上次总结时间=2026-05-30T22:15:10
2026-05-30 23:39:32.224 INFO 14304 --- [io-11511-exec-9] c.j.a.s.i.EvaluationSummaryServiceImpl : 查询新评价: targetTypeId=7, targetId=1696706462195150849, afterTime=2026-05-30T22:15:10
2026-05-30 23:39:32.244 INFO 14304 --- [io-11511-exec-9] c.j.a.s.i.EvaluationSummaryServiceImpl : 评价查询返回: length=2, preview=[]
2026-05-30 23:39:32.244 INFO 14304 --- [io-11511-exec-9] c.j.a.s.i.EvaluationSummaryServiceImpl : 无新评价, 返回旧总结: targetTypeId=7, targetId=1696706462195150849
通过游标查询发现无新记录,返回旧数据
增量总结:
2026-05-30 23:42:20.538 DEBUG 14304 --- [o-11511-exec-10] c.j.a.m.E.selectList : ==> Preparing: SELECT id,target_type_id,target_id,summary_content,last_evaluation_id,last_evaluation_time,create_time,update_time FROM evaluation_summary WHERE (target_type_id = ? AND target_id = ?)
2026-05-30 23:42:20.540 DEBUG 14304 --- [o-11511-exec-10] c.j.a.m.E.selectList : ==> Parameters: 7(Integer), 1696706462195150849(Long)
2026-05-30 23:42:20.541 DEBUG 14304 --- [o-11511-exec-10] c.j.a.m.E.selectList : <== Total: 1
2026-05-30 23:42:20.541 INFO 14304 --- [o-11511-exec-10] c.j.a.s.i.EvaluationSummaryServiceImpl : 增量总结: targetTypeId=7, targetId=1696706462195150849, 上次总结时间=2026-05-30T22:15:10
2026-05-30 23:42:20.541 INFO 14304 --- [o-11511-exec-10] c.j.a.s.i.EvaluationSummaryServiceImpl : 查询新评价: targetTypeId=7, targetId=1696706462195150849, afterTime=2026-05-30T22:15:10
2026-05-30 23:42:20.571 INFO 14304 --- [o-11511-exec-10] c.j.a.s.i.EvaluationSummaryServiceImpl : 评价查询返回: length=705, preview=[{"id":120,"targetTypeId":7,"targetId":1696706462195150849,"targetName":"机构03","relationId":2026051516579879,"evaluatorId":1695339358949949440,"evaluatorNickname":"微信用户","evaluatorAvatar":"https://thi
2026-05-30 23:42:20.572 INFO 14304 --- [o-11511-exec-10] c.j.a.s.i.EvaluationSummaryServiceImpl : 发现 1 条新评价: targetTypeId=7, targetId=1696706462195150849
2026-05-30 23:42:20.573 INFO 14304 --- [o-11511-exec-10] c.j.a.s.i.EvaluationSummaryServiceImpl : 发送 AI 请求: sessionId=eval-summary-637e443c, prompt 长度=855, prompt 末尾(300字符)=": 3.7, \"itemId\": \"1\", \"itemName\": \"专业能力\"}, {\"score\": 4.1, \"itemId\": \"2\", \"itemName\": \"服务态度\"}, {\"score\": 3.2, \"itemId\": \"3\", \"itemName\": \"准时到达\"}]","pictureArray":"[]","status":0,"createTime":1780155707000,"updateTime":1780155707000}]
请用一句话概括新增评价的核心观点(50字以内,口语化,不要任何格式标记)。
2026-05-30 23:42:20.573 INFO 14304 --- [o-11511-exec-10] c.j.ai.client.AiEngineWebSocketClient : 建立 WebSocket, sessionId=eval-summary-637e443c, reconnectable=true, attempt=0
2026-05-30 23:42:25.224 INFO 14304 --- [o-11511-exec-10] c.j.a.s.i.EvaluationSummaryServiceImpl : AI 总结完成: targetTypeId=7, targetId=1696706462195150849, 长度=37
2026-05-30 23:42:25.226 DEBUG 14304 --- [o-11511-exec-10] c.j.a.m.E.updateById : ==> Preparing: UPDATE evaluation_summary SET target_type_id=?, target_id=?, summary_content=?, last_evaluation_id=?, last_evaluation_time=?, create_time=?, update_time=? WHERE id=?
2026-05-30 23:42:25.227 DEBUG 14304 --- [o-11511-exec-10] c.j.a.m.E.updateById : ==> Parameters: 7(Integer), 1696706462195150849(Long), 维修水龙头清理起泡器解决了问题,服务态度不错但准时一般,整体评分中规中矩。(String), 120(Long), 2026-05-30T23:41:47(LocalDateTime), 2026-05-15T20:19:09(LocalDateTime), 2026-05-15T20:19:09(LocalDateTime), 1(Long)
2026-05-30 23:42:25.231 DEBUG 14304 --- [o-11511-exec-10] c.j.a.m.E.updateById : <== Updates: 1

未通过,理由:只总结了新增的评论: 维修水龙头清理起泡器解决了问题,服务态度不错但准时一般,整体评分中规中矩。
定位问题: prompt:“请用一句话概括新增评价的核心观点(50字以内,口语化,不要任何格式标记)。”明确指出只需参照新增评价
解决措施: 修改prompt:“请将历史总结与新增评价融合,用一句话概括该服务人员/服务项的整体评价(80字以内,口语化,不要任何格式标记)。如果新旧评价有矛盾,应体现变化趋势。”
再次验证

增量总结结果符合预期,验收通过
FR-7
运营端可强制触发全量重新生成(忽略已有总结和增量逻辑)
可以和上一张图片做对比,由于提示词不同,所以全量和增量最终效果也不同
日志:
2026-05-31 00:10:36.003 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.selectList : ==> Preparing: SELECT id,target_type_id,target_id,summary_content,last_evaluation_id,last_evaluation_time,create_time,update_time FROM evaluation_summary WHERE (target_type_id = ? AND target_id = ?)
2026-05-31 00:10:36.003 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.selectList : ==> Parameters: 7(Integer), 1738873712110256130(Long)
2026-05-31 00:10:36.004 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.selectList : <== Total: 1
2026-05-31 00:10:36.005 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : 全量总结: targetTypeId=7, targetId=1738873712110256130
2026-05-31 00:10:36.005 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : 查询新评价: targetTypeId=7, targetId=1738873712110256130, afterTime=null
2026-05-31 00:10:36.022 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : 评价查询返回: length=3440, preview=[{"id":18,"targetTypeId":7,"targetId":1738873712110256130,"targetName":"mm","relationId":2026051516579880,"evaluatorId":1695064056785940480,"evaluatorNickname":"abc","evaluatorAvatar":"abc","isAnonymous":0,"content":"卫生间排气扇不运转,更换电机配件,清理扇叶积灰,排风效果恢复如初。","totalScore":4.3,"scoreLevel":3,"scoreItems":"[{\"score\": 4.3, \"itemId\": \"1\", \"itemName\": \"专业能力\"}, {\"score\": 4.5, \"itemId\": \"2\", \"itemName\": \"服务态度\"}, {\"score\": 4.0, \"itemId\": \"3\", \"itemName\": \"准时到达\"}]","pictureArray":"[
2026-05-31 00:10:36.023 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : 发现 6 条新评价: targetTypeId=7, targetId=1738873712110256130
2026-05-31 00:10:36.023 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : 发送 AI 请求: sessionId=eval-summary-1a87c8d6, prompt 长度=3553, prompt 末尾(300字符)=": 0.3, \"itemId\": \"1\", \"itemName\": \"专业能力\"}, {\"score\": 1.1, \"itemId\": \"2\", \"itemName\": \"服务态度\"}, {\"score\": 1.3, \"itemId\": \"3\", \"itemName\": \"准时到达\"}]","pictureArray":"[]","status":0,"createTime":1780155707000,"updateTime":1780155707000}]
请用一句话概括这些评价的核心观点(50字以内,口语化,不要任何格式标记)。
2026-05-31 00:10:36.023 INFO 44128 --- [io-11511-exec-5] c.j.ai.client.AiEngineWebSocketClient : 建立 WebSocket, sessionId=eval-summary-1a87c8d6, reconnectable=true, attempt=0
2026-05-31 00:10:41.497 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : AI 总结完成: targetTypeId=7, targetId=1738873712110256130, 长度=34
2026-05-31 00:10:41.500 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.updateById : ==> Preparing: UPDATE evaluation_summary SET target_type_id=?, target_id=?, summary_content=?, last_evaluation_id=?, last_evaluation_time=?, create_time=?, update_time=? WHERE id=?
2026-05-31 00:10:41.500 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.updateById : ==> Parameters: 7(Integer), 1738873712110256130(Long), 保洁维修都干得很细致,但窗帘安装出了大问题还态度恶劣,水平不太稳定。(String), 118(Long), 2026-05-30T23:41:47(LocalDateTime), 2026-05-15T20:30:06(LocalDateTime), 2026-05-15T20:30:06(LocalDateTime), 2(Long)
2026-05-31 00:10:41.504 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.updateById : <== Updates: 1
FR-7验收通过
非功能需求
NFR-1
-
查询总结接口:P99 ≤ 1s,支持 500 QPS
进行JMeter压测
JMeter关键参数如下:

进行5分钟压测:
QPS 500, P99 50ms -
聊天界面查询总结:P99 < 10s
2026-05-30 23:28:04.057 INFO 14304 --- [io-11511-exec-1] c.j.a.c.consumer.ChatController : 收到聊天请求, sessionId: 1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:28:04.059 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Preparing: INSERT INTO ai_chat_record ( user_id, user_type, session_id, role, content, status, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
2026-05-30 23:28:04.059 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Parameters: 1696706462195150849(Long), 3(Integer), 1a038089-035c-4256-ba0b-e88b419c5743(String), user(String), 查看mm的评价总结(String), 1(Integer), 2026-05-30T23:28:04.057678600(LocalDateTime)
2026-05-30 23:28:04.062 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : <== Updates: 1
2026-05-30 23:28:04.063 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Preparing: INSERT INTO ai_chat_record ( user_id, user_type, session_id, role, content, status, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
2026-05-30 23:28:04.063 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Parameters: 1696706462195150849(Long), 3(Integer), 1a038089-035c-4256-ba0b-e88b419c5743(String), assistant(String), (String), 0(Integer), 2026-05-30T23:28:04.062410400(LocalDateTime)
2026-05-30 23:28:04.066 DEBUG 14304 --- [io-11511-exec-1] c.j.ai.mapper.AiChatRecordMapper.insert : <== Updates: 1
2026-05-30 23:28:04.066 DEBUG 14304 --- [io-11511-exec-1] com.jzo2o.ai.service.impl.AsyncFlusher : AsyncFlusher 创建, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, recordId=484
2026-05-30 23:28:04.066 INFO 14304 --- [io-11511-exec-1] c.j.ai.client.AiEngineWebSocketClient : 建立 WebSocket, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, reconnectable=false, attempt=0
2026-05-30 23:28:06.093 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : ==> Preparing: UPDATE ai_chat_record SET content=? WHERE id=?
2026-05-30 23:28:06.094 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : ==> Parameters: 以下是 **mm** 的服务评价总结 📋---**📝 当前总结内容:**> 服务细致到位,维修保洁都做得好,主动验收有礼貌,客户强烈推荐。(String), 484(Long)
2026-05-30 23:28:06.097 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : <== Updates: 1
2026-05-30 23:28:07.111 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : ==> Preparing: UPDATE ai_chat_record SET content=? WHERE id=?
2026-05-30 23:28:07.111 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : ==> Parameters: 以下是 **mm** 的服务评价总结 📋---**📝 当前总结内容:**> 服务细致到位,维修保洁都做得好,主动验收有礼貌,客户强烈推荐。**⏰ 上次总结时间:** 2026年5月30日 19:37---**mm 的服务评价概览:**- 共收到 **5条** 客户评价- 涉及 **日常保洁、家电维修、燃气安检** 等服务- 客户普遍反馈:**服务认真细致、沟通温和有礼貌、主动邀请验收**- 评分在 **3.7 ~ 4.7分** 之间,整体表现不错(String), 484(Long)
2026-05-30 23:28:07.114 DEBUG 14304 --- [ async-flush] c.j.a.m.AiChatRecordMapper.updateById : <== Updates: 1
2026-05-30 23:28:07.121 DEBUG 14304 --- [ctor-http-nio-8] c.j.a.m.AiChatRecordMapper.updateById : ==> Preparing: UPDATE ai_chat_record SET content=?, status=? WHERE id=?
2026-05-30 23:28:07.122 DEBUG 14304 --- [ctor-http-nio-8] c.j.a.m.AiChatRecordMapper.updateById : ==> Parameters: 以下是 **mm** 的服务评价总结 📋---**📝 当前总结内容:**> 服务细致到位,维修保洁都做得好,主动验收有礼貌,客户强烈推荐。**⏰ 上次总结时间:** 2026年5月30日 19:37---**mm 的服务评价概览:**- 共收到 **5条** 客户评价- 涉及 **日常保洁、家电维修、燃气安检** 等服务- 客户普遍反馈:**服务认真细致、沟通温和有礼貌、主动邀请验收**- 评分在 **3.7 ~ 4.7分** 之间,整体表现不错如需更新/合并最新评价生成新的总结,也可以随时告诉我!😊(String), 1(Integer), 484(Long)
2026-05-30 23:28:07.126 DEBUG 14304 --- [ctor-http-nio-8] c.j.a.m.AiChatRecordMapper.updateById : <== Updates: 1
2026-05-30 23:28:07.126 INFO 14304 --- [ctor-http-nio-8] com.jzo2o.ai.service.impl.AsyncFlusher : AsyncFlusher 最终落盘, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, recordId=484, status=1, contentLen=256
2026-05-30 23:28:07.126 INFO 14304 --- [ctor-http-nio-8] c.jzo2o.ai.service.impl.ChatServiceImpl : 聊天会话完成(WS), sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:28:07.128 INFO 14304 --- [io-11511-exec-2] c.j.ai.client.AiEngineWebSocketClient : SSE 完成, 取消 WebSocket, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:28:07.128 INFO 14304 --- [io-11511-exec-2] c.j.ai.client.AiEngineWebSocketClient : 取消会话: 找到上下文, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, state=ACTIVE, cancelReason=user_cancel, wsOpen=true
2026-05-30 23:28:07.128 INFO 14304 --- [ctor-http-nio-8] c.j.ai.client.AiEngineWebSocketClient : cancel 帧已发送, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:28:07.128 INFO 14304 --- [ctor-http-nio-8] c.j.ai.client.AiEngineWebSocketClient : cancel 帧发送完成, 清理会话, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:28:07.128 INFO 14304 --- [ctor-http-nio-8] c.jzo2o.ai.service.impl.ChatServiceImpl : 用户取消会话(WS), sessionId=1a038089-035c-4256-ba0b-e88b419c5743, reason=user_cancel
耗时3s
- 首次全量生成:P95 ≤ 60s(取决于历史评价数量)。
2026-05-31 00:10:36.003 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.selectList : ==> Preparing: SELECT id,target_type_id,target_id,summary_content,last_evaluation_id,last_evaluation_time,create_time,update_time FROM evaluation_summary WHERE (target_type_id = ? AND target_id = ?)
2026-05-31 00:10:36.003 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.selectList : ==> Parameters: 7(Integer), 1738873712110256130(Long)
2026-05-31 00:10:36.004 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.selectList : <== Total: 1
2026-05-31 00:10:36.005 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : 全量总结: targetTypeId=7, targetId=1738873712110256130
2026-05-31 00:10:36.005 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : 查询新评价: targetTypeId=7, targetId=1738873712110256130, afterTime=null
2026-05-31 00:10:36.022 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : 评价查询返回: length=3440, preview=[{"id":18,"targetTypeId":7,"targetId":1738873712110256130,"targetName":"mm","relationId":2026051516579880,"evaluatorId":1695064056785940480,"evaluatorNickname":"abc","evaluatorAvatar":"abc","isAnonymous":0,"content":"卫生间排气扇不运转,更换电机配件,清理扇叶积灰,排风效果恢复如初。","totalScore":4.3,"scoreLevel":3,"scoreItems":"[{\"score\": 4.3, \"itemId\": \"1\", \"itemName\": \"专业能力\"}, {\"score\": 4.5, \"itemId\": \"2\", \"itemName\": \"服务态度\"}, {\"score\": 4.0, \"itemId\": \"3\", \"itemName\": \"准时到达\"}]","pictureArray":"[
2026-05-31 00:10:36.023 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : 发现 6 条新评价: targetTypeId=7, targetId=1738873712110256130
2026-05-31 00:10:36.023 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : 发送 AI 请求: sessionId=eval-summary-1a87c8d6, prompt 长度=3553, prompt 末尾(300字符)=": 0.3, \"itemId\": \"1\", \"itemName\": \"专业能力\"}, {\"score\": 1.1, \"itemId\": \"2\", \"itemName\": \"服务态度\"}, {\"score\": 1.3, \"itemId\": \"3\", \"itemName\": \"准时到达\"}]","pictureArray":"[]","status":0,"createTime":1780155707000,"updateTime":1780155707000}]
请用一句话概括这些评价的核心观点(50字以内,口语化,不要任何格式标记)。
2026-05-31 00:10:36.023 INFO 44128 --- [io-11511-exec-5] c.j.ai.client.AiEngineWebSocketClient : 建立 WebSocket, sessionId=eval-summary-1a87c8d6, reconnectable=true, attempt=0
2026-05-31 00:10:41.497 INFO 44128 --- [io-11511-exec-5] c.j.a.s.i.EvaluationSummaryServiceImpl : AI 总结完成: targetTypeId=7, targetId=1738873712110256130, 长度=34
2026-05-31 00:10:41.500 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.updateById : ==> Preparing: UPDATE evaluation_summary SET target_type_id=?, target_id=?, summary_content=?, last_evaluation_id=?, last_evaluation_time=?, create_time=?, update_time=? WHERE id=?
2026-05-31 00:10:41.500 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.updateById : ==> Parameters: 7(Integer), 1738873712110256130(Long), 保洁维修都干得很细致,但窗帘安装出了大问题还态度恶劣,水平不太稳定。(String), 118(Long), 2026-05-30T23:41:47(LocalDateTime), 2026-05-15T20:30:06(LocalDateTime), 2026-05-15T20:30:06(LocalDateTime), 2(Long)
2026-05-31 00:10:41.504 DEBUG 44128 --- [io-11511-exec-5] c.j.a.m.E.updateById : <== Updates: 1
耗时5s
- 增量生成:P95 ≤ 10s(因为只处理少量新评价)。

耗时5s
NFR-1验收通过
NFR-2
可靠性:当总结功能、读取总结功能不可用时返回友好提示
关闭Python服务,执行总结全量总结以模拟:
后端
2026-06-02 12:07:43.825 INFO 14164 --- [io-11511-exec-4] c.j.ai.client.AiEngineWebSocketClient : 建立 WebSocket, sessionId=eval-summary-06938b14, reconnectable=true, attempt=0
2026-06-02 12:07:43.964 ERROR 14164 --- [ctor-http-nio-2] c.j.ai.client.AiEngineWebSocketClient : WebSocket 连接异常, sessionId=eval-summary-06938b14, attempt=1: Connection refused: no further information: localhost/127.0.0.1:8000
2026-06-02 12:07:43.964 INFO 14164 --- [ctor-http-nio-2] c.j.ai.client.AiEngineWebSocketClient : 计划重连, sessionId=eval-summary-06938b14, attempt=1/3, delay=1000ms
2026-06-02 12:07:44.074 INFO 14164 --- [2.168.101.68-38] com.alibaba.nacos.common.remote.client : [91932143-1d77-4ca4-8e5a-db7b4436f96b] Receive server push request, request = NotifySubscriberRequest, requestId = 31
2026-06-02 12:07:44.074 INFO 14164 --- [2.168.101.68-38] com.alibaba.nacos.common.remote.client : [91932143-1d77-4ca4-8e5a-db7b4436f96b] Ack server push request, request = NotifySubscriberRequest, requestId = 31
2026-06-02 12:07:44.977 INFO 14164 --- [ ws-session-mgr] c.j.ai.client.AiEngineWebSocketClient : 建立 WebSocket, sessionId=eval-summary-06938b14, reconnectable=true, attempt=1
2026-06-02 12:07:44.981 ERROR 14164 --- [ctor-http-nio-3] c.j.ai.client.AiEngineWebSocketClient : WebSocket 连接异常, sessionId=eval-summary-06938b14, attempt=2: Connection refused: no further information: localhost/127.0.0.1:8000
2026-06-02 12:07:44.982 INFO 14164 --- [ctor-http-nio-3] c.j.ai.client.AiEngineWebSocketClient : 计划重连, sessionId=eval-summary-06938b14, attempt=2/3, delay=2000ms
2026-06-02 12:07:46.991 INFO 14164 --- [ ws-session-mgr] c.j.ai.client.AiEngineWebSocketClient : 建立 WebSocket, sessionId=eval-summary-06938b14, reconnectable=true, attempt=2
2026-06-02 12:07:46.995 ERROR 14164 --- [ctor-http-nio-4] c.j.ai.client.AiEngineWebSocketClient : WebSocket 连接异常, sessionId=eval-summary-06938b14, attempt=3: Connection refused: no further information: localhost/127.0.0.1:8000
2026-06-02 12:07:46.995 INFO 14164 --- [ctor-http-nio-4] c.j.ai.client.AiEngineWebSocketClient : 计划重连, sessionId=eval-summary-06938b14, attempt=3/3, delay=4000ms
2026-06-02 12:07:50.998 INFO 14164 --- [ ws-session-mgr] c.j.ai.client.AiEngineWebSocketClient : 建立 WebSocket, sessionId=eval-summary-06938b14, reconnectable=true, attempt=3
2026-06-02 12:07:51.001 ERROR 14164 --- [ctor-http-nio-5] c.j.ai.client.AiEngineWebSocketClient : WebSocket 连接异常, sessionId=eval-summary-06938b14, attempt=4: Connection refused: no further information: localhost/127.0.0.1:8000
2026-06-02 12:07:51.001 ERROR 14164 --- [ctor-http-nio-5] c.j.ai.client.AiEngineWebSocketClient : 重连次数耗尽, sessionId=eval-summary-06938b14, attempts=3
2026-06-02 12:07:51.005 ERROR 14164 --- [io-11511-exec-4] c.j.a.s.i.EvaluationSummaryServiceImpl : AI 总结失败: targetTypeId=7, targetId=1696706462195150849
java.util.concurrent.ExecutionException: java.lang.RuntimeException: WebSocket 重连失败, 已尝试 3 次
Caused by: java.lang.RuntimeException: WebSocket 重连失败, 已尝试 3 次
2026-06-02 12:07:51.011 ERROR 14164 --- [io-11511-exec-4] c.j.a.c.inner.InnerAiController : AI 全量评价总结失败: targetTypeId=7, targetId=1696706462195150849
前端
NFR-2通过
NFR-3
安全性:网关不暴露inner路由
从外部直接请求http://localhost:11500/ai/inner/ai/evaluation/summarize


成功被拦截
NFR-3验收通过
NFR-4
可观测性:日志需包括调用的详情,包括:调用的工具、接口、返回的值等
发生异常时日志
2026-05-30 23:15:16.957 INFO 14304 --- [io-11511-exec-8] c.j.a.c.consumer.ChatController : 收到聊天请求, sessionId: 1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:15:16.959 DEBUG 14304 --- [io-11511-exec-8] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Preparing: INSERT INTO ai_chat_record ( user_id, user_type, session_id, role, content, status, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
2026-05-30 23:15:16.959 DEBUG 14304 --- [io-11511-exec-8] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Parameters: 1696706462195150849(Long), 3(Integer), 1a038089-035c-4256-ba0b-e88b419c5743(String), user(String), 看看mm的总结(String), 1(Integer), 2026-05-30T23:15:16.957676200(LocalDateTime)
2026-05-30 23:15:16.964 DEBUG 14304 --- [io-11511-exec-8] c.j.ai.mapper.AiChatRecordMapper.insert : <== Updates: 1
2026-05-30 23:15:16.965 DEBUG 14304 --- [io-11511-exec-8] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Preparing: INSERT INTO ai_chat_record ( user_id, user_type, session_id, role, content, status, create_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
2026-05-30 23:15:16.965 DEBUG 14304 --- [io-11511-exec-8] c.j.ai.mapper.AiChatRecordMapper.insert : ==> Parameters: 1696706462195150849(Long), 3(Integer), 1a038089-035c-4256-ba0b-e88b419c5743(String), assistant(String), (String), 0(Integer), 2026-05-30T23:15:16.965266100(LocalDateTime)
2026-05-30 23:15:16.968 DEBUG 14304 --- [io-11511-exec-8] c.j.ai.mapper.AiChatRecordMapper.insert : <== Updates: 1
2026-05-30 23:15:16.968 DEBUG 14304 --- [io-11511-exec-8] com.jzo2o.ai.service.impl.AsyncFlusher : AsyncFlusher 创建, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, recordId=482
2026-05-30 23:15:16.969 INFO 14304 --- [io-11511-exec-8] c.j.ai.client.AiEngineWebSocketClient : 建立 WebSocket, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, reconnectable=false, attempt=0
2026-05-30 23:15:22.506 INFO 14304 --- [nPool-worker-19] com.jzo2o.ai.client.ToolExecutor : 执行远程工具: query_evaluations_by_name (id=call_00_jTY5DMRB4rgWjOnMUEsy3866), args={target_name=mm}
2026-05-30 23:15:24.487 INFO 14304 --- [nPool-worker-19] com.jzo2o.ai.client.ToolExecutor : 执行远程工具: get_evaluation_summary (id=call_00_lZhFGj5fP4zYgtKLXxLo1679), args={target_type_id=7, target_id=1738873712110256130}
2026-05-30 23:15:24.489 DEBUG 14304 --- [nPool-worker-19] c.j.a.m.E.selectList : ==> Preparing: SELECT id,target_type_id,target_id,summary_content,last_evaluation_id,last_evaluation_time,create_time,update_time FROM evaluation_summary WHERE (target_type_id = ? AND target_id = ?)
2026-05-30 23:15:24.489 DEBUG 14304 --- [nPool-worker-19] c.j.a.m.E.selectList : ==> Parameters: 7(Integer), 1738873712110256130(Long)
2026-05-30 23:15:24.490 DEBUG 14304 --- [nPool-worker-19] c.j.a.m.E.selectList : <== Total: 1
2026-05-30 23:20:17.917 INFO 14304 --- [io-11511-exec-7] c.j.ai.client.AiEngineWebSocketClient : SSE 超時, 取消 WebSocket, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:20:17.917 INFO 14304 --- [io-11511-exec-7] c.j.ai.client.AiEngineWebSocketClient : 取消会话: 找到上下文, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, state=ACTIVE, cancelReason=timeout, wsOpen=true
2026-05-30 23:20:17.917 INFO 14304 --- [ctor-http-nio-7] c.j.ai.client.AiEngineWebSocketClient : cancel 帧已发送, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:20:17.917 INFO 14304 --- [ctor-http-nio-7] c.j.ai.client.AiEngineWebSocketClient : cancel 帧发送完成, 清理会话, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:20:17.917 INFO 14304 --- [ctor-http-nio-7] c.jzo2o.ai.service.impl.ChatServiceImpl : 用户取消会话(WS), sessionId=1a038089-035c-4256-ba0b-e88b419c5743, reason=timeout
2026-05-30 23:20:17.919 DEBUG 14304 --- [ctor-http-nio-7] c.j.a.m.AiChatRecordMapper.deleteById : ==> Preparing: DELETE FROM ai_chat_record WHERE id=?
2026-05-30 23:20:17.920 DEBUG 14304 --- [ctor-http-nio-7] c.j.a.m.AiChatRecordMapper.deleteById : ==> Parameters: 482(Long)
2026-05-30 23:20:17.921 DEBUG 14304 --- [ctor-http-nio-7] c.j.a.m.AiChatRecordMapper.deleteById : <== Updates: 1
2026-05-30 23:20:17.923 DEBUG 14304 --- [ctor-http-nio-7] com.jzo2o.ai.service.impl.AsyncFlusher : AsyncFlusher 最终: 空记录已删除, sessionId=1a038089-035c-4256-ba0b-e88b419c5743, recordId=482
2026-05-30 23:20:17.940 ERROR 14304 --- [io-11511-exec-7] c.j.mvc.advice.CommonExceptionAdvice : 请求异常,
org.springframework.web.context.request.async.AsyncRequestTimeoutException: null
at org.springframework.web.context.request.async.TimeoutDeferredResultProcessingInterceptor.handleTimeout(TimeoutDeferredResultProcessingInterceptor.java:42) ~[spring-web-5.3.26.jar:5.3.26]
at org.springframework.web.context.request.async.DeferredResultInterceptorChain.triggerAfterTimeout(DeferredResultInterceptorChain.java:79) ~[spring-web-5.3.26.jar:5.3.26]
at org.springframework.web.context.request.async.WebAsyncManager.lambda$startDeferredResultProcessing$5(WebAsyncManager.java:438) ~[spring-web-5.3.26.jar:5.3.26]
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) ~[na:na]
at org.springframework.web.context.request.async.StandardServletAsyncWebRequest.onTimeout(StandardServletAsyncWebRequest.java:151) ~[spring-web-5.3.26.jar:5.3.26]
2026-05-30 23:20:17.945 WARN 14304 --- [io-11511-exec-7] .m.m.a.ExceptionHandlerExceptionResolver : Failure in @ExceptionHandler com.jzo2o.mvc.advice.CommonExceptionAdvice#noCustomException(Exception)
org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class com.jzo2o.mvc.model.Result] with preset Content-Type 'text/event-stream'
2026-05-30 23:20:17.953 WARN 14304 --- [io-11511-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Async request timed out
2026-05-30 23:20:17.953 WARN 14304 --- [io-11511-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.context.request.async.AsyncRequestTimeoutException]
2026-05-30 23:20:17.954 INFO 14304 --- [io-11511-exec-7] c.j.ai.client.AiEngineWebSocketClient : SSE 完成, 取消 WebSocket, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
2026-05-30 23:20:17.954 DEBUG 14304 --- [io-11511-exec-7] c.j.ai.client.AiEngineWebSocketClient : 取消会话: 上下文已清理, sessionId=1a038089-035c-4256-ba0b-e88b419c5743
正常查询日志
2026-06-01 23:34:43.400 INFO 17676 --- [io-11502-exec-2] com.alibaba.nacos.client.naming : [SUBSCRIBE-SERVICE] service:jzo2o-ai, group:DEFAULT_GROUP, clusters:
2026-06-01 23:34:43.400 INFO 17676 --- [io-11502-exec-2] com.alibaba.nacos.client.naming : [GRPC-SUBSCRIBE] service:jzo2o-ai, group:DEFAULT_GROUP, cluster:
2026-06-01 23:34:43.404 INFO 17676 --- [io-11502-exec-2] com.alibaba.nacos.client.naming : init new ips(1) service: DEFAULT_GROUP@@jzo2o-ai -> [{"instanceId":"192.168.247.1#11511#DEFAULT#DEFAULT_GROUP@@jzo2o-ai","ip":"192.168.247.1","port":11511,"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"DEFAULT","serviceName":"DEFAULT_GROUP@@jzo2o-ai","metadata":{"preserved.register.source":"SPRING_CLOUD"},"ipDeleteTimeout":30000,"instanceHeartBeatTimeOut":15000,"instanceHeartBeatInterval":5000}]
2026-06-01 23:34:43.404 INFO 17676 --- [io-11502-exec-2] com.alibaba.nacos.client.naming : current ips:(1) service: DEFAULT_GROUP@@jzo2o-ai -> [{"instanceId":"192.168.247.1#11511#DEFAULT#DEFAULT_GROUP@@jzo2o-ai","ip":"192.168.247.1","port":11511,"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"DEFAULT","serviceName":"DEFAULT_GROUP@@jzo2o-ai","metadata":{"preserved.register.source":"SPRING_CLOUD"},"ipDeleteTimeout":30000,"instanceHeartBeatTimeOut":15000,"instanceHeartBeatInterval":5000}]
2026-06-01 23:34:43.755 INFO 17676 --- [io-11502-exec-2] com.jzo2o.mvc.filter.PackResultFilter : result : {"code":200,"message":"OK","msg":"OK","success":true,"result": {"summary":"维修水龙头清理起泡器解决了问题,服务态度不错但准时一般,整体评分中规中矩。"},"data": {"summary":"维修水龙头清理起泡器解决了问题,服务态度不错但准时一般,整体评分中规中矩。"}}
2026-06-01 23:34:43.909 INFO 17676 --- [.168.101.68-246] com.alibaba.nacos.common.remote.client : [de3e9d34-d326-431b-ba23-457a472c11a4] Receive server push request, request = NotifySubscriberRequest, requestId = 14
2026-06-01 23:34:43.909 INFO 17676 --- [.168.101.68-246] com.alibaba.nacos.common.remote.client : [de3e9d34-d326-431b-ba23-457a472c11a4] Ack server push request, request = NotifySubscriberRequest, requestId = 14
调用的工具:
执行远程工具: query_evaluations_by_name (id=call_00_jTY5DMRB4rgWjOnMUEsy3866), args={target_name=mm}
接口:
收到聊天请求, sessionId: 1a038089-035c-4256-ba0b-e88b419c5743
返回的值:
{“code”:200,“message”:“OK”,“msg”:“OK”,“success”:true,“result”: {“summary”:“维修水龙头清理起泡器解决了问题,服务态度不错但准时一般,整体评分中规中矩。”},“data”: {“summary”:“维修水龙头清理起泡器解决了问题,服务态度不错但准时一般,整体评分中规中矩。”}}
NFR-4验收通过
NFR-5
兼容性:API变更是否向后兼容,不得删除或修改已有字段的类型/含义
本人是单机环境而且没引入契约测试,所以放弃这部分
NFR-6:
成本控制:采用增量策略后,每次生成(除首次和强制全量外)的 token 消耗应比全量减少 75% 以上。
对机构03进行总结,有207条评论
上面是全量,下面是增量
(30012 - 1560) / 30012 ≈ 94.8%
NFR-6验收通过
收尾
本篇完成了 AI 评价总结模块的全流程开发与验收,基于 SpringCloud 微服务架构结合原生 LangChain 能力,落地了全量首次汇总 + 增量持续更新的评价总结策略。从产品需求梳理、数据库设计、接口规划,到功能开发、多维度测试与压测,整套能力均达到预设指标:不仅将人工整理评价的效率提升 90% 以上,还通过增量机制把 Token 消耗降低近 95%,在性能、安全性、容错性、可观测性上均满足生产环境要求
更多推荐



所有评论(0)