Files
his/AGENTS.md

413 lines
15 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OpenHIS - AI Agent Development Guide
## 项目概览
OpenHIS 是一个医院管理系统,采用 Java 17 + Spring Boot 后端和 Vue 3 + Vite 前端架构。
## 构建和运行命令
### 后端Java/Spring Boot
```bash
# 构建整个项目
cd openhis-server-new
mvn clean package -DskipTests
# 运行后端(开发模式)
cd openhis-server-new/openhis-application
mvn spring-boot:run
# 运行特定模块
cd openhis-server-new/[module-name]
mvn spring-boot:run
```
### 前端Vue 3 + Vite
```bash
# 安装依赖
cd openhis-ui-vue3
npm install
# 开发服务器
npm run dev
# 生产构建
npm run build:prod
# 测试环境构建
npm run build:test
# 预览构建结果
npm run preview
```
### 测试
项目当前没有配置正式的测试框架。如需添加测试:
- 后端:考虑使用 JUnit 5 + Mockito
- 前端:考虑使用 Vitest + Vue Test Utils
## 代码风格规范
### Java 后端规范
- **Java 版本**: 17
- **框架**: Spring Boot 2.5.15
- **ORM**: MyBatis Plus 3.5.5
- **数据库**: PostgreSQL
- **包结构**:
- `com.openhis` - 业务逻辑
- `com.core` - 核心框架
- **命名约定**:
- 类名PascalCase`UserController`
- 方法名camelCase`getUserList`
- 常量SCREAMING_SNAKE_CASE
- 配置文件kebab-case
- **注解使用**:
- 使用 `@Slf4j` 替代手动声明 logger
- 使用 `@Data` 在实体类中
- 使用 `@Service/@Controller/@Repository` 等 Spring 注解
- **异常处理**:
- 使用统一的异常处理机制
- 自定义业务异常继承 `RuntimeException`
### Vue 前端规范
- **框架**: Vue 3 + Composition API
- **UI 库**: Element Plus
- **状态管理**: Pinia
- **路由**: Vue Router 4
- **构建工具**: Vite 5
- **组件命名**: PascalCase
- **文件命名**: kebab-case
- **变量命名**: camelCase
- **常量命名**: SCREAMING_SNAKE_CASE
- **函数命名**:
- 事件处理:`handle` 前缀
- 数据获取:`get`/`load` 前缀
- 提交操作:`submit` 前缀
### 导入顺序
#### Java
1. `java.*`
2. `javax.*`
3. 第三方库
4. `com.core.*`
5. `com.openhis.*`
6. `*.*`(其他包)
#### JavaScript/Vue
1. `vue` 相关
2. 第三方库
3. `@/` 别名导入
4. 相对路径导入
### 代码格式
#### Java
- 缩进4个空格
- 行长度120字符
- 左大括号不换行
#### Vue/JavaScript
- 缩进2个空格
- 字符串:优先使用单引号
- 行长度100字符
## 关键配置文件
### 后端配置
- 主配置:`openhis-server-new/openhis-application/src/main/resources/application.yml`
- 环境配置:`application-{profile}.yml`
- Maven 父 POM`openhis-server-new/pom.xml`
### 前端配置
- Vite 配置:`openhis-ui-vue3/vite.config.js`
- 环境变量:`.env.*` 文件
- 路由配置:`openhis-ui-vue3/src/router/index.js`
## 开发约定
### API 设计
- RESTful API 风格
- 统一响应格式
- 使用 Swagger 文档
- 错误码统一管理
### 数据库
- 表名snake_case
- 字段名snake_case
- 主键:使用 `id`
- 软删除:使用 `valid_flag` 字段
### 前端组件
- 单一职责原则
- Props 使用 camelCase
- Events 使用 kebab-case
- 使用 Composition API
- 组件文档使用 JSDoc
### 状态管理
- 模块化设计
- 异步操作使用 actions
- 避免在组件中直接修改状态
## 环境变量
### 前端
- `VITE_APP_BASE_API`: API 基础路径
- `VITE_APP_ENV`: 环境标识
### 后端
- `spring.profiles.active`: 激活的配置文件
- `core.name`: 应用名称
- `core.version`: 应用版本
## 安全规范
- 所有 API 接口需要权限验证
- 敏感信息使用环境变量
- SQL 注入防护
- XSS 攻击防护
## 性能优化
- 后端使用连接池Druid
- 前端使用路由懒加载
- 图片使用 WebP 格式
- 大列表使用虚拟滚动
## 常用工具类
- 后端:`com.core.common.utils.*`
- 前端:`@/utils/*`
## 注意事项
1. 修改数据库结构需要同步 SQL 脚本
2. 新增功能需要添加权限配置
3. 前端路由需要在权限系统中注册
4. 接口变更需要更新 Swagger 文档
5. 遵循现有代码风格,避免不必要的变化
## 故障排除
- 后端端口18080
- 前端端口81
- API 前缀:`/openhis`
- Swagger UI`/openhis/swagger-ui/index.html`
- Druid 监控:`/openhis/druid/login.html`
## 铁律:全链路修复原则 ⚠️
> 修 Bug / 做需求时,**不得"就事论事"**,必须走通完整的**数据流全链路**
### 检查清单(每一环都确认)
1. **录入** → 前端有无输入入口?(弹窗、表格行编辑、表单…)
2. **保存** → 前端 → API → 后端 Controller → Service → Entity → DB**每一个保存入口**都传了该字段吗?(注意多个 Service 实现类可能走不同入口)
3. **查询** → DB → Mapper XML注意 UNION ALL 子查询要统一加)→ DTO → 前端展示,列和数据绑定都完整吗?
4. **修改** → 已有数据编辑回显 → 修改再保存 → 数据能正确更新吗?
5. **删除/停止/撤回** → 相关状态变更会丢失该字段数据吗?
6. **关联模块** → 上游(如医嘱录入后护士站要看到备注)和下游(如打印、计费、报表)是否也需要同步修改?
### 常见陷阱
- ❌ 只修了「主入口」的保存逻辑,忘了「批量保存」「签发保存」等其他入口
- ❌ 前端加了输入框,后端 Service 没传字段(不同模块可能走不同 Service 实现类)
- ❌ Mapper XML 是 UNION ALL 查询,只改了其中一个子查询,导致列数不匹配或漏加
- ❌ DTO 层级继承关系没检查(如 `RegAdviceSaveDto extends AdviceSaveDto`,父类改了对不对)
- ❌ 只测了新增,没测编辑已有数据的回显和修改再保存
### 执行细则
- 每个字段的新增/修改,先在纸上(或文档里)画出完整的数据流向图再动手
- 提交前逐个环节检查一遍,确保没有断链
- 编译通过不等同于功能正确,必要时做端到端验证
## Harness Engineering — Agent 工作方法论
> 约束清晰 + 反馈快速 = 高成功率。Harness 质量决定 Agent 产出质量。
### 工作流程Plan → Generate → Validate → Review
```
阶段 0需求分析你主导
→ 写清楚 BUG 现象 / 需求描述 / 验收标准
阶段 1任务规划Agent 制定 + 你确认)
→ 画出数据流向图(前端 → API → Service → Mapper → DB
→ 列出涉及的所有文件
→ 标注每个环节的约束(不可删文件、必须编译通过)
阶段 2执行修改Agent 自主)
→ 一次只改一个文件或一组逻辑相关的文件
→ 每步执行后保存检查点
阶段 3验证自动
→ mvn compile -pl openhis-application -am 必须通过
→ 检查数据流每个节点:输入字段 → 保存 → 查询 → 展示
→ 多入口验证(新增 vs 编辑 vs 批量等)
阶段 4审查提交你确认
→ git diff 审查变更范围
→ 确认没有误删/误改
```
### 三层约束执行
| 阶段 | 约束 | 执行方式 |
|---|---|---|
| **修改前** | 禁止删除文件、禁止改动包名/类名/方法签名 | task-plan 阶段检查 |
| **修改中** | 不改与任务无关的代码、不改非 AI 写的代码(除非编译必须) | 每次 diff 自查 |
| **修改后** | `mvn compile` 必须通过、数据流全链路验证 | 提交前自动执行 |
### 反馈优化循环
```
Agent 提交代码
编译器反馈 → 失败则分析根因(非运气式重试),定位具体符号错误
数据流验证 → 检查每个环节字段是否贯通
你审查 → 发现问题后:
├── 立即修复
└── 同步更新 AGENTS.md 规则(沉淀教训)
通过 → 提交代码
```
### 持续优化:从每次失败中学习
每次编译失败或你审查发现问题,都应触发 Harness 优化:
1. **收集数据** → 失败原因是什么?(缺字段、少文件、改错位置…)
2. **识别模式** → 这是第几次犯同类错误?是否有规则盲区?
3. **优化 Harness** → 更新 AGENTS.md / 补充检查清单
4. **验证效果** → 后续类似任务是否不再出错
### Agent 角色定位
你不是工具,是团队成员。你的角色演变:
- ~~阶段 1代码补全~~ → 我们已跳过
- ~~阶段 2结对编程~~ → 我们已跳过
-**阶段 3自主开发者** → 你在 Harness本文件定义的约束、流程、反馈中自主完成开发任务
人类工程师(用户)设计 HarnessAgent在 Harness 中执行。
## 四大核心组件
### 1. 约束机制Constraints
让 Agent 在正确边界内工作:
| 约束层 | 内容 | 本项目的具体规则 |
|---|---|---|
| **架构约束** | 项目结构、模块划分、接口规范 | 已有包结构不可改;不可删除文件;不可改包名/类名/方法签名 |
| **代码规范** | 编码风格、命名约定、安全规则 | 见上方「代码风格规范」章节 |
| **业务规则** | 领域模型、业务逻辑校验 | 全链路修复原则:每个字段的保存/查询/修改/删除链路必须完整 |
| **编译约束** | 必须通过编译 | `mvn compile -pl openhis-application -am` 强制门禁 |
### 2. 反馈回路Feedback Loops
让 Agent 知道自己的输出是否正确:
```
Agent 生成代码
编译检查 ──失败──→ 分析根因(具体符号/类型错误),定位到文件+行号
↓ 通过
数据流验证 ──断链──→ 补全缺失的字段链路
↓ 通过
你审查 ──发现问题──→ 立即修复 + 同步更新 AGENTS.md
↓ 通过
提交
```
### 3. 控制平面Control Plane
管理和监控 Agent 的执行:
| 组件 | 功能 | 本项目的实现方式 |
|---|---|---|
| **任务调度** | 分配管理任务 | 你发起任务Agent 按工作流执行 |
| **状态管理** | 跟踪执行状态 | 每个任务用 update_plan 记录进度 |
| **可观测性** | 记录完整执行链路 | git diff 审查变更范围;编译结果作为门禁 |
| **人机协作** | 人类介入触发点 | 你做最终审查批准Agent 自主执行 |
### 4. 持久执行Durable Execution
保障 Agent 长时间可靠运行:
| 组件 | 功能 | 本项目的实现方式 |
|---|---|---|
| **状态持久化** | 定期保存执行状态 | 每个任务用 update_plan 记录进度和当前状态 |
| **断点续传** | 中断后自动恢复继续执行 | 编译失败后不从头重来,从失败点继续修复 |
| **超时处理** | 长时间任务的优雅处理 | 超过单次 token 预算时做 checkpoint下次继续 |
| **资源清理** | 任务完成后释放资源 | git commit 后清理中间文件,保持工作区干净 |
## Harness 设计原则
### 渐进式构建
- **从简单任务开始**:先修单一字段遗漏(如 #597 加 remark再处理跨模块联动
- **先建立基础约束**:不可删文件、必须编译通过 → 这是底线
- **再完善反馈回路**:数据流全链路验证 → 补充 AGENTS.md 规则
- **持续迭代 Harness**:每次失败都是优化 Harness 的机会
### 可观测性优先
- 所有修改必须可 git diff → 可追溯
- 编译结果必须有日志 → 可诊断
- 任务进度必须 update_plan → 可见
### Harness 即代码
- AGENTS.md 本身是代码需要版本化管理git commit
- 每次规则迭代都要提交 AGENTS.md 变更
- 规则变更和业务代码变更一样,需要你审查
## 人机协作边界
| 决策类型 | 你(人类工程师)主导 | Agent执行 | 协作方式 |
|---|---|---|---|
| **需求定义** | ✅ 写清楚 BUG 现象 / 验收标准 | — | — |
| **技术方案** | ✅ 确认方向 | 提出建议 | 你拍板 |
| **代码修改** | 审查批准 | ✅ 自主执行 | 编译通过后你审查 |
| **质量验证** | 端到端验证 | ✅ 数据流检查 + 编译 | 你确认功能正确 |
| **规则沉淀** | ✅ 补充 AGENTS.md | 记录失败模式 | 你决定什么值得写 |
| **架构变更** | ✅ 必须由你决策 | 标记需要你关注 | 不可擅自改动 |
## 工程师的转型:从编码者到 Harness 设计师
在 Agent-First 模式下,你的角色正在转变:
| 传统能力 | → Harness Engineering 能力 |
|---|---|
| 写代码实现功能 | → 设计约束和规则,让 Agent 高效产出 |
| 调试修复 Bug | → 设计自动化反馈回路,让 Agent 自愈 |
| Code Review | → 审查 Agent 的 Harness 执行是否符合规范 |
| 技术选型 | → 设计 Agent 工作流和协作边界 |
> 你 80% 的时间花在设计 Harness本文件而不是手写业务代码。
> Agent负责执行编码你负责确保执行环境好到不需要你频繁介入。
## 范式定位:三次跃迁中的本项目
| 范式 | 关注 | 本项目的状态 |
|---|---|---|
| **Prompt Engineering** | 优化单次提示词 | ✅ 已超越 — 系统提示 + AGENTS.md 定义长期上下文 |
| **Context Engineering** | 管理外部上下文RAG、检索 | ✅ 已内置 — AGENTS.md + 代码库结构作为 Agent 的上下文 |
| **Harness Engineering** | 设计 Agent 工作环境(约束+反馈+控制) | ✅ **当前范式** — 本文件定义完整的约束、流程、反馈循环 |
**核心转变**你不再是提问者Prompt或信息提供者Context而是**系统设计师Harness**。
## 未来方向Meta-Harness
当 Harness Engineering 成熟后,下一个跃迁可能是 **Meta-Harness** — AI 自动设计和优化自身的工作环境(约束规则、反馈回路、工作流程)。
在这个项目中的具体表现:
- 每次编译失败后Agent 自动分析根因并**建议**更新的 AGENTS.md 规则
- 但你(人类工程师)始终保留**最终审批权** — 规则沉淀需要你确认
- 目标:从"你主动教我" → "我自己学习并请你确认"
> 这是 Harness Engineering 的终局Agent 不仅能写代码,还能自我优化执行的框架。
> 但**底线不可放弃** — 删除文件、架构变更等红线始终由你控制。
## 思维模式转变
当 Agent 出现问题时,不要问"怎么修这个 Bug",该问:
| 旧思维 | → Harness 思维 |
|---|---|
| "这段代码有 Bug" | "约束机制哪里不够完善?" |
| "我来修复这个问题" | "反馈回路为什么没有捕获?" |
| "Code Review 通过" | "自动化验证全部通过了?" |
| "这个功能怎么实现?" | "如何让 Agent 理解这个需求?" |
| "项目进度如何?" | "Harness 效率指标如何?" |
| 关注具体实现 | 关注系统设计 |
| 关注个人产出 | 关注环境效率 |
| 关注代码质量 | 关注约束完善 |
> 你的成功不再取决于你写的代码行数,而是取决于你设计的 Harness 质量。