最短路径体验
完整 Agent 运行时

按“先体验 Harness,再安装一个插件,最后完整部署和开发插件”的路径操作。每一步都有可复制的命令,第一次使用不需要先理解全部架构。

1. 最小体验与完整部署入口

第一次使用不需要先克隆部署仓库。直接启动 Harness 镜像,先体验 Web 控制台和 H2;完成后再进入下方的完整部署流程。

第一步:单容器体验 Harness

docker run -d \
  --name dsh-java-web \
  --restart unless-stopped \
  -p 127.0.0.1:8090:8090 \
  --add-host=host.docker.internal:host-gateway \
  -e DEEPSEEK_BASE_URL='http://host.docker.internal:8777/v1' \
  -e DEEPSEEK_API_KEY='你的模型 API Key' \
  -e DEEPSEEK_DEFAULT_MODEL='glm-5.3-flash' \
  -v dsh-web-data:/app/data \
  -v dsh-web-storage:/app/storage \
  registry.cn-hangzhou.aliyuncs.com/xfg-studio/deepseek-harness-java:0.1.6

浏览器打开 http://127.0.0.1:8090/,先进入「设置 → 模型设置 → 添加模型」,填写模型服务地址、模型名称和 API Key,保存后再新建工作区和会话,发送:请介绍一下你当前可以使用的工具,并说明哪些操作需要人工审批。

进入下一步前执行 docker rm -f dsh-java-web,避免容器名和端口冲突。

第二步:部署插件服务并安装一个 JAR

先只启动 Harness 和 MySQL 管理服务,体验一个插件,不必一次启动商城和所有组件:

git clone https://github.com/fuzhengwei/dsh-java-deploy.git
cd dsh-java-deploy
cp .env.example .env
# 编辑 .env,填写 DEEPSEEK_API_KEY
docker compose up -d dsh-java-web dsh-java-mysql
./scripts/install-plugins.sh --mysql-only

访问 http://127.0.0.1:8091/ 添加数据库连接,再用下面的命令确认插件已经激活:

curl http://127.0.0.1:8090/api/harness/plugins

在 Harness 会话中发送:请列出当前已配置的数据库连接,并说明这个插件提供哪些只读能力。

第三步:标准部署 Harness 与商城

下载并执行 标准部署脚本。脚本会拉取 Harness 与 2D Weekend Mall 镜像,使用 host 网络启动两个容器,并挂载数据、存储和插件卷:

curl -fsSLO https://dsh-java.xiaofuge.cn/scripts/deploy-standard.sh
chmod +x deploy-standard.sh
./deploy-standard.sh

启动后访问:

http://127.0.0.1:8090    # Harness Web
http://127.0.0.1:8091    # DSH MySQL
http://127.0.0.1:18080   # 2D Weekend Mall

部署完成后打开 Harness,进入「设置 → 模型设置 → 添加模型」,填写模型服务地址、模型名称和 API Key,保存后即可开始对话。

验证插件:

curl http://127.0.0.1:8090/api/harness/plugins
安装商城插件:部署完成后,从 GitHub 下载 mall-agent-plugin-1.0.0-SNAPSHOT.jar,打开 http://127.0.0.1:8090,进入“设置 → 插件管理 → 选择 JAR”,上传后点击“安装并启用”。
验证:访问 http://127.0.0.1:8090/api/harness/plugins,确认 mall-weekend-assistant 已激活;商城访问地址为 http://127.0.0.1:18080

2. 使用 Web 控制台

启动完成后,在浏览器打开:

http://localhost:8090/
  1. 新建或选择一个工作区,用于隔离文件操作和运行上下文。
  2. 创建 Agent 会话,左侧可切换、恢复或删除会话。
  3. 进入模型设置,确认默认 provider、model 与 API Key。
  4. 发送第一条消息,观察 SSE 流式输出和工具卡片。
  5. 需要人工确认时,在审批面板批准或拒绝任务。
  6. 打开插件页面,安装、启用、停用或配置插件。

