1. 项目概述:从意图到可上线技能的完整流程
在人工智能和语言模型领域,构建高效、可靠的技能系统是提升模型实用性的关键。本文介绍了一套基于LangGraph的技能创作工作流,将自然语言需求转化为可执行的SKILL.md文件。这套流程不仅关注文件格式合规性,更注重技能的实际可用性和执行效果。
核心流程包含六个关键阶段:
- 需求结构化(Capture Intent):将用户模糊的自然语言需求转化为结构化规格
- 技能撰写:基于规格生成完整的SKILL.md文件
- 静态校验与修复:确保文件格式和基本要素符合规范
- 冒烟测试:通过Executor执行和Judge评分验证技能实际效果
- 测试驱动的修订:根据测试结果迭代改进技能内容
- 落盘入库:最终确认并存储技能文件
这套工作流特别适用于需要高质量、可验证技能的场景,如Dockerfile安全审查这类对准确性和完整性要求较高的任务。
2. 核心设计思路与技术架构
2.1 状态机驱动的创作流程
整个技能创作过程被建模为一个状态机,每个状态代表流程中的一个关键节点。这种设计有三大优势:
- 清晰的流程控制:每个状态有明确的输入输出和转移条件
- 可观测性:可以精确追踪技能在创作流程中的位置和状态
- 容错能力:失败时可以回退或重试特定阶段
状态机包含以下主要节点:
- START → capture → write → validate
- validate → run_tests(通过)或fix_validate(未通过)
- run_tests → persist(全部通过)或refine_tests(部分失败)
2.2 双循环验证机制
为确保技能质量,系统实现了双重验证循环:
内循环(静态校验):
- 检查frontmatter格式
- 验证name字段合规性
- 确保description长度达标
- 确认正文内容充分
外循环(动态测试):
- 执行预定义的测试用例
- 评估技能输出质量
- 根据评分决定是否进入修订
这种双循环设计借鉴了软件工程中的CI/CD理念,将"编译时检查"和"运行时测试"相结合。
2.3 Executor-Judge评估模式
冒烟测试采用独特的双模型评估架构:
- Executor:严格遵循技能指令回答问题
- Judge:根据评分标准(rubric)评估回答质量
这种分离的设计避免了模型"既当运动员又当裁判员"的问题,提高了评估的客观性。Judge使用专门的评分模板,从多个维度对Executor的输出进行量化评价。
3. 关键实现细节与代码解析
3.1 状态定义与流转
系统使用TypedDict定义技能创作状态,包含所有必要字段:
python复制class SkillCreationState(TypedDict):
user_request: str # 用户原始需求
intent_spec: dict # 结构化规格
skill_md: str # 当前SKILL.md内容
validation_ok: bool # 静态校验结果
validation_errors: str # 校验错误信息
validate_fix_round: int # 校验修复轮次
max_validate_fix: int # 最大修复次数
test_results: list # 测试结果
test_refine_round: int # 测试修订轮次
max_test_refine: int # 最大修订次数
eval_suite: dict # 评测套件
output_path: str # 输出路径
registry_ok: bool # 注册校验结果
final_message: str # 最终消息
verbose: NotRequired[bool] # 详细模式
状态转移通过条件边实现:
python复制def route_after_validate(state: SkillCreationState):
if state.get("validation_ok"):
return "run_tests"
if state.get("validate_fix_round", 0) < state.get("max_validate_fix", 3):
return "fix_validate"
return "fail_validate"
3.2 需求结构化实现
Capture Intent阶段使用特定prompt提取结构化信息:
python复制CAPTURE_INTENT_PROMPT = """你是技能需求分析师。用户会用自然语言描述想创建的 Agent Skill。请输出仅一个合法JSON对象:
- suggested_name: 小写+连字符名称
- description: 一句话说明技能功能
- triggers: 2-5条典型触发场景
- output_format: 期望输出结构
- checklist: 3-8条核心步骤
- domain_notes: 领域约束
用户原始需求:
{user_request}
"""
处理流程包括:
- 调用LLM生成原始响应
- 从响应中提取JSON对象
- 验证必填字段
- 失败时返回默认结构
3.3 技能撰写与静态校验
技能撰写阶段将结构化规格转换为完整SKILL.md:
python复制def write_skill_md(intent_spec: Dict[str, Any]) -> str:
llm = ChatOpenAI(model=cfg.model, temperature=0.3)
chain = ChatPromptTemplate.from_template(WRITE_SKILL_PROMPT) | llm
text = chain.invoke({
"spec_summary": _load_spec_summary(),
"intent_spec_json": json.dumps(intent_spec, ensure_ascii=False, indent=2),
}).content.strip()
return text[text.index("---"):] if "---" in text else text
静态校验检查以下内容:
- Frontmatter存在且格式正确
- name字段符合命名规范
- description达到最小长度
- 正文内容充分
- 总行数不超过限制
3.4 冒烟测试实现
测试执行流程:
- 加载测试套件
- 对每个测试用例:
- Executor执行技能
- Judge评估结果
- 记录评分和通过状态
python复制def run_one_case(skill_md: str, case: Dict[str, Any]) -> Dict[str, Any]:
# Executor执行
executor = ChatOpenAI(temperature=0.15)
ans = executor.invoke([
SystemMessage(content=EXECUTOR_SYSTEM),
HumanMessage(content=EXECUTOR_USER.format(
skill_body=_skill_body_only(skill_md),
user_prompt=case["user_prompt"]
)),
]).content.strip()
# Judge评估
judge = ChatOpenAI(temperature=0.0)
judge_raw = (ChatPromptTemplate.from_template(JUDGE_PROMPT) | judge).invoke({
"min_score": case.get("min_score", 70),
"rubric": case["rubric"],
"user_prompt": case["user_prompt"],
"model_answer": ans,
}).content.strip()
score, passed, reason = _parse_judge_json(judge_raw)
return {
"id": case["id"],
"pass": score >= case.get("min_score", 70),
"score": score,
"reason": reason,
"model_answer": ans[:2000],
}
4. 实操案例:Dockerfile安全审查技能
4.1 测试用例设计
系统使用JSON格式定义测试用例:
json复制{
"suite_name": "dockerfile-security-review-smoke",
"cases": [
{
"id": "non-root",
"user_prompt": "请审查下面Dockerfile...",
"rubric": "应指出使用root运行进程的风险...",
"min_score": 72
},
{
"id": "secrets-and-copy",
"user_prompt": "审查:FROM alpine...",
"rubric": "应指出将私钥打入镜像的风险...",
"min_score": 75
}
]
}
每个用例包含:
- 唯一ID
- 用户提示
- 评分标准
- 最低通过分数
4.2 技能输出示例
生成的Dockerfile安全审查技能包含详细检查项:
markdown复制---
name: dockerfile-security-review
description: 对Dockerfile进行静态安全审查...
---
# Dockerfile安全审查技能
## 步骤1:高优先级风险
### 检查1.1:容器是否以root用户运行
- 规则:必须存在USER指令且不为root
- 输出格式:HIGH: Container runs as root — line 12
## 步骤2:中优先级风险
### 检查2.1:基础镜像是否非最小化
- 规则:检查FROM指令镜像名
- 输出格式:MEDIUM: Non-minimal base image...
4.3 测试执行结果
典型测试输出:
code复制[test] non-root pass=True score=95
reason=���确指出USER root的高风险并强调以root运行进程的问题
[test] secrets-and-copy pass=False score=65
reason=未充分说明密钥管理的替代方案
5. 经验总结与避坑指南
5.1 关键成功因素
- 明确的需求捕获:结构化规格显著提升后续步骤成功率
- 分阶段验证:先格式后功能的渐进式验证减少返工
- 客观评估:独立的Judge模型提供可靠质量反馈
5.2 常见问题与解决方案
问题1:技能描述过于简略导致匹配不准
- 解决:在Capture Intent阶段强制description最小长度
- 检查:静态校验确保description≥50字
问题2:测试用例覆盖不足
- 解决:为每种核心功能设计至少一个测试用例
- 检查:测试套件需包含所有关键场景
问题3:评审标准不一致
- 解决:为Judge提供详细的评分标准(rubric)
- 检查:定期校准Judge评分结果
5.3 性能优化建议
- 缓存机制:对未修改的中间结果跳过重复验证
- 并行测试:独立测试用例可并行执行
- 早期终止:关键测试失败后提前终止流程
6. 扩展应用与未来方向
这套工作流可应用于各类技能创作场景:
- 代码审查类技能:如SQL注入检测、API安全检查
- 文档生成类技能:自动生成技术文档、用户手册
- 数据处理类技能:数据清洗、格式转换
未来可扩展方向包括:
- 技能版本管理与diff
- 基于使用数据的自动优化
- 跨技能的知识共享
