🧰 工程全景

第14章 工程全景:API、控制台、数据与测试

把学习手册落到仓库协作:看清接口、界面、数据、测试与发布

14.1 本章导读

前 13 章沿着“跑起来 → 架构 → 核心机制 → 扩展 → 治理 → 生产”的主线读源码。这一章换成工程视角,把散落在 README、Maven 模块、Controller、SQL、静态资源和 CI 中的事实收拢成一张全景图。读完后,你应该能独立回答三个问题:接口契约在哪里;修改一个功能要动哪些模块;提交前怎样验证不破坏主线。

本章定位:不是重复讲解 ReAct、插件和审批原理,而是给已经理解机制的人提供工程地图。你可以把它当作代码评审、功能交接和上线前的检查底稿。

14.2 Maven 模块矩阵

项目由 7 个业务模块加 2 个插件工程组成。业务代码的依赖方向遵守六边形架构:trigger 只转协议,case 编排用例,domain 持有业务与端口,infrastructure 实现技术适配。

模块工程职责代表性内容快照规模
triggerHTTP/SSE、鉴权拦截器、DTO 绑定AgentController、命令/查询 Controller、ApiKeyAuthInterceptor25 个 Java 文件,1,398 行
api用例接口与 API 契约IAgentApi、查询/命令 API、请求与响应记录56 个 Java 文件,2,040 行
case用例编排与责任链Agent 意图/分发/收集节点,任务提交与权限检查45 个 Java 文件,1,761 行
domain业务内核、聚合、端口与领域服务ReactLoopAgentSessionLog、工具、插件、MCP、工作流344 个 Java 文件,17,861 行
infrastructure数据库、LLM、执行环境和外部网关适配MyBatis DAO、DeepSeek 网关、插件/工具网关、本地工作流引擎88 个 Java 文件,9,424 行
types插件 SPI 与公共契约ToolDefinition、执行输入输出、运行上下文21 个 Java 文件,998 行
appSpring Boot 装配与静态控制台DeepseekHarnessJavaApplication、预置插件装载器、static/3 个 Java 文件,155 行
plugins/sample-tools-pluginJava Native 插件样例示例工具、插件入口与打包可安装 JAR
plugins/plugin-archetype插件脚手架Maven Archetype、插件主类、示例工具模板新插件生成器

行数只是导航用的工程快照,不是质量指标。真正需要记住的是边界:domain 不依赖 Spring Web,infrastructure 承接可替换适配器,trigger 不写业务规则。

14.3 REST 契约全景

HTTP 层按“资源 + 动作”分组。下表来自 trigger/http 中的实际路由,可以直接对照 Controller 评审新增接口。

能力端点说明
AgentPOST /api/agent/message阻塞式对话,返回完整消息结果
POST /api/agent/streamSSE 流式对话,输出 metareasoningchunkstep_breaktool_resultfinishdone
GET /api/agent/{agentId}/status读取 Agent 运行状态
POST /api/agent/{agentId}/cancel取消正在执行的 Agent
工作区GET /api/agent/workspaces读取工作区列表
GET /api/agent/workspaces/list按可选路径读取目录列表
POST /api/agent/workspaces创建工作区
DELETE /api/agent/workspaces/{name}删除工作区
PATCH /api/agent/workspaces/{name}重命名工作区
PUT /api/agent/workspaces/order更新工作区排序
任务与审批POST /api/harness/tasks/submit提交 Harness Task
GET/POST /api/harness/goals/{sessionId}查询或推进目标状态
GET /api/harness/approvals/pending读取提交期待审批项
POST /api/harness/approvals/{sessionId}/approve通过提交期审批
运行期审批GET /api/harness/approvals/runtime/pending轮询 Agent 挂起的实时审批
POST /api/harness/approvals/runtime/{approvalId}/resolveALLOW_ONCEALLOW_SESSIONDENYCANCEL
模型配置GET/POST /api/harness/settings/models读取或保存模型设置
DELETE /api/harness/settings/models/{channelCode}删除模型渠道
POST /api/harness/settings/models/discover从模型网关发现模型
GET /api/harness/runtime/models读取运行时可选模型
插件GET /api/harness/plugins插件列表
GET /api/harness/plugins/{pluginId}/status插件运行状态
POST /api/harness/plugins/install|activate|run安装、激活和执行插件
POST /api/harness/plugins/{pluginId}/enable启用插件
POST /api/harness/plugins/{pluginId}/disable停用插件
POST /api/harness/plugins/{pluginId}/uninstall卸载插件
终端POST /api/harness/terminal/sessions打开终端会话
GET /api/harness/terminal/sessions终端会话列表
POST /api/harness/terminal/sessions/{id}/send发送命令
GET /api/harness/terminal/sessions/{id}/read增量读取输出
POST /api/harness/terminal/sessions/{id}/close关闭终端
工作流POST /api/workflow/start启动工作流,返回 runId
POST /api/workflow/{runId}/cancel取消运行
POST /api/workflow/stream以 SSE 方式启动并输出运行状态
控制台回放GET /api/harness/console/sessions分页历史会话列表
GET /api/harness/console/sessions/{sessionId}/messages历史消息回放
POST /api/harness/sessions/{sessionId}/restore恢复历史会话并重建消息轨迹
运行期审批请求示例
curl -X POST http://localhost:8090/api/harness/approvals/runtime/{approvalId}/resolve \
  -H 'Content-Type: application/json' \
  -d '{"verdict":"ALLOW_ONCE"}'

