Files
RiskAgent/AIcoding.md
T

9.0 KiB
Raw Blame History

AI Coding 方法与技巧总结 — 外包项目风险评估系统

本文复盘本项目(outsourcing-risk-assessment)在 AI 辅助编码(AI Coding)下沉淀的方法论、协作技巧与工程实践,并附优化建议,供后续项目复用。


一、项目概览

  • 业务:外包项目风险评估 AI 系统。销售录入项目 → AI 解析分类 → 确定性引擎评分/分级/红线/盈利测算 → 风控/管理层分级审批 → 归档与审计。
  • 技术栈
    • 后端:TypeScript(严格模式)+ Hono + PostgreSQLnode-pg-migrate,29 个迁移)+ 通义千问 qwen-plus
    • 前端:React 18 + Vite + Zustand + Recharts + 自建 Design System
    • 测试:Vitest + fast-check(属性测试)+ Testing Library + axe(可访问性)+ PlaywrightE2E
    • 部署:deploy.sh 一键部署(PM2 + nginx + Let's Encrypt),生产 https://pm.hr8ai.top
  • 规模:113 个测试文件、40+ 属性测试文件、规格文档 2387 行(requirements/design/tasks)。

二、核心方法论

1. 规格驱动开发(Spec-Driven Development

项目以 .kiro/specs/ 下的三份文档为"地面真值",先规格后代码:

文档 作用
requirements.md EARS 格式需求(WHEN/IF/WHERE/SHALL),可测试、可追溯
design.md 架构、数据模型、模块边界、正确性属性(Correctness Properties
tasks.md 可执行任务清单,逐项实现并验证

要点:每个需求都映射到验收标准;每条正确性属性都对应一个属性测试(如 computeRiskScore.property18.test.ts)。代码改动先回到规格确认,避免"凭感觉写"。

2. 确定性引擎 + LLM 语言层 的分层(最关键的架构决策)

这是本项目最重要、最值得复用的原则:

凡是涉及金额、评分、分级、红线、裁决的逻辑,一律是确定性纯函数,绝不交给 LLM;LLM 只做语言理解(分类、指标预填、岗位抽取、综合研判)。

  • 纯函数核心src/scoringsrc/cost/profitability.tssrc/strategy 等均为无副作用、可复算、可属性化测试的纯函数。相同输入永远得到相同输出。
  • LLM 边界src/llmsrc/adapters 负责把自然语言转成结构化输入;失败/超时自动降级到确定性兜底(fallback.ts),不阻塞主流程。
  • 收益:可审计、可回归、结果稳定、合规可解释——金融/风控类系统的硬要求。LLM 的不确定性被隔离在"翻译层",不污染决策。

3. 属性化测试(Property-Based Testing, PBT

用 fast-check 对核心引擎做属性测试,而非只写样例用例。例如:

  • 风险总分恒在 [0,100],且分级恒等于 classifyGrade(score)
  • 编辑重评时未改动的维度评分必须保持不变(preserve 属性);
  • 持久化往返(save → load)必须等价(roundtrip 属性)。

收益:用随机输入覆盖边界,暴露样例测试漏掉的缺陷;属性即"活的规格",重构时是安全网。


三、AI 协作中验证过的有效技巧

1. 小步快跑 + 每批验证

长任务拆成小批,每批改完立刻跑验证三件套:

npx tsc --build                       # 后端类型检查(改后必须重启 dist 进程)
npx tsc -p web/tsconfig.json --noEmit # 前端类型检查
npx vitest run                        # 全量测试(456 用例)

绝不在未验证的情况下连续堆改动。类型检查 + 测试通过才进入下一批。

2. 严格的 TypeScript 配置

开启 exactOptionalPropertyTypesnoUncheckedIndexedAccess 等最严选项。编译器把大量运行期 bug 前移到编码期——AI 生成的代码尤其受益于强类型护栏。

3. 每个改动独立 commit

每完成一个可工作的改动就 commit,信息写清"根因 + 改法 + 验证"。便于回滚、便于审计 AI 的每一步。

4. 根因优先,不打补丁

遇到问题(如"盈利收入为 0"、"校准重复提示")先定位根因再动手:

  • 收入为 0 → 根因是报价口径录入缺失,不是计算 bug → 加录入校验而非改公式。
  • 校准重复提示 → 根因是偏差来自历史数据 + 公式累加 → 改为基于未校准基准的幂等计算,并暴露"已校准"状态。

5. 生产环境的真实验证

改完不止单测,还在生产上端到端验证(登录拿 token → 调接口 → 查数据库确认副作用)。例如验证"登出留痕":

TOKEN=$(curl ... /api/auth/login ...)
curl -X POST .../api/auth/logout -H "Authorization: Bearer $TOKEN"
# 再查 system_logs 确认出现"登出"记录

6. 复用既有组件与模式

新功能优先沿用既有约定(如统一 Table 组件、Icon 图标集、复合键分隔符 \u0000、用户 ID 关联),而非另起炉灶。一处修复(如给 Table 加横向滚动容器)让全站受益。

7. 规避工具/环境陷阱(踩坑沉淀)

  • 多字节中文 curl 输出常被 shell 截断 → 用 printf / 写临时文件 + python 读取。
  • bash 命令不用全角括号;复杂逻辑放 node -e / python3 -c
  • 后端改完必须 tsc --build 再重启 dist 进程,否则跑的是旧代码。
  • JSONB 不能存裸 \u0000 → 入库前编码(\u0000\uE000)、读出时解码。

四、工程实践沉淀

  • 数据库迁移化:所有 schema 变更走 migrations/*.cjs,可重放、可回滚,生产与本地一致。
  • 配置惰性读取AUTH_SECRET 等密钥惰性读取(避免模块导入时固化导致 RBAC 失效);密钥放 gitignore 的 deploy.env
  • 全局审计中间件:一个 app.use('/api/*') 中间件统一记录所有写操作 + 登录/登出 + 关键只读(导出/查看),自动解析操作人/角色/目标项目/决策/IP/耗时,跳过高频轮询端点避免噪音。
  • 数据隔离与 ID 关联:全部人员用稳定用户 ID 关联记录,界面实时解析成姓名;销售只见本人发起的评估(行级隔离)。
  • 可访问性内建:用 axe 在测试中校验对比度、焦点、ARIA 角色,UI 一致性由 Design System 保证。

五、优化建议(我的视角)

工程与质量

  1. 补 E2E 回归:已装 Playwright,但回归仍靠手测。建议补一条主链路 E2E(登录→新建→申报→风控→管理层→归档→审计),纳入 CI,防止"改 A 坏 B"。
  2. CI 门禁.github/workflows/ci.yml 应强制 typecheck + lint + vitest 全绿才可合并/部署;deploy.sh 前置一次测试闸门。
  3. 前端测试拆分:详情页改动频繁,按功能区拆 snapshot/交互测试,降低脆性。
  4. 大数据量性能:列表已服务端分页,建议补关键查询索引(如 system_logs(ts)assessments(assessor_id,status));前端列表上虚拟滚动。

架构与可维护性

  1. 拆分 src/server/index.ts:单文件已超 2500 行,建议按资源域拆成路由模块(assessments / users / calibration / logs …),降低认知负担与合并冲突。
  2. 审计中间件的请求体重复读取:登录/审批分支在 next() 后再次 c.req.json(),依赖框架缓存。建议显式缓存一次请求体,避免框架升级后行为变化。
  3. 校准语义文档化:把"目标净利率基准 / 历史偏差 / 幂等校准"的语义写进 design.md,避免未来再次误解为可累加。

LLM 层

  1. LLM 输出校验与可观测:对分类/预填的 LLM 结果做 schema 校验 + 置信度阈值(部分已做),并把 LLM 调用耗时/降级率纳入系统日志,便于评估模型稳定性与成本。
  2. 提示词与模型版本治理:把 prompt 模板与模型名集中管理、版本化,便于灰度与回滚。
  3. 经验库闭环experience_library 已具雏形,可把"预测 vs 实际"偏差与驳回原因反哺到 LLM 预填的 few-shot,形成数据飞轮。

安全与合规

  1. JWT 增强:当前为自实现 HMAC,建议迁移到 jose,支持密钥轮换与更短有效期 + 刷新令牌。
  2. 密钥与备份:确认 .env/deploy.env 不入库(已 gitignore);定期演练数据库备份恢复(已有 baidu-backup.sh,建议加恢复演练)。
  3. 登出令牌失效:当前登出仅前端丢弃 token,服务端无状态。若需"立即失效",可引入短期 token + 服务端黑名单/版本号。

六、可复用的"黄金法则"清单

  1. 决策逻辑确定性纯函数化,LLM 只做语言层,二者严格隔离。
  2. 先规格(需求/设计/正确性属性)后代码,规格是地面真值。
  3. 核心逻辑写属性测试,而不仅是样例测试。
  4. 小步改动 + 每批 typecheck + test 验证 + 独立 commit。
  5. 根因优先,拒绝表面打补丁。
  6. 改完在生产做端到端真实验证(含数据库副作用)。
  7. 严格 TS + 迁移化 schema + 全局审计,让系统可回归、可审计、可解释。

本文由项目实践复盘整理,可随项目演进持续更新。