切换主题
02. 第一个 ReviewCoachAgent:让回答像教练,而不是像闲聊
上一章练习参考答案
第一题,应该先提示边界。用户已经从复盘训练跳到了“下一笔要不要做回来”,这很容易变成实盘决策建议。系统可以引导他改写问题,比如“这笔交易有没有遵守原计划”,但不能顺着回答下一笔怎么做。
第二题,HTTP DTO 和业务 Command 字段一样也建议拆开。接口会变,业务命令也会变,拆开之后你可以在 Controller 做校验、默认值、兼容旧字段,而不污染业务层。
第三题,boundaryNotice 应该放在响应里。因为边界不是内部日志,它要被用户看见,也要被前端、审计和测试稳定拿到。
MVP 的第一个问题
上一章的 MVP 能返回结果了,但它还不像教练。
如果系统只是说:
“这笔交易亏损,建议下次注意风险。”
这种话没有训练价值。用户听完不会知道自己下一次该练什么。真正的教练要能固定住几个动作:
- 先声明边界:只复盘训练样本。
- 再看计划:这笔交易原本想练什么。
- 再看执行:入场、止损、止盈和退出有没有偏离计划。
- 最后给训练任务:下一组样本要怎么练。
所以第二章引入 ReviewCoachService,它就是本地版的 ReviewCoachAgent。等接入 Spring AI Alibaba 时,这个角色可以映射为一个带系统提示词、工具、记忆和保护栏的 Agent。
先看它的职责
ReviewCoachService 不是“会写一段话”的类,而是复盘编排器:
java
public class ReviewCoachService {
public ReviewReport review(ReviewRequest request) {
if (guardrailService.isLiveAdviceRequest(request.question())) {
return blocked(request);
}
TradeRecord trade = tradeRepository.findById(request.tradeId())
.orElseThrow(() -> new IllegalArgumentException("trade not found"));
if (!trade.hasRiskPlan()) {
return needsMoreContext(trade);
}
RiskMetrics risk = riskCalculator.calculate(trade);
// 组装结构化复盘报告
}
}这段逻辑故意写得很直白。你以后接大模型,也不要把所有判断都交给模型。像越界拦截、交易读取、风险计算、信息缺失判断,这些都应该是稳定代码先做。
为什么叫 Agent
在教程里我们先用 ReviewCoachService 承载 Agent 职责,因为它能本地跑通。但你要理解真正的 Agent 边界:
- 它有角色:PA 训练复盘教练。
- 它有任务:复盘已发生的训练交易。
- 它有工具:读交易、读 K 线、算风险。
- 它有记忆:训练者长期问题。
- 它有保护栏:不回答实盘买卖方向。
如果以后换成 Spring AI Alibaba,可以把这部分抽成类似:
java
ChatClient reviewCoachClient = chatClientBuilder
.defaultSystem("你是 PA 训练复盘教练,只复盘已经发生的训练交易。")
.defaultTools(tradeTools, riskTools, klineTools)
.build();本章重点不是 API 长什么样,而是 Agent 的职责边界不能乱。
这一章怎么验证
继续调用同一个接口:
powershell
Invoke-RestMethod `
-Uri "http://127.0.0.1:18091/api/pa-review/reviews" `
-Method Post `
-ContentType "application/json; charset=utf-8" `
-Body '{"tradeId":"T-1001","includeKline":true,"question":"复盘这笔训练交易"}'这次你重点看这些字段:
json
{
"status": "REVIEWED",
"primaryProblem": "没有等待回踩确认,入场动作和 plannedSetup 不一致",
"nextTrainingTask": "连续记录 20 笔突破后是否等待回踩确认的训练样本",
"sections": {
"coachSummary": "这是一笔突破后追多训练失败样本,重点不是预测行情,而是复盘执行动作。"
}
}它不是泛泛地说“注意风险”,而是把问题落到“入场动作和计划不一致”。
这一章真正解决了什么
第一章解决的是能不能闭环。第二章解决的是:闭环之后,输出有没有训练味。
一个复盘教练不能只安慰用户,也不能只吐槽用户。它要把一笔交易变成下一次训练动作。
练习题
- 如果用户写了很长一段情绪化描述,ReviewCoachAgent 应该先共情,还是先抽取交易事实?
- 哪些判断适合放在稳定代码里,哪些部分适合交给大模型生成?
- 如果后面要接 Spring AI Alibaba,你会把 Agent 的系统提示词写在哪里?