鉴权由 ApiKeyAuthInterceptor 统一处理:静态资源和 /actuator 放行;harness.auth.api-keys 为空时本地全放行;非空时接受 X-API-KeyAuthorization: Bearer。新增公开路径前必须重新评估安全边界。

14.4 Web 控制台与前端资产

内置控制台位于 deepseek-harness-java-app/src/main/resources/static,不是打包后的前端工程,也没有 Node 构建链。核心文件只有两个:app.js 负责状态、请求、会话渲染、工具卡片、推理过程和会话管理;app.css 负责界面样式。第三方能力全部本地化:marked 解析 Markdown,purify 过滤 HTML,highlight-corehighlight-common 高亮代码。

资产职责工程要点
index.html控制台骨架轻量入口,适合随 Spring Boot 一起发布
app.js调用 Agent、工作区、模型、插件、审批、控制台回放等 API无框架依赖;修改时保持事件边界清晰
app.css完整 UI 样式与响应式布局避免引入运行时 CSS 框架
lib/*本地 Markdown、XSS 过滤和代码高亮升级前核对许可证、体积和安全公告

控制台的核心体验包括:新建/切换/重命名/删除工作区,创建、恢复、重命名、删除和清空会话,分页加载历史会话,懒加载历史消息,普通或流式对话,渲染工具调用卡片与推理过程,取消运行,管理模型,启停插件,审批任务,以及查看历史消息。排查 UI 问题时不要只看后端日志,应先在 Network 面板确认请求路径、响应码和 SSE 帧,再进入 Controller 或用例层。

14.5 数据与事件模型

MySQL 初始化脚本定义 12 张表;standalone profile 使用 H2 文件库并以 MODE=MySQL 兼容运行,两套数据源共用同一 schema。事件相关表支持过程记录、界面投影与历史回放。

作用工程关注点
harness_session会话聚合基础状态大多数记录通过 session_id 关联
harness_session_header会话头、目录、父会话、委托深度等上下文影响 Agent 运行边界与提示组装
harness_session_event会话过程事件注意 JSON 载荷体积
harness_session_event_log带序号的事件日志与投影操作session_id + seq 唯一,是回放顺序的关键
harness_task任务提交与执行状态任务队列与审批链路的入口记录
harness_goal_state目标状态支撑长期任务与目标恢复
harness_plugin_installation插件安装元数据保存来源、版本和运行类型
harness_plugin_runtime_binding插件运行绑定隔离插件生命周期与安装记录
harness_model_setting模型与 Provider 配置密钥应注入环境,不提交仓库
harness_tool_catalog工具目录初始化文件、Shell、Web、MCP 工具
harness_tool_profile_binding工具与 Profile 绑定控制不同运行形态可见的工具集

迁移注意:当前初始化脚本偏向首次建库,修改已有表结构时不要只改 CREATE TABLE;应引入可重复执行的迁移脚本或使用 Flyway/Liquibase,并在 H2 与 MySQL 上同时验证。

14.6 测试与质量门禁

当前共有 23 个 Java 测试类,分布在六个模块:api 1 个,case 5 个,domain 8 个,infrastructure 7 个,app 1 个,trigger 1 个。它们覆盖 ReAct 循环、意图与分发、工具执行、Hook、超时、提示组装、目标、终端、待办、插件桥接、MCP 配置、扩展配置、审批链路和若干查询/命令用例。

常用验证命令
# 全量测试
mvn test

# 只验证领域内核
mvn -pl deepseek-harness-java-domain test

# 快速打包
mvn package -DskipTests

# 完整发布前验证
mvn clean verify

当前缺口apptrigger 没有 Java 测试,HTTP/SSE 层缺少端到端契约测试;CI 也没有独立 Maven 测试工作流。改动 Controller、鉴权、SSE 或 Dockerfile 时,必须本地补跑构建并手工验证控制台关键路径。

建议按变更类型选择验证范围:

变更最低验证更完整验证
领域服务、Agent、工具mvn -pl deepseek-harness-java-domain test全量 mvn test + 本地对话
Controller/SSE/API DTO启动应用,curl 验证请求与响应trigger 增加 MockMvc/WebTestClient 测试
SQL/DAOH2 standalone 启动MySQL 容器启动 + 数据迁移验证
静态 UI打开控制台完成一次对话验证工具卡片、取消、审批和历史回放
插件/MCP启动后查看插件列表安装、启用、执行、停用、卸载全链路

14.7 配置、发布与观测

本地最小配置在 deepseek-harness-java-app/src/main/resources/harness.yml:默认端口 8090application.yml 提供,模型网关默认 http://127.0.0.1:8777/v1。模型、审批、沙箱、Skills、MCP 和插件使用同一配置入口。发布镜像时至少注入 DEEPSEEK_API_KEY,并按环境覆盖数据库与认证配置。

场景关键配置检查点
本地零依赖--spring.profiles.active=standaloneH2 文件、自动 schema、无外部 MySQL
开发 MySQLspring.datasource.*可连接、schema 可初始化、日志可读
生产 APIharness.auth.api-keys非空、可轮换、不把服务直接暴露公网
模型调用base-urlapi-keydefault-model网关兼容、模型可用、密钥来自环境
审批沙箱harness.approval.*harness.sandbox.*高风险工具默认受限,容器和目录权限收紧
有效配置GET /api/harness/config/effective启动后检查合并结果;敏感项应被脱敏
扩展生态harness.extensions.*Skills、MCP 和插件统一装配与校验

发布链路由 .github/workflows/docker-build-push.yml 处理:推送 tag-v* 标签(例如 tag-v0.1.6)或手动触发时,Workflow 使用多阶段 Dockerfile 构建 JAR,并同时推送到 fuzhengwei/deepseek-harness-javaregistry.cn-hangzhou.aliyuncs.com/xfg-studio/deepseek-harness-java。标签构建会发布去掉 tag-v 前缀的版本号与 latest;手动触发时可输入 0.1.7v0.1.7tag-v0.1.7,留空则发布 latest 与短 SHA 标签。仓库当前没有独立的 Maven CI 工作流,这是后续工程化最值得补的一环。

上线后至少观测四类信号:JVM 与 HTTP 指标、模型请求耗时与失败率、工具执行耗时与拒绝原因、数据库连接池和事件表增长。/actuator 方便排障,但公网部署必须放在认证、网关或内网之后。

14.8 工程协作与变更检查清单

项目已经很大,单靠“看一下代码”很难保证变更质量。建议把下面清单放进 PR 描述,评审时逐项确认。

阶段检查项
定位明确属于 Trigger 协议、Case 编排、Domain 业务、Infrastructure 适配、Types 契约或 App 装配中的哪一层。
契约新增 API 先定义 request/response record;字段命名、错误码、状态语义与旧接口保持一致。
架构不把 HTTP 类型引入 Domain;不把 DAO 直接暴露给 Trigger;外部能力都通过端口进入领域层。
安全评估路径、输入、Shell、文件、插件、MCP、密钥和日志泄漏;高风险动作必须接入权限或审批。
数据确认索引、唯一键、事件顺序、JSON 大小、H2/MySQL 兼容和历史数据迁移。
并发确认线程池、取消、超时、重试、SSE 生命周期和阻塞点;避免无界资源无限增长。
测试补领域测试或 HTTP 契约测试;跑 mvn test;必要时完成手工冒烟。
文档更新 README、相关章节或插件指南;配置变化要有默认值和风险说明。
发布确认镜像标签、数据库迁移、回滚方式、监控告警和事件表归档。

14.9 常用仓库地图

文件/目录用途
README.md项目介绍、快速启动、架构、机制、API、配置、边界与运维清单
pom.xmlMaven 模块清单和 Java/Spring Boot 版本管理
Dockerfile依赖缓存、构建镜像、运行镜像三层结构
docker-compose.yml挂载 dataplugins.dshworkspaces 并运行 standalone
docs/dev-ops/mysql/sql/deepseek_harness_java.sqlMySQL 建库脚本和初始工具数据
docs/html本学习手册的静态站点与构建脚本
docs/md架构图、领域设计与插件开发补充文档
.github/workflowsDocker 镜像构建与推送流水线

14.10 小结与下一章预告

第 14 章把学习视角切回仓库:模块矩阵决定修改边界,REST 表决定前后端契约,数据表决定事实存放方式,测试命令决定提交信心,CI 和 Docker 决定交付路径。你现在既有“为什么这样设计”的原理链,也有“怎么安全地改”的工程链。

实践建议:不要把第 14 章当作终点。挑一个真实需求,沿着 API → Case → Domain → Infrastructure → Test → 文档走一遍;如果一次变更无法清楚说出自己跨越了哪些模块,通常说明设计还没有收敛。

下一章继续进入平台能力:工作流如何启动、取消和收敛结果,子代理又如何把复杂任务委派给另一个执行者。