Files
knowledge-base/2 - Projects/Trading-Agents/Trading Agents 调试与优化记录.md

358 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
created: "2026-03-21"
type: project
status: active
tags: [trading, multi-agent, openclaw, debugging, optimization]
---
# Trading Agents 调试与优化记录
部署后的调试过程、发现的问题、尝试的方案和最终修复。
---
## 一、问题时间线
| 时间 | 事件 | 状态 |
|------|------|------|
| 14:00 | 初次部署4 个辩论 bot 登录成功 | ✅ |
| 14:05 | 发现 `openclaw status --deep` 超时 | ⚠️ bind=lan 导致 CLI WebSocket 无法连 localhost |
| 14:09 | 发现 invest-analyst 有 typing 超时 | ⚠️ `google-antigravity-auth` 插件刷日志 |
| 14:11 | 日志被 Config warning 洪水淹没 | 🔧 删除 `plugins.entries.google-antigravity-auth` |
| 14:33 | 用户消息被 `no-mention` 拒绝 | 🔍 辩论 bot `requireMention: true` 正常拒绝 |
| 14:41 | invest-analyst 回复了快速分析而非触发辩论 | 🔍 LLM 选择了捷径 |
| 14:45 | 测试 @ mention 模式——invest-bear 设 `requireMention: false` 后响应 | ✅ 确认 bot 能工作 |
| 14:55 | 添加 `groupChat.mentionPatterns`,切换到 ds-* 风格 @ mention 协调 | 🔧 |
| 15:00 | **NVDA 辩论成功触发!** Bull/Bear/Hawk/Dove 全部参与 | ✅ 辩论质量很高 |
| 15:00-15:05 | **辩论进入无限循环**——agent 通过 @ mention 不断互相回复 | ❌ 核心问题 |
| 15:05 | 强制 gateway restart 停止循环 | 🔧 |
| 15:05 | AMZN 分析——invest-analyst 跳过辩论直接回答 | ❌ LLM 没调用 trade-analyze |
| 15:22 | 最终修复:移除辩论 agent mentionPatterns + 强化 sessions_send 流程 | 🔧 |
---
## 二、发现的问题与修复
### 问题 1Config Warning 日志洪水
**现象**`google-antigravity-auth` 插件每隔几秒刷一条 warning导致所有有用日志被淹没。
**修复**
```python
del config["plugins"]["entries"]["google-antigravity-auth"]
```
**教训**OpenClaw 中已卸载的插件如果还留在 config 里,会持续刷 warning。应及时清理。
### 问题 2@ Mention 模式导致辩论无限循环
**现象**invest-analyst 通过 `@Bull` 在频道中触发 BullBull 回复后 Bear 看到消息并回复,然后 Bull 又回复……无限循环。
**根本原因**@ mention 模式下没有内建的轮次限制。每条消息都会触发对方回复。`REPLY_SKIP` 在 SOUL.md 中写了,但 LLM 没有严格执行。
**尝试的方案**
| 方案 | 结果 |
|------|------|
| `requireMention: true` + `groupChat.mentionPatterns` | ❌ 循环——agent 在频道中互相 @ |
| SOUL.md 中写 `REPLY_SKIP` 规则 | ❌ LLM 不严格执行 |
| **最终方案:移除辩论 agent 的 `groupChat.mentionPatterns`** | ✅ 辩论 agent 不再响应频道消息 |
**最终修复**
- 辩论 agentbull/bear/hawk/dove**没有** `groupChat.mentionPatterns`
- 辩论 agent 保持 `requireMention: true`
- 只能通过 `sessions_send` A2A 协议调用
- invest-analyst 通过 `sessions_send` 明确控制每一轮,手动决定何时停止
### 问题 3LLM 跳过辩论流程
**现象**:用户发 `/trade-analyze AMZN`invest-analyst 直接用 `invest-api` skill 做了快速分析,没有调用 trade-analyze skill 触发辩论。
**根本原因**kimi-coding/k2p5 模型倾向于走捷径——直接回答比调用复杂的多 agent 流程更快。AGENTS.md 中没有足够强的指令区分两种模式。
**修复**
1. 精简 AGENTS.md明确触发条件`/trade-analyze` 或 "要不要买" → **必须使用 trade-analyze skill**
2. 重写 trade-analyze SKILL.md加入 `CRITICAL` 级别指令和逐步 sessions_send 调用模板
3. Skill description 中直接写明 "MUST use sessions_send"
### 问题 4Discord bot 频繁断开
**现象**`health-monitor: restarting (reason: disconnected)` 反复出现。
**可能原因**10 个 Discord bot 同时从一台机器连接,可能触发 Discord rate limit 或 WebSocket 连接限制。
**当前状态**health-monitor 自动重连,功能不受影响,但会导致短暂的消息丢失窗口。
---
## 三、@ Mention vs sessions_send 对比
经过实测验证的结论:
| 维度 | @ Mentionds-* 风格) | sessions_send |
|------|----------------------|---------------|
| 触发方式 | 在频道中写 `@智库 请分析...` | 调用 `sessions_send` 工具 |
| 可见性 | 用户能在频道中看到完整对话 | 后台执行,用户看不到过程 |
| 轮次控制 | ❌ 无内建限制,容易循环 | ✅ `maxPingPongTurns: 5` 硬限制 |
| 适用场景 | 人类协调(如大统领派任务给智库) | agent 间自动协作 |
| 辩论场景 | ❌ 不适合——agent 间 @ 会死循环 | ✅ 适合——编排者控制每轮 |
**结论**ds-* 的 @ mention 模式适合**人类在中间协调**的场景(大统领手动 @ 智库做任务)。但对于**自动化辩论**agent 自动互相辩论),必须用 `sessions_send`,由编排者手动控制每轮。
---
## 四、NVDA 辩论验证结果
虽然出现了循环问题,但辩论本身的质量很高,验证了架构的可行性。
### Bull 核心论点
- 分析师共识目标价 $269较现价 $172.70 有 56% 上行
- RSI 37.8 接近超卖,布林带下轨形成支撑
- AI 需求周期才刚开始Blackwell 放量
### Bear 核心论点
- 85% 分析师看多是情绪极端化危险信号
- MACD 负值且柱状图扩大,下跌动能强化
- PE 35x 对 $4.2T 市值需要持续 30%+ 增长支撑
### Hawk 风控评估
- 风险收益比 8:1止损 $160 vs 目标 $269
- 建议 15-20% 仓位,现价直接建仓 50%
### Dove 风控评估
- 5% 仓位上限
- 减仓 25% 锁定利润
- 更宽止损 $155 避免被正常波动震出
### 最终方案(辩论共识)
- 减仓 25%8 股)锁定利润
- 保留 25 股核心仓位
- 止损 $155
- 目标 $220-250
---
## 五、最终配置状态
### openclaw.json 关键配置
```json5
{
agents: {
list: [
// invest-analyst: 有 groupChat.mentionPatterns响应频道消息
// invest-bull/bear/hawk/dove: 无 groupChat只响应 sessions_send
]
},
tools: {
agentToAgent: {
enabled: true,
allow: ["ds-*系列", "invest-analyst", "invest-bull", "invest-bear", "invest-hawk", "invest-dove"]
}
},
session: {
agentToAgent: { maxPingPongTurns: 5 }
}
}
```
### invest-analyst AGENTS.md 关键逻辑
```
触发条件判断:
- 简单问题 → 直接用 invest-api skill
- /trade-analyze 或 "要不要买" → 必须用 trade-analyze skill
trade-analyze 流程:
1. curl 收集 4 类数据
2. sessions_send → invest-bullRound 1
3. sessions_send → invest-bearRound 2
4. sessions_send → invest-bullRound 3 FINAL
5. sessions_send → invest-hawk
6. sessions_send → invest-dove
7. 综合裁决 → BUY/SELL/HOLD
```
### 辩论 Agent 配置
- `requireMention: true`(不响应频道消息)
-`groupChat.mentionPatterns`(不能被 @ mention 触发)
- 只通过 `sessions_send` A2A 协议被 invest-analyst 调用
- SOUL.md 中有 `REPLY_SKIP` 规则和字数限制
---
## 六、Gateway WebSocket 超时修复(根本问题)
### 问题
`sessions_send``sessions_spawn` 全部报错:
```
gateway timeout after 10000ms
Gateway target: ws://127.0.0.1:18789
Source: local loopback
```
所有 session 工具、`openclaw status --deep``openclaw gateway call` 都超时。
### 根因分析
1. Gateway 配置 `bind: "lan"`,监听 `0.0.0.0:18789`
2.**`127.0.0.1:18789` 实际连不通**`curl http://127.0.0.1:18789/` 超时,但 `curl http://192.168.68.108:18789/` 成功)
3. OpenClaw 内部工具默认连 `ws://127.0.0.1:18789`,导致所有 RPC 超时
4. 同时存在 [v2026.3.13 WebSocket handshake bug](https://github.com/openclaw/openclaw/issues/48167)handshake timeout 只有 3 秒
### 修复
**修复 1Systemd 环境变量**
`~/.config/systemd/user/openclaw-gateway.service` 中添加:
```ini
Environment=OPENCLAW_GATEWAY_URL=ws://192.168.68.108:18789
Environment=OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1
```
然后 `systemctl --user daemon-reload`
这让 gateway 内部工具通过 LAN IP而非 localhost连接绕过了 loopback 不通的问题。
**修复 2Patch handshake timeout来自 [PR #47388](https://github.com/openclaw/openclaw/pull/47388)**
文件:`~/.nvm/versions/node/v24.13.1/lib/node_modules/openclaw/dist/gateway-cli-CuZs0RlJ.js`(和 `Ol-vpIk7.js`
```javascript
// 原始(第 7588 行)
const DEFAULT_HANDSHAKE_TIMEOUT_MS = 3e3;
// 修改为
const DEFAULT_HANDSHAKE_TIMEOUT_MS = 10e3;
```
**修复 3Patch scope grant来自 [PR #47388](https://github.com/openclaw/openclaw/pull/47388)**
同一文件,第 22605 行附近:
```javascript
// 原始
if (!device && (!isControlUi || decision.kind !== "allow")) clearUnboundScopes();
// 修改为
if (!device && (!isControlUi || decision.kind !== "allow")) { clearUnboundScopes(); } else if (!device && decision.kind === "allow") { scopes = ["operator.read"]; connectParams.scopes = scopes; }
```
### 验证
修复后 `openclaw gateway call status` 返回正常 JSON`sessions_spawn` 成功:
```
15:49:43 status: "accepted", childSessionKey: "agent:invest-bull:subagent:ad2d265d..."
15:50:06 [subagent task] bull-AMZN: completed successfully
```
### 注意事项
- 这些 patch 在 `npm update openclaw` 后会被覆盖,需要重新打
- 关注 [PR #47388](https://github.com/openclaw/openclaw/pull/47388) 和 [PR #48950](https://github.com/openclaw/openclaw/pull/48950) 的合并状态
- 合并后升级即可去掉手动 patch
---
## 七、最终验证AMZN 辩论流程
### 完整时间线
| 时间 (UTC) | 事件 | 状态 |
|------------|------|------|
| 15:48:20 | 读取 trade-analyze skill | ✅ |
| 15:48:36 | 收集 AMZN 数据curl API | ✅ |
| 15:49:13 | metrics + sentiment 数据返回 | ✅ |
| 15:49:27 | technical + macro 返回 503 | ⚠️ K8s API pod 暂时不可用 |
| 15:49:43 | `sessions_spawn` → invest-bull | ✅ accepted |
| 15:50:06 | Bull 完成,结果返回 | ✅ |
| 15:50:25 | `sessions_spawn` → invest-bear | ✅ accepted |
| 15:50:53 | Bear 完成,结果返回 | ✅ |
| 15:51:04 | `sessions_spawn` → invest-bull (final rebuttal) | ✅ accepted |
| 15:51:08 | 等待 Bull Final + Hawk + Dove... | ⏳ |
### 关键确认
1. **`sessions_spawn` 成功调用了辩论 agent** ✅
2. **辩论 agent 在后台执行,不在 Discord 输出**Discord 已禁用)
3. **结果通过 subagent announce 自动返回给 invest-analyst**
4. **流程按顺序执行**Bull → Bear → Bull Final → (Hawk → Dove) ✅
5. **没有循环**sessions_spawn 是一次性的,不会互相触发)
---
## 八、sessions_send vs sessions_spawn 最终结论
| 工具 | 能否工作 | 原因 |
|------|---------|------|
| **@ mention** | ❌ | 导致无限循环 |
| **sessions_send** | ❌ | Gateway 内部 WebSocket 死锁(同进程内自连) |
| **sessions_spawn** | ✅ | 非阻塞,独立 lane 执行announce 回传结果 |
**最终方案sessions_spawn + announce 回传。**
---
## 九、Session 文件位置
| Agent | Session 路径 |
|-------|-------------|
| invest-analyst | `~/.openclaw/agents/invest-analyst/sessions/*.jsonl` |
| invest-bull | `~/.openclaw/agents/invest-bull/sessions/*.jsonl` |
| invest-bear | `~/.openclaw/agents/invest-bear/sessions/*.jsonl` |
| invest-hawk | `~/.openclaw/agents/invest-hawk/sessions/*.jsonl` |
| invest-dove | `~/.openclaw/agents/invest-dove/sessions/*.jsonl` |
查看辩论内容:
```bash
python3 -c "
import json
with open('SESSION_FILE.jsonl') as f:
for line in f:
d = json.loads(line)
msg = d.get('message', d)
role = msg.get('role', '')
content = msg.get('content', '')
if isinstance(content, list):
for c in content:
if isinstance(c, dict) and c.get('type') == 'text':
content = c.get('text', '')
break
if role == 'assistant' and len(str(content)) > 50:
print(f'[{role}] {str(content)[:300]}')
print()
"
```
---
## 七、监控命令速查
```bash
# 实时日志(过滤噪音)
journalctl --user -u openclaw-gateway.service -f --output=cat | grep -v "Config warn"
# 检查辩论 agent 是否有新 session
for a in invest-bull invest-bear invest-hawk invest-dove; do
echo "$a: $(ls ~/.openclaw/agents/$a/sessions/*.jsonl 2>/dev/null | wc -l) sessions"
done
# 检查 bot 登录状态
journalctl --user -u openclaw-gateway.service --no-pager -n 100 | grep "logged in"
# 检查是否有循环(大量 lane wait
journalctl --user -u openclaw-gateway.service --no-pager --since "5 min ago" | grep -c "lane wait"
# Gateway 重启(需要 nvm
export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; openclaw gateway restart
```
---
## Related
- [[Trading Agents 混合架构方案]]
- [[Trading Agents 部署记录]]
- [[TradingAgents 原始架构分析]]
- [[OpenClaw 部署配置分析]]