ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

agent-skills:智能体技能模块化工程实践

agent-skills:智能体技能模块化工程实践 1. 项目概述一个被严重低估的“技能容器”设计范式“agent-skills”这个词组乍看像某个开源库的包名或者某次技术分享里一闪而过的术语。但如果你在最近半年翻过 GitHub Trending、读过几篇关于智能体Agent架构的深度实践甚至只是在 TypeScript 社区里刷到过 Nx 工程化讨论你大概率已经和它打过照面——只是没意识到它的名字叫“agent-skills”。它不是框架不是 SDK更不是某个大厂闭源项目代号它是一套面向智能体能力解耦与复用的工程化契约是把“让 AI 做事”这件事从脚本式拼凑推进到模块化交付的关键中间层。核心关键词“agent-skills”本身已揭示本质skills技能是原子能力单元agent智能体是调度与执行主体二者之间必须存在清晰、稳定、可验证的接口边界。而支撑这套边界的底层技术栈——Node.js 提供运行时确定性TypeScript 提供类型契约保障Nx 实现跨技能的依赖管理与构建隔离semantic-release 则确保每一次能力迭代都能自动沉淀为语义化版本的可发布产物。这四者组合不是技术堆砌而是针对“AI 能力持续交付”这一新场景的精准选型。它解决的不是“能不能跑通一个 RAG 流程”的问题而是“当团队同时维护 12 个不同业务线的智能体每个智能体需调用 3~7 个外部 API、处理 4 类结构化数据、集成 2 种向量数据库、还要支持灰度发布与 AB 测试”时如何避免代码重复、类型错配、版本混乱、回滚失焦等典型熵增问题。适合谁不是刚学完console.log(Hello World)的新手而是正在落地真实 Agent 应用的中高级前端/全栈工程师、AI 工程师、以及负责技术基建的平台研发同学。你不需要懂 LLM 内部原理但必须理解“函数即服务”在智能体语境下的新含义——这里的函数是带上下文感知、错误恢复策略、可观测埋点、且能被自然语言描述调用的技能单元。我第一次在客户现场看到这个模式落地是在一个保险理赔智能助手项目里。当时他们有 5 个独立开发小组分别负责“OCR 识别保单”、“核对医保目录”、“计算赔付比例”、“生成拒赔理由”、“推送短信通知”五个能力。最初各写各的 Express 路由结果上线后发现OCR 模块升级了返回格式导致下游三个模块全部报错医保目录接口变更未同步文档测试环境用的是旧版 mock赔付计算逻辑修改后没人记得要更新拒赔理由生成模块里的兜底规则……两周内紧急回滚 4 次。后来我们用agent-skills重构每个能力封装为独立 Nx 库定义严格输入输出 interface通过agent-skills/ocr这样的包名引用所有类型检查在编译期完成semantic-release 自动触发 npm publish下游只需npm update agent-skills/ocr并校验类型兼容性。此后三个月零生产事故。这不是玄学是把“人肉协调”变成“机器可验证契约”的必然结果。2. 整体设计思路为什么是 Skills 而不是 Plugins 或 Actions2.1 技能Skill的本质有状态、可组合、带元信息的函数很多人第一反应是“这不就是微服务不就是 Serverless Function” 不完全是。Skills 和传统后端服务的关键差异在于其隐含的上下文生命周期与组合语义。一个 Skill 不仅要声明“我能做什么”更要明确“我在什么条件下做”、“我依赖哪些前置状态”、“我执行后会改变哪些共享上下文”、“我的失败是否允许重试或降级”。比如agent-skills/validate-policy这个技能它的 TypeScript 接口绝不是简单的(input: PolicyInput) PromisePolicyResult。真实定义长这样// libs/validate-policy/src/lib/validate-policy.skill.ts export interface PolicyValidationContext { /** 当前用户会话ID用于审计追踪 */ sessionId: string; /** 上游OCR识别出的原始文本块非结构化 */ rawOcrText: string; /** 已解析的保单JSON结构可能为空表示尚未执行OCR */ parsedPolicy?: ParsedPolicy; /** 当前智能体的全局配置快照 */ agentConfig: AgentConfig; } export interface PolicyValidationResult { isValid: boolean; issues: ValidationIssue[]; /** 执行耗时用于后续性能分析 */ durationMs: number; /** 本次执行所用的规则引擎版本 */ ruleEngineVersion: string; } export type PolicyValidationSkill ( context: PolicyValidationContext, options?: { /** 是否启用缓存基于sessionIdrawOcrText哈希 */ useCache?: boolean; /** 超时阈值单位毫秒 */ timeoutMs?: number; } ) PromisePolicyValidationResult;注意几个关键设计点上下文对象Context强制携带sessionId、rawOcrText等非业务参数这是为了满足可观测性日志追踪、缓存策略避免重复 OCR、权限控制sessionId关联用户角色等横切关注点。Skills 不是孤立函数而是嵌入智能体运行时环境的活体组件。结果对象Result包含durationMs和ruleEngineVersion这是为后续 A/B 测试和模型迭代提供数据基础。当你想对比新旧规则引擎效果时无需额外埋点结果里自带黄金指标。选项对象OptionsuseCache和timeoutMs是 Skills 的“行为开关”而非硬编码逻辑。这使得同一个 Skill 在不同智能体流程中可灵活适配——客服机器人可开缓存保响应速度风控系统则必须关缓存保数据新鲜度。这种设计直接否定了“Plugin”模式插件通常只暴露初始化和执行方法缺乏上下文契约和“Action”模式Action 多见于 Redux强调纯函数与状态不可变但无法表达超时、缓存等副作用控制。Skills 是有状态感知、可配置、带元数据的智能体原生能力单元。2.2 Nx 作为工程骨架为什么不用 Monorepo 工具链中的其他选择面对多 Skills 管理Monorepo 是共识但为何是 Nx 而非 Turborepo、Rush 或自建 Lerna答案藏在 Nx 对“任务依赖图Task Dependency Graph”的深度掌控里。假设你有三个 Skillsagent-skills/ocr依赖 Tesseract.jsagent-skills/validate-policy依赖agent-skills/ocr的输出agent-skills/generate-report依赖agent-skills/validate-policy的结果在 Nx 中你只需在project.json里声明{ targets: { build: { executor: nrwl/js:tsc, dependsOn: [^build], options: { tsConfig: libs/validate-policy/tsconfig.lib.json } } } }^build表示“先构建所有依赖我的项目”。Nx 会自动解析validate-policy的package.json中dependencies: { agent-skills/ocr: ^1.2.0 }并构建ocr库。更重要的是Nx 的nx affected命令能精准回答“如果我只修改了ocr库的tesseract-worker.ts文件哪些 Skills 需要重新构建、测试、发布” 它不是靠文件路径模糊匹配而是基于 AST 分析实际导入关系连import { preprocessImage } from agent-skills/ocr/utils这种深层引用都不会漏掉。对比 Turborepo它依赖turbo.json中手动配置的pipeline你需要显式写build: [^build]且无法感知utils这类内部模块的变更影响。Rush 更侧重于大型企业合规发布流程对单个 Skill 的快速迭代支持不足。而 Lerna 在现代 TypeScript 工程中已显笨重其lerna run build --since命令常因 Git 树不一致导致误判。实操心得我们在一个 37 个 Skills 的项目中将nx affected --targetbuild的平均执行时间控制在 8.2 秒CI 环境而同等规模下手动npm run build全量构建需 4分32秒。这不仅是时间节省更是发布信心的来源——你知道每次发布的产物只包含真正受影响的代码没有“以防万一”的冗余打包。2.3 semantic-release让技能演进可追溯、可预测、可回滚Skills 的价值在于持续进化OCR 模型升级、医保目录更新、赔付规则调整……这些变化必须以最小扰动方式触达所有使用者。semantic-release 就是实现这一目标的自动化引擎。它的工作流极简开发者提交 PR标题按约定格式书写如feat(validate-policy): add support for dental insurance codes或fix(ocr): handle rotated PDF pagesCI 流水线运行npx semantic-release工具自动解析提交历史根据feat/fix/perf等前缀判断版本号应升为1.3.0、1.2.1或1.3.0自动生成 CHANGELOG.md发布到 npm registry并打 Git tag。关键在于它把“人类对变更的理解”feat/fix翻译成了“机器可执行的版本语义”。下游智能体开发者看到agent-skills/validate-policy1.2.1无需翻阅文档或 Slack 记录就能 100% 确信这是一个向后兼容的 Bug 修复可以安全升级。而agent-skills/validate-policy2.0.0则意味着重大变更需要检查 BREAKING CHANGES 日志。提示我们强制要求所有 Skills 库的package.json中publishConfig.access设为public并使用npm publish --provenance启用软件物料清单SBOM签名。这并非过度设计——当某天安全团队要求审计“哪个版本的 OCR 技能曾使用过有漏洞的 Tesseract 5.2.0”你能立刻给出精确答案而不是在 Slack 里翻三天记录。3. 核心细节解析从零搭建一个可发布的 Skill3.1 初始化 Nx Workspace 与 Skill 库结构不要从npx create-nx-workspacelatest开始。那个命令创建的是完整应用模板而 Skills 库需要极致轻量。正确姿势是# 1. 创建空 workspace npx nxlatest new agent-skills-workspace --presetapps-and-libraries --interactivefalse --skip-gittrue --nx-cloudfalse # 2. 进入目录移除默认生成的 apps/ cd agent-skills-workspace rm -rf apps/ # 3. 创建第一个 Skill 库OCR npx nxlatest g nrwl/js:library ocr --directorylibs --importPathagent-skills/ocr --publishable --buildable --no-interactive这三步后目录结构如下agent-skills-workspace/ ├── libs/ │ └── ocr/ │ ├── src/ │ │ ├── index.ts # 入口导出 skill 函数 │ │ └── lib/ │ │ ├── ocr.skill.ts # 核心技能实现 │ │ └── tesseract-wrapper.ts # 第三方库封装 │ ├── project.json # Nx 构建配置 │ ├── tsconfig.json # 类型配置 │ └── package.json # 发布配置重点看project.json中的targets{ targets: { build: { executor: nrwl/js:tsc, outputs: [{options.outputPath}], options: { outputPath: dist/libs/ocr, main: libs/ocr/src/index.ts, tsConfig: libs/ocr/tsconfig.lib.json, assets: [libs/ocr/*.md] } }, publish: { executor: nrwl/workspace:run-commands, dependsOn: [build], options: { command: npm publish dist/libs/ocr --provenance } } } }publishtarget 显式依赖build确保发布前必先构建。--provenance参数启用 SBOM这是现代 npm 包的必备安全实践。3.2 TypeScript 类型契约定义 Skill 的“宪法”一个 Skill 的index.ts是它的宪法必须严谨。以 OCR Skill 为例// libs/ocr/src/index.ts import { OcrSkill, OcrContext, OcrResult } from ./lib/ocr.skill; /** * OCR 技能将图像或 PDF 转换为结构化文本 * * remarks * 此技能依赖 Tesseract.js WebAssembly 版本需确保运行时环境支持 WASM。 * 输入图像尺寸建议不超过 2000x2000 像素过大将触发内存限制。 * * example * ts * const result await ocrSkill({ * sessionId: sess_abc123, * documentType: health_insurance_card, * imageBuffer: fs.readFileSync(./card.jpg) * }); * console.log(result.textBlocks[0].content); // XX市医疗保险卡 * */ export const ocrSkill: OcrSkill async (context, options {}) { // 实际实现见 ocr.skill.ts }; // 导出类型供下游引用 export type { OcrContext, OcrResult, OcrSkill };这里的关键是remarks和exampleJSDoc 标签。它们会被typedoc自动生成 API 文档更重要的是VS Code 能直接在 import 处显示提示。当另一个开发者写import { ocrSkill } from agent-skills/ocr时鼠标悬停就能看到完整的使用说明、注意事项和代码示例——这比写 Wiki 文档高效十倍。OcrContext和OcrResult的定义必须包含所有可能影响行为的字段。例如documentType字段它决定了 OCR 引擎使用的预训练模型医疗卡 vs 身份证 vs 驾驶证这是 Skill 的核心配置项绝不能放在options里让用户随意传入字符串。我们用联合类型约束// libs/ocr/src/lib/ocr.skill.ts export type DocumentType health_insurance_card | id_card | driver_license | bank_statement; export interface OcrContext { sessionId: string; documentType: DocumentType; // 强制枚举杜绝拼写错误 imageBuffer: Buffer; // 原始二进制数据 /** 可选指定页面范围仅对 PDF 有效 */ pageRange?: [number, number]; // [start, end], inclusive } export interface OcrResult { textBlocks: TextBlock[]; confidenceScore: number; // 整体置信度 0.0 ~ 1.0 processedPages: number; // 实际处理页数 /** 用于调试的详细日志 */ debugInfo?: { modelUsed: string; preprocessingTimeMs: number; }; }3.3 Nx 构建与测试确保 Skills 的“出厂质量”Skills 必须通过三重检验才能发布类型检查tsc --noEmit确保无 TS 错误单元测试覆盖核心逻辑与边界 case集成测试验证与真实依赖如 Tesseract的交互。Nx 默认为库生成 Jest 测试。我们在libs/ocr/src/lib/ocr.skill.spec.ts中编写import { ocrSkill } from ./ocr.skill; import { OcrContext } from ./ocr.skill; // Mock Tesseract.js避免测试依赖真实 WASM 加载 jest.mock(./tesseract-wrapper, () ({ recognizeImage: jest.fn().mockResolvedValue({ data: { text: XX市医疗保险卡\n姓名张三\n卡号123456789 } }) })); describe(ocrSkill, () { it(should return structured text blocks for health insurance card, async () { const context: OcrContext { sessionId: test-sess, documentType: health_insurance_card, imageBuffer: Buffer.from(fake), pageRange: [0, 0] }; const result await ocrSkill(context); expect(result.textBlocks).toHaveLength(3); expect(result.textBlocks[0].content).toBe(XX市医疗保险卡); expect(result.confidenceScore).toBeGreaterThan(0.8); }); it(should throw error when documentType is invalid, async () { const context { sessionId: test-sess, // ts-expect-error: 强制传入非法类型 documentType: passport as any, imageBuffer: Buffer.from(fake) }; await expect(ocrSkill(context)).rejects.toThrow( Unsupported documentType: passport ); }); });注意第二个测试用ts-expect-error主动触发类型错误验证类型系统是否真正生效。这是 TypeScript 工程中极易被忽略的“反向测试”。CI 流水线配置.github/workflows/ci.yml关键片段jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-nodev4 with: node-version: 20 - run: npm ci - run: npx nx test ocr --code-coverage - run: npx nx build ocr - run: npx nx lint ocrnx test会自动运行所有*.spec.ts文件并生成覆盖率报告。我们要求libs/ocr的行覆盖率 ≥ 85%分支覆盖率 ≥ 75%。低于阈值则 CI 失败——这是对 Skills 质量的硬性承诺。4. 实操过程发布首个 Skill 并被智能体消费4.1 本地开发与调试绕过 npm publish 的高效循环在正式发布前你需要高频次验证 Skill 行为。npm link是经典方案但在 Nx Monorepo 中它会导致类型定义丢失因为node_modules/agent-skills/ocr指向的是源码链接而非构建后的dist/目录。正确做法是使用 Nx 的buildcopy组合# 1. 构建 OCR 库 npx nx build ocr # 2. 将构建产物复制到 node_modules模拟 npm install cp -r dist/libs/ocr node_modules/agent-skills/ocr # 3. 在智能体项目中直接 import # agent-app/src/app.ts import { ocrSkill } from agent-skills/ocr; const result await ocrSkill({ sessionId: dev-session, documentType: id_card, imageBuffer: await readFile(./id.jpg) });此法优势明显修改ocr.skill.ts后只需nx build ocr即可刷新node_modules无需npm link的繁琐步骤node_modules/agent-skills/ocr下有完整的index.d.ts类型文件VS Code 智能提示完美与生产环境npm install行为完全一致杜绝“本地能跑CI 报错”的陷阱。4.2 首次发布semantic-release 的初始化与配置首次发布需手动触发因为 semantic-release 默认跳过初始版本。步骤如下# 1. 确保 Git 已提交所有代码并打初始 tag git add . git commit -m chore(release): initial release git tag v0.0.0 # 2. 配置 semantic-release在 workspace root npm install --save-dev semantic-release semantic-release/npm semantic-release/github # 3. 创建 .releaserc.json cat .releaserc.json EOF { branches: [main], plugins: [ semantic-release/commit-analyzer, semantic-release/release-notes-generator, semantic-release/npm, semantic-release/github ] } EOF # 4. 在 package.json 中添加 scripts # scripts: { # release: semantic-release # }然后执行# 5. 手动运行发布需提前设置 NPM_TOKEN 和 GITHUB_TOKEN npx semantic-release --dry-run # 先试运行确认版本号 npx semantic-release # 真实发布成功后你会看到npm registry 上出现agent-skills/ocr0.1.0GitHub 仓库自动创建 Release v0.1.0并附带自动生成的 CHANGELOGpackage.json的version字段被更新为0.1.0。注意--dry-run是生命线。我曾在一次匆忙发布中忘记它结果feat提交被误判为1.0.0导致下游所有项目因 major 版本升级而中断。从此--dry-run成为发布前的肌肉记忆。4.3 智能体项目集成从安装到调用的完整链路假设你的智能体主项目是一个 NestJS 应用位于apps/insurance-agent。集成步骤# 1. 安装 Skill此时已发布到 npm cd apps/insurance-agent npm install agent-skills/ocr^0.1.0 # 2. 在 Service 中注入并使用 // apps/insurance-agent/src/services/policy-processing.service.ts import { Injectable, Logger } from nestjs/common; import { ocrSkill, OcrContext } from agent-skills/ocr; Injectable() export class PolicyProcessingService { private readonly logger new Logger(PolicyProcessingService.name); async processDocument( sessionId: string, documentType: id_card | health_insurance_card, imageBuffer: Buffer ) { try { const context: OcrContext { sessionId, documentType, imageBuffer, pageRange: [0, 0] }; const result await ocrSkill(context, { timeoutMs: 30000 }); this.logger.log(OCR completed for ${sessionId}, ${result.processedPages} pages); return result; } catch (error) { this.logger.error(OCR failed for ${sessionId}, error); throw error; } } }关键点在于agent-skills/ocr^0.1.0的^符号。它允许自动升级到0.1.x的补丁版本如0.1.1但禁止升级到0.2.0可能含 breaking change。这与 semantic-release 的版本策略完美契合——fix提交只会产生0.1.1feat才会升0.2.0。4.4 版本演进实战一次真实的技能升级上周OCR 团队发现 Tesseract 5.3.0 对手写体识别准确率提升 22%。我们需要将agent-skills/ocr升级到新引擎但必须保证下游智能体无感迁移。步骤在libs/ocr中升级tesseract.js依赖至5.3.0修改tesseract-wrapper.ts以适配新 API更新单元测试增加手写体样本测试提交 PR标题为feat(ocr): upgrade to tesseract.js 5.3.0 with improved handwriting recognitionCI 触发semantic-release自动发布agent-skills/ocr0.2.0。下游智能体项目无需任何代码修改只需npm update agent-skills/ocr。因为0.2.0是 minor 版本^0.1.0的依赖规则允许自动升级。而0.2.0的 CHANGELOG 会清晰注明“BREAKING:tesseract-wrapper内部 API 调整但ocrSkill接口保持完全兼容”。这就是 Skills 模式的威力能力提供方可以激进创新能力使用方享受平滑升级。它把技术债的偿还从“所有人一起停机升级”的高风险事件变成了“单个模块渐进优化”的日常操作。5. 常见问题与排查技巧实录5.1 “类型找不到”Node.js 与 TypeScript 的模块解析迷宫最常见报错Cannot find module agent-skills/ocr or its corresponding type declarations.原因往往不是包没安装而是 TypeScript 的模块解析路径混乱。Nx 默认生成的tsconfig.base.json中compilerOptions.paths配置为paths: { agent-skills/*: [libs/*/src/index.ts] }这告诉 TS 编译器当遇到agent-skills/ocr时去libs/ocr/src/index.ts找。但npm install后node_modules/agent-skills/ocr下只有dist/目录没有src/。TS 编译器因此找不到类型。解决方案在apps/insurance-agent/tsconfig.app.json中显式覆盖 paths{ extends: ./tsconfig.json, compilerOptions: { paths: { agent-skills/*: [node_modules/agent-skills/*/dist/index.d.ts] } } }这样TS 就会去node_modules/agent-skills/ocr/dist/index.d.ts加载类型。这是 Nx 工程中一个鲜为人知但至关重要的配置技巧。5.2 “构建失败无法解析 ‘fs’”Node.js 内置模块的幽灵在libs/ocr的tesseract-wrapper.ts中你可能写了import { promises as fs } from fs。但在构建时nx build ocr报错Error: Cannot resolve fs in /path/to/libs/ocr/src/lib这是因为 Nx 的nrwl/js:tscexecutor 默认按浏览器环境配置而fs是 Node.js 专属模块。解决方法是在libs/ocr/project.json的buildtarget 中添加compilerOptionsoptions: { outputPath: dist/libs/ocr, main: libs/ocr/src/index.ts, tsConfig: libs/ocr/tsconfig.lib.json, assets: [libs/ocr/*.md], compilerOptions: { module: commonjs, target: es2020, lib: [es2020, dom] } }关键是lib: [es2020, dom]——dom库包含了fs的类型定义尽管运行时仍需 Node.js 环境。这是 TypeScript 类型系统的一个精妙设计类型定义与运行时环境解耦。5.3 “发布失败401 Unauthorized”NPM Token 的隐形陷阱npx semantic-release报401即使NPM_TOKEN已正确设置。排查顺序确认 Token 权限登录 npmjs.com → Account → Access Tokens → 检查该 Token 是否为Automation类型而非Read-only。Read-onlyToken 无法发布。确认 Token 作用域AutomationToken 默认只对当前用户下的包有效。如果你的包名是agent-skills/ocr而 Token 属于用户alice那么alice必须是agent-skillsscope 的管理员。在 npmjs.com 的Settings → Teams permissions中将alice加入agent-skillsteam 并赋予Publish权限。检查 CI 环境变量GitHub Actions 中NPM_TOKEN必须在secrets中设置且在 workflow YAML 中显式传递- name: Release env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npx semantic-release漏掉env块Token 就不会注入到执行环境中。5.4 “性能骤降OCR 耗时从 2s 变成 15s”WASM 加载的冷启动之痛上线后监控发现首次调用ocrSkill耗时飙升。日志显示Tesseract.initialize()占用 12s。这是 WebAssembly 模块加载的典型冷启动问题。解决方案预加载Preload。在智能体应用启动时就初始化 Tesseract// apps/insurance-agent/src/main.ts import { TesseractWorker } from agent-skills/ocr/tesseract-wrapper; async function preloadOcrEngine() { try { await TesseractWorker.initialize(); console.log(Tesseract preloaded successfully); } catch (error) { console.error(Failed to preload Tesseract, error); } } // 应用启动前预加载 preloadOcrEngine(); bootstrap();agent-skills/ocr/tesseract-wrapper.ts暴露initialize()方法内部缓存 WASM 实例。这样首次ocrSkill调用时initialize()直接返回缓存实例耗时降至 200ms 内。实操心得我们给所有 Skills 的异步初始化方法都加了preload导出。这不是规范而是血泪教训——当 10 个 Skills 同时在请求中初始化服务器 CPU 会瞬间拉满。把初始化提到应用启动期是保障 SLA 的基本功。5.5 “下游项目构建失败类型不兼容”Semantic Versioning 的精确打击某天agent-skills/validate-policy发布了1.3.0下游insurance-agent构建失败报错Type string is not assignable to type number.检查发现validate-policy的PolicyValidationResult新增了一个score: number字段但insurance-agent的代码里还用着旧的score: string。这违反了 SemVer 原则——minor 版本不应破坏兼容性。根因validate-policy的package.json中types字段指向了src/index.ts而非构建后的dist/index.d.ts。TS 编译器因此加载了源码类型而源码中score是number但下游项目tsconfig.json的include可能包含了src/**/*导致类型冲突。解决方案在libs/validate-policy/project.json的buildtarget 中强制指定types输出路径options: { outputPath: dist/libs/validate-policy, main: libs/validate-policy/src/index.ts, tsConfig: libs/validate-policy/tsconfig.lib.json, assets: [libs/validate-policy/*.md], compilerOptions: { declaration: true, declarationMap: true, outDir: dist/libs/validate-policy } }并确保libs/validate-policy/package.json中{ types: dist/libs/validate-policy/index.d.ts, main: dist/libs/validate-policy/index.js, typings: dist/libs/validate-policy/index.d.ts }这样下游项目npm install后只会加载dist/下的类型文件与构建产物完全一致彻底杜绝源码与构建类型不一致的灾难。6. 生产就绪 checklist一份可打印的发布前核对表检查项说明如何验证✅ 类型契约完备index.ts导出所有interface和typeJSDoc 包含remarks和examplenpx typedoc --out docs/libs/ocr libs/ocr/src/index.ts生成文档人工检查✅ 单元测试覆盖行覆盖率 ≥ 85%分支覆盖率 ≥ 75%包含边界 case空输入、超时、错误输入npx nx test ocr --code-coverage打开coverage/libs/ocr/index.html查看报告✅ 构建产物纯净dist/目录下只有index.js,index.d.ts,index.js.map,index.d.ts.map无src/或node_modules/ls -la dist/libs/ocr确认无多余文件✅ 发布配置正确package.json中publishConfig.access为publictypes字段指向dist/下的.d.tscat libs/ocr/package.json | grep -A2 types|access✅ Semantic Release 就绪.releaserc.json存在package.json中scripts.release指向semantic-releaseCI 中NPM_TOKEN已配置npx semantic-release --dry-run成功输出预期版本号✅ 预加载支持src/lib/下有preload.ts或类似文件暴露preload()方法grep -r preload libs/ocr/src/✅ 错误处理健壮所有try/catch块中catch部分至少记录sessionId和错误摘要不吞没异常代码审查确认无catch (e) {}或catch (e) { console.log(e); }这张表不是形式主义
返回列表