前言

上篇文章已经在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_01jzo2o-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_01jzo2o-ai
URL /ai/inner/ai/evaluation/summarize
方法 GET

请求/响应字段同接口 1。

接口 5:内部 Feign — 查询新增评价(EvaluationApi.queryByTargetIdAndTime
调用方 jzo2o-aijzo2o-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 请求参数缺失或格式错误 targetTypeIdtargetId 未传;前端 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来模拟
xxxlljjoobb

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

python服务

未通过,理由:只总结了新增的评论: 维修水龙头清理起泡器解决了问题,服务态度不错但准时一般,整体评分中规中矩。

定位问题: 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 重连失败, 已尝试 32026-06-02 12:07:51.011 ERROR 14164 --- [io-11511-exec-4] c.j.a.c.inner.InnerAiController          : AI 全量评价总结失败: targetTypeId=7, targetId=1696706462195150849

前端
qianduan
NFR-2通过

NFR-3

安全性:网关不暴露inner路由
从外部直接请求http://localhost:11500/ai/inner/ai/evaluation/summarize

内部
网关日志
成功被拦截
NFR-3验收通过

NFR-4

可观测性:日志需包括调用的详情,包括:调用的工具、接口、返回的值等
发生异常时日志
python端报错

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条评论
207条

上面是全量,下面是增量
全量增量

(30012 - 1560) / 30012 ≈ 94.8%

NFR-6验收通过

收尾

本篇完成了 AI 评价总结模块的全流程开发与验收,基于 SpringCloud 微服务架构结合原生 LangChain 能力,落地了全量首次汇总 + 增量持续更新的评价总结策略。从产品需求梳理、数据库设计、接口规划,到功能开发、多维度测试与压测,整套能力均达到预设指标:不仅将人工整理评价的效率提升 90% 以上,还通过增量机制把 Token 消耗降低近 95%,在性能、安全性、容错性、可观测性上均满足生产环境要求

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