用 Code Agent 开发 Skill 和场景
开发时先按标准 Agent Skill 组织能力,再用 lingxi.json 告诉 Lingxi 如何展示、配置和暴露命令。场景是另一种安装包,负责用户入口、能力选择和任务要求。Demo 只是完整样例,不是必须兼容的协议。
lingxi.json.entrypoint,并由 Python 解释器执行。两个 Runtime 都不会直接执行 scripts/ 中的 Shell、Node 或 Java 文件。Lingxi 实际关心什么
SKILL.md。lingxi.json 是放在 Skill 目录中的平台扩展。它不属于标准 Skill,也不替代 SKILL.md。标准 Agent Skill 目录
name 和 description。name 是稳定身份,目录名应与它一致;description 说明能力是什么以及何时使用。正文写 Agent 真正需要遵守的工作方法、边界和资源导航。entrypoint。Codex Runtime 不投影这个目录,Lingxi Runtime 也只通过公开命令调用平台 launcher;Shell、Node 和 Java 文件不能直接作为 Lingxi 命令入口。纯说明型 Skill 可以没有此目录。SKILL.md 应说明什么时候读取哪个文件,避免把所有长资料一次性塞入上下文。SKILL.md 最小示例
--- name: project-context description: "读取组织项目中心中的项目、环境和资源信息。处理需要确认项目归属、环境配置或关联资源的任务时使用。" --- # 项目上下文 说明这个 Skill 能提供什么,以及不负责什么。 ## 工作方法 - 根据当前任务线索确定项目和环境。 - 读取与问题有关的资料,不遍历无关项目。 - 无法唯一确定对象且会影响结论时,再向用户确认。 ## 资源 - 需要接口字段说明时读取 references/api.md。 ## 安全边界 - 不在结果或日志中展示访问凭证。 - 不把连接失败解释成没有数据。
SKILL.md 要简洁。每次触发都必须遵守的内容留在正文;较长的接口字段、公司规则和变体说明放进 references/。
lingxi.json 是做什么的
标准 Skill 不知道 Lingxi 的表单、安装状态和命令展示。lingxi.json 只补这层信息。其他 Agent 平台可以忽略它,Skill 的身份和使用方法仍以 SKILL.md 为准。
哪些字段必须生成
schemaVersion、version、presentation.displayName、enabledByDefault、taskParameters、configurationParameters。两个参数数组没有内容也要写 []。scripts/、位于该目录下的 Python entrypoint,以及每个命令的 command、displayName 和 icon。presentation.icon、guides、commands.description、commands.executionMode、commands.outputs、参数选项和默认值。executionMode 省略时按 SERIAL 执行;确认命令只读且允许并行时才写 READ_ONLY。凡是填写了文件路径,对应文件必须真实存在。Command 可用图标
WRENCH、TERMINAL、BOOK_OPEN、FILE_TEXT、FILE_PLUS、FILE_MAGNIFYING_GLASS、MAGNIFYING_GLASS、BRACKETS_CURLY、CODE、GRAPH、GIT_DIFF、TREE_STRUCTURE、PLUGS_CONNECTED、QUESTION、LIST_BULLETS、CHECK_CIRCLE、CALENDAR、CLOCK、DATABASE、FOLDER、GIT_BRANCH、GIT_COMMIT、SHIELD_CHECK、ARROW_COUNTER_CLOCKWISE、PLAY_CIRCLE、VIDEO_CAMERA、IMAGE_SQUARE、EYE、HISTORY、BROWSER、HEAD_CIRCUIT、WARNING_CIRCLE、X_CIRCLE。
1。0.0.1 开始,但这不是平台强制值。references/ 中的补充资料登记到 Lingxi。只登记需要平台管理的说明。scripts/ 下真实存在的 .py 文件。Codex Runtime 和 Lingxi Runtime 都通过同一个平台 launcher 调用它,当前没有 Shell、Node 或 Java entrypoint。project-hub project-list。没有自带工具的 Skill 不需要 entrypoint 和 commands。例如,commands 声明 project-hub project-list,entrypoint 指向 scripts/project_hub.py。Agent 调用公开命令时,Lingxi 启动这个文件;文件内部如何访问项目中心由 Skill 自己决定。如果 Skill 只有操作说明或使用已有工具,这两个字段都不写。
{
"schemaVersion": 1,
"version": "0.0.1",
"presentation": {
"displayName": "项目上下文"
},
"enabledByDefault": false,
"taskParameters": [
{
"key": "projectId",
"name": "项目",
"type": "text",
"required": false,
"description": "本次任务选择的项目",
"visible": false
}
],
"configurationParameters": [
{
"key": "baseUrl",
"name": "服务地址",
"type": "text",
"required": true,
"description": "项目中心地址"
},
{
"key": "token",
"name": "访问令牌",
"type": "password",
"required": true,
"description": "访问项目中心所需的令牌"
}
]
}带自有命令的完整示例
下面两个文件必须对应:commands.command 是 Agent 看到的命令,entrypoint 是 Lingxi 实际启动的 Python 文件。Lingxi 会把公开命令转换成第一个参数 project-context.project-list 传给入口。
{
"schemaVersion": 1,
"version": "0.0.1",
"presentation": {
"displayName": "项目上下文"
},
"enabledByDefault": false,
"entrypoint": "scripts/project_context.py",
"taskParameters": [
{
"key": "projectId",
"name": "项目",
"type": "text",
"required": false,
"description": "本次任务选择的项目",
"visible": false
}
],
"configurationParameters": [
{
"key": "baseUrl",
"name": "服务地址",
"type": "text",
"required": true,
"description": "项目中心地址"
},
{
"key": "token",
"name": "访问令牌",
"type": "password",
"required": true,
"description": "访问项目中心所需的令牌"
}
],
"commands": [
{
"command": "project-context project-list",
"displayName": "查询项目列表",
"icon": "LIST_BULLETS"
}
]
}#!/usr/bin/env python3
import json
import sys
import urllib.parse
import urllib.request
import capability_runtime as runtime
def project_list(args):
service = runtime.service_config_data("project-context", required=True)
config = service.get("config", {})
base_url = str(config.get("baseUrl") or "").rstrip("/")
token = str(config.get("token") or "")
if not base_url:
print("项目中心未配置服务地址", file=sys.stderr)
return 2
query = ""
if "--query" in args:
index = args.index("--query")
if index + 1 < len(args):
query = args[index + 1]
url = base_url + "/projects?" + urllib.parse.urlencode({"query": query})
request = urllib.request.Request(url)
if token:
request.add_header("Authorization", "Bearer " + token)
try:
with urllib.request.urlopen(request, timeout=30) as response:
result = json.loads(response.read().decode("utf-8"))
except Exception as exception:
print("读取项目列表失败:" + str(exception), file=sys.stderr)
return 1
print(json.dumps(result, ensure_ascii=False))
return 0
def main():
if len(sys.argv) < 2:
print("缺少命令动作", file=sys.stderr)
return 2
selector = sys.argv[1]
args = sys.argv[2:]
if selector == "project-context.project-list":
return project_list(args)
print("不支持的命令:" + selector, file=sys.stderr)
return 2
if __name__ == "__main__":
raise SystemExit(main())SKILL.md 负责让 Agent 会做事,lingxi.json 负责让 Lingxi 会安装和展示。不要把整套工作流复制进 JSON,也不要把 Lingxi 表单写进标准 Skill。让 Code Agent 生成 Skill
把目标服务资料和下面这段指令一起交给 Code Agent。指令同时覆盖纯说明型 Skill 和带 Lingxi 命令的 Skill。
请创建一个可通过 Lingxi 预检和安装的标准 Agent Skill。
## 输入资料
- 输出目录:[路径]
- Skill 要解决的问题:[说明]
- 触发示例:[用户会怎样提出任务]
- 目标服务或工具:[API、SDK、CLI、文件或其他工具]
- 目标资料:[代码、API 文档、脱敏响应样例]
- 每次任务变化的值:[项目、环境、时间范围等]
- 管理员长期配置的值:[服务地址、Token、租户等]
- 是否需要 Lingxi 自带命令:[是 / 否]
信息不足且会影响接口、字段或权限时先指出缺口,不要猜。Demo 只用于参考目录,不是目标服务必须兼容的协议。
## 目录
[skill-name]/
SKILL.md
lingxi.json
scripts/[entrypoint].py # 仅 commands 非空时必需
references/[document].md # 仅有按需读取资料时创建
assets/[icon-file] # 仅 lingxi.json 引用了文件时创建
agents/openai.yaml # 仅需要 Codex UI 元数据时创建
目录名、SKILL.md 的 name 必须完全相同。name 只能使用小写字母、数字和连字符,最长 64 位。不要创建空目录。
## SKILL.md
必须使用下面的结构,description 同时说明“做什么”和“何时使用”,正文不能为空:
---
name: project-context
description: "读取组织项目中心中的项目、环境和资源信息。处理需要确认项目归属、环境配置或关联资源的任务时使用。"
---
# 项目上下文
## 工作方法
- 根据当前任务确定要读取的项目和环境。
- 只读取完成任务需要的信息。
- 连接失败、无权限和空结果必须明确区分。
## 参考资料
- 需要目标服务字段说明时读取 references/api.md。
## 安全边界
- 不输出访问凭证。
- 不把未验证信息写成事实。
按真实 Skill 改写内容。没有 references/api.md 时删掉对应导航,不要留下无效路径。commands 非空时,在 SKILL.md 或它直接引用的 reference 中列出每个公开命令的准确签名、参数、返回内容和适用时机;Lingxi 不会从脚本自动生成参数 Schema。
## lingxi.json
始终必需的顶层字段:
- schemaVersion:固定为 1。
- version:包版本,例如 0.0.1。
- presentation:必须包含非空 displayName;icon 可选,填写时文件必须存在。
- enabledByDefault:布尔值。
- taskParameters:数组,没有参数也必须写 []。
- configurationParameters:数组,没有配置也必须写 []。
每个参数必须包含 key、name、type、required、description;可选 options、defaultValue、visible。常用 type 为 text、textarea、password、number、switch、date、time、datetime、select。select 的 options 使用 {"label":"测试环境","value":"test"},defaultValue 必须写成字符串。
纯说明型 Skill 使用完整的最小定义:
{
"schemaVersion": 1,
"version": "0.0.1",
"presentation": {
"displayName": "项目上下文"
},
"enabledByDefault": false,
"taskParameters": [],
"configurationParameters": []
}
只有 Skill 自带工具并要让 Agent 通过 Lingxi 调用时,才生成 scripts/、entrypoint 和 commands。此时 Lingxi 当前只支持 Python entrypoint。使用下面的完整结构:
{
"schemaVersion": 1,
"version": "0.0.1",
"presentation": {
"displayName": "项目上下文"
},
"enabledByDefault": false,
"entrypoint": "scripts/project_context.py",
"taskParameters": [
{
"key": "projectId",
"name": "项目",
"type": "text",
"required": false,
"description": "本次任务已确定的项目标识",
"visible": false
}
],
"configurationParameters": [
{
"key": "baseUrl",
"name": "服务地址",
"type": "text",
"required": true,
"description": "项目中心服务地址"
},
{
"key": "token",
"name": "访问令牌",
"type": "password",
"required": true,
"description": "访问项目中心所需的令牌"
}
],
"commands": [
{
"command": "project-context project-list",
"displayName": "查询项目列表",
"icon": "LIST_BULLETS"
}
]
}
commands 非空时,每个命令必须生成以下三项:
- command:小写 group action 格式,两段都可使用连字符,例如 project-context project-list。
- displayName:必填的中文动作短语,例如“查询项目列表”,不能只写“项目列表”。
- icon:必须从下方枚举中选择。
description 和 executionMode 可选;executionMode 省略时按 SERIAL 执行,只有确认命令只读且允许并行时才写 READ_ONLY。
可用 icon 只有:
WRENCH, TERMINAL, BOOK_OPEN, FILE_TEXT, FILE_PLUS,
FILE_MAGNIFYING_GLASS, MAGNIFYING_GLASS, BRACKETS_CURLY, CODE, GRAPH,
GIT_DIFF, TREE_STRUCTURE, PLUGS_CONNECTED, QUESTION, LIST_BULLETS,
CHECK_CIRCLE, CALENDAR, CLOCK, DATABASE, FOLDER, GIT_BRANCH,
GIT_COMMIT, SHIELD_CHECK, ARROW_COUNTER_CLOCKWISE, PLAY_CIRCLE,
VIDEO_CAMERA, IMAGE_SQUARE, EYE, HISTORY, BROWSER, HEAD_CIRCUIT,
WARNING_CIRCLE, X_CIRCLE
需要把 references 文件登记到 Lingxi 时,guides 每项必须包含 key、title、description、file,file 必须以 references/ 开头且真实存在:
"guides": [
{
"key": "api-reference",
"title": "接口字段说明",
"description": "目标服务的请求和响应字段",
"file": "references/api.md"
}
]
只有 stdout JSON 中的文件或目录路径需要被 Lingxi 登记为命令输出,或需要据此启用文件访问、代码索引等平台特征时,才声明 outputs。普通结果字段和仅供后续命令传递的路径不声明。每项必须包含 type、pathField,features 可选:
"outputs": [
{
"type": "file-root",
"pathField": "workspacePath",
"features": ["file-access", "code-index"]
}
]
## Python entrypoint
commands 非空时,入口必须位于 scripts/,并处理 Lingxi 传入的第一个参数 group.action。下面是与上述 lingxi.json 对应的最小可运行入口:
#!/usr/bin/env python3
import json
import sys
import urllib.parse
import urllib.request
import capability_runtime as runtime
def main():
if len(sys.argv) == 1:
print("缺少命令动作", file=sys.stderr)
return 2
selector = sys.argv[1]
args = sys.argv[2:]
if selector != "project-context.project-list":
print("不支持的命令:" + selector, file=sys.stderr)
return 2
service = runtime.service_config_data("project-context", required=True)
config = service.get("config", {})
base_url = str(config.get("baseUrl") or "").rstrip("/")
token = str(config.get("token") or "")
if not base_url:
print("未配置项目中心服务地址", file=sys.stderr)
return 2
query = ""
if "--query" in args:
position = args.index("--query")
query = args[position + 1] if position + 1 != len(args) else ""
url = base_url + "/projects?" + urllib.parse.urlencode({"query": query})
request = urllib.request.Request(url)
if token:
request.add_header("Authorization", "Bearer " + token)
try:
with urllib.request.urlopen(request, timeout=30) as response:
result = json.loads(response.read().decode("utf-8"))
except Exception as exception:
print("查询项目失败:" + str(exception), file=sys.stderr)
return 1
print(json.dumps(result, ensure_ascii=False))
return 0
if __name__ == "__main__":
raise SystemExit(main())
根据真实服务替换请求逻辑,但保留 selector 分发、非零失败码、stderr 错误和 stdout 机器可读结果。不得把地址、Token、私钥路径写死在脚本里。
## 完成前检查
- SKILL.md、lingxi.json 都存在,正文和必填字段非空。
- 目录名等于 Skill name;version 格式合法。
- lingxi.json 通过 docs/schemas/lingxi-capability.schema.json 校验,没有未定义字段。
- commands 为空时没有伪造 entrypoint;commands 非空时 scripts/ 和 Python entrypoint 真实存在。
- 每个 command 都有 displayName、合法 icon 且不重复。
- SKILL.md 或它直接引用的 reference 已写清公开命令签名、参数、返回内容和适用时机。
- presentation.icon、guides.file、entrypoint 引用的文件都存在。
- 有脚本时运行正常、失败和无权限测试;使用脱敏数据。
- ZIP 内只放一个以 Skill name 命名的一级目录,定义文件位于该目录中。
- ZIP 不超过 20MB,解压后不超过 50MB,文件不超过 500 个,不含符号链接、密钥、缓存、日志和数据库。
最后给出文件清单、测试结果、ZIP 路径以及仍缺少的真实联调资料。Lingxi 场景目录
code 是稳定身份且与目录名一致;version 由场景包自己维护,当前 Demo 场景统一为 0.0.1;capabilities 引用 Skill 的 name;capabilityCommands 可继续收窄命令;parameters 定义用户可填写的场景输入。manifest.json 的 icon 字段引用,颜色由 color 提供。{
"code": "release-risk-review",
"version": "0.0.1",
"name": "发布风险评估",
"description": "结合项目、代码和运行资料评估发布风险。",
"slogan": "要评估哪次发布?",
"scenario": "RELEASE_RISK_REVIEW",
"icon": "icon.svg",
"color": "#176a91",
"promptFile": "prompt.md",
"enabled": true,
"resultFormat": "markdown-sections",
"presentations": ["evidence", "mermaid"],
"queuePriority": 100,
"capabilities": [
"project-context",
"code-repository",
"log-query"
],
"parameters": [
{
"key": "userInput",
"name": "评估要求",
"type": "textarea",
"required": true,
"description": "说明发布范围和关注风险",
"sortOrder": 10,
"visible": true
}
]
}让 Code Agent 生成场景
场景单独生成、单独打包。先提供可用 Skill 的 name 和 command,避免 AI 猜错引用。
请创建一个可通过 Lingxi 预检和安装的场景包。场景负责描述任务和选择 Skill,不实现 Skill,也不保存外部服务数据。
## 输入资料
- 输出目录:[路径]
- 用户要完成的任务:[具体例子]
- 场景中文名称:[名称]
- 可用 Skill name:[逐项列出]
- 每个 Skill 可用 command code:[例如 project-context.project-list]
- 用户需要填写的信息:[问题描述、时间范围等]
- 结果要求:[章节、证据、图表等]
- 禁止事项:[权限或业务边界]
没有确认的 Skill name 和 command 不得猜测。需要新 Skill 时单独提出,不要把 Skill 文件生成进场景目录。
## 目录
release-risk-review/
manifest.json
prompt.md
icon.svg # 仅 manifest.json 声明 icon 时必需
目录名必须与 manifest.json 的 code 完全相同。code 只能使用小写字母、数字和连字符,最长 64 位。
## manifest.json
按下面的结构替换业务内容。capabilityCommands 只在需要收窄某个 Skill 的命令权限时保留,否则删除:
{
"code": "release-risk-review",
"version": "0.0.1",
"name": "发布风险评估",
"description": "结合项目、代码和运行证据评估发布风险。",
"slogan": "要评估哪次发布?",
"scenario": "RELEASE_RISK_REVIEW",
"icon": "icon.svg",
"color": "#176a91",
"promptFile": "prompt.md",
"enabled": true,
"resultFormat": "markdown-sections",
"presentations": ["evidence", "mermaid"],
"queuePriority": 100,
"capabilities": [
"project-context",
"code-repository",
"log-query"
],
"capabilityCommands": {
"project-context": [
"project-context.project-list"
]
},
"parameters": [
{
"key": "userInput",
"name": "评估要求",
"type": "textarea",
"required": true,
"description": "说明发布范围和关注风险",
"sortOrder": 10,
"visible": true
}
]
}
字段规则:
- 必需:code、version、name、description、scenario、promptFile;promptFile 必须指向存在且非空的 Markdown。
- version 使用合法包版本,新场景可从 0.0.1 开始。
- slogan、icon、color、resultFormat、presentations、queuePriority 按页面和结果需要填写。
- 声明 icon 时必须创建对应文件;不创建图标就同时删掉 icon 字段。
- capabilities 只能填写真实 Skill 的 name。
- capabilityCommands 可选。key 必须属于 capabilities;值使用 command 的点号 code,例如 group.action。省略时默认允许所选 Skill 的全部命令。
- capabilityConditions 仅在某个 Skill 需要由场景参数控制是否挂载时填写。key 必须属于 capabilities;parameter 必须是 parameters 中的 key;values 是触发该 Skill 的字符串值数组。
- presentations 只能使用 evidence、mermaid、steps、links、timeline、metrics;只选择结果确实需要的类型。
- resultRenderer 仅在需要专用结果页面时填写:workflow 用于流程型结果,document 用于文档型结果;普通 Markdown 结果省略。
- userVisible 仅用于不应出现在用户场景列表中的内部场景;这类场景显式写 false,普通场景省略。
- parameters 每项使用 key、name、type、required、description、sortOrder、visible;select 选项使用 {"label":"必要时","value":"NECESSARY"}。
- 服务地址、仓库地址、数据库地址、Token、私钥路径不属于场景,不得写入 manifest.json 或 prompt.md。
如果使用上面的 icon 字段,同时创建 icon.svg。可以换成符合场景含义的图形,但文件必须是有效 SVG:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
<path d="M4 19V9l8-4 8 4v10"/>
<path d="M8 19v-6h8v6M3 19h18"/>
</svg>
## prompt.md
必须非空,并按真实任务写清目标、决策原则、证据充分条件、输出和边界。使用下面的最小结构:
# 发布风险评估
## 目标
根据当前发布范围和可获得的真实证据,识别会影响发布的风险,并说明判断依据。
## 决策原则
- 先确认本次发布对象和范围,再选择与问题有关的 Skill。
- 只补充会改变结论的证据,不要求每次调用所有 Skill。
- 连接失败、无权限、未找到证据和确认无异常必须区分。
- 证据不足时明确写出未验证项,不编造结论。
## 输出
说明发布范围、已确认风险、证据、影响和建议;复杂调用关系可以使用 Mermaid。
## 边界
- 不在场景中写死 Skill 的脚本、接口参数、凭证和固定调用顺序。
- 不执行用户未授权的代码或数据变更。
## 完成前检查
- manifest.json、prompt.md 存在,code 等于目录名,version、name、description、scenario 非空。
- promptFile 和 icon 引用的文件真实存在,prompt.md 非空。
- capabilities 全部是已提供的 Skill name;capabilityCommands 全部是对应 Skill 的真实点号 command code。
- presentations 只使用平台支持的类型;capabilityConditions 引用真实参数;resultRenderer 只使用 workflow 或 document。
- 参数名称面向用户,不让用户填写内部编码;敏感接入信息没有进入场景。
- ZIP 内只放一个以 scenario code 命名的一级目录,定义文件位于该目录中。
- ZIP 不超过 10MB,解压后不超过 20MB,文件不超过 100 个,不含符号链接、密钥、缓存、日志和数据库。
最后给出文件清单、引用的 Skill 与 command、检查结果和场景 ZIP 路径。Lingxi 仓库里的相关目录
lingxi-capability.schema.json 的开发 Schema。它用于编辑和校验 lingxi.json,不是运行时定义目录。Demo 应该怎么参考
Demo 展示结构和职责,不要求你的服务与它兼容。个人或公司的服务只要能被自己的 Skill 正确使用即可。
wiki-ingest展示正文检索、版本和媒体资料如何拆到 Skill 与 references。公司 Wiki 支持什么功能,就让自己的 Skill 描述什么,不需要补齐 Demo 的全部命令。查看示例目录从公司项目中心开始
- 先定义 Agent 需要的能力,例如“确定项目和环境”“读取仓库配置”“获取项目关系”。
- 按标准格式创建一个 Skill。公司 API、SDK 和字段映射由 Skill 自己处理,放进脚本还是只写操作说明由实际用法决定。
- 在
lingxi.json中只登记页面参数。项目、环境属于任务参数;服务地址、Token 等属于配置参数。 - 需要业务问答、故障分析等入口时,再创建场景并引用这个 Skill。场景不关心项目中心内部怎么实现。
日志中心和 Wiki 也是同样的关系:先做能独立使用的标准 Skill,再决定哪些场景需要它。不要为了复用 Demo 而强行模仿 Demo 服务。
开发、打包和安装
# ZIP 内只放一个与 Skill name / 场景 code 同名的一级目录 zip -qr dist/my-skill.zip my-skill zip -qr dist/my-scenario.zip my-scenario # 安装 # 1. 管理端 -> 能力管理:上传并预检 Skill ZIP # 2. 安装 Skill,填写它在 lingxi.json 中声明的配置 # 3. 管理端 -> 场景管理:上传并预检场景 ZIP # 4. 检查场景授权的 Skill 和 command,再确认安装 # 5. 在分析情境中选择场景并填写任务参数 # 6. 运行一条真实任务,检查能力调用和最终结果
Skill 有脚本时测试脚本;没有脚本时不要为了测试而造脚本。更新定义后重新打包并安装同编码 ZIP,Lingxi 会保留管理员维护的启停、场景授权和服务接入配置。