控制台原生实现了 Markdown 渲染、代码高亮、DOMPurify XSS 净化、历史会话回放、轨迹视图、插件启停与审批处理。

2.1 用 API 发起第一条消息

阻塞式接口适合脚本测试;SSE 接口适合观察流式行为:

curl -X POST http://localhost:8090/api/agent/message \
  -H 'Content-Type: application/json' \
  -d '{
    "agentId": "local-agent",
    "message": "Hello!",
    "provider": "deepseek",
    "model": "gpt-5.5",
    "maxTokens": 8192,
    "cwd": "."
  }'
curl -N -X POST http://localhost:8090/api/agent/stream \
  -H 'Content-Type: application/json' \
  -d '{"agentId": "local-agent", "message": "介绍这个项目的架构"}'
注意:如果配置了 harness.auth.api-keys,请求需额外携带 X-API-Key: your-api-keyAuthorization: Bearer your-api-key

3. 完整商城案例:2D Weekend Mall

2D Weekend Mall 是完整部署阶段的 PC 虚拟商城,商品、购物车、订单、支付和物流在浏览器闭环。使用标准部署脚本即可启动 Harness 与商城服务,再通过 Harness 插件管理安装客服插件 JAR。

推荐:执行标准部署脚本

curl -fsSLO https://dsh-java.xiaofuge.cn/scripts/deploy-standard.sh
chmod +x deploy-standard.sh
./deploy-standard.sh

打开 http://127.0.0.1:18080/ 访问商城;然后从 GitHub 下载 mall-agent-plugin-1.0.0-SNAPSHOT.jar,在 http://127.0.0.1:8090 的“设置 → 插件管理”中选择 JAR、安装并启用。插件配置使用 mall.base-url=http://127.0.0.1:18080,服务令牌使用脚本输出的值。

源码开发时启动商城

只有需要修改商城源码时才使用下面的本地启动方式;普通部署请使用上面的标准部署脚本。

git clone https://github.com/fuzhengwei/2d-weekend-mall.git
cd 2d-weekend-mall

mvn -pl mall-app spring-boot:run

打开 http://localhost:18080,默认演示用户是 customer-1

构建并安装客服插件

mvn package

JAR="$PWD/mall-agent-plugin/target/mall-agent-plugin-1.0.0-SNAPSHOT.jar"

curl -X POST http://localhost:8090/api/harness/plugins/install \
  -H 'Content-Type: application/json' \
  -d "{
    \"pluginId\": \"mall-weekend-assistant\",
    \"displayName\": \"2D Weekend Mall Assistant\",
    \"pluginVersion\": \"1.0.0\",
    \"runtimeType\": \"JAVA_NATIVE\",
    \"sourcePath\": \"$JAR\",
    \"entrypoint\": \"mall-agent-plugin-1.0.0-SNAPSHOT.jar\"
  }"

curl -X POST http://localhost:8090/api/harness/plugins/run \
  -H 'Content-Type: application/json' \
  -d '{"pluginId":"mall-weekend-assistant"}'

配置商城凭证

  • 在 Harness 插件配置中设置 mall.service-token,与商城 mall.security.service-token 一致。
  • 建议设置 mall.base-urlhttp://127.0.0.1:18080
  • 保存后停用并重新启用插件,确保重新执行 configure(context)

安装成功后,Agent 会看到 plugin__mall-weekend-assistant__search_products 等工具,可以搜索商品、查询订单和物流。

打开商城案例

4. 插件服务:dsh-java-mysql

这个案例提供 MySQL 管理后台与 AI 助手。部署体验优先使用 dsh-java-deploy 的预构建 JAR,只启动两个服务并安装一个插件;需要修改源码时,再使用下面的本地构建方式。

推荐:只启动服务并安装插件

cd dsh-java-deploy
docker compose up -d dsh-java-web dsh-java-mysql
./scripts/install-plugins.sh --mysql-only
curl http://127.0.0.1:8090/api/harness/plugins

