保密检查在本项目中的总体链路从按钮到任务清单摘要本文围绕标题所述主题结合本仓库当前源码行进行说明。仅供技术理解与内部培训不构成定密、法务或密码测评结论。文中代码块均摘自本地仓库对应路径与行号。正文0. 结论先行结论先行保密检查由内置助手触发大模型按模板输出审查意见程序再从摘要中抽取命中片段并尝试挂批注。长文档依赖分块与结构化 JSON 提示。下文每节先说明要点紧接着给出仓库中的对应源码片段。本篇标题保密检查在本项目中的总体链路从按钮到任务清单1. 助手标识与默认写回方式保密检查对应内置助手 id 为 analysis.security-check。下列片段展示其在注册表中的默认动作与输入来源等字段便于与界面行为对照。// src/utils/assistantRegistry.js 第653-667行 { id: analysis.security-check, label: 保密检查, shortLabel: 保密检查, group: analysis, modelType: chat, defaultModelCategory: chat, supportsRibbon: true, defaultDisplayLocations: [ribbon-main], allowedActions: [comment, link-comment, insert, append, none], defaultAction: link-comment, defaultOutputFormat: markdown, defaultInputSource: INPUT_SOURCE_DOCUMENT, description: 基于关键词和上下文检查文档中的涉密、涉军、单位名称、密级标识和敏感业务信息风险。,2. 研判原则写入提示词模板研判原则与风险级别枚举写在 userPromptTemplate 的长模板中模型据此输出 Markdown 小节。下列片段为模板中研判原则与风险级别相关行。// src/utils/assistantRegistry.js 第704-713行 研判原则 1. 关键词命中不等于泄密必须结合上下文判断不要机械命中即报高风险 2. 对常见公开词、泛化称谓、新闻公开语境、教材示例语境要谨慎降噪避免误报 3. 仅依据原文内容作出审慎判断不要臆测背景、来源、真实单位或法律结论 4. 对每项风险必须说明命中片段、风险类别、风险级别、判断依据、建议处理方式 5. 风险级别统一使用 - 高风险直接出现密级标识、具体部队/单位身份、具体部署计划、未公开内部编号、明确敏感联系人信息等 - 中风险出现敏感关键词且上下文指向内部事项但是否涉密仍需人工确认 - 低风险或待人工复核存在可疑词或敏感线索但公开性、敏感性、上下文不足暂不能直接判定 6. 如果文本未发现明显保密风险明确写“未发现明显保密风险”3. Ribbon 按钮如何启动该助手功能区按钮在 ribbon 的 OnAction 分支中调用 executeAssistantFromRibbon并传入 taskTitle。// src/components/ribbon.js 第3364-3370行 // 脱密分组 case btnDocumentDeclassifyCheck: executeAssistantFromRibbon(analysis.security-check, { taskTitle: 保密检查 }).catch((e) { console.error(保密检查失败:, e) alert(保密检查失败: (e?.message || e)) }) break4. 任务运行器中的专项提示对保密检查助手任务运行器追加一条最佳实践说明强调关键词命中须结合上下文分级。// src/utils/assistantTaskRunner.js 第310-312行 if (assistantId analysis.security-check) { return 保密检查时关键词命中必须结合上下文分级判断避免武断下结论并明确哪些内容需要人工复核。 }5. 结构化批次系统提示骨架长文档走结构化 JSON 批次时buildStructuredBatchInstruction 拼接 schemaVersion、模式说明与 ChunkText 约束。// src/utils/assistantStructuredPipeline.js 第90-104行 export function buildStructuredBatchInstruction(assistantId, options {}) { const mode getStructuredAssistantMode(assistantId) return [ 你必须只输出一个合法 JSON 对象schemaVersion 固定为 ${STRUCTURED_PIPELINE_SCHEMA_VERSION}。, 不要输出 Markdown不要输出 JSON 之外的解释。, getModeSpecificInstruction(mode, options), getStructuredJsonAnchorExtraRules(assistantId, options.documentAction), 你将收到一个带 ChunkMeta / LineMap / ChunkText 的结构化原文块所有定位都必须以 ChunkText 为唯一依据。, String(options.documentAction || ).trim() replace ? 当文档动作是 replace 时只有在 originalText 可以从 ChunkText 中精确截取时才输出 replace否则改为 comment。 : , 统一 JSON 结构如下, {schemaVersion:,mode:,summary:,content:,operations:[{type:replace|comment|insert-after|prepend|append|none,target:absolute-range|chunk-relative-range|text-anchor|paragraph-range,start:0,end:0,originalText:,replacementText:,commentText:,reason:,suggestion:,confidence:high|medium|low,paragraphIndex:0,prefix:,suffix:,sentence:}]}, 若没有可执行操作operations 返回 []若没有正文结果content 返回空字符串。 ].filter(Boolean).join(\n)6. 从 Markdown 摘要抽取命中片段程序不直接信任自由格式而用 extractHitFragmentsFromSecurityCheckMarkdown 做多模式正则抽取供后续批注锚点。// src/utils/structuredCommentPolicy.js 第22-52行 export function extractHitFragmentsFromSecurityCheckMarkdown(markdown) { const text String(markdown || ) const out [] const seen new Set() const add (raw) { let t String(raw || ).trim() t t.replace(/^[「“]|[」”]$/g, ).replace(/\*\*/g, ).trim() if (t.length 2 || seen.has(t)) return if (/^(无|暂无|未发现|没有|不适用)\s*$/u.test(t)) return seen.add(t) out.push(t) } let m // 模型常见变体- **命中片段** 原文加粗标签 中英文冒号 反引号 const reBacktickPatterns [ /\*\*命中片段[:]\*\*\s*([^\n])/g, /[-*]\s*\*\*命中片段[:]\*\*\s*([^\n])/g, /[-*]\s*\*{1,2}\s*命中片段\s*\*{1,2}\s*[:]\s*([^\n])/g, /命中片段\s*\*{0,2}\s*[:]\s*\*{0,2}\s*([^\n])/g ] for (const reBacktick of reBacktickPatterns) { while ((m reBacktick.exec(text)) ! null) add(m[1]) } const reLinePatterns [ /[-*]\s*\*\*命中片段[:]\*\*\s*(?!)([^\n])/g, /[-*]\s*命中片段[:]\s*(?!)([^\n])/g ] for (const reLine of reLinePatterns) { while ((m reLine.exec(text)) ! null) add(m[1]) } return out7. 保密检查在结构化 JSON 下的额外锚点规则getStructuredJsonAnchorExtraRules 为保密检查追加「命中片段须逐字来自 ChunkText」等说明与批注类文档动作组合使用。// src/utils/structuredCommentPolicy.js 第119-127行 export function getStructuredJsonAnchorExtraRules(assistantId, documentAction ) { const id String(assistantId || ).trim() const act String(documentAction || ).trim() const parts [] if (id ANALYSIS_SECURITY_CHECK_ID) { parts.push([ 保密检查须将完整审查结论写入 JSON 的 summary 字段summary 内仍使用模板要求的 Markdown 小节## 高风险项 等。, 每条风险项必须包含「命中片段」且反引号内为 ChunkText 中的连续原文逐字照抄推荐格式- **命中片段** 原文片段加粗与否均可反引号内必须与正文一致operations 可留空 []。 ].join(\n))8. 与定密流程的边界README 已说明检查结论仅为辅助参考。实现上判断来自大模型与提示词不包含法定密级鉴定接口。组织对外处置仍须走正式流程。