AgentScope-Java 入门:完善 Vue 前端、发布 GitHub,并规划下一步
到第 06 篇为止,Review Copilot 的核心能力已经跑通:
- 读取本地 Git diff。
- 读取源码上下文。
- 执行规则检查。
- 显式配置模型后调用 AgentScope-Java。
- 生成结构化
ReviewFinding。 - 通过 SSE 推送进度。
- 保存 Markdown 报告。
- 保持被评审仓库只读。
最后一篇,我们不再继续堆后端能力,而是把项目收口成一个真正可以交付、可以学习、可以发布的入门项目。
这一篇主要做四件事:
- 完善 Vue 前端体验。
- 默认使用简体中文。
- 补齐 README 和验证脚本。
- 按章节分支和 tag 发布到 GitHub。
这一步很关键。
很多教程代码"功能有了",但读者拉下来之后不知道怎么启动、怎么验证、怎么对照章节学习。
项目式入门系列不能只给代码,还要给路径。
本篇对应代码
本篇对应分支:
bash
git checkout chapter/07-ui-and-release
完成后合并回 main,并打 tag:
bash
git tag chapter-07-complete
项目仓库:
text
https://github.com/ynzz-j/agentscope-review-copilot
前端为什么选 Vue 3 + TypeScript + Vite
这个系列的重点是 AgentScope-Java,不是前端框架选型。
所以前端要满足三个条件:
- 创建方式成熟。
- 学习成本可控。
- 能覆盖真实应用需要的状态、路由和构建流程。
因此我们采用 Vue 官方成熟脚手架:
bash
npm create vue@latest frontend
选择项固定为:
text
TypeScript: Yes
JSX: No
Vue Router: Yes
Pinia: Yes
Vitest: Yes
E2E: No
ESLint: Yes
Prettier: Yes
这套组合足够支撑一个入门级工程应用:
- Vue 负责页面。
- TypeScript 负责类型约束。
- Vite 负责开发和构建。
- Vue Router 负责页面流转。
- Pinia 管理评审任务状态。
- Vitest 做单元测试。
- ESLint 和 Prettier 保持代码质量。
页面结构
Review Copilot 的前端不做营销页,打开就是可用的工具界面。
路由很简单:
ts
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
redirect: '/reviews/new',
},
{
path: '/reviews/new',
name: 'review-create',
component: ReviewCreateView,
},
{
path: '/reviews/:id/progress',
name: 'review-progress',
component: ReviewProgressView,
},
{
path: '/reviews/:id/result',
name: 'review-result',
component: ReviewResultView,
},
],
})
三个核心页面分别对应用户的三个动作:
- 创建评审。
- 查看进度。
- 查看结果。
这比做一个大而全的单页更清晰。
创建页:输入仓库路径和评审范围
ReviewCreateView 负责创建任务。
用户需要填写:
- 仓库路径。
- Diff 范围。
- 基准分支。
- 会话 ID。
- 评审重点。
表单默认值:
ts
const form = reactive({
repoPath: '',
diffMode: 'WORKING_TREE' as DiffMode,
baseRef: '',
sessionId: 'demo-session',
focusCategories: [...reviewCategories] as ReviewCategory[],
})
提交后调用 store:
ts
async function submit() {
const job = await store.create({
repoPath: form.repoPath,
diffMode: form.diffMode,
baseRef: form.baseRef,
sessionId: form.sessionId,
focusCategories: form.focusCategories,
})
await router.push(`/reviews/${job.id}/progress`)
}
这里没有在页面里直接写 fetch。
前端也要有分层:
text
View
-> Store
-> API module
-> Backend
这样后面要替换接口、加错误处理、加缓存,都不会让页面组件变得很乱。
进度页:用 SSE 看评审流水线
评审任务不是同步返回的。
因为后端要经历:
- 读取 diff。
- 读取文件上下文。
- 执行规则检查。
- 调用模型。
- 生成报告。
所以第 02 篇我们引入了 SSE。
前端通过 reviewStore.connectEvents(id) 订阅事件流:
ts
function connectEvents(id: string) {
eventSource?.close()
eventSource = connectReviewEvents(id, {
onEvent(event) {
if (!events.value.some((existing) => existing.timestamp === event.timestamp && existing.type === event.type)) {
events.value.push(event)
}
if (event.type === 'JOB_COMPLETED' || event.type === 'JOB_FAILED') {
void load(id)
eventSource?.close()
eventSource = null
}
},
onError() {
error.value = 'SSE 连接已中断。请重新加载任务以刷新状态。'
},
})
}
这个实现里有几个细节:
- 新连接前先关闭旧连接。
- 用事件类型和时间戳做简单去重。
- 完成或失败后自动加载最新任务。
- 完成或失败后关闭连接。
- 中断时给出中文错误提示。
这样用户能看到评审任务真实推进,而不是盯着一个不确定的 loading。
结果页:发现项、筛选和报告复制
ReviewResultView 负责展示最终结果。
结果页分两块:
- 结构化发现项。
- Markdown 报告。
发现项支持按严重级别和类型过滤:
ts
const filteredFindings = computed(() =>
store.findings.filter((finding) => {
const severityOk = severity.value === 'ALL' || finding.severity === severity.value
const categoryOk = category.value === 'ALL' || finding.category === category.value
return severityOk && categoryOk
}),
)
报告复制也放在结果页:
ts
async function copy() {
await store.copyReport()
copied.value = true
window.setTimeout(() => (copied.value = false), 1800)
}
对应 store:
ts
async function copyReport() {
if (!reportMarkdown.value) return
await navigator.clipboard.writeText(reportMarkdown.value)
}
为什么要保留一键复制?
因为代码评审报告经常要进入其他系统:
- GitHub PR 评论。
- GitLab Merge Request 评论。
- 飞书或企业微信。
- 工单系统。
- 知识库记录。
一键复制比强行做第三方平台集成更适合作为入门项目的收尾功能。
默认语言:简体中文
这个项目的目标读者是中文技术读者,所以前端默认显示简体中文。
语言标签集中在 i18n/zhCN.ts:
ts
export const statusLabels: Record<ReviewStatus, string> = {
CREATED: '已创建',
RUNNING: '评审中',
COMPLETED: '已完成',
FAILED: '失败',
}
export const categoryLabels: Record<ReviewCategory, string> = {
'bug-risk': '缺陷风险',
maintainability: '可维护性',
concurrency: '并发与状态',
'api-contract': 'API 契约',
'test-gap': '测试缺口',
'agent-boundary': 'Agent 边界',
}
这样做有两个好处:
第一,页面组件里不用到处写重复中文。
第二,如果后面要补英文界面,可以扩展成真正的 i18n 结构。
当前 GitHub README 也默认使用中文:
text
README.md
README.en.md
中文是默认入口,英文作为补充。
README 要写什么
一个项目式教程的 README 不应该只写一句"这是一个 Demo"。
它至少要让读者知道:
- 这个项目是什么。
- 技术栈是什么。
- 怎么启动。
- 怎么配置模型。
- 有哪些 API。
- 评审范围是什么。
- 安全边界是什么。
- 每章分支和 tag 怎么对应。
- 怎么验证。
当前 README 的结构是:
text
# AgentScope Review Copilot
## 技术栈
## 快速启动
## 模型配置
## API
## 评审范围
## 安全边界
## 分支与 Tag 策略
## 验证
其中模型配置部分要继续强调:
text
本项目不会指定默认模型提供商。
这是整个系列的重要边界。
不要在最后一篇为了"看起来更完整",又偷偷写成"默认使用 DashScope"。
分支和 tag 策略
这个系列采用章节分支。
main 保存稳定版本,每章开发在独立分支完成。
对应关系如下:
| 阶段 | 分支 | 完成 tag | 说明 |
|---|---|---|---|
| 基础框架 | main |
base-framework |
可运行基础框架 |
| 第 01 章 | chapter/01-skeleton |
chapter-01-complete |
Spring Boot + Vue 脚手架 |
| 第 02 章 | chapter/02-streaming-review |
chapter-02-complete |
SSE 评审进度 |
| 第 03 章 | chapter/03-review-tools |
chapter-03-complete |
Git diff、评审工具与最小 Agent 摘要 |
| 第 04 章 | chapter/04-review-state |
chapter-04-complete |
状态与报告存储 |
| 第 05 章 | chapter/05-permission-boundary |
chapter-05-complete |
只读权限边界 |
| 第 06 章 | chapter/06-audit-middleware |
chapter-06-complete |
AgentScope Middleware 审计 |
| 第 07 章 | chapter/07-ui-and-release |
chapter-07-complete |
Vue 页面完善与 GitHub 发布 |
每章完成后的流程:
bash
git checkout main
git pull --ff-only
git checkout -b chapter/NN-topic
# implement chapter
git add .
git commit -m "feat: implement chapter NN topic"
git checkout main
git merge --no-ff chapter/NN-topic
git tag chapter-NN-complete
git push origin main
git push origin chapter/NN-topic
git push origin chapter-NN-complete
这对读者很友好。
读者可以直接:
bash
git checkout chapter-03-complete
然后对照第 03 篇文章学习对应代码。
验证脚本
项目里保留了统一验证脚本:
powershell
.\scripts\verify.ps1 -SkipFrontendInstall
它会做这些检查:
- Java package 必须以
com.ynzz开头。 - 后端测试通过。
- 前端类型检查通过。
- 前端单元测试通过。
- 前端生产构建通过。
- 前端 lint 通过。
脚本里有一个包名检查:
powershell
$badPackages = rg -n "^package " "$Backend/src/main/java" "$Backend/src/test/java" |
Where-Object { $_ -notmatch "package com\.ynzz" }
if ($badPackages) {
$badPackages | ForEach-Object { Write-Host $_ -ForegroundColor Red }
throw "Found Java package declarations that do not start with com.ynzz"
}
这个检查对应系列计划里的硬约束:
Java 包名必须以
com.ynzz开头。
当前项目后端基础包名固定为:
text
com.ynzz.agentscope.reviewcopilot
Maven groupId 固定为:
text
com.ynzz
Smoke Review
除了单元测试和构建,还需要端到端 smoke test。
项目提供:
powershell
.\scripts\smoke-review.ps1
它用于验证:
- 后端服务能响应。
- 能创建评审任务。
- 能读取本地 Git diff。
- 能生成 findings。
- 能生成 Markdown 报告。
入门项目最好不要只依赖单元测试。
因为这类 Agent 应用经常出问题的地方不在某个纯函数,而在端到端连接:
- 前端请求字段和后端 DTO 不一致。
- SSE URL 不对。
- Vite proxy 配置缺失。
- 路径在 Windows 下转义异常。
- 模型配置存在但实际没有被调用。
- 报告生成了但前端没有加载。
Smoke test 可以快速发现这些连接问题。
最终验收清单
这个系列完成后,项目至少应该满足下面这些条件:
backend能启动。GET /health返回正常。frontend能启动。- Vite dev proxy 能访问后端
/api。 - 页面默认显示简体中文。
- 能输入本地 Git 仓库路径。
- 能选择 diff 范围。
- 能通过 SSE 看到评审阶段。
- 能读取 Git diff。
- 显式配置模型后能先生成 diff 摘要。
- 能读取允许范围内的源码上下文。
- 能执行规则检查。
- 配置模型后能真实调用 AgentScope-Java。
- 未配置模型时不默认选择 provider。
- 能生成结构化 findings。
- 能生成 Markdown 报告。
- 能一键复制报告。
- 不修改被评审源码。
- 报告只写入 Review Copilot 自己的数据目录。
- GitHub README 默认中文。
- 每章分支和 tag 可对照文章学习。
这份清单比"功能看起来能跑"更具体。
后续如果用 AI 自动开发,也可以直接把这份清单作为验收目标。
这个项目还有哪些可扩展方向
到这里,Review Copilot 是一个完整的入门项目,但还不是一个完整商业产品。
后续可以沿几个方向继续扩展。
1. PR 平台集成
当前输入是本地仓库路径和 diff 范围。
后续可以接入:
- GitHub Pull Request。
- GitLab Merge Request。
- Gitea。
- Gerrit。
那时 GitDiffTool 可以扩展成统一 diff source:
text
LocalGitDiffSource
GitHubPullRequestDiffSource
GitLabMergeRequestDiffSource
2. 规则配置化
当前规则写在 RuleCheckTool 里。
后续可以把规则配置化:
- 哪些严重级别启用。
- 哪些文件类型启用。
- 哪些目录忽略。
- 哪些规则在团队内必须阻断。
这样项目会更接近团队代码规范工具。
3. 更细粒度上下文裁剪
现在上下文读取还比较朴素。
后续可以优化为:
- 只读取 diff hunk 附近代码。
- 读取相关调用链。
- 读取测试文件。
- 读取接口定义。
- 读取配置文件。
这会显著提升模型评审质量。
4. 历史记录和数据库
当前任务和报告保存在本地 JSON 和 Markdown 文件中。
后续可以接入数据库:
- SQLite。
- PostgreSQL。
- MySQL。
这样可以支持:
- 历史查询。
- 评审趋势。
- 问题类型统计。
- 团队质量看板。
5. 多 Agent 协作
现在是一个评审 Agent。
后续可以拆成多个角色:
- Bug Risk Reviewer。
- API Contract Reviewer。
- Test Gap Reviewer。
- Agent Boundary Reviewer。
- Report Summarizer。
每个 Agent 关注不同维度,再由汇总 Agent 合并结果。
这会更贴近 AgentScope 的多 Agent 使用场景。
6. 自动修复,但必须谨慎
很多人看到代码评审助手,第一反应是:
能不能直接帮我改?
可以,但不应该在入门阶段直接开放。
自动修复至少需要:
- patch 预览。
- 用户确认。
- 修改范围限制。
- 回滚机制。
- 测试执行。
- 明确的安全边界。
在当前系列里,我们故意只做到"评审"和"报告",不做自动修改。
这是工程边界,不是能力不足。
回到 AgentScope-Java
这个系列不是为了做一个"代码评审玩具"。
它真正想带你走完的是 AgentScope-Java 项目的基本骨架:
- Spring Boot 集成。
ModelFactory。AgentFactory。ReActAgent。Toolkit。- Tool。
- 权限边界。
- RuntimeContext。
- Middleware。
- SSE。
- 状态和报告。
- 前端交互。
学完之后,你应该能把这个骨架迁移到其他项目里。
例如:
- 文档审查助手。
- 本地知识库问答助手。
- 数据分析任务助手。
- 测试用例生成助手。
- 运维排障助手。
这些项目的差异在业务工具和上下文来源,但 Agent 应用的主干很相似。
本篇小结
这一篇完成了系列收尾:
- Vue 3 前端页面完善。
- 创建页、进度页、结果页打通。
- Pinia 管理评审状态。
- 默认简体中文。
- Markdown 报告一键复制。
- 中文 README 作为 GitHub 默认入口。
- 分支和 tag 策略落地。
- 验证脚本和 smoke review 收口。
- 梳理了后续扩展路线。
至此,AgentScope-Java 2.0.0-RC4 项目式入门系列的第一版项目完成。
你可以从 base-framework 开始,也可以直接看 chapter-07-complete 的最终版本。
最推荐的学习方式是:
bash
git checkout chapter-01-complete
# 看第 01 篇
git checkout chapter-02-complete
# 看第 02 篇
git checkout chapter-07-complete
# 对照最终效果
这样能清楚看到一个 AgentScope-Java 项目是怎么一步一步长出来的。
系列导航
| 篇目 | 标题 | 状态 |
|---|---|---|
| 1 | AgentScope-Java 入门:搭建 Review Copilot 项目骨架 | 已发布 |
| 2 | AgentScope-Java 入门:用 SSE 展示评审任务进度 | 已发布 |
| 3 | AgentScope-Java 入门:让评审助手读懂 Git diff | 已发布 |
| 4 | AgentScope-Java 入门:保存评审状态并生成 Markdown 报告 | 已发布 |
| 5 | AgentScope-Java 入门:给代码评审助手加上只读安全边界 | 已发布 |
| 6 | AgentScope-Java 入门:用 Middleware 审计 Agent 调用 | 已发布 |
| 7 | AgentScope-Java 入门:完善 Vue 前端、发布 GitHub,并规划下一步 | 本文 |
作者:亦暖筑序
系列仓库:https://github.com/ynzz-j/agentscope-review-copilot
AgentScope-Java 版本:2.0.0-RC4