启动管理后台

git clone https://github.com/fuzhengwei/dsh-java-mysql.git
cd dsh-java-mysql

mvn clean package
java -jar dsh-java-mysql-app/target/dsh-java-mysql-app-*.jar

打开 http://localhost:8091,添加数据库连接后即可浏览表、执行 SQL 和查看 AI 分析。

安装 MySQL 插件

JAR="$PWD/dsh-java-mysql-plugin/target/dsh-java-mysql-plugin-0.1.0-SNAPSHOT.jar"

curl -X POST http://localhost:8090/api/harness/plugins/install \
  -H 'Content-Type: application/json' \
  -d "{\"pluginId\":\"dsh-java-mysql-plugin\",\"displayName\":\"DSH MySQL Plugin\",\"pluginVersion\":\"0.1.0\",\"runtimeType\":\"JAVA_NATIVE\",\"sourcePath\":\"$JAR\",\"entrypoint\":\"dsh-java-mysql-plugin-0.1.0-SNAPSHOT.jar\"}"

curl -X POST http://localhost:8090/api/harness/plugins/activate \
  -H 'Content-Type: application/json' \
  -d '{"pluginId":"dsh-java-mysql-plugin"}'
工具能力
mysql_list_connections列出本地已配置连接
mysql_read_query执行 SELECT、SHOW、DESC 等只读查询
mysql_explain_query获取 SQL 执行计划
mysql_performance_snapshot查看性能快照
mysql_sql_review本地 SQL 风险审计,不连库
安全边界:AI 链路全程只读,服务端会二次校验 SQL;写操作只能在 SQL 控制台勾选“写操作”并人工确认后执行。

5. 插件开发教程 · SPI 与 AI Prompt

插件先选择合适的运行模式,再实现 SPI 契约并注册工具。当前工程版本为 v0.1.6,Java Native Plugin 只依赖 deepseek-harness-java-types,可用 archetype 生成骨架,再用安装脚本验证。

用 v0.1.6 Archetype 生成工程

cd /path/to/deepseek-harness-java
mvn -q -pl deepseek-harness-java-types install -DskipTests
mvn -q -pl plugins/deepseek-harness-plugin-archetype install -DskipTests
mvn archetype:generate \
  -DarchetypeGroupId=cn.xiaofuge \
  -DarchetypeArtifactId=deepseek-harness-plugin-archetype \
  -DarchetypeVersion=0.1.6 \
  -DgroupId=com.acme -DartifactId=acme-weather-plugin \
  -Dversion=1.0.0-SNAPSHOT -Dpackage=com.acme.weather \
  -DpluginId=acme-weather -DpluginName="Acme Weather Plugin" \
  -DpluginClass=WeatherPlugin -DinteractiveMode=false

JAR 必须包含 META-INF/plugin.yamlMETA-INF/services/cn.xiaofuge.deepseek.harness.domain.spi.JavaHarnessPlugin。工具最终以 plugin__<pluginId>__<toolName> 的名称提供给 Agent。

打包并安装验证

cd acme-weather-plugin
mvn package
bash /path/to/deepseek-harness-java/scripts/install-plugin.sh \
  --jar target/acme-weather-plugin-1.0.0-SNAPSHOT.jar \
  --host http://127.0.0.1:8090
模式适用场景
Java NativeJava 工具、数据库/业务 API、低延迟进程内调用,使用 URLClassLoader 隔离。
Node Bridge复用 Node 生态,sidecar 进程以 JSON-RPC 与宿主通信。
MCP stdio已有 MCP Server 能力接入,适合标准化工具生态。

最小 Java 插件结构

your-plugin/
├── pom.xml
└── src/main/
    ├── java/cn/xiaofuge/plugin/
    │   ├── YourPlugin.java
    │   └── YourTool.java
    └── resources/META-INF/
        ├── plugin.yaml
        └── services/cn.xiaofuge.deepseek.harness.domain.spi.JavaHarnessPlugin

