AgentScope第2式·筑基环境

AgentScope第2式·开发基线

环境不统一,后面二十七式都在还债。

[读者] 会 Java、准备把 Agent 做成真项目的人
[痛点] 每章重装一次环境,密钥乱放,调试靠打印
[现在读] 第3式要冻结数字人底座,底座之前必须先立基线
[读完] 一台新机器从 clone 到 compile/test/debug 全通
[旧方案] 每章各装各的 JDK,密钥随手写进配置文件
    |
    v
[新需求] 29 式共用一套可复现环境,统一测试与调试口径
    |
    v
[冲突] Agent 工程同时压着 JVM 依赖树、Python 辅助服务、
       实时音视频链路和容器化集成测试,版本面比单体应用宽
    |
    v
[后果] 环境差异被当成框架 Bug,章节之间无法增量演进

我是老李,在深圳做了十几年 Java,最近两年被 Agent 项目反复摩擦。第1式我们把 AgentScope Java 2.x 的选型讲透了,也确认这条路线值得投入;但选型讲得再漂亮,只要环境立不住,后面每一章都会退化成装环境的复读机。

我们手上贯穿全系列的项目只有一个:最小交互数字人 Demo。业务很朴素——管理端建项目、配开场白、运行页接 LiveKit、推理交给 AgentScope Java。可它的链路比普通 CRUD 长得多:浏览器、WebRTC、Spring Boot、JVM、Python 辅助服务、模型 API,任何一环版本不一致,都能伪装成框架 Bug。

所以这一式不讲 Agent 能力,只做一件事:把“能在我机器上跑”变成“在新机器上按 README 就能跑”。这也是第3式能安心冻结数字人底座的前置条件。

JDK 17 明明也能跑,为什么教程非要把基线抬到 JDK 21?

Python 到底装不装?装了会不会把一个 Java Agent 项目做成半吊子混合工程?

如果这一式的基线没立住,等第3式把 Demo 冻结之后再回头补,代价有多大?

01、故事

周一早上九点半,三个人的三台机器摆在同一个会议室里。

老李的 MacBook 是 M2 芯片,JDK 21 装了,Maven 停在 3.8.6;小周的 Windows 11 上 JDK 17 和 JDK 21 都在,JAVA_HOME 指向 17;运维同学的 Ubuntu 22.04 自带 Python 3.12,但没装 python3-venv,python -m venv 直接报错。

那天早上的任务是:让三台机器跑出同一条命令的同一份输出。

结果三条命令三种结果。IDE 里跑得好好的类,换到终端 mvn compile 就报版本不支持;模型 API Key 在小周机器上生效,在老李机器上 401;Python 虚拟环境在 Ubuntu 上根本建不起来。

没有人改过一行业务代码,问题全部出在环境。而更麻烦的是:这些报错长得特别像框架的报错。

三台机器三套环境
一句命令三种结果
先立基线再谈框架
否则后章全是补丁

02、问题

旧做法很自然:谁缺什么装什么,缺哪个版本装哪个版本,能跑通就算过。

为什么不够?因为第2式之后的每一章,都会踩到三类环境敏感区。

第一类,调试要进框架源码。我们后面要断点进 HarnessAgent、ReActAgent、Toolkit 这些类,IDE 必须有可用的 sources,必须和 Maven 用的是同一个 JDK。IDE 用 21、命令行用 17,断点行为差异会让你怀疑源码读错了。

第二类,异步链路要看事件流。Agent 的流式与异步调用建立在 Reactor 之上(具体依赖以 v2.0.3 依赖树为准),版本漂移会让 StepVerifier 的断言在不同机器上表现不一致。

第三类,外部依赖要联调。LiveKit、Python 辅助服务、Redis/PostgreSQL 容器,端口、虚拟环境、Docker 版本任意一项飘了,排查成本就成倍上升。

