mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-09 22:10:57 +08:00
change v1
This commit is contained in:
926
docs/architecture/AGENT_ARCHITECTURE_STATUS.zh-CN.md
Normal file
926
docs/architecture/AGENT_ARCHITECTURE_STATUS.zh-CN.md
Normal file
@@ -0,0 +1,926 @@
|
||||
# NOFXi Agent 架构现状说明
|
||||
|
||||
本文档说明当前 `nofxi-dev/agent` 的整体设计、关键执行链路、内存与快照机制、skill 协作方式,以及这套实现是怎么逐步收成现在这个样子的。
|
||||
|
||||
适用范围:
|
||||
- `nofxi-dev/agent`
|
||||
- 与 Agent 强相关的 tool / store / workflow / frontend chat 行为
|
||||
|
||||
## 1. 当前目标
|
||||
|
||||
当前 Agent 的目标不是“单轮问答机器人”,而是一个可持续管理配置、跨多轮续接、可在多个对象之间切换上下文的任务型 Agent。
|
||||
|
||||
核心要求有 4 个:
|
||||
|
||||
1. 用户一句模糊话,也要先判断是在继续当前任务、切回旧任务、开新任务,还是取消。
|
||||
2. `model / exchange / trader / strategy` 四个 management skill 都要能被统一路由、统一理解、统一执行。
|
||||
3. 用户说的是名称,系统执行的是 ID,中间必须有稳定映射。
|
||||
4. 快照、当前引用对象、最近对话、执行状态,不能只是“存着”,而要真的被 LLM 当成决策输入。
|
||||
|
||||
---
|
||||
|
||||
## 2. 顶层执行链路
|
||||
|
||||
当前主入口在:
|
||||
- [planner_runtime.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/planner_runtime.go:820)
|
||||
|
||||
整体顺序是:
|
||||
|
||||
1. `tryLLMIntentRoute`
|
||||
2. `tryStatePriorityPath`
|
||||
3. `tryInstantDirectReply`
|
||||
4. `tryReadFastPath`
|
||||
5. `tryHardSkill`
|
||||
6. `runPlannedAgent`
|
||||
|
||||
也就是说,现在系统优先做“统一语义判断”,然后才看 active flow、direct reply、hard skill 和 planner。
|
||||
|
||||
### 2.1 统一语义网关
|
||||
|
||||
顶层语义网关在:
|
||||
- [llm_skill_router.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/llm_skill_router.go:25)
|
||||
|
||||
LLM 目前先判断一条消息属于哪种 intent:
|
||||
|
||||
- `continue_active`
|
||||
- `resume_snapshot`
|
||||
- `start_new`
|
||||
- `cancel`
|
||||
- `instant_reply`
|
||||
|
||||
如果是 `start_new`,再继续判断 route:
|
||||
|
||||
- `skill`
|
||||
- `workflow`
|
||||
- `planner`
|
||||
|
||||
这层的意义是:先判断“这句话在和哪个上下文说话”,再判断“具体怎么做”。
|
||||
|
||||
### 2.2 顾问式系统前缀
|
||||
|
||||
现在统一语义网关和 Planner 共享同一份顾问式系统前缀,而不再只是“路由器”或“计划器”口吻。
|
||||
|
||||
这份前缀的核心基调是:
|
||||
|
||||
- 你是 NOFX 的核心智能中枢 `NOFXi`
|
||||
- 你的首要目标不是盲目执行命令
|
||||
- 你需要以资深量化顾问身份,确保每一次配置都正确、安全且符合逻辑
|
||||
- 当用户遇到问题时,你要结合当前状态和平台边界主动诊断,并给出具体解决方案
|
||||
|
||||
统一前缀已经抽成共享 helper:
|
||||
- [prompt_persona.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/prompt_persona.go)
|
||||
|
||||
当前已注入:
|
||||
|
||||
- 顶层统一语义网关
|
||||
- `one-pass` 统一语义网关
|
||||
- planner
|
||||
- replanner
|
||||
|
||||
这样做的目的,是让“理解用户意图”和“后续制定执行计划”都遵守同一套顾问式人格、安全边界和诊断基调。
|
||||
|
||||
### 2.3 兼容式 One-Pass JSON 网关
|
||||
|
||||
为了减少 `router -> classifier -> extractor` 的串行 LLM 调用次数,当前已经在统一语义网关前面接入了一个兼容式 `One-Pass JSON` 网关:
|
||||
- [llm_skill_router.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/llm_skill_router.go)
|
||||
|
||||
它会在一次调用里尝试同时输出:
|
||||
|
||||
- `intent`
|
||||
- `target_skill`
|
||||
- `target_snapshot_id`
|
||||
- `extracted_fields`
|
||||
- `need_planner_help`
|
||||
|
||||
典型返回形状如下:
|
||||
|
||||
```json
|
||||
{
|
||||
"intent": "continue_active",
|
||||
"target_skill": "trader_management:create",
|
||||
"target_snapshot_id": "draft_7788",
|
||||
"extracted_fields": {"leverage": "100"},
|
||||
"need_planner_help": false
|
||||
}
|
||||
```
|
||||
|
||||
当前它采用的是“兼容式接入”,不是硬切:
|
||||
|
||||
1. 先尝试 `one-pass` 网关
|
||||
2. 如果输出不可用,回退到原有统一语义网关
|
||||
3. 原有 `planner / workflow / hard skill` 分层继续保留
|
||||
|
||||
这意味着系统已经开始减少多次串行 LLM 往返,但不会因为一次新网关输出失误就直接把旧链路全部推翻。
|
||||
|
||||
---
|
||||
|
||||
## 3. 状态优先层
|
||||
|
||||
状态优先层在:
|
||||
- [planner_runtime.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/planner_runtime.go:954)
|
||||
|
||||
它负责优先处理这些场景:
|
||||
|
||||
- 是否要恢复挂起任务
|
||||
- 是否已有 active workflow
|
||||
- 是否已有 active skill session
|
||||
- 是否已有 active execution state
|
||||
|
||||
这层不是重新发明语义,而是消费上层已经决定好的“继续当前 / 切回旧快照 / 新开任务”。
|
||||
|
||||
如果当前有 active skill session,它会进一步进入:
|
||||
|
||||
- `resolveSkillSessionTurn`
|
||||
- `classifySkillSessionIntentWithLLM`
|
||||
- `extractSkillSessionFieldsWithLLM`
|
||||
|
||||
如果当前是 execution state,则会尝试:
|
||||
|
||||
- `bridgeExecutionStateToSkillSession`
|
||||
|
||||
这一层的目标,是把“planner 等待态”或者“执行等待态”桥接成真实 skill session,而不是让后续执行时丢上下文。
|
||||
|
||||
---
|
||||
|
||||
## 4. 四层上下文
|
||||
|
||||
当前 Agent 在规划和路由时,主要使用四层上下文:
|
||||
|
||||
1. `Current reference summary`
|
||||
2. `Execution state JSON`
|
||||
3. `Recent conversation`
|
||||
4. `Task state`
|
||||
|
||||
它们现在被显式写进 planner prompt,相关逻辑在:
|
||||
- [planner_runtime.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/planner_runtime.go:2950)
|
||||
|
||||
当前优先级是:
|
||||
|
||||
1. 当前引用对象
|
||||
2. 当前执行状态
|
||||
3. 最近对话
|
||||
4. 持久化压缩背景
|
||||
|
||||
这解决的是“明明刚才就在说某个 trader / strategy,但后面又像不认识了一样”的问题。
|
||||
|
||||
---
|
||||
|
||||
## 5. CurrentReferences、快照和持久引用记忆
|
||||
|
||||
### 5.1 CurrentReferences
|
||||
|
||||
`CurrentReferences` 表示当前锁定的对象,例如:
|
||||
|
||||
- 当前 trader
|
||||
- 当前 model
|
||||
- 当前 exchange
|
||||
- 当前 strategy
|
||||
|
||||
它会进入:
|
||||
|
||||
- router prompt
|
||||
- planner prompt
|
||||
- active flow classifier
|
||||
- flow extraction
|
||||
|
||||
相关读取点包括:
|
||||
- [llm_skill_router.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/llm_skill_router.go:38)
|
||||
- [planner_runtime.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/planner_runtime.go:2950)
|
||||
- [llm_flow_extractor.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/llm_flow_extractor.go:73)
|
||||
|
||||
### 5.2 Suspended snapshots
|
||||
|
||||
挂起任务快照用于:
|
||||
|
||||
- 打断当前流程
|
||||
- 以后恢复到具体旧流程
|
||||
- 让 LLM 在“刚才那个”“前面那个”这种模糊指代下仍能选对上下文
|
||||
|
||||
快照信息会进入:
|
||||
|
||||
- top-level router
|
||||
- active flow classifier
|
||||
- flow extraction
|
||||
|
||||
### 5.3 Persistent reference memory
|
||||
|
||||
现在 `CurrentReferences` 不只存在于 `ExecutionState` 里。
|
||||
|
||||
新增了持久引用记忆:
|
||||
- [reference_memory.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/reference_memory.go)
|
||||
|
||||
核心函数:
|
||||
|
||||
- `semanticCurrentReferences`
|
||||
- `semanticReferenceHistory`
|
||||
- `rememberReferencesFromToolResult`
|
||||
|
||||
这层的作用是:
|
||||
|
||||
- 即使 `ExecutionState` 被清掉
|
||||
- 当前对象记忆仍可延续
|
||||
- 后续 follow-up 仍能命中“当前 trader / 当前 strategy”
|
||||
|
||||
### 5.4 DB 活性校验
|
||||
|
||||
持久化记忆不能被 100% 信任,因为真实对象可能已经被前端或其他入口删除。
|
||||
|
||||
因此现在在真正执行实体更新前,会先做一次轻量级活性校验:
|
||||
|
||||
- 若当前 `TargetRef` 指向的对象已经不存在
|
||||
- 不再盲目继续执行
|
||||
- 会清掉失效引用,并要求用户重新指定目标对象
|
||||
|
||||
这解决的是:
|
||||
|
||||
- Agent 记得“当前策略 A”
|
||||
- 但真实数据库里的 `Strategy A` 已被网页前端删掉
|
||||
- 后续再说“就按当前策略来”时,不会直接拿悬空 ID 去执行
|
||||
|
||||
---
|
||||
|
||||
## 6. Skill 体系
|
||||
|
||||
当前正式 management skill 有四个:
|
||||
|
||||
- `trader_management`
|
||||
- `exchange_management`
|
||||
- `model_management`
|
||||
- `strategy_management`
|
||||
|
||||
Skill 定义的正式来源在:
|
||||
- [agent/skills/trader_management.json](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skills/trader_management.json)
|
||||
- [agent/skills/exchange_management.json](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skills/exchange_management.json)
|
||||
- [agent/skills/model_management.json](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skills/model_management.json)
|
||||
- [agent/skills/strategy_management.json](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skills/strategy_management.json)
|
||||
|
||||
---
|
||||
|
||||
## 7. 统一 skill 上下文:单一真源
|
||||
|
||||
之前的问题是:
|
||||
|
||||
- skill JSON 有一份简介
|
||||
- router prompt 又手写一份
|
||||
- workflow prompt 再手写一份
|
||||
- classifier / extraction 又各有自己的上下文说明
|
||||
|
||||
这会导致不同层看到的 skill 描述不一致。
|
||||
|
||||
现在已经收成统一 helper:
|
||||
- [skill_registry.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skill_registry.go)
|
||||
|
||||
关键函数:
|
||||
|
||||
- `buildSkillDefinitionSummary`
|
||||
- `buildSkillDependencySummary`
|
||||
- `buildSkillForbiddenSummary`
|
||||
- `buildManagementSkillContext`
|
||||
|
||||
### 7.1 buildManagementSkillContext
|
||||
|
||||
这是现在 management skill 上下文的统一入口。
|
||||
|
||||
它输出两类信息:
|
||||
|
||||
1. 四个 management skill 的简要说明
|
||||
2. 四个 management skill 的负向约束
|
||||
3. 当前 active skill 的依赖说明
|
||||
|
||||
例如对于 `trader_management:create`,它现在会明确告诉模型:
|
||||
|
||||
- 创建 trader 依赖已启用交易所
|
||||
- 依赖已启用模型
|
||||
- 依赖可用策略
|
||||
- 修复这些依赖时,仍属于 trader create 的主流程
|
||||
|
||||
同时它也会告诉模型一些“不能做什么”的边界,例如:
|
||||
|
||||
- `model_management` 不负责测试连接和诊断上游错误
|
||||
- `exchange_management` 不负责行情和交易执行
|
||||
- `strategy_management` 只负责模板管理,不负责直接运行
|
||||
|
||||
### 7.2 已接入的层
|
||||
|
||||
这个统一 helper 现在已经接入:
|
||||
|
||||
- [llm_skill_router.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/llm_skill_router.go:39)
|
||||
- [workflow.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/workflow.go:569)
|
||||
- [llm_flow_extractor.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/llm_flow_extractor.go:73)
|
||||
- [planner_runtime.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/planner_runtime.go:2010)
|
||||
- [planner_runtime.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/planner_runtime.go:2951)
|
||||
|
||||
也就是说,现在 router、workflow、classifier、extraction、planner 使用的是同一套 management skill 说明。
|
||||
|
||||
---
|
||||
|
||||
## 7.3 语义就绪检查
|
||||
|
||||
仅仅把消息路由到某个 skill 还不够,还要判断这条消息在“语义上是否已经准备好进入执行层”。
|
||||
|
||||
这层现在在:
|
||||
- [skill_semantic_gate.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skill_semantic_gate.go)
|
||||
|
||||
关键点:
|
||||
|
||||
- `evaluateHardSkillCandidate`
|
||||
- `semanticReadinessMissingSlots`
|
||||
- `skillSemanticReadinessSummary`
|
||||
|
||||
设计目标是:
|
||||
|
||||
- 如果 LLM/规则已经判到某个 skill/action
|
||||
- 但当前消息还明显缺少核心必填字段
|
||||
- 就不要直接往 hard skill 执行层掉
|
||||
|
||||
例如:
|
||||
|
||||
- 用户说“帮我新建一个模型配置”
|
||||
- 但还没有 `provider / api_key / custom_model_name`
|
||||
|
||||
这时系统会优先把控制权交给 planner / ask_user,而不是直接返回程序式“缺字段”提示。
|
||||
|
||||
这样做的价值是:
|
||||
|
||||
- 减少生硬的 hard skill 报错
|
||||
- 让交互更像“LLM 正在推进表单”
|
||||
- 避免路由下坠到执行层后再回滚
|
||||
|
||||
---
|
||||
|
||||
## 8. Active flow 内部是怎么继续的
|
||||
|
||||
如果顶层判断是 `continue_active`,当前消息不会直接执行 tool,而是进入当前 flow 的续接过程。
|
||||
|
||||
进一步地,当前只要已经进入某个 active `skill:action`,系统会优先沿着当前 action 继续推进。
|
||||
旧的 `detectManagementAction / has*Patch / detect*Patch` 这类文本 heuristics 仍然保留,但已经更明确地退到:
|
||||
|
||||
1. 没有 active skill session 时,用于粗路由和兜底识别
|
||||
2. active skill session 内,只有在 session/patch 都无法给出结果时,才作为 fallback 参与判断
|
||||
|
||||
这保证了:
|
||||
|
||||
- 先尊重已经由 LLM 和状态机确定下来的当前 flow
|
||||
- 再在必要时使用旧 heuristics 补洞
|
||||
- 避免“已经在当前 skill 里了,却又被文本规则抢去改 action”的抖动
|
||||
|
||||
现在 active flow 的打断条件也更收紧了:
|
||||
|
||||
- 单纯在当前 flow 里提到 `model / exchange / strategy`
|
||||
- 或者在补依赖时顺带提到其他 domain 名词
|
||||
|
||||
不再默认视为“跳到新任务”。
|
||||
|
||||
只有当消息整体更像一个新的顶层请求时,跨 domain 提及才会触发中断和重新路由。
|
||||
|
||||
### 8.1 Skill session 续接
|
||||
|
||||
相关逻辑:
|
||||
- [planner_runtime.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/planner_runtime.go:1583)
|
||||
- [llm_flow_extractor.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/llm_flow_extractor.go:61)
|
||||
|
||||
主要分两步:
|
||||
|
||||
1. `classifySkillSessionIntentWithLLM`
|
||||
- 判断是继续、取消、打断还是闲聊
|
||||
2. `extractSkillSessionFieldsWithLLM`
|
||||
- 把这条消息抽成结构化字段
|
||||
|
||||
然后把结构化字段 merge 回当前 skill session。
|
||||
|
||||
### 8.1.1 对话驱动式 skill 收集
|
||||
|
||||
对于高价值的多轮 management flow,当前已经开始把“补槽”从代码猜测迁到 LLM 对话驱动器:
|
||||
- [llm_skill_conversation.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/llm_skill_conversation.go)
|
||||
|
||||
目前最先落地的是:
|
||||
- `trader_management:create`
|
||||
- `trader_management:update_bindings`
|
||||
- `trader_management:configure_strategy`
|
||||
- `trader_management:configure_exchange`
|
||||
- `trader_management:configure_model`
|
||||
- `model_management:update / update_status / update_endpoint / update_name`
|
||||
- `exchange_management:update / update_status / update_name`
|
||||
- `strategy_management:update / update_name / update_prompt / update_config / activate / duplicate`
|
||||
|
||||
这层的设计目标不是“让代码先把用户的话拆碎”,而是:
|
||||
|
||||
1. 先由 LLM 理解当前这句话在当前 flow 里到底是什么意思
|
||||
2. 再按需披露当前 `skill:action` 的规则书
|
||||
3. 再按当前缺失槽位,动态注入最相关的资源列表
|
||||
4. 最后由代码校验结果并落地执行
|
||||
|
||||
当前 `llmSkillConversationDriver` 会显式拿到:
|
||||
|
||||
- 当前 active `skill:action` 的 contract
|
||||
- 当前已收集字段
|
||||
- 当前缺失槽位
|
||||
- 最近一轮对话
|
||||
- 只和当前缺失槽位相关的资源列表(例如只缺 `model` 时,只注入模型列表)
|
||||
|
||||
它返回的核心结果是:
|
||||
|
||||
- `ready`
|
||||
- `question`
|
||||
- `extracted`
|
||||
- `needs_clarification`
|
||||
- `cancel`
|
||||
|
||||
也就是说,现在 active skill 内部已经开始从:
|
||||
|
||||
- `代码先猜字段`
|
||||
- `模型后补救`
|
||||
|
||||
迁移到:
|
||||
|
||||
- `模型先理解当前回答的语义`
|
||||
- `代码只做 guardrail 与执行`
|
||||
|
||||
进一步地,执行层现在也开始优先消费 `skillSession` 里已经由 LLM 提取好的字段和目标对象。
|
||||
只有当 session 中还没有对应值时,才会退回到旧的文本解析 fallback。
|
||||
|
||||
更具体地说,当前高频 management update 动作的执行顺序已经开始统一成:
|
||||
|
||||
1. 先消费 `session` 中已经由 LLM 提取好的字段/patch
|
||||
2. 若 `session` 仍为空,再看当前整句是否能直接形成结构化 patch
|
||||
3. 只有前两步都失败时,才退回到 `update_field + 单字段值` 这类旧文本猜测
|
||||
|
||||
这意味着旧的 `detect... / parse... / pick...` 路径仍然存在,但已经逐步退到真正的兜底层。
|
||||
|
||||
### 8.1.2 按需资源披露
|
||||
|
||||
对话驱动器不会每轮都把用户所有模型、交易所、策略全量塞进 Prompt。
|
||||
|
||||
现在这层已经改成:
|
||||
|
||||
- 缺 `exchange` 才查并注入交易所列表
|
||||
- 缺 `model` 才查并注入模型列表
|
||||
- 缺 `strategy` 才查并注入策略列表
|
||||
- 某个槽位填完后,下一轮立即把对应资源列表从 Prompt 中移除
|
||||
|
||||
这就是“按需喂饭(Just-In-Time Context Injection)”:
|
||||
|
||||
- 节省 token
|
||||
- 降低延迟
|
||||
- 避免注意力稀释
|
||||
- 减少无关资源对当前推理的干扰
|
||||
|
||||
### 8.2 Execution state 到 skill session 的桥接
|
||||
|
||||
如果当前是 planner / execution waiting 状态,会尝试桥接成 skill session:
|
||||
- [planner_runtime.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/planner_runtime.go:1211)
|
||||
|
||||
这解决的是:
|
||||
|
||||
- planner 已经问到一半
|
||||
- 用户回复了字段
|
||||
- 但后续 hard skill 执行时又像“没收到”
|
||||
|
||||
现在系统已经能把 execution waiting 中收集到的信息投影回 skill session。
|
||||
|
||||
### 8.3 子任务成功后的父任务回流
|
||||
|
||||
现在快照不只是“可恢复存档”,还带有父任务信息。
|
||||
|
||||
相关结构在:
|
||||
- [execution_state.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/execution_state.go)
|
||||
|
||||
新增字段包括:
|
||||
|
||||
- `intent_id`
|
||||
- `parent_intent_id`
|
||||
- `resume_on_success`
|
||||
- `resume_triggers`
|
||||
|
||||
构建点在:
|
||||
- [planner_runtime.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/planner_runtime.go:2214)
|
||||
|
||||
执行成功后的回流点在:
|
||||
- [skill_dispatcher.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skill_dispatcher.go)
|
||||
|
||||
这解决的是:
|
||||
|
||||
- 用户本来在 `trader_management:create`
|
||||
- 中途去启用一个被禁用的交易所或模型
|
||||
- 子任务成功后,系统不再“断片”
|
||||
- 会自动恢复父任务上下文,并继续提示主流程剩余缺失项
|
||||
|
||||
因此现在的 suspended snapshot 已更接近“带返回指针的任务栈”。
|
||||
|
||||
### 8.4 取消时的任务栈回溯清理
|
||||
|
||||
如果用户在子任务中途说:
|
||||
|
||||
- `算了`
|
||||
- `不改了`
|
||||
- `换话题`
|
||||
|
||||
系统现在不会只取消当前子任务就结束,而是会检查栈里是否还有父任务挂起。
|
||||
|
||||
如果存在父任务,会明确追问:
|
||||
|
||||
- 当前子任务已经取消
|
||||
- 之前的父任务是否还要继续
|
||||
- 或者是否“一并取消”
|
||||
|
||||
这样做是为了防止:
|
||||
|
||||
- 父任务长期挂在栈底
|
||||
- 子任务被取消后无人接管
|
||||
- 最终形成僵尸任务和状态堆积
|
||||
|
||||
---
|
||||
|
||||
## 9. Trader create 为什么特殊重要
|
||||
|
||||
`trader_management:create` 是当前最复杂的 management flow 之一,因为它天然依赖另外三个 skill 的资源状态:
|
||||
|
||||
- exchange
|
||||
- model
|
||||
- strategy
|
||||
|
||||
因此它不是一个封闭 skill,而是一个“父 skill”。
|
||||
|
||||
用户在创建交易员时说:
|
||||
|
||||
- 启用某个交易所
|
||||
- 换一个模型
|
||||
- 使用现有策略
|
||||
|
||||
这些都不应该默认被理解成新的平级 top-level 任务,而应优先理解成:
|
||||
|
||||
- 为 `trader create` 补齐依赖
|
||||
- 然后继续主流程
|
||||
|
||||
目前这一层的 prompt 级理解已经通过统一 skill dependency summary 接入,但执行层的“修复依赖后自动回流主流程”还需要继续补强。
|
||||
|
||||
---
|
||||
|
||||
## 10. 名称和 ID 的连接
|
||||
|
||||
用户说的是自然语言名称,比如:
|
||||
|
||||
- `test`
|
||||
- `DeepSeek AI`
|
||||
- `高频做空策略`
|
||||
- `白开水`
|
||||
|
||||
执行层需要的是稳定 ID。
|
||||
|
||||
当前这层连接主要做在:
|
||||
- [skill_dispatcher.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skill_dispatcher.go)
|
||||
|
||||
核心函数:
|
||||
|
||||
- `hydrateCreateTraderSlotReferences`
|
||||
- `findOptionByIDOrName`
|
||||
|
||||
设计原则是:
|
||||
|
||||
1. 用户层允许说名字
|
||||
2. 系统尽快解析出唯一对象
|
||||
3. 一旦唯一,就落成真实 ID
|
||||
4. 展示给用户时仍然优先显示友好名字
|
||||
|
||||
这解决的是“确认文案看起来正确,但真正执行又说缺字段”的问题。
|
||||
|
||||
### 10.1 歧义引用澄清
|
||||
|
||||
除了“名字映射到 ID”,系统现在也开始处理“多个候选对象同名或近似”的情况。
|
||||
|
||||
相关逻辑在:
|
||||
|
||||
- [skill_dispatcher.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skill_dispatcher.go)
|
||||
- [skill_management_handlers.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skill_management_handlers.go)
|
||||
|
||||
核心做法是:
|
||||
|
||||
1. 若唯一命中,直接解析成 ID
|
||||
2. 若多个候选同时命中,不再静默选择
|
||||
3. 统一返回澄清问题,让用户明确要操作哪一个对象
|
||||
|
||||
这比“猜一个”更安全,也避免了对象误绑。
|
||||
|
||||
---
|
||||
|
||||
## 10.2 用户级串行化
|
||||
|
||||
同一个用户可能在网络卡顿或前端重发的情况下,几乎同时发出两条修改消息。
|
||||
|
||||
为了避免:
|
||||
|
||||
- 两条消息并发进入同一个 active flow
|
||||
- extraction 结果交叉 merge
|
||||
- `skillSession` / `ExecutionState` 变成缝合状态
|
||||
|
||||
现在 `thinkAndAct` 和 `thinkAndActStream` 已经在用户维度上做了串行化处理。
|
||||
|
||||
也就是说:
|
||||
|
||||
- 同一个 `userID`
|
||||
- 任意时刻只允许一条主消息进入 flow merge/execute 链路
|
||||
|
||||
这比只在单个 `save*` 调用上加锁更有效,因为它保护的是整条“读状态 -> 理解 -> merge -> 执行 -> 写状态”的事务链。
|
||||
|
||||
---
|
||||
|
||||
## 11. Tool 层约束
|
||||
|
||||
之前一个根问题是:上层像是“创建成功”了,但底层实际上没拿到完整必填字段。
|
||||
|
||||
现在部分 create 约束已经下沉到 tool 层:
|
||||
- [tools.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/tools.go)
|
||||
|
||||
当前明确加了必填约束的包括:
|
||||
|
||||
- `model_management:create`
|
||||
- `exchange_management:create`
|
||||
|
||||
这意味着:
|
||||
|
||||
- 不再只靠上层 prompt 判断“够不够建”
|
||||
- tool 自己也会拒绝缺关键字段的 create
|
||||
|
||||
这能防止“草稿像成功了,但对象其实是半残”的情况。
|
||||
|
||||
### 11.1 Tool 层安全硬隔离
|
||||
|
||||
安全不能只靠 Prompt。
|
||||
|
||||
因此现在 Tool 层已经补了两类后端硬边界:
|
||||
|
||||
1. 敏感凭证永不明文返回
|
||||
说明:
|
||||
- `toolGetModelConfigs`
|
||||
- `toolGetExchangeConfigs`
|
||||
- 以及对应 create / update 响应
|
||||
|
||||
都会先走安全视图,再做一层递归敏感字段剥离。
|
||||
也就是说,像 `api_key`、`secret_key`、`passphrase`、私钥这类字段,不会因为 LLM 被注入而通过 Tool 明文吐回去。
|
||||
|
||||
系统只允许返回类似:
|
||||
|
||||
- `has_api_key`
|
||||
- `has_secret_key`
|
||||
- `has_passphrase`
|
||||
|
||||
这种布尔存在性信息。
|
||||
|
||||
2. 交易执行必须通过会话级授权
|
||||
说明:
|
||||
- `execute_trade` 不再只靠“模型说要下单”就能执行
|
||||
- Tool 层现在会检查当前请求上下文里的会话权限
|
||||
- 没有交易执行权限的 session,会被后端直接拒绝
|
||||
|
||||
这意味着即使 Prompt 被注入,模型生成了合法的 `execute_trade` 调用,只要当前 token/session 没有对应权限,后端仍然不会执行。
|
||||
|
||||
当前实现上,这条边界先采用:
|
||||
|
||||
- 已认证会话
|
||||
- 明确的 session policy
|
||||
- 服务端 `AllowTradeExecution` 开关
|
||||
|
||||
的组合约束。
|
||||
|
||||
也就是说,真正的安全边界现在开始下沉到了 Tool / Session / Server Policy,而不是停留在提示词层。
|
||||
|
||||
---
|
||||
|
||||
## 11.1 Planner 的多槽补齐策略
|
||||
|
||||
语义就绪检查把“准备不足”的请求挡回 planner 后,如果 planner 还是一轮只问一个槽位,用户体验会很差。
|
||||
|
||||
因此现在 planner prompt 已经明确被要求:
|
||||
|
||||
- 优先一次性询问多个核心缺失字段
|
||||
- 在安全且常见的场景下,可以同时提出合理默认值
|
||||
|
||||
目标不是简单的“防止 hard skill 报错”,而是:
|
||||
|
||||
- 让补槽更像一次有组织的表单引导
|
||||
- 减少挤牙膏式的一问一答
|
||||
|
||||
---
|
||||
|
||||
## 12. 为什么要保留 planner、workflow、hard skill 三层
|
||||
|
||||
当前不是所有请求都应该直接落到 hard skill。
|
||||
|
||||
### 12.1 Hard skill
|
||||
|
||||
适合:
|
||||
|
||||
- 结构明确
|
||||
- skill 明确
|
||||
- action 明确
|
||||
- 必填足够
|
||||
|
||||
### 12.2 Workflow
|
||||
|
||||
适合:
|
||||
|
||||
- 多个 management action 串联
|
||||
- 存在依赖关系
|
||||
|
||||
### 12.3 Planner
|
||||
|
||||
适合:
|
||||
|
||||
- 开放式目标
|
||||
- 需要先探索当前状态
|
||||
- 结构还不够稳定
|
||||
|
||||
当前的设计方向是:
|
||||
|
||||
- LLM 先判断当前在和哪个上下文说话
|
||||
- 再决定 route
|
||||
- 再进入 skill / workflow / planner
|
||||
|
||||
而不是一开始就靠 hard skill 猜。
|
||||
|
||||
### 12.4 Planner 的人格与职责
|
||||
|
||||
Planner 现在不只是“拆步骤”的模块,也共享了同一份 `NOFXi` 顾问式系统前缀。
|
||||
|
||||
这意味着 Planner 在生成计划时,会优先遵守这些原则:
|
||||
|
||||
- 先保证配置正确、安全、逻辑一致
|
||||
- 先做状态诊断,而不是机械执行
|
||||
- 缺信息时,优先组织更像顾问的多槽追问和默认值建议
|
||||
|
||||
因此 Planner 现在承担的是:
|
||||
|
||||
- 任务澄清
|
||||
- 风险控制
|
||||
- 配置诊断
|
||||
- 计划生成
|
||||
|
||||
这也是为什么统一语义网关和 Planner 必须共用同一份系统前缀。
|
||||
|
||||
---
|
||||
|
||||
## 13. 前端聊天页的运行形态
|
||||
|
||||
前端聊天页之前的问题是:
|
||||
|
||||
- 切页就 abort 流式请求
|
||||
- 正在生成的消息会消失
|
||||
|
||||
现在这部分已经调整成:
|
||||
|
||||
- 流式回复由更全局的 runtime/store 托管
|
||||
- 站内切页不会立刻中断流
|
||||
- 已生成内容会保留
|
||||
|
||||
这让 Agent 更接近“后台持续回复”,而不是“仅页面内临时回复”。
|
||||
|
||||
---
|
||||
|
||||
## 14. 这套结构是怎么一步步收出来的
|
||||
|
||||
当前架构不是一次性设计出来的,而是沿着这些问题逐步收口:
|
||||
|
||||
### 阶段 1:先把快照恢复链打通
|
||||
|
||||
目标:
|
||||
|
||||
- 挂起任务可恢复
|
||||
- `target_snapshot_id` 真能驱动恢复
|
||||
|
||||
结果:
|
||||
|
||||
- router、flow extraction、runtime 都开始理解 snapshot
|
||||
|
||||
### 阶段 2:把状态续接和全局路由收成统一语义网关
|
||||
|
||||
目标:
|
||||
|
||||
- 不再一层判断“是不是当前流程”,另一层再重新猜一遍
|
||||
|
||||
结果:
|
||||
|
||||
- 先做 `continue_active / resume_snapshot / start_new / cancel / instant_reply`
|
||||
- 再进入具体执行层
|
||||
|
||||
### 阶段 3:让 CurrentReferences 真正成为“参考书”
|
||||
|
||||
目标:
|
||||
|
||||
- 当前对象不能只是埋在 JSON 里
|
||||
- 要显式进入 prompt 决策
|
||||
|
||||
结果:
|
||||
|
||||
- router、planner、classifier、extraction 都看当前引用对象
|
||||
|
||||
### 阶段 4:把 skill 说明和依赖说明收成单一真源
|
||||
|
||||
目标:
|
||||
|
||||
- 不再在每层 prompt 写一份不同的 skill 描述
|
||||
|
||||
结果:
|
||||
|
||||
- `buildManagementSkillContext` 成为统一入口
|
||||
|
||||
### 阶段 5:把名字和 ID 连接起来
|
||||
|
||||
目标:
|
||||
|
||||
- 用户交互说名字
|
||||
- 系统执行用 ID
|
||||
|
||||
结果:
|
||||
|
||||
- draft -> resolved object -> ID 的链路更稳
|
||||
|
||||
---
|
||||
|
||||
## 15. 当前已经验证过的方向
|
||||
|
||||
当前已经补过定向测试的方向包括:
|
||||
|
||||
- 顶层 router prompt 包含 management skill summary
|
||||
- 顶层 router / one-pass gateway / planner prompt 共享顾问式系统前缀
|
||||
- 顶层/flow prompt 包含 management skill negative constraints
|
||||
- 顶层 router prompt 包含 current reference summary
|
||||
- active flow extraction prompt 包含 suspended snapshots
|
||||
- `trader create` 的依赖说明进入统一 skill context
|
||||
- semantic readiness 会把未准备好的 create 请求挡回 planner
|
||||
- Tool 层不会明文返回配置秘钥,只返回存在性标记
|
||||
- `execute_trade` 必须通过会话级授权和服务端开关
|
||||
- 子任务成功后会自动恢复父任务上下文
|
||||
- 名称歧义会触发澄清,而不是静默命中
|
||||
- execution waiting state 能桥接回 skill session
|
||||
- persistent reference memory 在 execution state 清掉后仍能命中当前对象
|
||||
- `model/exchange` create 的 tool 必填约束生效
|
||||
|
||||
相关测试文件主要包括:
|
||||
|
||||
- [llm_intent_router_test.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/llm_intent_router_test.go)
|
||||
- [skill_dispatcher_test.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skill_dispatcher_test.go)
|
||||
- [skill_registry_test.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skill_registry_test.go)
|
||||
- [config_tools_test.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/config_tools_test.go)
|
||||
|
||||
另外,仓库里现在已经有一套“AI 对练”种子回放骨架:
|
||||
|
||||
- [self_play_replay_test.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/self_play_replay_test.go)
|
||||
- [agent_self_play_seed.zh-CN.json](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/docs/qa/fixtures/agent_self_play_seed.zh-CN.json)
|
||||
- [AGENT_AI_SELF_PLAY.zh-CN.md](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/docs/qa/AGENT_AI_SELF_PLAY.zh-CN.md)
|
||||
|
||||
它的用途是:
|
||||
|
||||
- 让代码助手或大模型根据产品说明生成极端对话场景
|
||||
- 把这些场景写成 JSON fixture
|
||||
- 用统一回放器批量喂给 `thinkAndAct`
|
||||
- 再把暴露的问题沉淀为:
|
||||
- Skill JSON 说明
|
||||
- Validator / Resolver / Readiness Gate
|
||||
- 按需上下文注入规则
|
||||
|
||||
---
|
||||
|
||||
## 16. 当前仍需要继续收的点
|
||||
|
||||
虽然主链已经比之前完整很多,但还有几块需要继续收:
|
||||
|
||||
1. `configure_strategy / configure_exchange / configure_model` 这类 action 的语义落地
|
||||
说明:
|
||||
这些已经在动作语义上更清晰,但要继续让 LLM 和执行层稳定对齐。
|
||||
|
||||
2. 更完整的 create 约束下沉
|
||||
说明:
|
||||
`strategy / trader` 的部分约束还可以继续更严格地下沉到执行层和 tool 层。
|
||||
|
||||
3. 更完整的跨 skill 依赖图
|
||||
说明:
|
||||
现在重点收了 `trader create` 的依赖图,未来可以继续扩展到其他多 skill 依赖场景。
|
||||
|
||||
4. 歧义消除的 LLM 参与度
|
||||
说明:
|
||||
当前歧义澄清、活性校验、父任务回溯已经有了规则级保护;后续可以继续让 LLM 参与“如何问得更自然、如何结合上下文缩小候选范围”。
|
||||
|
||||
5. 更细粒度的事务型状态版本控制
|
||||
说明:
|
||||
当前已经做了用户级串行化,足以挡住同一用户的大部分并发污染;后续如果要支持更复杂的多端并发或后台异步写入,可以继续升级成显式版本号或乐观锁。
|
||||
|
||||
---
|
||||
|
||||
## 17. 一句话总结
|
||||
|
||||
当前 NOFXi Agent 已经从“多个局部 if-else 叠起来的 chat handler”,逐步收成了一套:
|
||||
|
||||
- 统一语义网关
|
||||
- 快照恢复
|
||||
- 当前对象引用记忆
|
||||
- 单一真源 skill context
|
||||
- skill/workflow/planner 分层执行
|
||||
|
||||
的任务型 Agent 架构。
|
||||
|
||||
它现在最核心的设计原则是:
|
||||
|
||||
- 先判断用户在和哪个上下文说话
|
||||
- 再判断在当前上下文里要做什么
|
||||
- 再把自然语言解析成结构化状态
|
||||
- 最后由对应 skill/workflow/tool 去安全执行
|
||||
272
docs/qa/AGENT_SKILL_ACCEPTANCE_CHECKLIST.zh-CN.md
Normal file
272
docs/qa/AGENT_SKILL_ACCEPTANCE_CHECKLIST.zh-CN.md
Normal file
@@ -0,0 +1,272 @@
|
||||
# Agent 4 Skill 验收清单
|
||||
|
||||
本文档用于验收 Agent 对 4 个管理类 skill 的字段认知、工具调用和用户可见行为是否与页面编辑能力对齐。
|
||||
|
||||
当前范围:
|
||||
- `model_management`
|
||||
- `exchange_management`
|
||||
- `trader_management`
|
||||
- `strategy_management`
|
||||
|
||||
验收目标:
|
||||
- 页面上能手动改的核心字段,Agent 也能稳定改
|
||||
- Agent 能回答页面上可见的字段与选项
|
||||
- 模糊请求不会被硬塞进错误 skill
|
||||
- 多字段一句话更新时,不会被窄动作截断
|
||||
|
||||
## 0. 前置条件
|
||||
|
||||
- 已完成登录
|
||||
- 后端已启动
|
||||
- 至少准备 1 条可编辑的模型、交易所、交易员、策略数据
|
||||
- 测试前如果有旧上下文,先在 Agent 会话里执行 `/clear`
|
||||
|
||||
建议先跑自动化回归:
|
||||
|
||||
```bash
|
||||
go test ./agent -run 'Test(ManageModelToolSchemaExposesEditableFields|ManageExchangeToolSchemaExposesEditableFields|ManageTraderToolSchemaExposesAdvancedFields|ManageStrategyToolSchemaExposesFieldLevelConfig|ModelManagementManualEditableFieldsAreCoveredByAgent|ExchangeManagementManualEditableFieldsAreCoveredByAgent|TraderManagementManualEditableFieldsAreCoveredByAgent|StrategyManagementManualEditableFieldsAreCoveredByAgent|ExchangeManagementUpdateSupportsManualFields|ModelManagementThinkAndActSupportsCompositeFieldUpdates|TraderManagementUpdateSupportsAdvancedManualFields|StrategyManagementThinkAndActSupportsGridAndRiskFields)'
|
||||
```
|
||||
|
||||
对应测试主要在:
|
||||
- [skill_dispatcher_test.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/skill_dispatcher_test.go)
|
||||
- [config_tools_test.go](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/agent/config_tools_test.go)
|
||||
|
||||
## 1. 自动化覆盖基线
|
||||
|
||||
通过以下检查后,才进入手工验收:
|
||||
|
||||
- [ ] 4 个 skill 的 tool schema 已暴露字段级参数
|
||||
- [ ] 4 个 skill 的 manual editable field 集合都被 agent 字段目录覆盖
|
||||
- [ ] `model` 支持一句话同时改 `enabled + custom_api_url + custom_model_name`
|
||||
- [ ] `exchange` 支持一句话同时改 `account_name + hyperliquid_wallet_addr + testnet`
|
||||
- [ ] `trader` 支持高级字段更新
|
||||
- [ ] `strategy` 支持 grid/risk 多字段更新
|
||||
|
||||
## 2. Model Skill
|
||||
|
||||
页面参考:
|
||||
- [ModelConfigModal.tsx](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/web/src/components/trader/ModelConfigModal.tsx)
|
||||
|
||||
核心字段:
|
||||
- `provider`
|
||||
- `name`
|
||||
- `api_key`
|
||||
- `custom_api_url`
|
||||
- `custom_model_name`
|
||||
- `enabled`
|
||||
|
||||
手工验收:
|
||||
|
||||
- [ ] 说“列出我的模型配置”时,能列出当前模型
|
||||
- [ ] 说“这个模型的接口地址改成 xxx,模型名称改成 yyy,并且禁用”时,能一次成功更新
|
||||
- [ ] 说“这个模型有哪些字段能改”时,回答至少覆盖 `API Key / 接口地址 / 模型名称 / 启用状态`
|
||||
- [ ] 说“把这个模型启用”时,不会误触发重命名流程
|
||||
- [ ] 说“把这个模型改成最好的”这类抽象诉求时,不应硬造字段值;应该解释或引导
|
||||
|
||||
通过标准:
|
||||
- 回复文本明确说明已更新模型配置
|
||||
- 页面刷新后字段真实变化
|
||||
- 不出现“我还需要你明确要操作哪个对象”这种错误兜底
|
||||
|
||||
## 3. Exchange Skill
|
||||
|
||||
页面参考:
|
||||
- [ExchangeConfigModal.tsx](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/web/src/components/trader/ExchangeConfigModal.tsx)
|
||||
|
||||
核心字段:
|
||||
- 公共字段:
|
||||
- `exchange_type`
|
||||
- `account_name`
|
||||
- `enabled`
|
||||
- `testnet`
|
||||
- CEX:
|
||||
- `api_key`
|
||||
- `secret_key`
|
||||
- `passphrase`
|
||||
- Hyperliquid:
|
||||
- `api_key`
|
||||
- `hyperliquid_wallet_addr`
|
||||
- Aster:
|
||||
- `aster_user`
|
||||
- `aster_signer`
|
||||
- `aster_private_key`
|
||||
- Lighter:
|
||||
- `lighter_wallet_addr`
|
||||
- `lighter_api_key_private_key`
|
||||
- `lighter_api_key_index`
|
||||
|
||||
手工验收:
|
||||
|
||||
- [ ] 说“把 Dex 的账户名改成 Dex Pro,Hyperliquid 钱包改成 0xabc,testnet 打开”时,能一次成功更新
|
||||
- [ ] 说“这个交易所有哪些字段能改”时,能按当前交易所类型回答差异字段
|
||||
- [ ] 说“把这个交易所禁用”时,不会误进入改名分支
|
||||
- [ ] 说“列出我的交易所配置”时,能读出当前配置
|
||||
- [ ] 对缺少必填凭证的创建请求,会明确指出缺哪一项,而不是模糊失败
|
||||
|
||||
通过标准:
|
||||
- 回复文本明确说明已更新交易所配置
|
||||
- 页面刷新后对应字段真实变化
|
||||
- 不因为对象解析失败而掉到“请明确对象”
|
||||
|
||||
## 4. Trader Skill
|
||||
|
||||
页面参考:
|
||||
- [TraderConfigModal.tsx](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/web/src/components/trader/TraderConfigModal.tsx)
|
||||
|
||||
页面核心字段:
|
||||
- `name`
|
||||
- `ai_model_id`
|
||||
- `exchange_id`
|
||||
- `strategy_id`
|
||||
- `is_cross_margin`
|
||||
- `show_in_competition`
|
||||
- `scan_interval_minutes`
|
||||
- `initial_balance`
|
||||
|
||||
Agent 扩展字段:
|
||||
- `btc_eth_leverage`
|
||||
- `altcoin_leverage`
|
||||
- `trading_symbols`
|
||||
- `custom_prompt`
|
||||
- `override_base_prompt`
|
||||
- `system_prompt_template`
|
||||
- `use_ai500`
|
||||
- `use_oi_top`
|
||||
|
||||
手工验收:
|
||||
|
||||
- [ ] 说“把交易员 A 切换到策略 B,扫描间隔改成 8 分钟,全仓关闭,竞技场显示关闭”时,能一次成功更新
|
||||
- [ ] 说“把高级交易员的 BTC/ETH 杠杆改成 8,山寨币杠杆改成 4,交易对改成 BTC、ETH,自定义 prompt 改成 xxx,启用 AI500”时,能成功更新
|
||||
- [ ] 说“这个交易员有哪些字段能改”时,至少能回答页面核心字段和 Agent 扩展字段
|
||||
- [ ] 说“启动这个交易员”时,仍会保留高风险确认链路
|
||||
- [ ] 说“为什么我的交易员不交易”时,仍能走诊断 skill,不会被错误识别成 update
|
||||
|
||||
通过标准:
|
||||
- 回复文本明确说明更新了交易员配置或绑定
|
||||
- 页面刷新或查询结果能看到真实变化
|
||||
- `交易对` 提取不会误吞后半句自然语言
|
||||
|
||||
## 5. Strategy Skill
|
||||
|
||||
页面参考:
|
||||
- [StrategyStudioPage.tsx](/Users/zheweifang/Desktop/Nofx2/nofxi-dev/web/src/pages/StrategyStudioPage.tsx)
|
||||
|
||||
编辑器模块:
|
||||
- `grid_config`
|
||||
- `coin_source`
|
||||
- `indicators`
|
||||
- `risk_control`
|
||||
- `prompt_sections`
|
||||
- `custom_prompt`
|
||||
- `publish_settings`
|
||||
|
||||
重点字段:
|
||||
- 元信息:
|
||||
- `name`
|
||||
- `description`
|
||||
- `strategy_type`
|
||||
- `is_public`
|
||||
- `config_visible`
|
||||
- Grid:
|
||||
- `symbol`
|
||||
- `grid_count`
|
||||
- `total_investment`
|
||||
- `upper_price`
|
||||
- `lower_price`
|
||||
- `use_atr_bounds`
|
||||
- `atr_multiplier`
|
||||
- `distribution`
|
||||
- `enable_direction_adjust`
|
||||
- `direction_bias_ratio`
|
||||
- `max_drawdown_pct`
|
||||
- `stop_loss_pct`
|
||||
- `daily_loss_limit_pct`
|
||||
- `use_maker_only`
|
||||
- Coin source:
|
||||
- `source_type`
|
||||
- `static_coins`
|
||||
- `excluded_coins`
|
||||
- `use_ai500`
|
||||
- `ai500_limit`
|
||||
- `use_oi_top`
|
||||
- `oi_top_limit`
|
||||
- `use_oi_low`
|
||||
- `oi_low_limit`
|
||||
- Risk:
|
||||
- `max_positions`
|
||||
- `min_confidence`
|
||||
- `min_risk_reward_ratio`
|
||||
- `btceth_max_leverage`
|
||||
- `altcoin_max_leverage`
|
||||
- `btceth_max_position_value_ratio`
|
||||
- `altcoin_max_position_value_ratio`
|
||||
- `max_margin_usage`
|
||||
- `min_position_size`
|
||||
- Indicators / timeframe:
|
||||
- `primary_timeframe`
|
||||
- `primary_count`
|
||||
- `selected_timeframes`
|
||||
- `ema_periods`
|
||||
- `rsi_periods`
|
||||
- `atr_periods`
|
||||
- `boll_periods`
|
||||
- `enable_ema`
|
||||
- `enable_macd`
|
||||
- `enable_rsi`
|
||||
- `enable_atr`
|
||||
- `enable_boll`
|
||||
- `enable_volume`
|
||||
- `enable_oi`
|
||||
- `enable_funding_rate`
|
||||
- Prompt:
|
||||
- `role_definition`
|
||||
- `trading_frequency`
|
||||
- `entry_standards`
|
||||
- `decision_process`
|
||||
- `custom_prompt`
|
||||
|
||||
手工验收:
|
||||
|
||||
- [ ] 说“把策略 A 改成网格策略,网格数量改成 14,ATR 倍数改成 2.5,最大保证金使用率改成 0.6”时,能一次成功更新
|
||||
- [ ] 说“把选币来源改成静态,静态币改成 BTC、ETH,排除 DOGE,AI500 关闭”时,能成功更新
|
||||
- [ ] 说“选币来源有哪些”时,能回答当前面板的来源类型与相关选项,而不是重复草稿摘要
|
||||
- [ ] 说“这个策略里面的参数和 prompt 分别是什么样的”时,能走 explain/detail,不会误更新
|
||||
- [ ] 说“帮我创建一个不亏钱的策略”这类抽象请求时,不应直接强绑到字段创建;应该回退 planner 或引导细化
|
||||
|
||||
通过标准:
|
||||
- 回复文本明确说明已更新策略参数或进入合理引导
|
||||
- Strategy Studio 刷新后真实反映更新
|
||||
- 不会把开放式目标误当作已可执行的精确配置
|
||||
|
||||
## 6. 跨 Skill 语义验收
|
||||
|
||||
- [ ] 模糊输入先过统一语义网关,再决定 `continue_active / resume_snapshot / start_new`
|
||||
- [ ] 一个 skill 进行中时,问页面字段选项,优先走 explain,不要硬落 execute
|
||||
- [ ] 开放式目标型请求在参数不足时,优先回 planner,不要强行进 hard skill
|
||||
- [ ] 同一句话改多个字段时,不会只改其中一个窄字段
|
||||
- [ ] `/clear` 后,旧的 skill session / workflow / execution state / snapshots 都被清空
|
||||
- [ ] 切回旧话题时,snapshot restore 能恢复到正确对象,而不是凭 heuristics 误接
|
||||
|
||||
## 7. 回归记录模板
|
||||
|
||||
每次验收建议记录:
|
||||
|
||||
- 日期:
|
||||
- 提交版本:
|
||||
- 后端 PID:
|
||||
- 前端地址:
|
||||
- 本轮执行人:
|
||||
|
||||
逐项记录:
|
||||
- 用例:
|
||||
- 用户原话:
|
||||
- 预期:
|
||||
- 实际:
|
||||
- 是否通过:
|
||||
- 备注:
|
||||
|
||||
## 8. 当前结论口径
|
||||
|
||||
当本文档第 1 节自动化基线和第 2-6 节核心手工项全部通过后,才建议对外宣称:
|
||||
|
||||
“Agent 对 4 个 skill 已基本对齐当前页面可编辑能力,并具备稳定的 explain / execute / planner fallback 行为。”
|
||||
38
docs/qa/fixtures/agent_self_play_seed.zh-CN.json
Normal file
38
docs/qa/fixtures/agent_self_play_seed.zh-CN.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"name": "trader_create_reports_all_missing_prereqs",
|
||||
"desc": "空白环境下创建交易员,应一次性报告所有必填槽位和依赖缺口。",
|
||||
"turns": [
|
||||
{
|
||||
"user": "帮我创建一个交易员",
|
||||
"want_all": ["名称", "交易所", "模型", "策略", "当前还没有可用交易所配置", "当前还没有可用模型配置", "当前还没有可用策略"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "strategy_update_risk_control_clamp_requires_acceptance",
|
||||
"desc": "策略参数越界时,应先给出风控收敛说明,再等待确认应用。",
|
||||
"setup": [
|
||||
{
|
||||
"tool": "manage_strategy",
|
||||
"args": {
|
||||
"action": "create",
|
||||
"name": "风险策略",
|
||||
"lang": "zh"
|
||||
}
|
||||
}
|
||||
],
|
||||
"turns": [
|
||||
{
|
||||
"user": "把风险策略的杠杆改成100",
|
||||
"want_any": ["手动面板允许的范围", "按风控范围收敛"]
|
||||
},
|
||||
{
|
||||
"user": "确认应用",
|
||||
"want_any": ["确认应用", "风控范围", "已更新策略参数"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user