宿主加载后会解析 plugin.yaml,创建插件实例,注册工具并进入生命周期管理;Agent 只能调用注册成功的工具。

AI Prompt 1 · 需求到插件设计

需求拆解
你是一名 Java Agent 插件架构师。请把下面的需求整理成 DSH Java Java Native 插件设计文档:

业务需求:【在这里粘贴需求】

输出要求:
1. 插件 ID、显示名、版本、运行时类型。
2. 工具清单:工具名、用途、输入参数、返回结构、异常分支。
3. 每个工具的风险等级:只读 / 写操作 / 高危操作。
4. 需要外部配置的 key、默认值和校验规则。
5. 下载/调用边界:允许访问的域名、超时、重试、审计点。
6. 用表格列出实现文件、职责和依赖方向。

AI Prompt 2 · 生成 Maven + SPI 骨架

骨架生成
请根据下面的插件设计文档,生成一个可编译的 DSH Java Java Native 插件骨架:

插件名:【your-plugin】
基础包名:【cn.xiaofuge.plugin】
Java 版本:17

输出要求:
1. pom.xml:不引入 Spring 容器,最小依赖。
2. plugin.yaml:包含 pluginId、displayName、pluginVersion、runtimeType、entrypoint。
3. JavaHarnessPlugin SPI 服务声明文件。
4. YourPlugin 类:初始化、configure、start、stop 生命周期。
5. YourTool 类:返回 ToolDefinition,实现 execute。
6. 只输出文件,不要解释。文件路径注释放在每个文件块顶部。

AI Prompt 3 · 生成业务工具实现

工具实现
请实现 Java Native 插件工具:

工具名:【your_tool】
功能:【查询业务数据 / 调用业务 API / 读取本地资源】
输入参数:【参数名、类型、是否必填、校验规则】
返回要求:【字段、示例、空结果结构】
异常要求:【超时、认证失败、业务失败】

实现要求:
1. 不使用 Spring 注解,只依赖 SPI 和标准库。
2. 输入必须校验,错误信息给 Agent 可读的结构。
3. 外部 HTTP 请求要设置超时、失败分类和日志脱敏。
4. 只做指定能力,不额外扩展写操作。
5. 返回 Java 原生 Map/List/String,避免序列化到 UI 的副作用。

AI Prompt 4 · 打包、安装与验证

安装验证
请根据当前插件项目生成验证文档:

插件路径:【/absolute/path/to/your-plugin.jar】
插件 ID:【your-plugin】
Harness 地址:【http://localhost:8090】

输出要求:
1. mvn clean package 命令。
2. /api/harness/plugins/install curl 命令。
3. 插件启动或激活 curl 命令。
4. 3 个能证明工具生效的 Agent Prompt。
5. 3 个应触发错误分支的测试用例。
6. 安装失败时的日志检查清单。
推荐流程:先用 Prompt 1 锁定边界,再用 Prompt 2 生成骨架;不要让 AI 直接一次性生成完整业务系统。工具应保持小而清晰,一个工具只做一类动作。

6. 发布插件到社区收录

插件开发完成并本地验证通过后,可以发布到 GitHub 与社区共享。社区通过 GitHub topic 统一收录插件——只要给仓库添加 dsh-plugin-java 标签,就会出现在 github.com/topics/dsh-plugin-java 主题页,被其他开发者发现。

发布步骤

  1. 把插件源码推送到一个公开的 GitHub 仓库。
  2. 完善 README:插件能力、工具清单、安装命令、配置项和截图。
  3. 建议附上构建好的 JAR(Release 附件或明确的构建命令)。
  4. 给仓库添加 dsh-plugin-java 标签(topic),等待被社区收录。

添加收录标签

方式一:打开仓库主页,点击右上角 About 区域的设置图标,在 Topics 输入框中添加 dsh-plugin-java 并保存。

方式二:使用 GitHub CLI 一行完成:

