# FWH Agent MCP:设计 > 状态:设计初稿,2026-10-24。基于 ToolBox master `a10cbda`、AgentServer `969a993`(ADR-0021 第三方 MCP 服务)。本文描述为新 AI 助手**新建**的 MCP Server(下称 Agent MCP),与旧助手的 `service/cmd/mcp` 无关:旧 MCP 保持现状继续服务 Kiro,新 MCP 不复用其工具代码。 ## 1. 定位 Agent MCP 是 FWH 业务数据的**无用户状态的工具服务**: - 只回答“数据是什么”,不知道、也不关心是谁在问。没有 `userId`、`sessionId` 参数,不按用户隔离数据,不记录调用人。 - 由 AgentServer 后台“MCP 服务”登记为远程 HTTP 服务(ADR-0021),经 MCP Gateway 转接给 Agent。Gateway 用固定请求头连接、多个会话共用连接,本来就不传会话信息,与“无用户”的定位一致。 - 谁能用、能用到什么程度,由 ToolBox 和 AgentServer 在上层控制:ToolBox 决定用户能否使用 AI 助手、创建会话时选用哪个 Profile;Profile 决定勾选哪些 MCP 服务;AgentServer 按工具策略决定是否审批。调用追溯走“ToolBox 会话归属 → AgentServer 审计(gateway_call 含参数)”,见 [technical-design.md](technical-design.md)。 ### 1.1 为什么不沿用旧 MCP | 旧 MCP 的做法 | 在新框架下的问题 | | --- | --- | | 工具参数里带 `userId`/`sessionId`,由模型填写(`storage_*`、反馈、批量下载 owner 等) | 身份不可信;新框架不传用户信息,参数失去意义 | | 大结果写到 `/tmp/fwh-toolbox-agent/results` 并返回本地路径 | AgentServer 的 Agent 在沙箱里,看不到这个目录 | | 文件经 MinIO `upload/`、`download/` 前缀与 Agent 交换 | 新框架的上传和产出都在 AgentServer 会话工作区 | | 222 个工具都没有声明 `readOnlyHint` | ADR-0021 默认策略下全部变成“跟随权限模式”,每次查询都弹审批;逐个手工设置也难以维护 | | 大量一对一包装接口和原始存储访问(`data_mongo_*`、`data_redis_*`、`data_pgsql_*`、Plane 全量接口) | 工具多、描述短,模型选错工具;原始访问的结果大、难控制 | | 只有 stdio | 只能作为本地进程接入;本地进程在 AgentServer 的 bwrap 沙箱中运行,要开放网络和读取 `.env`,不合适 | | 依赖 Kiro steering 中的路由表决定用哪个工具 | 新框架没有 steering,工具描述要能自解释 | ## 2. 设计原则 1. **无用户**:不接收、不推断调用人;写操作(若有)以固定的服务账号身份执行。 2. **任务粒度**:一个工具对应一个排查/分析动作(“查站点概况”“查一段时间的告警事件”),在服务端完成过滤、分页、聚合,而不是暴露底层接口或存储。 3. **结果小而明确**:默认返回紧凑结果并给出总数与是否截断;需要大量数据时用专门的导出工具,以文件形式交给 Agent(见第 5 节),不把明细塞进上下文。 4. **自解释**:工具描述写清用途、适用场景、参数格式、单位和返回字段;不依赖外部路由表。 5. **全部显式声明读写**:每个工具声明 `readOnlyHint`,由测试保证。 6. **读写分离部署**:只读工具与写工具放在两个 MCP 服务中(第 7 节),Profile 按需勾选,权限边界清晰。 ## 3. 框架 ### 3.1 位置与目录 放在 ToolBox 仓库,与主服务同一个 Go module,直接复用 `repositories`、`services`、`dto`、`config`。 ``` service/ cmd/agent-mcp/main.go 入口:读取配置、初始化基础设施、启动 HTTP 服务 agentmcp/ bootstrap.go 初始化 DB / Redis / MinIO / repositories / FWH API / Plane(与主服务相同的依赖,只取需要的部分) server.go NewServer(set):创建 MCPServer、挂中间件、按工具集注册 http.go Streamable HTTP(无状态)+ Bearer 鉴权 + /healthz kit/ tool.go 工具定义 Def[T]、注册函数 result.go 结果构造:Object / List / Table / Export,统一的截断与大小上限 errors.go UserError:给模型看的错误信息(参数不对、无数据、上游不可用) middleware.go 日志、panic 恢复、单次超时、并发上限 tools/ site.go alarm.go shutdown.go logs.go faultrecord.go tou.go sim.go emspara.go plane.go util.go readonly.go 只读工具集 ops.go 写工具集(第 7 节,二期) agentmcp_test.go 约束测试(第 3.5 节) utils/pii/ 从 cmd/mcp/tools/helper 的 pii_*.go 拷贝为独立包(旧 MCP 不改) ``` 同一个二进制,用参数选择工具集: ``` fwh-agent-mcp -set=readonly -listen=127.0.0.1:8091 # 只读服务 fwh-agent-mcp -set=ops -listen=127.0.0.1:8092 # 写服务(二期) ``` ### 3.2 工具定义 使用 mcp-go v1.4(`go.mod` 当前版本)的结构体生成参数 schema(`mcp.WithInputSchema[T]`)和类型化处理函数(`mcp.NewTypedToolHandler`),参数校验交给 `server.WithInputSchemaValidation()`: ```go // kit/tool.go type Def[T any] struct { Name string // <领域>_<动作>,小写下划线,≤ 40 字符 Title string // 中文短标题,审批卡片与后台显示 Description string // 用途、适用场景、返回字段与单位 ReadOnly bool Handler func(ctx context.Context, args T) (*mcp.CallToolResult, error) } func (d Def[T]) Register(s *server.MCPServer) { s.AddTool( mcp.NewTool(d.Name, mcp.WithDescription(d.Description), mcp.WithInputSchema[T](), mcp.WithTitleAnnotation(d.Title), mcp.WithReadOnlyHintAnnotation(d.ReadOnly), mcp.WithDestructiveHintAnnotation(d.Destructive), // 覆盖、删除类写操作为 true:自动模式下也每次审批 mcp.WithOpenWorldHintAnnotation(false), ), mcp.NewTypedToolHandler(func(ctx context.Context, _ mcp.CallToolRequest, args T) (*mcp.CallToolResult, error) { return d.Handler(ctx, args) }), ) } ``` 一个工具的写法: ```go // tools/alarm.go type alarmEventsArgs struct { SN string `json:"sn" jsonschema:"站点 SN(aGate 序列号)"` From string `json:"from" jsonschema:"开始时间,yyyy-MM-dd HH:mm:ss,站点当地时间"` To string `json:"to" jsonschema:"结束时间,同上;与开始时间相差不超过 31 天"` Kind string `json:"kind,omitempty" jsonschema:"alarm / event / all,默认 all"` Limit int `json:"limit,omitempty" jsonschema:"最多返回条数,1~500,默认 100"` } var AlarmEvents = kit.Def[alarmEventsArgs]{ Name: "alarm_events", Title: "查询站点告警/事件记录", Description: "查询单个站点在一段时间内的告警和事件记录,按时间倒序。用于排查某次故障前后发生了什么。" + "返回字段:time(站点当地时间)、code、name、level、device、status。超过 limit 时返回 truncated=true,请缩短时间范围。", ReadOnly: true, Handler: func(ctx context.Context, a alarmEventsArgs) (*mcp.CallToolResult, error) { from, to, err := kit.ParseRange(a.From, a.To, 31*24*time.Hour) if err != nil { return kit.Fail(err), nil } rows, err := repositories.QueryEventOrAlarmListOnTimeRange(a.SN, from, to, kindOf(a.Kind)) if err != nil { return kit.Upstream("FWH 平台", err), nil } return kit.List(mapAlarmRows(rows), kit.Limit(a.Limit, 100)), nil }, } ``` 处理函数只做三件事:校验与换算参数、调用 `repositories`/`services`、把上游数据映射成精简的行结构。字段映射集中写,丢弃对分析无用的字段,统一时间格式与单位。 schema 由 mcp-go 依赖的 `google/jsonschema-go` 生成:`jsonschema` 标签的内容就是字段描述(不支持 `key=value` 选项),没有 `omitempty` 的字段为必填。枚举、取值范围写进描述,并在处理函数中校验(`kit.Enum`、`kit.Limit` 等辅助函数);需要在 schema 中声明枚举、取值范围或数组长度时,用 `Def.Properties` 对生成的字段 schema 做补充(合并进对应字段,服务端按补充后的 schema 校验);Go 的切片字段默认生成可空类型(`null | array`),必填数组要用它改为 `array`。AgentServer 网关只接受 `type: object` 的 inputSchema,测试中要检查。 ### 3.3 结果构造 `kit/result.go` 提供统一的返回形式,所有工具都通过它返回: | 函数 | 用途 | 形式 | | --- | --- | --- | | `Object(v)` | 单个对象(站点概况、模版详情) | 紧凑 JSON(不缩进、省略空值) | | `List(rows, limit)` | 列表 | `{"total":N,"returned":n,"truncated":bool,"items":[...]}` | | `Table(cols, rows, limit)` | 行多、字段固定的数据 | 首行列名的 TSV 文本,比 JSON 省一半以上字符 | | `Export(name, csv)` | 导出工具(第 5 节) | `EmbeddedResource`(`text/csv`) | | `Fail(err)` / `Upstream(name, err)` | 错误 | `isError` + 一句中文说明 + 处理建议。`Upstream` 只返回数据源、错误类别与错误编号,原始错误(可能含内部地址、SQL)只写日志 | 统一限制:单次结果(非导出)不超过 30,000 字符;超过时按行截断并标明 `truncated`,附一句“请缩小范围或使用 xxx_export”。这样不会触发 AgentServer 的 10 万字截断(那条路径会把前 10 万字仍放进上下文)。 所有对象和行在序列化前经过 `utils/pii` 脱敏(规则沿用旧 MCP:用户姓名、电话、邮箱、详细地址等)。 ### 3.4 中间件与运行约束 - 日志:工具名、参数摘要(截断到 2KB)、耗时、结果大小、是否截断、错误;写入独立日志文件,不含调用人。 - 超时:单次调用默认 60 秒(导出工具 300 秒),超时返回 `Upstream` 错误。AgentServer 侧第三方工具超时为 10 分钟,不会先于 Agent MCP 超时。 - 并发:全局信号量(默认 8),保护 FWH 云平台与数据库;排队超过 30 秒返回“服务繁忙”。 - panic 恢复:返回“内部错误”,日志记录堆栈。 ### 3.5 约束测试 `agentmcp_test.go` 注册全部工具集后检查: - 名称匹配 `^[a-z][a-z0-9_]{2,39}$`,且全局唯一。AgentServer 中引擎侧完整名称为 `mcp__gateway__<服务名>__<工具名>`,服务名用 3~6 个字符(`fwh`、`fwhops`)时总长不超过 64; - 每个工具都有 `title`、非空中文描述,并显式声明 `readOnlyHint`;`readonly` 工具集中不得有 `readOnlyHint=false` 的工具,`ops` 工具集中不得有只读工具; - inputSchema 的 `type` 为 `object`; - `kit.List`、`kit.Table` 的截断与 30,000 字符上限。 各领域的映射函数(上游结构 → 精简行)配单测,用固定的上游 JSON 样本。 ## 4. 工具清单(一期,只读) 按领域组织,只读服务 45 个、写服务 7 个(工具数量超过接入指南建议的 20 个,全部完成后再统一考虑分组拆分)。“来源”列是复用的现有数据访问函数,实现时以代码为准。 | 领域 | 工具 | 说明 | 来源 | | --- | --- | --- | --- | | 站点 | `site_search` | 按关键字与条件(国家、州省、在线、激活、运行状态、联网方式、固件/协议版本、aGate 硬件、激活时间,全部为“且”)搜索站点,分页;关键字与包含匹配按字面值(转义正则) | `QuerySiteInfoDataList`、站点信息表 | | | `site_get` | 单站点概况:基本信息、版本、网络、工作模式、当前告警数 | `QuerySiteBaseInfoList`、`QuerySiteModeInfo`、`QuerySiteAlarmList` | | | `site_power_flow` | 单站点单日功率流(5 分钟粒度,`Table`) | `QuerySitePowerFlow` | | | `site_power_flow_export` | 单站点多日功率流导出(≤ 31 天,CSV) | 同上,按天循环 | | | `site_info_sync_status` | 站点信息表同步状态:最近一次同步的进度、请求/完成时间,最近一次成功同步的时间与站点数,是否需要重新同步的建议 | `GetSiteInfoUpdateNewRecord`、`GetSiteInfoUpdateLastComplete` | | 告警 | `alarm_current` | 站点当前告警列表 | `QuerySiteAlarmList` | | | `alarm_events` | 站点一段时间内的告警/事件记录 | `QueryEventOrAlarmListOnTimeRange` | | | `alarm_snapshot` | 站点某日的告警快照 | `QueryAlarmSnapshotInfo`、PG 快照数据 | | | `alarm_stats` | 全量站点的告警统计(按日期、国家汇总) | `QueryAlarmStatistics`、告警统计服务 | | | `alarm_sites_by_code` | 触发某告警码的站点列表 | `QueryAlarmStatisticsFromCode` | | 停机 | `shutdown_stats` | 某日停机统计汇总(不传日期取最新) | 停机统计服务 | | | `shutdown_sites` | 某日停机站点列表 | `QuerySiteShutdownList` | | 日志 | `mqtt_log_search` | 站点 MQTT 日志,按命令类型与时间范围 | `QueryMqttLogListOnTimeRange` | | | `ems_log_records` | EMS 日志召唤记录 | FWH Pro API | | | `update_log_system` | 系统升级记录;传记录 ID 时返回详情 | FWH Pro API | | | `update_log_ahub` | aHub 升级记录 | FWH Pro API | | 故障录波(直连设备) | `fault_record_devices` | 站点可做录波操作的设备(aGate、aPower-PE/MPPT、aHub) | `GetFaultRecordSiteDevices` | | | `fault_record_device_info` | 读取设备录波信息(故障总体信息、录波功能基本信息、录波总目录);长任务,经主服务 MQTT 收发 | `SubmitFaultRecordOperation`(device_info) | | | `fault_record_param_read` | 读取设备时间、录波开关;长任务 | 同上(param_read) | | | `fault_record_operations` / `fault_record_operation_get` | 操作记录、操作结果(逐项解析,不含原始报文) | `FaultRecordOperations` 集合 | | | `fault_record_data` | 解析录波文件:故障信息与波形概要(各通道 min、max、触发点值,不含逐点数据) | MinIO `fault-record/` | | | `fault_record_export` | 录波 CSV(zip,blob 资源) | 同上 | | 故障录波(云平台) | `cloud_fault_record_list` | 云平台故障录波日志列表 | FWH Pro API | | | `cloud_fault_record_detail` | 录波子记录 | FWH Pro API | | | `cloud_fault_record_callable` | 设备可召唤的录波列表 | FWH Pro API | | | `cloud_fault_record_call_history` | 录波召唤记录 | FWH Pro API | | MQTT 报文量 | `mqtt_traffic_trend` | 月总量与每日量(UTC) | iotcore-stat ES | | | `mqtt_traffic_sites` / `mqtt_traffic_site_cmd` | 某日站点报文量排行、站点命令类型分布 | 同上 | | | `mqtt_message_search` | 跨站点按命令类型、时间检索报文元数据 | 同上 | | 自动升级 | `auto_update_catalog` / `auto_update_config_get` | 升级目录;某 aGate 硬件类型的升级条件与步骤(附升级包标题) | 自动升级配置集合 | | 站点分析 | `site_analysis_list` / `site_analysis_timeline` / `site_analysis_export` | 页面创建的分析任务、时间线、结果 CSV(只读) | 站点分析集合 | | 调度 | `tou_template_list` | TOU 模版列表,`env=prod/test` | 调度配置服务 | | | `tou_template_get` | TOU 模版详情:按季节 × 日类型整理时段,附调度模式识别结果 | 同上 + 调度配置文档中的解析规则 | | SIM | `sim_get` | 按 ICCID 查询,自动判断平台(SmartHub / Acceleronix) | SIM 卡管理服务 | | | `sim_search` | 按状态、平台、关键字搜索 | 同上 | | | `sim_usage_monthly` | 单卡某月每日用量 | 同上 | | EMS 参数 | `ems_param_lookup` | 按 PID / VID 查询宏名与描述;`ids` 为十进制整数数组(0~65535,1~50 个,与快照 XID 的 `uint16` 编号一致),schema 中声明约束由服务端校验 | emspara | | Plane | `plane_issue_search` | 按关键字、状态、项目搜索工作项(只读) | Plane V1 | | | `plane_issue_get` | 工作项详情(含最近评论) | Plane V1 | | 工具 | `sn_parse` | 解析设备 SN 的含义(型号、产地、批次等) | 旧 `util_parse_sn` 的规则(拷贝) | 一期不提供: - 原始存储访问(Mongo / Redis / PG 任意查询)。确实需要时,二期增加限定集合、限定字段、只读账号、带行数上限的查询工具,或针对具体场景补任务级工具; - 批量下载、站点分析、站点监控配置等与 ToolBox 页面任务绑定的工具(它们的“任务属于谁”在无用户模型下没有意义); - 写工具(第 7 节)。 ## 5. 大数据与文件 ### 5.1 导出工具 需要明细分析的场景(多日功率流、长时间告警明细、批量 SIM 用量)用 `*_export` 工具:服务端分页拉齐数据,生成 CSV,以 `EmbeddedResource`(`text/csv`,URI 如 `fwh://export/site_power_flow/SN123_20261001_20261031.csv`)返回,同时附一段文本摘要(行数、列名、时间范围、前 5 行)。导出上限 20MB,超过时要求缩小范围。 ### 5.2 AgentServer 需要的小改动 ADR-0021 的结果处理(`mcp-gateway/server.ts` 的 `postProcess`)目前:超过 10 万字的文本保存到 `.agent/mcp/` 但前 10 万字仍放进上下文;`resource` 类型的内容原样交给引擎。为了让导出数据只落盘、不进上下文,建议在 AgentServer 增加一条通用规则: - **`resource` 内容一律保存到工作区 `.agent/mcp/`**(文件名取 URI 最后一段,`blob` 解码为二进制,`text` 原样写入),在结果中替换为“已保存到 `<路径>`(大小、MIME)”,不内联内容。 这是通用行为,不含 FWH 逻辑,约 20 行改动加测试。改动之前的过渡办法:导出工具改为返回普通文本并控制在 10 万字以内(约 1,500~3,000 行),超出部分要求分段导出。 ### 5.3 二进制文件 故障录波原始文件、日志包等二进制内容在一期不直接交给 Agent。需要时提供“解析后的结果”工具(如录波通道数据导出为 CSV),由 Agent MCP 在服务端解析;是否需要见 Q-03。上述 5.2 的改动落地后,也可以用 `blob` 资源交付原始文件。 ### 5.4 长任务(MCP Tasks) 超过 3 分钟的操作以 MCP 长任务执行(AgentServer 接入指南 §5、`docs/design/16-mcp-support.md` §3):工具立即返回任务,AgentServer 在后台按 `pollInterval` 查询,结束后把结果作为新消息发到会话、唤醒模型。不做“提交 + 查询”让模型轮询;查询进度的只读工具保留,供用户主动询问。 **任务状态不放在 MCP 进程里。** mcp-go 的任务只存在进程内存,fwh-agent-mcp 重启后平台查询得到“任务不存在”而按失败通知用户,而底层作业其实仍在执行。所以长任务工具用 `kit.TaskDef` 定义,由 `kit.TaskRouter` 在 mcp-go 之前处理任务协议: | 请求 | 处理 | | --- | --- | | `tools/call` 带 `task` | `Start`:启动或挂到已有作业上,立即返回任务(含 `pollInterval` 与给模型的即时说明 `model-immediate-response`) | | `tasks/get` | `Status`:读取业务数据(如 Mongo 中的作业记录)翻译为任务状态 | | `tasks/result` | 任务结束后返回工具结果(失败为 `isError`),带 `related-task` | | `tasks/cancel` | `Cancel`:由工具按任务 id 中的标记决定是否真的停止作业 | | 其他请求、不是本服务签发的任务 id | 原样交给 mcp-go | - 任务 id:`fwhtask.<工具>.<业务键>.<标记>.<随机数>.<签名>`,签名为以访问令牌为密钥的 HMAC,伪造或篡改的任务 id 一律返回“找不到任务”。 - MCP 进程不保存任何任务状态,重启后照常回答查询;业务数据长期保存,满足平台至少 24 小时的要求。 - 不带 `task` 的普通调用照常由 `Def.Handler` 同步返回。 `site_info_refresh` 是第一个长任务工具:业务键为同步记录(`SiteInfoManageRecord`)的 id,标记为本次调用的动作。 | 动作(标记) | 任务 | | --- | --- | | `triggered`(本次触发) | 跟随同步记录:pending / running → working(进度说明“同步中,已进行 N 分钟”);complete → completed(站点数、耗时、完成时间);error → failed;cancelled → cancelled;超过 6 小时未完成 → failed(疑似中断)。取消时停止同步 | | `tracking`(已有同步在进行) | 同上,但取消只停止跟踪,不停止同步(其他会话可能也在等它) | | `skipped_fresh` / `skipped_stale`(未触发) | 立即完成,结果为不触发的原因 | 取消同步由主服务配合:同步循环每页检查 ctx;`fwhQueue.CancelSiteInfoUpdate` 对执行中的任务发出取消(worker 停止后记为 cancelled),对排队中的直接删除。同步任务超时为 4 小时(`SiteInfoUpdateTimeout`),超时同样会停止同步并记为失败。 ## 6. 部署与接入 ### 6.1 Agent MCP - systemd 单元 `fwh-agent-mcp.service`:`fwh-agent-mcp -set=readonly -listen=127.0.0.1:8091`,工作目录与主服务相同。 - 独立配置文件 `config.agent-mcp.env`(`-config` 可指定,示例 `deploy/config.agent-mcp.env.example`):`AGENT_MCP_TOKEN`(Bearer 令牌)、`AGENT_MCP_MAX_CONCURRENCY`、`AGENT_MCP_LOG_PATH`,以及工具用到的数据库、Redis、FWH 生产/测试 API、Plane Web。不读主服务的 `config.env` 与旧 MCP 的 `config.mcp.env`,只放自己需要的凭证;文件缺失时拒绝启动。 - 部署脚本:新增 `service/cmd/deploy_agent_mcp.sh`(构建、拷贝、重启),不改动旧 MCP 的 `deploy_mcp.sh`。 - AgentServer 与 ToolBox 不在同一台机器时,监听内网地址,防火墙只放行 AgentServer 主机(见 requirements Q-01)。 ### 6.2 AgentServer 登记 后台“MCP 服务” › 添加: | 项 | 值 | | --- | --- | | 名称 | `fwh` | | 标题 | FWH 业务数据 | | 传输 | 远程 HTTP,`http://127.0.0.1:8091/mcp` | | 请求头 | `Authorization: Bearer ` | | 工具策略 | 全部只读,默认“直接调用” | Profile `fwh-assistant` 勾选 `fwh`。工具使用的业务说明(字段含义、常见排查流程、各工具的配合方式)写在 AgentServer 技能 `fwh-assistant` 中([technical-design.md](technical-design.md) 第 6 节);Gateway 不转发上游的 `instructions`,所以不依赖它。 ## 7. 写工具(二期) 写工具单独部署为第二个 MCP 服务 `fwhops`(`-set=ops`),只勾选进需要它的 Profile(例如只给运维角色用的 Profile)。工具策略保持“跟随权限模式”,Profile 的权限模式为“需审批”,每次调用都弹审批卡片。 候选: | 工具 | 说明 | 注意 | | --- | --- | --- | | `feedback_create` | 在 Plane 创建 Intake Issue | 提交人固定为服务账号“AI 助手”;描述中由 Agent 写明背景。需要真实提交人时由 ToolBox 页面提交,不经过 MCP | | `tou_template_save` | 保存测试服 TOU 模版 | 只允许测试服;写入前按调度配置需求中的规则校验,返回差异 | | `site_info_refresh` | 触发站点信息表同步,以长任务执行(5.4) | 触发前检查同步状态(与 `site_info_sync_status` 相同的判断):同步中改为跟踪,不重复触发;最近 24 小时内已成功、或超过 6 小时未完成疑似中断时不触发,`force=true` 可强制。同步结束后平台把结果发给模型。任务投递到主服务的队列执行(MCP 只创建入队客户端与 Inspector,Redis 库号与主服务一致) | | `fault_record_fetch` | 召唤设备故障录波,长任务 | 经主服务执行器收发 MQTT(MCP 不连 MQTT,只提交与读取 Mongo 中的操作);任务跟随操作记录 | | `fault_record_param_write` | 设置设备录波参数或执行动作,长任务 | 破坏性(清除波形不可恢复),每次审批 | | `fault_record_cancel` / `fault_record_retry_download` | 取消操作;上传完成但下载失败时重试下载 | | 无用户模型下,写工具的“谁做的”只记录在 ToolBox 会话归属和 AgentServer 审计中,业务系统里看到的是服务账号。如果某个写操作在业务上必须归属到具体的人,就不放进 MCP。 ## 8. 待确认 | 编号 | 问题 | 建议 | | --- | --- | --- | | Q-01 | 一期工具清单(第 4 节)是否覆盖主要使用场景,是否有遗漏的高频查询 | 按旧助手的调用日志统计高频工具补充 | | Q-02 | 是否需要原始存储查询工具(Mongo / PG) | 一期不做;收集到具体场景后补任务级工具 | | Q-03 | 故障录波、日志包等二进制数据是否需要交给 Agent 分析 | 先提供解析后的 CSV;原始文件待 5.2 改动后再评估 | | Q-04 | 5.2 的 AgentServer 改动是否接受 | 建议做,导出类工具依赖它 | | Q-05 | 写工具(第 7 节)是否需要、给哪些角色 | 一期不做;二期先上 `feedback_create` | | Q-06 | 是否需要访问测试服 FWH 平台的工具 | 只在调度模版上区分 `env`;其他工具只查生产服 |