官方资料给的边界很清楚:AgentScope Java 官方最低要求是 JDK 17+,这一点在 v2.0.3 的快速开始文档里可以直接核验(https://github.com/agentscope-ai/agentscope-java/blob/v2.0.3/docs/v2/zh/docs/quickstart.md );而模块划分、编译目标、依赖管理策略,写在 v2.0.3 的根 pom.xml 里(https://github.com/agentscope-ai/agentscope-java/blob/v2.0.3/pom.xml )。

本篇的完成标准是可验证的四条:

  1. 全新机器按 README 完成 clone → 环境检查 → compile → test → debug;
  2. 三个人三台机器,check-env 输出一致;
  3. Git 历史里没有任何真实密钥;
  4. 数字人项目有一个可编译的空骨架,而不是一堆待补文件。

能跑不等于可复现
最低不等于该统一
先把标准写成脚本
再让三个人去执行

03、原理

反直觉判断一:AgentScope Java 的运行时依赖里没有 Python,但本教程仍然要装 Python 3.11。

这里的误区是把“运行时依赖”和“工程依赖”混为一谈。AgentScope Java 是 JVM 侧的框架,跑 Agent 不需要 Python 解释器;但后续章节要做 MCP Server 联调、RAG 辅助服务、数据准备脚本、本地对照实验,这些工具链天然在 Python 生态里更省事。装 Python 不是为了跑框架,是为了让后续章节不用临时补环境。这也是为什么它用 venv 隔离,配合 python/requirements.txt 单独管理。

反直觉判断二:官方“最低 JDK 17”不是团队“基线 JDK 21”的替代项。

最低支持版本是兼容性承诺,回答的是“能不能跑”;基线版本是团队一致性契约,回答的是“我们所有人跑的是不是同一个东西”。教程选择 JDK 21 LTS,是因为它是长期支持版、是当前主流团队的统一选择,也能让第3式之后的代码落在一个确定的目标上编译。把最低版本当基线用,等于把兼容性下限当工程标准。

反直觉判断三:Agent 工程里,很多“框架 Bug”其实是依赖树和工具链问题。

Agent 项目会同时引入模型扩展模块、HTTP 客户端、JSON 库、Reactor、日志门面,依赖重叠概率远高于普通单体应用。Maven 的依赖调解规则——路径最近优先、同深度先声明优先——决定了你最终拿到的是哪一个版本。所以在怀疑框架之前,先看 mvn dependency:tree。

关于模块关系,需要按 v2.0.3 的仓库结构核对:根 pom.xml 的 modules 列表给出了全部子模块,其中 core 是内核,agentscope-harness 是更高层的运行与编排外壳,模型扩展模块负责对接不同模型提供方(具体 artifactId 与分组请以上述 pom.xml 为准,本文不凭类名猜结构)。三者版本必须对齐:harness 与 core、模型扩展之间如果版本错位,最容易出现的是运行时 NoSuchMethodError 之类的二进制不兼容,而不是编译期报错。

几个专有名词,这里各用一句话划边界:

  • HarnessAgent:把模型、工具、状态、记忆等组装起来的运行外壳,负责一次完整对话怎么跑;
  • ReActAgent:推理内核的一种实现,负责“想一步、调一次工具、再想一步”的循环;
  • Toolkit:工具的注册与调用中心,负责把 Java 方法暴露给 Agent 调用。

后续章节会依次深入,这里只需要知道:它们都属于框架内部,断点能进去,前提是你的工程能正确解析到源码。

运行时里没有蟒蛇
工程链上却少不了
依赖版本各自为政
越省事越在后面还

04、架构

[输入] 开发者 / CI 的构建与运行请求
    |
    v
[模块] JDK21 + Maven3.9 + Python3.11(venv) + Git/IDE/curl/jq + Docker(按需)
    |
    v
[数据/状态] .env(本地密钥) / pom.xml(版本锁) / venv / ~/.m2 / target
    |
    v
[处理] check-env -> compile -> test(单元/集成) -> run -> debug
    |
    v
[输出] 可复现的开发基线 + 数字人空骨架 + 统一测试基类

边界:

  • 这套基线只管“怎么装、怎么跑、怎么测、怎么调”,不管 Agent 怎么推理;
  • LiveKit 只作为实时通信层,不在本章引入;
  • Docker 在本章只登记,不强制安装,等 Sandbox / Testcontainers 章节前再落到必需项。

收益:

  • 环境差异导致的假 Bug 大幅减少;
  • 后续每一章的增量都是业务代码,不是环境说明;
  • 新同学入场成本从“找老李”变成“读 README”。

代价:

  • 前期要多花半天搭骨架、写脚本;
  • 版本一旦固定,升级需要走单独变更,不能顺手改;
  • 多维护一个 Python 工具链目录,对纯 Java 同学来说是额外认知负担。

适用条件:多人协作、长周期教程或产品、需要反复 Debug 进框架源码。

不适用条件:只想在单机上花十分钟验证框架某个 API——那时装一堆 Testcontainers 依赖是纯浪费。

AgentScope 侧的依据位置:模块与版本以 v2.0.3 根 pom.xml 为准(https://github.com/agentscope-ai/agentscope-java/blob/v2.0.3/pom.xml );最小可运行示例以官方 examples 模块为准(https://github.com/agentscope-ai/agentscope-java/tree/v2.0.3/agentscope-examples );入门步骤以 v2.0.3 快速开始文档为准。

输入命令一条
输出结果一份
中间所有变量
都写进版本表

05、实战一次

本章的“实战”不是写业务功能,而是把基线做出来。以下内容未在当前环境实测,命令与输出为预期结果,请以你本机实际输出为准。

第一步:版本矩阵。

组件 教程基线 官方最低 说明
JDK 21 LTS 17+ 官方最低 17,教程统一 21
Maven 3.9+ 未在本文核验 3.9 对 JDK 21 支持更稳
Python 3.11.x 非运行时必需 仅工程辅助,venv 隔离
Git 2.40+ 未在本文核验 常规要求
IntelliJ IDEA 2024.x+ 未在本文核验 社区版够用
Docker 按需 非必需 Sandbox/Testcontainers 前安装
curl / HTTPie / jq 按需 非必需 接口联调与 JSON 处理

第二步:三平台安装思路。

Windows:用 winget 安装 OpenJDK 21、Git、Python 3.11,Maven 可以解压后配置 MAVEN_HOME 与 PATH;Docker 用 Docker Desktop。安装 Python 时记得勾选加入 PATH。

macOS:用 Homebrew,brew install openjdk@21 maven python@3.11 git jq,openjdk 需要额外做软链或配置 JAVA_HOME。

Linux:优先发行版包管理器,或使用 SDKMAN 统一管理 JDK 与 Maven;python3-venv 需要单独安装,这是 Ubuntu 上最常见的坑。

第三步:版本核验命令。

java -version
mvn -version
python --version
git --version
docker version

预期输出形如(示例输出):

openjdk version 21.0.x ...
Apache Maven 3.9.x ...
Python 3.11.x
git version 2.4x.x
Docker version 2x.x.x

注意 mvn -version 会同时打印 Java version,这一行是判断“Maven 用的哪个 JDK”的关键,比 java -version 更能暴露 Java 与 Maven 不一致的问题。

第四步:仓库目录。

agentscopepractice/
├── pom.xml
├── README.md
├── .env.example
├── .gitignore
├── Makefile
├── scripts/
│   ├── check-env.sh
│   └── check-env.ps1
├── python/
│   └── requirements.txt
└── src/
    ├── main/java/io/agentscope/practice/demo/DemoApplication.java
    └── test/java/io/agentscope/practice/
        ├── support/BaseUnitTest.java
        └── DemoApplicationSmokeTest.java

第五步:.env.example 与密钥规则。

# 复制为 .env 后填入本地真实值,不要把 .env 提交到 Git
AGENTSCOPE_MODEL_API_KEY=
AGENTSCOPE_MODEL_BASE_URL=
AGENTSCOPE_MODEL_NAME=
LIVEKIT_URL=
LIVEKIT_API_KEY=
LIVEKIT_API_SECRET=

.gitignore 关键行:

.env
.env.*
!.env.example
.venv/
target/
*.log

规则只有三条:真实密钥只存在于本地 .env 或系统环境变量;.env.example 只放键名不放值;提交前用 git status 和 git diff --cached 自查。check-env 脚本只校验键是否存在,绝不打印值。

第六步:pom.xml 固定版本。

<properties>
  <maven.compiler.release>21</maven.compiler.release>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <agentscope.version>2.0.3</agentscope.version>
</properties>

<dependencies>
  <dependency>
    <groupId>io.agentscope</groupId>
    <artifactId>agentscope-harness</artifactId>
    <version>${agentscope.version}</version>
  </dependency>
</dependencies>

groupId 与 artifactId 请按 v2.0.3 根 pom.xml 核对后再落盘;如果官方在该版本提供了依赖管理(BOM)模块,优先用 BOM 统一版本,避免逐条手写版本号。模型扩展模块(对接具体模型提供方的那一组模块)按需引入,版本与 harness 保持一致。

第七步:空骨架类。

package io.agentscope.practice.demo;

public final class DemoApplication {

    private DemoApplication() {
    }

    public static void main(String[] args) {
        System.out.print("digital-human skeleton ready");
    }
}

第八步:统一测试基类与冒烟用例。

package io.agentscope.practice.support;

import org.junit.jupiter.api.Tag;

@Tag("unit")
public abstract class BaseUnitTest {
}
package io.agentscope.practice;

import io.agentscope.practice.support.BaseUnitTest;
import org.junit.jupiter.api.Test;

class DemoApplicationSmokeTest extends BaseUnitTest {

    @Test
    void skeletonShouldBeLoadable() {
        Class<?> type = io.agentscope.practice.demo.DemoApplication.class;
        org.assertj.core.api.Assertions.assertThat(type).isNotNull();
    }
}

这一步是给后续每章立的规矩:每个功能至少一个正常用例、一个异常用例,异常用例优先放在 *IT 集成测试里。

第九步:环境检查脚本。

#!/usr/bin/env bash
set -euo pipefail

fail=0

require() {
  if ! command -v $1 >/dev/null 2>&1; then
    echo missing: $1
    fail=1
  else
    echo ok: $1
  fi
}

require java
require mvn
require python
require git

java -version 2>&1 | head -n 1
mvn -version 2>&1 | head -n 1
python --version 2>&1 | head -n 1
git --version

if [ -f .env ]; then
  echo found .env
else
  echo no .env, copy .env.example first
fi

exit $fail

Makefile 里加一个入口,Windows 上用 PowerShell 等价脚本:

check-env:
	bash scripts/check-env.sh

第十步:运行方式与 Debug。

运行方式三种,后面章节都会用到:

  • IDE Main:直接运行 DemoApplication,适合断点调试;
  • mvn exec:java:命令行运行,适合验证“不依赖 IDE 也能跑”;
  • mvn spring-boot:run:第3式之后 Spring Boot 接入后的标准入口。
mvn -q compile
mvn -q exec:java -Dexec.mainClass=io.agentscope.practice.demo.DemoApplication
mvn test

Debug 清单,本章一次讲清,后面不再重复:

  • 普通断点:断在业务入口;
  • 条件断点:对话轮次等于 3 时停,避免流式输出把断点刷爆;
  • 异常断点:对 NullPointerException 之类开 Any Exception,比翻日志快;
  • 源码断点:在 HarnessAgent、ReActAgent、Toolkit 上打断点,需要 IDE 能下载或关联框架 sources,这是“读源码”和“猜源码”的分界线;
  • 远程调试参数:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005,容器内部署时注意端口暴露;
  • Reactor 链路:优先看事件流而不是调用栈,用 StepVerifier 把异步行为写成测试;开发期可临时打开 Hooks.onOperatorDebug() 观察算子装配,它有性能开销,不要长期留在代码里。

本章对应教程分支 chapter/02-dev-environment,从第1式分支继续创建;建议提交信息为 chore(ch02): bootstrap Java Python and test toolchain。

从零复现一遍
三个平台同验
骨架编译通过
密钥不入仓库

06、排查

证据链一:IDE 能跑,命令行编译失败。

现象:IDE 运行 DemoApplication 正常,终端执行 mvn compile 报编译版本不支持,或者报 class file version 不匹配。

怀疑:AgentScope Java 需要更高版本的 JDK,或者框架依赖里有高版本字节码。

检查:

java -version
mvn -version
echo $JAVA_HOME

证据:mvn -version 输出的 Java version 与 java -version 不一致;官方快速开始文档明确 JDK 17+ 即可运行框架(v2.0.3 quickstart)。

根因:IDE 的 Project SDK 与终端 JAVA_HOME 指向了不同的 JDK,Maven 用的是终端那一套。

修复:把 JDK 版本判断收敛到 check-env 脚本,在 pom.xml 里固定 maven.compiler.release,必要时用 Maven Toolchains 显式声明编译器。

错误尝试:直接把 pom.xml 的编译目标从 21 降到 17,让命令行先过。为什么错?它只解决了当前这台机器,掩盖了 JAVA_HOME 不一致这个真因;换一台机器、换一个 CI 环境,同样的问题会以另一种形式复现。更糟的是,它让“基线”这个概念失效了。

证据链二:模型调用报鉴权失败,怀疑框架。

现象:第一次调模型接口返回 401 或等价鉴权错误。

怀疑:框架的模型扩展模块没有正确读取 API Key。

检查:确认 .env 是否被加载、环境变量是否注入进程、git status 是否出现 .env。

证据:错误发生在远端鉴权,栈顶落在 HTTP 客户端,真正的原因在本地配置。官方 examples 里给出的配置读取方式可作为对照(v2.0.3 的 agentscope-examples 目录)。

根因:密钥写进了会被提交的配置文件,或者 .env 存在但没被加载进进程环境。

修复:密钥只走环境变量或本地 .env;.env.example 只留键名;check-env 只校验存在性不打印值;提交前自查暂存区。

证据链三:异步链路里异常消失。

现象:调用发出后没有结果,日志里看不到业务异常,只在超时后报错。

怀疑:框架把异常吞掉了。

检查:用 StepVerifier 把这段异步逻辑单独写成一个测试,观察是 onNext 没来还是 onError 没被消费。

证据:异常在 Reactor 里是 onError 信号而不是抛出异常,没有被订阅者处理时就会体现为“什么都没发生”。这一步要在开发期临时开 Hooks.onOperatorDebug() 看算子装配顺序,定位完立即关掉。

根因:异步边界上的异常没有在合适的算子处记录或转换。

修复:在链路边界统一 doOnError 记录、onErrorResume 兜底,并把这条链路固化成一个 StepVerifier 用例。

上游贡献判断:本章的三条证据链都能在最小工程里复现,但根因全部落在本地环境与代码写法上,v2.0.3 与 main 是否存在同类问题需要另行核验,目前不构成上游 Issue 候选。

现象先记下来
别急着怪框架
证据摆上桌面
根因自然浮现

07、优化

基于第06章的三条证据,V2 的改动全部指向“让环境问题在第一步就暴露”。

根因一:工具链版本判断分散在人和 IDE 里。修改:check-env 脚本前置校验 java、mvn、python、git,并打印 mvn -version 的 Java 行。新行为:换机器只需跑一条命令。验证:三台机器输出一致。

根因二:密钥来源不唯一。修改:删掉仓库内所有明文密钥,只保留 .env.example,.gitignore 覆盖 .env 及其变体。新行为:Git 历史里查不到真实密钥。验证:对暂存区和历史做一次检索自查。

根因三:异步问题靠猜。修改:把 reactor-test、WireMock 或 MockWebServer、Testcontainers 依赖一次性纳入 pom,测试目录按职责分层:单元测试用 JUnit 5 加 AssertJ/Mockito,事件流用 Reactor Test 的 StepVerifier,外部 HTTP 用 WireMock 或 MockWebServer,容器集成用 Testcontainers(Redis/PostgreSQL 等)。新行为:每章至少一个正常用例加一个异常用例,异常用例必须可执行。验证:mvn test 跑单测,mvn verify 跑 *IT。

根因四:版本随手动。修改:agentscope.version 固定 2.0.3,升级另开分支。新行为:任何版本变化都是一次可回滚的变更。验证:mvn dependency:tree 输出稳定。

判断落成脚本
脚本变成门禁
门禁守到最后
人手才不会漏

08、演进

[同一输入] 新机器 clone 仓库后第一次启动
    |
    +--[V1] 各自装 JDK/Maven/Python,手动配环境变量
    |      代价:版本漂移,问题被误判成框架 Bug
    |
    +--[V2] check-env 一键校验 + pom 固定版本 + .env 隔离 + 测试分层
    |      代价:前期多花时间,多维护脚本与基线文档
    |
[Trade-off]
得到可复现、可交接、可增量演进;
失去随手改版本的便利,以及单机临时耍快的自由;
适用多人协作与长周期项目,不适用于一次性验证。

逐项比较:

正确性:V2 把“能不能跑”变成“跑的是不是同一个东西”,判断标准从感觉变成脚本输出。

稳定性:版本固定后,框架升级是可回滚的显式变更,而不是某天起床发现行为变了。

复杂度:V2 复杂度上升,主要体现在多一条 Python 工具链和一套测试分层约定。

成本:前期多半天,后期每章省下的环境折腾时间远超这个投入。

适用范围:多人协作、长周期教程、要持续 Debug 进框架源码的项目。

遗留问题:Docker 与 Testcontainers 在本章只登记不落地;模型扩展模块的具体依赖坐标需按 v2.0.3 根 pom.xml 核对;JDK 21 的虚拟线程等能力在框架内是否被使用,需要到源码章节再核验。

旧路各装各的
新路一表统管
得到的是复现
失去的是随意

09、洞见

9.1 最低支持版本解决兼容性,基线版本解决一致性

反直觉判断:把官方最低版本当作团队基线,短期看是“少装一个 JDK”,长期看是把兼容性下限当工程标准。最低版本回答“框架能不能在你机器上跑”,基线版本回答“所有人跑的是不是同一个东西”。前者是框架对你的承诺,后者是你对团队的承诺,二者不能互相替代。

9.2 反直觉判断:不是运行时依赖的东西,往往越晚补越贵

Python 不在 AgentScope Java 的运行时依赖里,按最省事的原则应该不装。但后续章节要在 MCP Server 联调、脚本、RAG 辅助服务上反复用到它。等到二十多章临时去装 Python、配 venv、解决 pip 源问题,成本远高于现在花二十分钟做完。判断标准不是“现在需不需要”,而是“后面会不会因为缺它而打断主线”。

9.3 反直觉判断:在 Agent 项目里,先怀疑依赖树,再怀疑框架

反直觉的地方在于,Agent 项目给人的心理暗示是“框架很新、框架很复杂、所以问题大概率在框架”。但实际上依赖重叠概率更高:模型扩展、HTTP 客户端、JSON 库、Reactor、日志门面同时进一个工程。mvn dependency:tree 一分钟能给出的答案,不要用猜框架源码的一下午去换。

9.4 什么时候不应该用本章这套基线

如果你只是想在单机上花十分钟验证某个 Agent API 是否可用,那就不要装 Testcontainers、不要拉 Docker、不要建 venv。基线的收益来自“重复”,一次性验证没有重复。反过来说,只要这件事要做第二遍、要在第二台机器上做、要交给第二个人做,本章的投入立刻回本。

反直觉有两条
一条关于版本
一条关于依赖
边界才是重点

10、系统落地

原来有什么:一条讲清楚了的选型结论,和若干台各装各的机器。

本篇新增了什么:统一版本矩阵、check-env 脚本、仓库目录规范、.env.example 与密钥规则、固定 2.0.3 的 Maven 基线、三种运行方式、一套 Debug 清单、测试分层约定,以及一个可编译的数字人空骨架和统一测试基类。

现在能做什么:新机器 clone 之后,按 README 跑 check-env,再跑 compile 和 test,然后用 IDE 断点进业务入口。整条路不依赖任何人的口头指导,也不依赖任何真实密钥入库。

还缺什么:空骨架里还没有 Spring Boot、没有数据库、没有 LiveKit、没有 AgentScope Java 的推理调用。数字人到目前为止还只是一个能被编译的壳。

下一步如何演进:第3式把壳变成能跑的最小闭环——项目 CRUD、配置项、运行页、LiveKit 房间和最小推理链路,并在那一式结束后冻结,后续章节全部在它上面增量开发。

开源参与点:本章未发现明确上游问题。需要说明的是,“最低版本是 JDK 17、教程用 21”属于教程选择而非框架缺陷;如果后续在核对 v2.0.3 根 pom.xml 与 quickstart 文档时发现描述不一致,应先到官方 Issues 检索,再判断是否作为候选。

原来只有选型
现在多了基线
还缺运行链路
下一式去打通

11、小结

Q1 → JDK 21 是团队基线,官方最低 17 是兼容性下限,两者不冲突
Q2 → 装。Python 不是运行时依赖,但是后续 MCP/RAG/脚本的工程依赖
Q3 → 代价是每章重装环境,且环境问题会被误判成框架 Bug
状态 → 全新机器可完成 clone → check-env → compile → test → debug

三问已有答案
状态可以交付
基线不再重装
只等数字人起

12、作业

12.1 理解题:官方最低 JDK 是 17,教程基线是 21。请打开 v2.0.3 的根 pom.xml,找出官方自己编译时使用的 release 配置与模块列表,说明你的工程应该以什么作为编译目标。

参考答案:以本教程基线为准固定为 21,并在 pom.xml 中显式写出 maven.compiler.release,同时用 mvn -version 确认 Maven 实际使用的 JDK。官方 pom.xml 的 modules 列表还能帮助你理解 core、harness、模型扩展模块的分层关系,核对地址:https://github.com/agentscope-ai/agentscope-java/blob/v2.0.3/pom.xml 。

12.2 实战题:把本章的 check-env 脚本改造成“能区分阻断项和提示项”的版本。

参考答案:把 java、mvn、git 归为阻断项,缺失时非零退出;把 python、docker、jq 归为提示项,缺失只打印警告。这样在只想跑单元测试的场景下,不必为了缺 Docker 而中断。改造后为正常与异常两种情况各加一个自检步骤或测试用例。

12.3 排障题:同事反馈“IDE 里跑得好好的,命令行 mvn test 全红”。请给出你的排查顺序。

参考答案:先看 mvn -version 打印的 Java 版本,再看 java -version 和 JAVA_HOME,对比 IDE 的 Project SDK;然后看 pom.xml 的编译目标;最后看是不是测试依赖只在 IDE 的 classpath 里存在。整个过程不要去改框架依赖版本,因为症状是工具链不一致,不是框架问题。

12.4 架构判断题:团队提出“为了简单,把 Python 环境去掉,需要时再装”。你是否同意?

参考答案:取决于时间尺度。如果这个仓库的生命周期只有一两周、只做单机验证,同意;如果它要支撑后面几十章的联调、脚本和辅助服务,不同意——去掉的是当期的复杂度,增加的是后期的中断成本。这是“工程依赖”和“运行时依赖”的区别,判断依据是复用次数而不是当前是否需要。

四题各有指向
源码要自己看
环境要自己验
判断要自己下

13、思考

这一式没有写一行 Agent 逻辑,却决定了后面二十七式会不会反复回到原点。

环境这件事的难点从来不在“装不装得上”,而在于它把三类问题混在了一起:框架问题、依赖问题、工具链问题。基线的作用,就是先把第三类问题消灭掉,让第二类问题能被 mvn dependency:tree 一眼看穿,只把第一类问题留给框架源码和 Issue 讨论区。顺序错了,你就会花大量时间去读框架源码,而真因只是 JAVA_HOME 指错了。

“会用框架”的边界是能把它跑起来;“能参与框架演进”的边界是能稳定复现、能定位到具体调用链、能判断问题在不在框架里。第2式做的正是这条分界线的前半段。

一念辨边界
一证定根因
一改知取舍
一役见真章

posted @ 2026-10-11 11:19  李福春  阅读(3)  评论(0)    收藏  举报