gh repo edit --add-topic dsh-plugin-java
命名建议:仓库名推荐以 dsh-java- 为前缀(如 dsh-java-mysql),README 首屏写清「这是一个 DSH Java 插件」,方便检索与识别。
质量约定:被收录的插件应能直接构建或通过 Release 安装;写操作类工具请在 README 明确标注风险等级与所需审批配置。
浏览社区插件

7. 持久化部署与安全

完整部署推荐使用 标准部署脚本。脚本使用 Harness 0.1.6.4 与商城 0.1.1 镜像,并创建持久化数据、存储和插件卷:

curl -fsSLO https://dsh-java.xiaofuge.cn/scripts/deploy-standard.sh
chmod +x deploy-standard.sh
./deploy-standard.sh

脚本部署完成后,请从 GitHub 下载商城插件 JAR,在 Harness 的“设置 → 插件管理”中选择 JAR、安装并启用。脚本会输出相同的下载地址、服务地址和商城服务令牌。

.env 关键配置项

变量说明建议
MALL_SERVICE_TOKEN商城与 Mall 插件之间的服务凭证改成随机值,两边必须一致
DEEPSEEK_BASE_URLHarness 调用 LLM 的网关地址容器内访问宿主机用 http://host.docker.internal:8777/v1
DEEPSEEK_API_KEY模型 API Key必填,否则对话无输出
DEEPSEEK_DEFAULT_MODEL默认模型glm-5.3-flash
HARNESS_PLUGIN_API_TOKEN插件接口写请求令牌暴露到非本机网络时必配
核心结论:三个容器必须同网络。容器内的 127.0.0.1 只指向容器自身,不是宿主机也不是 dsh-java-web。部署包已通过 Docker DNS 解决——dsh-java-mysql:80912d-weekend-mall:18080dsh-java-web:8090 互相用容器名访问,无需修改任何业务代码。

本地构建

git clone https://gitcode.net/KnowledgePlanet/deepseek-harness-java.git
cd deepseek-harness-java

mvn clean package -DskipTests

java -jar deepseek-harness-java-app/target/deepseek-harness-java-app-1.0.0-SNAPSHOT.jar \
  --spring.profiles.active=standalone

standalone profile 使用 H2 文件库,无需 MySQL。默认 profile 需要导入 MySQL 表并配置 SPRING_DATASOURCE_URLSPRING_DATASOURCE_USERNAMESPRING_DATASOURCE_PASSWORD

安全检查

  • 不要把 API Key 提交进仓库或写入公共镜像。
  • 生产环境启用 API Key、HTTPS、访问日志和最小化网络暴露。
  • Shell、写文件、插件和子进程默认属于高风险操作,保留人工审批。
  • 公开部署时补充限流、审计、备份与集中观测。
  • 当前定位是单实例 Agent 运行时,分布式多租户需自行扩展协调与隔离策略。

8. MySQL 库表导入与数据源配置

默认 profile 使用 MySQL 作为事件溯源与配置存储。建库脚本位于 deepseek-harness-java 仓库 docs/dev-ops/mysql/sql/deepseek_harness_java.sql,包含 12 张表与初始工具/模型配置数据。

1)导入建库脚本

脚本内含 CREATE DATABASE IF NOT EXISTS deepseek_harness_java 与全部建表语句,直接执行即可(重复执行会先 DROP 再建,注意备份):

mysql -h 127.0.0.1 -P 3306 -u root -p < docs/dev-ops/mysql/sql/deepseek_harness_java.sql

2)配置数据源环境变量

export SPRING_DATASOURCE_URL='jdbc:mysql://127.0.0.1:3306/deepseek_harness_java?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true'
export SPRING_DATASOURCE_USERNAME='root'
export SPRING_DATASOURCE_PASSWORD='your-password'

Docker 容器内访问宿主机 MySQL:把 127.0.0.1 换成 host.docker.internal(Mac/Windows)或宿主机内网 IP(Linux)。

3)启动应用(默认 profile)

