1. 项目概述:这不是一个“开箱即用”的魔法插件,而是一套需要亲手调试、反复验证的AI能力组装方案
“187K star 的 superpowers 我用了三个月:没你想的那么香”——这个标题一出来,我就知道又一批朋友被 GitHub Trending 页面上那个闪亮的星标晃花了眼。superpowers 项目确实在 2024 年初爆火,它把 Claude Code、Skill 脚本、本地模型调用、VS Code 插件集成这些关键词全塞进一个仓库里,主页 README 写得像产品发布会:一键接入 AI 编程助手、自动执行终端命令、读取 GitHub PR 评论、生成测试用例、甚至能帮你写周报。但实话讲,我从 fork 到真正让它在我 Ubuntu 22.04 + VS Code 1.89 + LM Studio 0.2.32 的环境里稳定跑通核心 workflow,前后花了整整 13 周,重装了 7 次 Python 环境,删掉了 42 个失败的 skill 配置文件,才搞明白一件事:superpowers 不是“安装即用”的软件,它更像一套开源的 AI 工具链说明书,而说明书里最关键的几页,被作者用注释形式藏在了SKILL.md文件第 37 行和diplay子模块的config.py里。
它解决的核心问题很真实:当你的日常开发工作流中,有大量重复性高、规则明确但又琐碎到不值得写完整 CLI 工具的任务时(比如每次提交前自动生成 commit message、根据 Jira ticket ID 自动拉取需求描述并生成函数 docstring、把 Markdown 技术文档实时转成 Confluence 兼容格式),你确实需要一种比 Copilot 更可控、比纯脚本更智能、比自己搭 LangChain Agent 更轻量的中间层。superpowers 就是冲着这个缝隙去的。但它不是成品,而是半成品工具包。适合谁?适合已经用熟 VS Code、能看懂 Python traceback、愿意花两小时 debug 一个 YAML 缩进错误、对subprocess.run()和json.loads()有肌肉记忆的中级以上开发者;不适合刚学完 Python 基础语法、期待“点一下就变强”的新手,也不适合追求企业级 SLA 保障、要求 99.9% 可用率的 SRE 团队。
我把它拆解成三个本质层:最外层是 VS Code 插件界面(claude-code),中间层是 Skill 执行引擎(diplay),最底层是技能定义与数据桥接(SKILL.md+skill/目录)。这三层之间没有强契约,全是靠约定俗成的 JSON Schema、硬编码的路径拼接和一堆try...except Exception as e: print(f"DEBUG: {e}")来维系。所以它的“不香”,不是功能不行,而是整个系统设计哲学就是“先跑起来,再修路”。接下来我会按这个分层逻辑,把这三个月踩过的坑、抄到的作业、验证过的参数,一条条摊开给你看。
2. 核心设计思路拆解:为什么选择这套松耦合架构?它规避了什么,又带来了什么新问题?
2.1 架构选型背后的现实妥协:不是技术最优,而是落地成本最低
superpowers 的整体结构乍看有点“复古”:它没用 FastAPI 做后端服务,没上 Docker Compose 编排,没引入 Redis 做任务队列,甚至连日志都只打到print()。但当你真正在公司内网、离线环境、或只有 8GB 内存的旧笔记本上部署时,就会发现这种“简陋”恰恰是它能活下来的关键。我们来算一笔账:
- 如果用 LangChain + LlamaIndex + Ollama 搭一个标准 RAG Agent,光是模型加载就要占掉 6GB 显存,启动时间 45 秒起,每次调用都要走 HTTP 请求+JSON 序列化+反序列化,延迟在 800ms~2.3s 之间波动;
- 如果用 VS Code 官方推荐的
vscode-extension-samples模板从头写一个 AI 插件,你需要处理 Webview 渲染、状态管理、跨进程通信、权限沙箱,光是让插件在 Windows 和 macOS 上表现一致,就得额外投入 3 人日; - 而 superpowers 的核心执行逻辑,就藏在
diplay/cli.py这个不到 200 行的脚本里:它用argparse解析命令行参数,用importlib.util.spec_from_file_location()动态加载.py技能文件,用subprocess.run()调用本地命令,最后把 stdout/stderr 当作结果返回给 VS Code 插件。整个过程全程在 Python 进程内完成,无网络 IO,无序列化开销,平均响应时间压到了 120ms 以内(实测数据:i5-8250U + 16GB RAM + NVMe SSD)。
这就是它选择“松耦合”的根本原因:用可预测的性能损耗,换取极低的部署门槛。它把复杂度从“运行时”转移到了“配置时”。你不需要懂异步编程,但必须会写 YAML;你不需要会调试 WebSocket,但得能看懂SKILL.md里那套input_schema和output_schema的字段映射规则。
提示:
SKILL.md不是文档,是契约。它定义了所有 Skill 必须遵守的输入输出接口规范。比如book-to-skill这个技能,要求输入必须包含book_path: string和target_format: enum["md", "html", "pdf"],输出必须是{ "status": "success" | "error", "output_path": string }。如果你写的技能脚本返回了{"result": "ok"},VS Code 插件会直接报错KeyError: 'status',且不会告诉你哪一行错了——因为错误发生在diplay/engine.py的validate_output()函数里,而这个函数的 except 块里只写了pass。
2.2 三层解耦带来的自由与混乱:你能改任何一层,但改错一层就全崩
superpowers 的三层结构(插件层 → 引擎层 → 技能层)给了你极大的修改自由度,但也埋下了“牵一发而动全身”的隐患。我举三个真实案例:
案例一:替换默认 LLM
官方默认用claude-code插件调用 Anthropic API。但我想用 LM Studio 本地跑 Qwen2-7B。很多人以为只要改settings.json里的claudeCode.model就行。错。你还得同步改三处:①diplay/config.py里的DEFAULT_LLM_PROVIDER = "lmstudio";②skill/codex-skill.py里requests.post("http://localhost:1234/v1/chat/completions")的 URL 和 headers;③SKILL.md中codex-skill条目下的requires_model: true必须保留,否则插件会跳过模型调用直接执行空逻辑。漏改任意一处,结果都是:插件显示“正在思考”,然后卡死 30 秒后弹出TimeoutError。
案例二:新增自定义 Skill
我想加一个git-pr-summary技能,自动解析当前分支的 PR 描述并生成中文摘要。我照着skill/template.py写好了脚本,放进skill/目录,也在SKILL.md里加了条目。但 VS Code 插件列表里就是不显示。查了 4 小时才发现:diplay/engine.py的load_skills()函数里,有一行硬编码if skill_name.startswith("test_") or skill_name == "template": continue——作者把 template 当作占位符过滤掉了,而我的文件名是git-pr-summary.py,但skill_name是从文件路径os.path.basename(file_path).replace(".py", "")提取的,git-pr-summary里有短横线,Python 的importlib加载时会报SyntaxError: invalid syntax,而这个错误被try...except吞掉了,日志里只有一行DEBUG: Failed to load skill git-pr-summary。解决方案?把文件名改成git_pr_summary.py,并在SKILL.md里对应条目写name: git_pr_summary。
案例三:禁用某个 Skill
官方没提供开关。有人想禁用dog-buddy-skill(狗头军师技能,会自动在代码注释里加调侃语句),以为删掉skill/dog-buddy-skill.py就行。结果第二天发现所有 Skill 都不工作了。原因:diplay/engine.py在初始化时会遍历skill/目录下所有.py文件并尝试导入,一旦某个文件 import 失败(比如dog-buddy-skill.py里引用了已卸载的emoji包),整个load_skills()函数就会return [],导致技能列表为空。正确做法是:在skill/目录下建个disabled/子目录,把不想用的技能文件移进去,并确保load_skills()的 glob pattern 不匹配该路径(默认是skill/*.py,所以skill/disabled/*.py是安全的)。
这三点说明了一个事实:superpowers 的“可扩展性”是建立在“你愿意深入每一层源码”的前提上的。它不是黑盒,而是透明的白盒,但白盒里布满了没写进文档的暗门。
3. 核心细节解析与实操要点:从SKILL.md到diplay引擎,每个环节的生死线在哪里?
3.1SKILL.md:不是 Markdown 文档,而是技能注册表与类型契约
SKILL.md是 superpowers 项目里最被低估、也最容易出错的文件。它表面是文档,实际承担着三重角色:① VS Code 插件读取技能元信息的唯一来源;②diplay引擎校验输入输出格式的 Schema 定义;③ 新手理解技能能力边界的速查手册。它的结构不是随意写的,而是严格遵循一套隐式规则。
我们以workbuddy-skill为例,看它的标准写法:
### workbuddy-skill - **Description**: 从当前 Git 仓库提取最近 3 次 commit 的 author、message、diff 摘要,生成团队周报草稿。 - **Input Schema**: - `repo_root` (string, required): 本地 Git 仓库根目录路径,如 `/home/user/project` - `include_diff` (boolean, default: false): 是否包含代码变更 diff 摘要 - **Output Schema**: - `status` (string, enum: ["success", "error"]) - `report_md` (string): 生成的 Markdown 格式周报内容 - `error_message` (string, optional): status=error 时的错误详情 - **Requires Model**: true - **Category**: devops这里每个字段都有深意:
Description字段会被直接显示在 VS Code 命令面板里,所以必须简洁(≤80 字),且不能含换行。我试过加<br>标签,结果插件直接崩溃——因为插件用的是markdown-it的极简 parser,不支持 HTML。Input Schema和Output Schema的字段名,必须和技能脚本里def execute(input_data: dict) -> dict:的input_data键名、返回字典的键名完全一致,包括大小写和下划线。include_diff写成includeDiff或includediff,都会导致KeyError。Requires Model: true这行是硬开关。如果设为true,diplay/engine.py在执行前会强制调用get_llm_response()函数;如果设为false,则跳过模型调用,直接执行技能脚本。这个开关不校验,全靠人工维护。我曾把book-to-skill的Requires Model改成false,结果它还是去调了模型——因为book-to-skill.py脚本内部自己写了requests.post(),和这个开关无关。所以这个字段的真实含义是:“此技能是否依赖diplay引擎内置的 LLM 调用流程”。
注意:
SKILL.md的解析逻辑在diplay/parser.py的parse_skill_md()函数里。它用正则r'###\s+(.+?)\n- \*\*Description\*\*:\s+(.+?)\n- \*\*Input Schema\*\*:\n((?:.|\n)*?)- \*\*Output Schema\*\*:'匹配,所以你的###和- **Description**:之间不能有空行,Input Schema和Output Schema之间必须有空行,否则解析失败,diplay会返回空技能列表,且不报错。
3.2diplay引擎:动态加载与沙箱执行的双刃剑
diplay是 superpowers 的心脏,但也是最脆弱的部分。它的核心逻辑在diplay/cli.py和diplay/engine.py里,总共不到 500 行代码,却决定了整个系统的稳定性。我把它拆成四个关键环节:
环节一:技能发现(find_skills())
它用glob.glob("skill/*.py")扫描目录,排除__init__.py和template.py,然后对每个文件做os.path.getmtime()排序(最新修改的优先)。这意味着:如果你同时编辑了git_pr_summary.py和codex-skill.py,git_pr_summary.py会优先被加载。但如果你在编辑时保存了空文件(比如 Ctrl+S 但没写内容),它的 mtime 会更新,导致diplay加载一个空模块,然后importlib报SyntaxError,整个加载流程中断。解决方案:编辑技能脚本时,务必保证文件内容合法,哪怕只写def execute(input_data): return {"status": "success"}。
环节二:动态加载(load_skill_module())
这是最危险的一步。diplay用importlib.util.spec_from_file_location(skill_name, file_path)创建 spec,再用importlib.util.module_from_spec(spec)创建模块对象,最后spec.loader.exec_module(module)执行。这个过程没有任何沙箱保护——你写的技能脚本可以import os; os.system("rm -rf /"),也可以while True: pass卡死整个进程。官方没做限制,因为它的定位就是“开发者工具”,不是“生产环境服务”。但我在测试champ-teleop-skill(一个模拟机器人遥控的技能)时,它内部用了threading.Timer,结果在 VS Code 里连续触发两次,生成了两个 Timer 线程,内存泄漏,VS Code 卡死。解决方法:在技能脚本开头加import threading; [t.cancel() for t in threading.enumerate() if t.name.startswith("superpowers_timer")]主动清理。
环节三:输入校验(validate_input())
它只做最基础的检查:①input_data是 dict;② 所有required字段都在input_data里;③ 字段类型匹配(string对应isinstance(v, str),boolean对应isinstance(v, bool))。但它不做值域校验。比如include_diff字段定义为boolean,但你传"true"(字符串)或1(整数),它会通过校验,然后技能脚本里if input_data["include_diff"]:就会出错(因为"true"是真值,但逻辑上应该是布尔)。我为此专门在diplay/engine.py里加了一段预处理:
# 在 validate_input() 后,execute() 前插入 for field in schema.get("fields", []): if field.get("type") == "boolean" and isinstance(input_data.get(field["name"]), str): input_data[field["name"]] = input_data[field["name"]].lower() in ["true", "1", "yes"]环节四:执行超时控制(run_with_timeout())diplay用concurrent.futures.ThreadPoolExecutor包裹技能执行,并设timeout=30。但这个 timeout 有个致命缺陷:它只对ThreadPoolExecutor.submit().result(timeout)生效,而对技能脚本内部的subprocess.run()、requests.get()等阻塞调用无效。比如github-diplay-skill里requests.get("https://api.github.com/repos/xxx")如果遇到 DNS 解析失败,会卡住 60 秒,ThreadPoolExecutor的 timeout 不起作用。最终解决方案:在技能脚本里,所有外部调用必须显式加 timeout,requests.get(url, timeout=(3.05, 27))(连接 3.05s,读取 27s,总和 30s)。
3.3 VS Code 插件层:claude-code的配置陷阱与调试技巧
claude-code插件本身是开源的(GitHub 上有镜像),但它的配置项分散在三个地方:① VS Code 设置 UI;② 工作区.vscode/settings.json;③diplay引擎的config.py。这三个地方的优先级是:工作区设置 > 用户设置 >config.py默认值。但很多坑就出在“你以为改了 A,其实生效的是 B”。
陷阱一:模型配置的三重覆盖
插件设置里有Claude Code: Model,settings.json里有"claudeCode.model",diplay/config.py里有DEFAULT_MODEL = "claude-3-haiku-20240307"。你以为改settings.json就行?错。claude-code插件在启动时,会先读settings.json,然后把这个值传给diplay的 CLI 命令,形如python -m diplay.cli --model claude-3-haiku-20240307 ...。但diplay/cli.py的argparse解析器里,--model参数的default值是config.DEFAULT_MODEL,所以如果你在settings.json里没写"claudeCode.model",它就会 fallback 到config.py的值。而config.py的值,又可能被你之前pip install的某个旧版本diplay包覆盖(因为diplay作为 PyPI 包安装时,config.py是打包进去的)。我遇到过一次:settings.json写了gpt-4o,但插件日志里一直打印Using model: claude-3-haiku-20240307。查到最后,是pip list | grep diplay显示装了diplay 0.1.2,而这个版本的config.py里DEFAULT_MODEL写死了claude-3-haiku。卸载pip uninstall diplay,改用git clone方式运行diplay,问题解决。
陷阱二:路径配置的绝对与相对之争SKILL.md里写的repo_root: /home/user/project,是绝对路径。但 VS Code 插件在调用diplay时,会把当前打开的文件夹路径(workspace folder)作为--cwd参数传入。如果你在 VS Code 里打开的是/home/user/project/src,而repo_root需要的是/home/user/project,技能脚本里git rev-parse --show-toplevel就会失败。官方没提供路径转换机制。我的做法是在diplay/engine.py的execute_skill()函数里,加了一段路径归一化:
# 在 execute_skill() 开头插入 if "repo_root" in input_data and input_data["repo_root"].startswith("."): # 如果是相对路径,拼接到当前工作目录 input_data["repo_root"] = os.path.abspath(os.path.join(cwd, input_data["repo_root"])) elif "repo_root" in input_data and not os.path.isabs(input_data["repo_root"]): # 如果是不带 ./ 的相对路径,也拼接 input_data["repo_root"] = os.path.abspath(os.path.join(cwd, input_data["repo_root"]))调试技巧:开启插件详细日志
在 VS Code 的命令面板(Ctrl+Shift+P)里,输入Developer: Toggle Developer Tools,打开控制台。然后在插件源码的extension.ts里,找到executeCommand()函数,在spawn()调用前后加console.log()。或者更简单:在settings.json里加"claudeCode.debug": true,插件会把所有 CLI 调用命令、参数、返回值都打到 VS Code 输出面板的Claude Code标签下。这是定位问题的第一现场。
4. 实操过程与核心环节实现:从零开始搭建一个可用的git-pr-summary技能全流程
4.1 环境准备:Ubuntu 22.04 + VS Code + LM Studio 的最小可行配置
我们以 Ubuntu 22.04 为基准环境,目标是让git-pr-summary技能在 VS Code 里正常工作。这个技能的需求是:读取当前 Git 分支的 PR 描述(假设 PR 信息存在.pr-description文件里,这是公司内部约定),调用本地 Qwen2-7B 模型生成中文摘要,并返回 Markdown 格式结果。
步骤一:安装基础依赖
# 确保 Python 3.10+(superpowers 要求) sudo apt update && sudo apt install -y python3.10-venv python3.10-dev build-essential # 创建虚拟环境(强烈建议,避免污染系统 Python) python3.10 -m venv ~/superpowers-venv source ~/superpowers-venv/bin/activate # 安装 diplay 引擎(必须从源码,不要 pip install) git clone https://github.com/shihabal3amri/diplay.git cd diplay pip install -e . # -e 表示 editable mode,改代码立即生效 # 安装 VS Code 插件(从 GitHub Release 下载 .vsix) # 访问 https://github.com/shihabal3amri/claude-code/releases # 下载最新版 claude-code-*.vsix,然后在 VS Code 里:Ctrl+Shift+P → "Extensions: Install from VSIX"步骤二:配置 LM Studio
- 下载 LM Studio 0.2.32(Linux 版),解压后运行
./LMStudio。 - 在 Models 标签页,点击
Download,搜索Qwen2-7B-Instruct,下载并加载。 - 在 Settings → Local Server,确保
Enable local server打开,Port设为1234(默认),Host设为127.0.0.1。 - 启动服务器,你会看到
Server is running on http://127.0.0.1:1234。
步骤三:配置diplay引擎
编辑diplay/config.py:
# 修改以下几行 DEFAULT_LLM_PROVIDER = "lmstudio" LMSTUDIO_API_URL = "http://127.0.0.1:1234/v1/chat/completions" DEFAULT_MODEL = "Qwen2-7B-Instruct" # 必须和 LM Studio 里加载的模型名完全一致 TIMEOUT_SECONDS = 30步骤四:配置 VS Code 插件
在工作区.vscode/settings.json里添加:
{ "claudeCode.model": "Qwen2-7B-Instruct", "claudeCode.diplayPath": "/home/yourname/diplay", // 指向你 clone 的 diplay 目录 "claudeCode.debug": true, "claudeCode.enableSkills": true }注意:
"claudeCode.diplayPath"必须是绝对路径,且指向diplay仓库的根目录(即包含cli.py的目录),不是diplay/子目录。我第一次就写成了"/home/yourname/diplay/diplay",结果插件报Error: Command failed: python -m diplay.cli --help,因为python -m diplay.cli要求diplay在 Python path 里,而diplay的setup.py里packages=find_packages()是从根目录扫描的。
4.2 编写git-pr-summary技能:从SKILL.md到.py脚本的完整闭环
第一步:在SKILL.md里注册技能
在SKILL.md文件末尾,添加:
### git_pr_summary - **Description**: 读取当前 Git 仓库的 .pr-description 文件,调用本地大模型生成中文摘要。 - **Input Schema**: - `repo_root` (string, required): Git 仓库根目录路径 - `max_length` (integer, default: 500): 摘要最大字符数 - **Output Schema**: - `status` (string, enum: ["success", "error"]) - `summary_md` (string): 生成的 Markdown 摘要 - `error_message` (string, optional) - **Requires Model**: true - **Category**: devops第二步:创建技能脚本skill/git_pr_summary.py
import os import json import requests from typing import Dict, Any def execute(input_data: Dict[str, Any]) -> Dict[str, Any]: try: repo_root = input_data["repo_root"] max_length = input_data.get("max_length", 500) # 1. 读取 .pr-description 文件 desc_path = os.path.join(repo_root, ".pr-description") if not os.path.exists(desc_path): return { "status": "error", "error_message": f".pr-description file not found in {repo_root}" } with open(desc_path, "r", encoding="utf-8") as f: pr_content = f.read().strip() if not pr_content: return { "status": "error", "error_message": "PR description is empty" } # 2. 构造 LLM 提示词 prompt = f"""你是一个专业的技术文档工程师。请将以下 Pull Request 描述,浓缩成一段不超过{max_length}字的中文摘要,要求: - 使用 Markdown 格式 - 突出改动范围(修改了哪些模块/文件) - 点明核心目的(解决了什么问题/实现了什么功能) - 语言简洁专业,避免口语化 PR 描述: {pr_content} """ # 3. 调用 LM Studio API payload = { "model": "Qwen2-7B-Instruct", "messages": [{"role": "user", "content": prompt}], "temperature": 0.3, "max_tokens": 1024 } headers = {"Content-Type": "application/json"} response = requests.post( "http://127.0.0.1:1234/v1/chat/completions", json=payload, headers=headers, timeout=(3.05, 27) # 关键!显式 timeout ) response.raise_for_status() result = response.json() summary = result["choices"][0]["message"]["content"].strip() # 4. 返回结果 return { "status": "success", "summary_md": summary } except requests.exceptions.Timeout: return { "status": "error", "error_message": "LM Studio API request timed out" } except requests.exceptions.RequestException as e: return { "status": "error", "error_message": f"LM Studio API error: {str(e)}" } except Exception as e: return { "status": "error", "error_message": f"Unexpected error: {str(e)}" }第三步:验证与调试
- 在终端里,进入
diplay目录,手动运行:python -m diplay.cli --skill git_pr_summary --input '{"repo_root": "/home/yourname/myproject", "max_length": 300}' - 如果返回
{"status": "success", "summary_md": "..."},说明技能脚本和diplay引擎都没问题。 - 如果报错,重点看
response.raise_for_status()和json.loads()的异常,它们会暴露 API 返回的非 200 状态码或 JSON 格式错误。
4.3 在 VS Code 中启用并使用技能:命令面板与快捷键配置
启用技能
- 重启 VS Code(确保插件重载)。
- 打开一个包含
.pr-description文件的 Git 仓库。 - 按
Ctrl+Shift+P打开命令面板,输入Superpowers: Run Skill,回车。 - 在弹出的列表里,应该能看到
git_pr_summary(名字来自SKILL.md的###标题)。 - 选择它,插件会弹出输入框,提示
Enter repo_root,输入你的仓库路径(如/home/yourname/myproject),回车。 - 等待几秒,右下角会弹出通知
Skill executed successfully,摘要内容会显示在 VS Code 的输出面板Claude Code标签下。
配置快捷键(可选)
在 VS Code 的keybindings.json里添加:
[ { "key": "ctrl+alt+p", "command": "superpowers.runSkill", "args": { "skillName": "git_pr_summary", "input": { "repo_root": "${fileWorkspaceFolder}", "max_length": 500 } } } ]这样,你在任意文件里按Ctrl+Alt+P,就能一键生成当前工作区的 PR 摘要。
5. 常见问题与排查技巧实录:那些让你抓狂三天的“幽灵 Bug”真相
5.1 “技能列表为空”:最常见,也最隐蔽的五种原因
这个问题几乎每个新手都会遇到,表面看是插件没加载技能,实际根因五花八门。我整理了一份速查表,按发生频率排序:
| 现象 | 根本原因 | 排查命令 | 解决方案 |
|---|---|---|---|
VS Code 命令面板里Superpowers: Run Skill下拉列表为空 | diplay引擎返回空列表 | cd /path/to/diplay && python -m diplay.cli --list-skills | 检查SKILL.md格式(空行、缩进)、skill/目录下是否有.py文件、diplay是否从正确路径运行 |
列表里有技能名,但点击后报Skill not found | diplay加载了技能,但插件传参错误 | 查看 VS Code 输出面板Claude Code标签,找Executing skill: xxx日志 | 检查SKILL.md里###标题名是否和文件名一致(git_pr_summaryvsgit-pr-summary);检查settings.json里claudeCode.diplayPath是否指向diplay根目录 |
列表里技能名显示为template或test_xxx | diplay/engine.py的load_skills()过滤逻辑生效 | grep -n "template|test_" diplay/engine.py | 确认你的技能文件名不含test_前缀,且不是template.py;检查load_skills()函数里是否有自定义过滤 |
列表里技能名显示乱码(如git_pr_summary\x00) | SKILL.md文件编码不是 UTF-8 | file -i SKILL.md | 用 VS Code 重新保存SKILL.md,编码选UTF-8(不要UTF-8 with BOM) |
列表正常,但执行时报ModuleNotFoundError | 技能脚本里import的第三方包未安装 | cd /path/to/diplay && python -c "import your_skill_module" | 在diplay虚拟环境中pip install所需包;或把包名写进diplay/requirements.txt并pip install -r requirements.txt |
实操心得:我解决第一个问题的方法是,在
diplay/engine.py的load_skills()函数开头加一行print(f"DEBUG: Scanning skill dir: {skill_dir}"),然后在终端里运行python -m diplay.cli --list-skills,看它扫描的路径是不是你预期的。很多时候,插件传的diplayPath是错的,它扫描了/tmp/diplay这种不存在的路径,自然找不到技能。
5.2 “执行卡死/超时”:不是模型慢,是你的网络或权限在拖后腿
TimeoutError是第二大高频问题。但diplay的timeout=30只管 Python 层,不管底层。以下是真实发生的三个案例:
案例:DNS 解析卡死
在公司内网,requests.get("http://127.0.0.1:1234/...")会先走 DNS 查询,而内网 DNS 服务器对127.0.0.1做了特殊处理,导致解析耗时 35 秒。解决方案:在git_pr_summary.py里,把requests.post()的 URL 改成 `http://