
Upsonic Agent Skills 深度解析渐进式技能发现系统的完整实现指南【免费下载链接】gpt-computer-assistantBuild autonomous AI agents in Python.项目地址: https://gitcode.com/GitHub_Trending/gp/gpt-computer-assistant导读本文以 documents/ai/explanation/skills/skills.md 为核心骨架结合 src/upsonic/skills/ 的实际源码实现完整剖析 Upsonic 的 Agent Skills渐进式工具/指令发现系统。你将掌握Skill 包的组成规范SKILL.md、scripts、references、assets、系统提示词中技能摘要的注入机制、四个技能访问工具的调用契约、本地/内联/内置/GitHub/URL 五类加载器的用法、版本约束、依赖解析、缓存与安全防护以及 Skills 如何与 Agent、Task、Team 深度集成。读完本文即可在自己的 Agent 中落地一套小提示词、大知识库的按需加载体系。1. Skills 是什么为 Agent 打包可发现、可加载的领域专长在 Upsonic 中一个Skill是一个自包含的领域专长包可以被Agent或单个Task按需发现和加载。它由四部分组成组成是否必需用途SKILL.md必需YAML frontmattername、description等加上给 Agent 的详细指令正文scripts/可选Agent 可以读取或执行的脚本Python、bash 等references/可选参考文档风格指南、速查表、OWASP 清单等assets/可选辅助文件模板、字体、图标、示例数据整个设计遵循渐进式发现progressive discovery工作流浏览Agent 仅在系统提示词中收到所有可用技能的摘要——技能名 一行描述 有哪些 scripts/references/assets加载当 Agent 判断某技能与当前任务相关时调用get_skill_instructions工具加载完整的 SKILL.md 正文引用/脚本/资产按正文指引再按需调用get_skill_reference、get_skill_script读取或执行、get_skill_asset拉取真正需要的片段。这样系统提示词始终保持精简而背后庞大的知识库可以在恰好需要的那一刻just-in-time被激活。Agent 遵循的具体规则由Skills.get_system_prompt_section写入提示词1. Browse — review the skill summaries below 2. Load — call get_skill_instructions(skill_name) when a task matches 3. Reference — get_skill_reference for documentation 4. Scripts — get_skill_script(executeTrue/False) for code除基本加载外该包还覆盖多种来源加载本地文件系统、内联对象、内置库、GitHub 仓库、通用 URL 归档、按 Agent Skills 规范校验、依赖解析、基于 embedding 的可选自动选择、内存 TTL 缓存、逐技能指标、安全引擎集成以及 semver 风格的版本约束。2. 目录结构与模块地图src/upsonic/skills/ ├── __init__.py # 公共 API 再导出 ├── skill.py # Skill 数据类纯数据容器 ├── skills.py # Skills 容器 —— 加载与调度工具 ├── validator.py # SKILL.md frontmatter 的规范校验 ├── metrics.py # SkillMetrics 数据类逐技能计数器 ├── version.py # SkillVersion VersionConstraintsemver ├── cache.py # SkillCache内存 TTL 缓存 ├── utils.py # 路径安全、shebang 解析、run_script ├── dependency.py # 依赖环检测 拓扑排序 ├── loader/ │ ├── __init__.py │ ├── base.py # SkillLoader ABC │ ├── local.py # LocalSkills文件系统 │ ├── inline.py # InlineSkills编程式 │ ├── builtin.py # BuiltinSkills随 Upsonic 内置 │ ├── remote_base.py # RemoteSkillLoader带缓存下载基类 │ ├── github.py # GitHubSkills仓库 tarball │ └── url.py # URLSkills.tar.gz / .zip └── builtins/ # 随 Upsonic 发布的技能 ├── code-review/ # SKILL.md references/owasp-top-10、severity-guide ├──>dataclass class Skill: name: str description: str instructions: str # SKILL.md 正文frontmatter 之后的所有内容 source_path: str # 技能文件夹的文件系统路径 scripts: List[str] # scripts/ 下的文件名 references: List[str] # references/ 下的文件名 assets: List[str] # assets/ 下的文件名 metadata: Optional[Dict] license: Optional[str] compatibility: Optional[str] allowed_tools: Optional[List[str]] version: Optional[str] dependencies: List[str]三个辅助方法方法用途to_dict()序列化为字典用于存储 / 跨进程传输from_dict()从字典重建对象__repr__紧凑表示如Skill(namecode-review, scripts0…)4.Skills容器编排中枢skills.py 中的Skills是 Upsonic 其余部分交互的入口职责包括加载遍历loaders每个实现SkillLoader接口同名技能冲突时后加载的覆盖先加载的源码_load_skills会打出Duplicate skill name警告日志解析依赖strict_depsTrue时对缺失依赖和依赖环抛出异常否则仅告警提供访问器get_skill、get_all_skills、get_skill_names生成系统提示词片段让 LLM 能浏览技能生成四个工具可调用对象供 LLM 实际加载 instructions / references / scripts / assets追踪指标逐技能记录load_count、reference_access_count等可选能力缓存结果、应用安全策略、通过 embedding 自动选择最相关技能。构造函数签名与源码 skills.py 完全一致Skills( loaders: List[SkillLoader], strict_deps: bool False, cache_ttl: Optional[int] None, # 秒提供后启用 SkillCache on_load: Optional[Callable] None, on_script_execute: Optional[Callable] None, on_reference_access: Optional[Callable] None, auto_select: bool False, # 将提示词过滤为相关技能 max_skills: int 5, # auto_select 开启时的上限 embedding_provider: Optional[Any] None, policy: Optional[Any] None, # safety_engine 策略或列表 )4.1get_system_prompt_section(task_descriptionNone)渲染一个带 XML 标签的区块列出可用技能以及它们各自的 scripts/references/assets 名称让 LLM 知道什么可以调用。当auto_selectTrue且提供了embedding_provider时会通过_select_relevant_skills用余弦相似度源码 skills.py 的_cosine_similarity纯 Python 实现过滤出与任务最相似的 top-max_skills个技能。示例输出skills_system ## What are Skills? Skills are packages of domain expertise … ## IMPORTANT: How to Use Skills 1. get_skill_instructions(skill_name) - Load the full instructions 2. get_skill_reference(skill_name, reference_path) - Access documentation 3. get_skill_script(skill_name, script_path, executeFalse) - Read or run scripts 4. get_skill_asset(skill_name, asset_path) - Read asset files ## Available Skills skill namecode-review/name descriptionPerform structured code reviews …/description scriptsnone/scripts referencesowasp-top-10.md, severity-guide.md/references /skill skill namedata-analysis/name descriptionAnalyze, explore, clean, and visualize datasets …/description scriptsprofile_data.py/scripts referencesstatistical-tests-guide.md/references /skill … /skills_system该结果在设置了cache_ttl时按fsystem_prompt:{task_description or }键缓存。提示词中还包含一条重要提醒技能名不是可调用函数必须使用四个技能访问工具且references是文档而非可执行文件仅当scripts列出真实脚本时才应调用get_skill_script。4.2get_tools(prefix)—— 四个工具可调用对象tools skills.get_tools() # 返回四个普通 Python 可调用对象 # 顺序get_skill_instructions, get_skill_reference, get_skill_script, get_skill_assetprefix会改写__name__/__qualname__避免任务级工具与 Agent 级工具命名冲突。Upsonic 对任务作用域技能使用prefixtask_见第 12 节。工具必填参数可选参数返回值JSON 字符串get_skill_instructionsskill_name—{skill_name, description, instructions, available_scripts, available_references, available_assets, dependencies, version, recommended_tools?}get_skill_referenceskill_name, reference_path—{skill_name, reference_path, content}get_skill_scriptskill_name, script_pathexecuteFalse, argsNone, timeout30executeFalse时{skill_name, script_path, content}executeTrue时{stdout, stderr, returncode}get_skill_assetskill_name, asset_path—{skill_name, asset_path, content}失败模式一律返回 JSON绝不抛出异常让 LLM 可以自行恢复{error: Skill foo not found, available_skills: code-review,>classmethod def merge(cls, *instances: Skills) - Skills: combined: Dict[str, Skill] {} for inst in instances: combined.update(inst._skills) return cls(loaders[InlineSkills(list(combined.values()))])4.4 其他辅助方法方法说明copy()浅拷贝共享 loaders/skills但指标全新——Team._propagate_skills用它让每个 Agent 独立计量自己reload()清空技能字典与缓存重新执行_load_skills磁盘技能被编辑时可热更新get_metrics()返回Dict[str, SkillMetrics]get_active_skill_metrics()/get_active_skill_tools()返回 Agent 实际加载过的技能的allowed_tools并集可用于工具绑定策略__len__、__contains__便捷运算符5. 校验Agent Skills 规范执行validator.py 实现公开的validate_skill_directory(path)与validate_metadata(meta, skill_dir)。返回人类可读错误列表空列表即合法。强制规则对应源码 validator.py字段规则name非空、≤ 64 字符、小写、仅字母数字与连字符、首尾及连续不得出现连字符、必须与目录名一致NFKC 归一化后比较description非空、≤ 1024 字符、不得包含或防止提示词注入compatibility字符串≤ 500 字符license字符串allowed-tools字符串列表dependencies字符串列表metadata字典frontmatter 键仅允许{name, description, version, license, allowed-tools, metadata, compatibility, dependencies}校验器还会检查 SKILL.md 必须以---开头且 frontmatter 正确闭合否则抛SkillParseError。如果环境未安装pyyaml会回退到_simple_yaml_parse保证最小化安装也能工作。6. 版本控制SkillVersionVersionConstraintversion.py 提供 semver 风格版本与复合约束SkillVersion.parse(1.2.3) # - SkillVersion(1, 2, 3) VersionConstraint(1.0,2).satisfies(SkillVersion(1, 4, 0)) # True每个逗号分隔段支持的运算符、、、、、!。LocalSkills(version_constraint…)用它过滤返回的技能——不满足约束、版本无效或无版本的技能其处理逻辑在 local.py无版本技能默认仍被包含并输出 debug 日志。7. 缓存SkillCachecache.py 是一个极简内存 TTL 缓存按字符串键存储由Skills在传入cache_ttl时创建默认 TTL 300 秒Skills传入时以cache_ttl为准。缓存两类数据system_prompt:task_description——get_system_prompt_section的输出instructions:skill_name——_get_skill_instructions的输出。invalidate()清空全部条目Skills.reload()会调用它。8. 安全与脚本执行utils.pyutils.py 是安全关键模块函数职责is_safe_path(base, requested)解析requested并确认其停留在base内Path.resolve()is_relative_to防路径穿越parse_shebang(script_path)从#!/usr/bin/env -S node等行解析出python3、bash、nodeget_interpreter_command(name)将python*映射到sys.executable从而保留当前虚拟环境run_script(...)subprocess.run timeoutWindows 下因无法原生执行 shebang会先解析 shebang 再构造命令read_file_safe(path)UTF-8 读取错误显式上抛ScriptResult是一个小数据类(stdout, stderr, returncode)由run_script返回。Unix 下run_script的执行策略有 shebang 则用映射后的解释器.py后缀默认sys.executable.sh/.bash默认bash否则确保可执行位后直接执行。9. 依赖图算法dependency.pydependency.py 提供三个图算法get_missing_dependencies(skills) - Dict[name, [missing_dep, …]] detect_cycles(skills) - List[List[name]] # 三色 DFS resolve_load_order(skills) - List[name] # Kahn 拓扑排序Skills._load_skills加载完成后调用get_missing_dependencies和detect_cyclesstrict_depsTrue时任一问题都致命抛SkillValidationError否则仅记 warning。resolve_load_order面向需要按依赖顺序遍历技能的调用方检测到环时会抛SkillValidationError并报告环路径。10. 加载器家族从文件系统到远程归档10.1SkillLoader—— 唯一接口契约loader/base.pyclass SkillLoader(abc.ABC): abc.abstractmethod def load(self) - List[Skill]: ...整个契约只有这一个方法。任何实现它的类都可以接入Skills(loaders[…])。10.2LocalSkills—— 文件系统主力加载器loader/local.py 接受两类路径单个技能文件夹内部直接含SKILL.md技能文件夹的父目录。它完成 SKILL.md 的真实解析可选执行validate_skill_directoryvalidateTrue默认开启开发期可关用正则^---\s*\n(.*?)\n---\s*\n?(.*)$把 frontmatter 与指令正文分开用pyyaml解析无 pyyaml 时回退_parse_simple_frontmatter从顶层version或metadata.version读取版本列出scripts/、references/、assets/下的文件排序、跳过隐藏文件可选按version_constraint用VersionConstraint过滤。10.3InlineSkills—— 编程式注册loader/inline.py 包装内存中的Skill对象列表用于两种场景用户代码不落盘直接注册技能Skills.merge作为快照 loader。validateTrue时通过validate_metadata执行 name/description/dependency 规则默认False。10.4BuiltinSkills—— 随包内置技能loader/builtin.py 通过importlib.resources.files(...)定位upsonic.skills.builtins/可编辑安装与 wheel 安装均可用然后委托给LocalSkills。skills[…]可选过滤暴露哪些内置技能available_skills()列出所有含SKILL.md的内置文件夹名。内置技能预校验默认validateFalse。10.5RemoteSkillLoader—— 下载型加载器基类loader/remote_base.py 为任何需要下载的加载器实现公共逻辑每来源独立缓存目录~/.upsonic/skills_cache/loader_name/sha256-of-source-key 前16位/通过.cache_meta.json文件实现 TTL 新鲜度检查默认cache_ttl3600秒force_refresh绕过缓存强制重新下载解压后委托LocalSkills加载。子类只需实现_download(target_dir)与_source_key()两个抽象方法。10.6GitHubSkills—— 从 GitHub 仓库加载loader/github.py 下载https://api.github.com/repos/{owner}/{name}/tarball/{branch}经httpx流式读取受_MAX_DOWNLOAD_SIZE 100 MB守卫仅解压path/默认skills/下的文件。自动识别 tarball 根前缀跳过符号链接与含..的穿越条目支持GITHUB_TOKEN/GH_TOKEN环境变量鉴权skills[…]可限制只取 tarball 内的特定技能目录。需要httpx未安装时抛SkillDownloadError并给出安装提示。10.7URLSkills—— 通用 URL 归档loader/url.py 与 GitHub 版本形态相同但面向任意 URL 上的.tar.gz/.tgz或.zip归档。从扩展名或 zip 魔数PK\x03\x04自动识别归档类型同样具备 100MB 上限与路径穿越/符号链接防护。11. 内置技能一览builtins/目录随 Upsonic 发布三个预校验技能技能教给 Agent 什么脚本参考文档code-review多维代码评审正确性、安全性、性能…—severity-guide.md、owasp-top-10.mddata-analysis数据清洗、探索、统计分析、A/B 测试、沟通profile_data.pystatistical-tests-guide.mdsummarization高管/技术/研究/会议/变更日志摘要—summary-templates.md每个 SKILL.md 都有 YAML frontmattername、description、metadata.version、metadata.author、metadata.tags和以第二人称写就的详细指令例如在发表任何评论前通读全部代码。例如 builtins/data-analysis/SKILL.md 明确指引 LLM 使用哪个工具调用- Execute profile_data.py with a data file path to get a quick profile … - Load statistical-tests-guide.md when choosing statistical tests …配套脚本 builtins/data-analysis/scripts/profile_data.py 是真实可运行的带argparseCLI 的 Python 程序——当 Agent 调用get_skill_script(data-analysis, profile_data.py, executeTrue, args[data.csv, --output, json])时Skills经utils.run_script真正 shell 出去执行并返回 stdout/stderr/returncode。12. 与 Upsonic 框架的集成12.1Agent.skills在 src/upsonic/agent/agent.py# Register skill tools if skills are provided if self.skills is not None: self.tools.extend(self.skills.get_tools())构造时四个技能工具get_skill_instructions…get_skill_asset像普通工具一样被追加进 Agent 的工具列表。Agent.skill_metrics()暴露Skills.get_metrics()。12.2Task.skillsTask.__init__接受可选skills参数src/upsonic/tasks/tasks.py。运行时 Agent 以带前缀的方式注册任务级技能工具agent.py# Register task-level skill tools with prefix to avoid name collision if hasattr(task, skills) and task.skills is not None: tools_to_register.extend(task.skills.get_tools(prefixtask_))这让同一个 Agent 可以同时暴露两套独立技能库自己的 任务的而不产生命名冲突——任务级版本名为task_get_skill_instructions、task_get_skill_reference等。任务还会通过Task._pickle/_unpickle用 cloudpickle 序列化技能使其在跨进程调度中存活。12.3 系统提示词构造src/upsonic/agent/context_managers/system_prompt_manager.py 决定注入哪个技能摘要区agent_skills getattr(self.agent, skills, None) task_skills getattr(self.task, skills, None) if self.task else None if agent_skills is not None and task_skills is not None: from upsonic.skills import Skills merged Skills.merge(agent_skills, task_skills) # task overrides agent skills_section merged.get_system_prompt_section() elif agent_skills is not None: skills_section agent_skills.get_system_prompt_section() else: skills_section task_skills.get_system_prompt_section() if skills_section: prompt_parts.append(skills_section)这就是skills_system区块进入每个系统提示词的方式。12.4Team传播src/upsonic/team/team.py 的_propagate_skills沿团队图递归传播技能每个Agent实体获得自己的Skills.copy()保证逐 Agent 指标独立若实体已有技能团队用Skills.merge(skills, entity.skills)合并实体技能冲突时获胜entity.add_tools(entity.skills.get_tools())在每个接收 Agent 上重新注册四个工具子Team递归处理。12.5 Autonomous Agentsrc/upsonic/agent/autonomous_agent/autonomous_agent.py 将skills参数直通底层Agent构造函数skillsskills因此 prebuilt 自治代理同样继承渐进式发现流程。13. 端到端实战从配置到技能执行13.1 组装一个带技能的 Agentfrom upsonic import Agent, Task from upsonic.skills import ( Skills, LocalSkills, BuiltinSkills, GitHubSkills, InlineSkills, Skill ) skills Skills( loaders[ BuiltinSkills(), # 随 Upsonic 内置 LocalSkills(/etc/team-skills), # 团队共享文件系统 LocalSkills(./project-skills, # 项目专属 版本约束 version_constraint1.0.0,2.0.0), GitHubSkills(repoacme/skills-library, branchmain, pathskills/), InlineSkills([ # 编程式注册 Skill(namehello, descriptionSay hi politely., instructionsAlways greet the user by name., source_path), ]), ], cache_ttl600, # 缓存指令 10 分钟 strict_depsFalse, auto_selectFalse, # 置 True embedding_provider 可启用过滤 ) agent Agent( modelanthropic/claude-sonnet-4-6, skillsskills, )13.2 Agent 在系统提示词中看到什么容器通过get_system_prompt_section注入skills_system区块列出每个已加载技能的摘要、可用脚本/引用/资产以及如何使用技能工具的规则和 4 步渐进式发现工作流。13.3 LLM 选中技能后发生了什么第 1 步 Browse—— 模型阅读摘要区块。第 2 步 Load—— 模型发出工具调用{tool: get_skill_instructions, args: {skill_name: data-analysis}}Skills._get_skill_instructions的内部流程skills.py检查SkillCache键instructions:data-analysis查找Skill对象不存在则返回带available_skills的错误 JSON将技能名加入self._active_skills供工具绑定策略使用对指令正文运行安全策略_validate_content被拦截时返回{error: Content blocked by policy: …}记录metrics.record_load(charslen(result))触发on_load(name, description)回调若配置缓存并返回 JSON 字符串。第 3 步 Reference—— 模型需要统计检验决策矩阵{tool: get_skill_reference, args: {skill_name: data-analysis, reference_path: statistical-tests-guide.md}}经is_safe_path针对source_path/references/校验read_file_safe读取策略检查更新指标后以 JSON 返回。第 4 步 Script—— 模型调用内置剖析脚本{tool: get_skill_script, args: {skill_name: data-analysis, script_path: profile_data.py, execute: true, args: [data.csv, --output, json], timeout: 30}}_get_skill_script的流程skills.py校验script_path在skill.scripts中经is_safe_path解析到source_path/scripts/下调用utils.run_script—— 解析 shebang#!/usr/bin/env python3把python3映射为sys.executable以复用当前虚拟环境执行subprocess.run(..., timeout30, cwdskill.source_path)返回{stdout, stderr, returncode}JSON递增metrics.script_execution_count超时返回Script execution timed out after 30 seconds错误 JSON。第 5 步 Asset—— 资产文件通过get_skill_asset(skill_name, asset_path)直接返回文件内容模板、字体、示例 CSV 等。13.4 清理、可观测性与错误路径agent.skill_metrics()返回Dict[str, dict]逐技能计数器可用于遥测与技能策展哪些技能配得上提示词里的位置Skills.get_active_skill_tools()返回模型实际加载过的技能声明的allowed_tools并集让 Upsonic 其他部分可依据技能激活状态门控其他工具所有错误技能不存在、路径非法、穿越尝试、超时、策略拦截、解释器缺失都以 JSON 字符串返回而非抛出LLM 可以继续对话并自我恢复Skills.reload()失效缓存并重跑加载器适合磁盘技能运行时被编辑的场景远程加载器按~/.upsonic/skills_cache/loader/hash/落盘缓存由 loader 自身的cache_ttl控制新鲜度与Skills(cache_ttl…)的内存提示词缓存相互独立。最终效果Upsonic Agent 拥有一座可选择性取用的结构化专长库只为实际决定使用的技能支付提示词 token 成本而框架把加载、校验、沙箱、缓存与可观测性都从 Agent 作者那里抽走。14. 测试验证仓库为 Skills 系统提供了完整的测试覆盖可作为行为契约参考单元测试tests/unit_tests/skills/test_skills_container.py容器初始化、多 loader 加载、后 loader 覆盖、访问器、tests/unit_tests/skills/test_skill_loaders.py、tests/unit_tests/skills/test_skill_metrics.py冒烟测试tests/smoke_tests/skills/ 下的test_skill_agent_integration.py、test_skill_task_integration.py、test_skill_team_integration.py、test_skill_tool_prefixing.py验证默认无前缀与task_前缀工具名见 test_skill_tool_prefixing.py、test_skill_version_filtering.py、test_skill_github_loader.py、test_skill_safety_policies.py、test_builtin_skills_agent.py等。总结Upsonic 的 Skills 系统用一套精炼的契约SkillLoader.load→Skill→Skills容器 → 四个工具实现了小提示词 大知识库的渐进式能力供给加载器家族覆盖本地、内联、内置与远程来源validator、is_safe_path、安全策略与超时机制共同构成安全边界版本约束、依赖解析、TTL 缓存与逐技能指标让大规模技能库可治理、可观测。结合 Agent、Task、Team 的三级集成前缀命名、Skills.merge、_propagate_skills你可以把同一套技能体系平滑地从小型单 Agent 扩展到多智能体团队。【免费下载链接】gpt-computer-assistantBuild autonomous AI agents in Python.项目地址: https://gitcode.com/GitHub_Trending/gp/gpt-computer-assistant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考