java -jar deepseek-harness-java-app/target/deepseek-harness-java-app-1.0.0-SNAPSHOT.jar

不加 --spring.profiles.active=standalone 即走 MySQL。首次启动会自动执行内嵌 schema.sql 补全缺失的表(幂等,可重复启动)。

12 张核心表与导入验证

  • harness_session_event_log:会话事件日志(事件溯源核心)
  • harness_goal_state:任务目标状态
  • harness_model_setting:模型配置(预置初始数据)
  • harness_plugin_config:插件配置
  • 其余覆盖任务、审批、工具与工作区投影

导入后验证:SHOW TABLES; 应有 12 张 harness_* 表;harness_model_setting 已有预置 provider/model 行。判断 MySQL 是否在跑用 nc -z 127.0.0.1 3306,别依赖进程列表。

迁移陷阱:schema.sql 使用 INSERT ... WHERE NOT EXISTS 只插不更——已存在的配置行(如模型设置)不会被覆盖。下线旧模型或更新配置时需手动 UPDATE;修改已有表结构时不要只改 CREATE TABLE,应引入可重复执行的迁移脚本或 Flyway/Liquibase。

9. H2 还是 MySQL

两套数据源共用同一 schema,通过 profile 一键切换,不需要改代码:

维度H2(standalone profile)MySQL(默认 profile)
部署零依赖,文件库 ./data/*.mv.db需独立 MySQL 实例 + 导入建库脚本
兼容性MODE=MySQL 兼容模式,共用同一 schema原生
适用本地开发、演示、单机轻量使用生产、联调、长期持久化
风险文件锁、并发能力有限需运维:备份、连接池、监控
本地零依赖启动:java -jar deepseek-harness-java-app-*.jar --spring.profiles.active=standalone。生产环境请勿使用 H2——本项目曾真实发生过「容器沙箱里 lsof/ps 看不到跨用户 MySQL 进程,误判没跑而切了 H2,结果应用连 H2、界面看的是 MySQL,两边数据对不上」的事故。

10. 上线前检查清单

把 Harness 部署到服务器或企业内部环境前,逐项确认:

安全

  • 配置 harness.auth.api-keys(为空则全放行)
  • 模型 API Key 走环境变量,绝不硬编码提交仓库
  • 确认审批覆盖 Shell / 写文件 / 插件 / 子进程
  • 服务不直接暴露公网,前置网关

稳定性

  • 外部 MySQL + 连接池 + 备份 + 事件表归档策略
  • 评估沙箱模式,生产可从 READ_ONLY 起步
  • 关注无界线程池,必要时改有界
  • 当前为单实例设计,多实例需自行扩展协调

11. 常见问题

访问 8090 打不开?

先用 docker logs -f dsh-java-web 查看启动日志;确认端口没有被占用,并检查宿主机防火墙或安全组规则。

容器之间 Connection refused?

确认三个服务都使用 dsh-net,并使用 dsh-java-webdsh-java-mysql2d-weekend-mall 这类容器名,不要在容器内写 127.0.0.1

对话没有模型输出?

检查 DEEPSEEK_BASE_URLDEEPSEEK_API_KEY。如果使用私有 OpenAI 兼容网关,地址需包含 /v1

插件启动后 Agent 看不到工具?

检查 plugin.yaml、SPI 服务声明和 JAR 路径。修改插件配置后应停用并重新启用,让插件重新执行 configure(context)

发布的插件没有被社区收录?

确认仓库是公开仓库,且 topic 名称完全是 dsh-plugin-java(GitHub topic 只允许小写字母、数字和连字符)。添加后稍等片刻即可在主题页看到。

Mall 插件 401/403?

确认插件配置 mall.service-token 与商城容器 MALL_SERVICE_TOKEN 一致,并检查插件里的 mall.base-url

插件配置保存后没生效?

停用再激活插件,让插件重新执行 configure()。非 127.0.0.1 的插件写请求必须携带 X-Plugin-Api-Token