109 lines
3.0 KiB
TypeScript
109 lines
3.0 KiB
TypeScript
export type SkillQualityNodeKey =
|
||
| "trigger"
|
||
| "inputs"
|
||
| "steps"
|
||
| "output"
|
||
| "constraints";
|
||
|
||
export type SkillNodeQuality = {
|
||
complete: boolean;
|
||
missing: string[];
|
||
};
|
||
|
||
function normalizedContent(content: string) {
|
||
return content.replace(/\s+/g, " ").trim();
|
||
}
|
||
|
||
function hasOrderedSteps(content: string) {
|
||
const numberedSteps =
|
||
content.match(/(?:^|[\n;;。])\s*(?:步骤\s*)?\d+[.、)::]/g)?.length ?? 0;
|
||
const sequenceMarkers = ["先", "再", "然后", "接着", "最后", "最终"].filter(
|
||
(marker) => content.includes(marker),
|
||
).length;
|
||
const actionSegments = content
|
||
.split(/[\n;;。]+/)
|
||
.filter((segment) =>
|
||
/(?:检查|识别|提取|分析|整理|比较|判断|生成|输出|复核|验证|标记)/.test(
|
||
segment,
|
||
),
|
||
).length;
|
||
|
||
return numberedSteps >= 2 || sequenceMarkers >= 2 || actionSegments >= 2;
|
||
}
|
||
|
||
export function evaluateSkillNodeQuality(
|
||
nodeKey: SkillQualityNodeKey,
|
||
content: string,
|
||
): SkillNodeQuality {
|
||
const normalized = normalizedContent(content);
|
||
const missing: string[] = [];
|
||
|
||
if (normalized.length < 8) {
|
||
missing.push("内容过短,尚未形成可执行规范");
|
||
return { complete: false, missing };
|
||
}
|
||
|
||
switch (nodeKey) {
|
||
case "trigger":
|
||
if (
|
||
!/(?:当|如果|遇到|用户|场景|适用|触发|不处理|不适用|请求)/.test(
|
||
normalized,
|
||
)
|
||
) {
|
||
missing.push("需要说明何时触发或适用场景");
|
||
}
|
||
break;
|
||
case "inputs":
|
||
if (
|
||
!/(?:必填|可选|输入|参数|提供|原文|材料|目标|字段|默认|缺失)/.test(
|
||
normalized,
|
||
)
|
||
) {
|
||
missing.push("需要列明执行所需的输入信息");
|
||
}
|
||
break;
|
||
case "steps":
|
||
if (!hasOrderedSteps(normalized)) {
|
||
missing.push("需要至少两个有明确顺序的执行动作");
|
||
}
|
||
break;
|
||
case "output":
|
||
if (
|
||
!/(?:输出|结果|格式|结构|标题|字段|表格|Markdown|JSON|列表|篇幅|语气|字数|包含)/i.test(
|
||
normalized,
|
||
)
|
||
) {
|
||
missing.push("需要明确结果结构、字段或格式");
|
||
}
|
||
break;
|
||
case "constraints":
|
||
if (
|
||
!/(?:不得|不能|禁止|必须|至少|至多|缺少|不足|失败|异常|验收|测试|反例|确保|待确认|质量)/.test(
|
||
normalized,
|
||
)
|
||
) {
|
||
missing.push("需要至少一条约束、质量标准或验收条件");
|
||
}
|
||
break;
|
||
}
|
||
|
||
return { complete: missing.length === 0, missing };
|
||
}
|
||
|
||
export function getSkillNodeQualityIssues(
|
||
nodes: Array<{
|
||
key: SkillQualityNodeKey;
|
||
title: string;
|
||
content: string;
|
||
}>,
|
||
) {
|
||
return nodes.flatMap((node) => {
|
||
const quality = evaluateSkillNodeQuality(node.key, node.content);
|
||
return quality.missing.map((missing) => `${node.title}:${missing}`);
|
||
});
|
||
}
|
||
|
||
export function skillNodeQualityErrorMessage(issues: string[]) {
|
||
return `Skill 节点尚未达到可发布标准。需补充:${issues.join(";")}`;
|
||
}
|