- 人工智能
- AI Agent
- AI 应用
- 前端
- 后端
- 即时通讯
- 交互助手
- 工具调用
【免费下载链接】holaOS
Open-source agentic workspace enterprises can make their own. Connect the systems you already run — 100+ integrations, MCP, chat tools, apps, browser, local files — with shared memory. Any agent (Claude Code, Codex), any model, or BYOK. Set up in clicks, not months. Local-first: your data never leaves your machines.
这篇技术指南以 holaOS 仓库中 linkedin-ghostwriter 内嵌能力 及其核心技能文档 SKILL.md 为主体,讲清它如何把"给一个话题、还你一篇像你本人写出来的 LinkedIn 帖子"这一需求,落实为一条可被 Agent 加载、调用并最终经linkedin_*工具发布的技能流水线。读完你会掌握:SKILL.md 的 frontmatter 契约与正文指令结构、技能如何从内嵌目录被解析、注入会话并被 Agent 执行,以及capability.yaml中集成依赖与安装/卸载的生命周期机制。
一、能力定位:LinkedIn Ghostwriter 是什么
在 holaOS 的 runtime(API 服务端)中,"LinkedIn Ghostwriter" 是一个内嵌能力(embedded capability),其完整定义位于 capability.yaml:
id: linkedin-ghostwriter name: LinkedIn Ghostwriter description: Draft LinkedIn posts in your voice from a topic or rough notes category: content icon: "ph:pen-nib-fill" skills: - path: ./skills/linkedin-post/SKILL.md integrations: - provider: linkedin required: true reason: Publishes the drafted posts从这份清单可以读出四个关键信息:
- id / name / description:能力唯一标识、展示名与能力说明,会被写入工作区的能力记录(workspace capability record),供后续查询与状态管理使用;
- category: content:能力归类为内容生产类,与
inbox-triage(productivity)、competitor-watch等并列于 embedded-capabilities 目录; - skills:声明该能力携带的技能清单,这里通过
path指向本技能文档./skills/linkedin-post/SKILL.md; - integrations:声明该能力对 LinkedIn 集成的硬依赖(
required: true),理由是"发布已起草的帖子"(Publishes the drafted posts)。
这与同目录下 competitor-watch(竞品周报)、content-repurposer(内容多平台改写)、inbox-triage(收件箱优先级处理)形成了 holaOS 的"内嵌内容/效率能力"体系。LinkedIn Ghostwriter 的职责非常聚焦:从话题、笔记或粗略想法出发,以用户本人的口吻起草 LinkedIn 帖子,并把"发布"环节交给linkedin_*工具完成。
二、技能文档主体:SKILL.md 的逐条拆解
技能的核心指令位于 SKILL.md,全文分为 frontmatter 与正文两大部分。
2.1 frontmatter:技能被发现与被校验的"身份证"
--- name: linkedin-post description: Draft a LinkedIn post in the user's voice from a topic, note, or rough idea. ---这两行不是可有可无的注释,而是技能能够被系统识别的硬性契约。从 workspace-skills.ts 的解析逻辑可以看到:
skillFrontmatter()(第 99–111 行)用正则^---\r?\n([\s\S]*?)\r?\n---解析出 frontmatter,再用yaml.load反序列化;hasValidSkillFormat()(第 272–292 行)要求 frontmatter 必须存在,且name与目录名(skill id)完全一致(frontmatterName !== params.skillId即判为非法),description也不能为空——缺 frontmatter、名字对不上、描述为空,技能都会被直接过滤掉,不会进入会话;readSkillMetadata()(第 294–326 行)进一步把name、description提取为ResolvedWorkspaceSkill的skill_id/skill_name/description字段。
此外,workspace-skills-catalog.ts 中的materializeSkill()与 workspace-capabilities.ts 中的frontmatterName()(第 332–352 行)也都在解析同一格式:当能力被安装时,技能正文会被写入工作区的skills/<skillId>/SKILL.md,frontmatter 的name会作为技能 id 兜底(缺失时用目录名)。
这意味着:如果你想新增一个同类技能,SKILL.md 的 frontmatter 必须严格遵循name(等于目录名)+description(非空)的结构,否则技能静默不可见。
2.2 正文:六步"以用户之声"起草法
正文是真正会被注入到 Agent 提示词中的指令(原文逐条如下):
Draft a LinkedIn post from a topic or rough notes, in the user's voice.
- Clarify the angle: the one idea, and who it's for.
- Open with a concrete, specific first line — never "I'm excited to share".
- Body: a short story, a lesson, or a contrarian take; keep paragraphs to 1-2 lines.
- End with a light prompt for discussion, not a hard CTA.
- Match the user's past posts for tone and length; avoid hashtag stuffing.
- Return the draft ready to review and publish via linkedin_*.
逐条解释其设计意图与执行要点:
- 明确角度:先确定"唯一的核心观点"以及"目标读者是谁"。这是防止发散、保证帖子聚焦的第一步——一帖一事。
- 第一行必须具体:指令用否定式强调了反例——永远不要以 "I'm excited to share" 这类空泛开场白。要求以具体的事实、场景或矛盾开局,让读者在首行就获得信息增量。
- 正文结构:短故事、经验教训或反常识观点(contrarian take)三选一;段落控制在 1–2 行,符合 LinkedIn 信息流里"短段易读"的排版习惯。
- 结尾轻互动:以轻量的讨论引导收尾,而不是强硬的 CTA(call to action)——这是内容社区互动率的常见做法。
- 模仿用户既往风格:语气与篇幅对齐用户过往帖子,并避免标签堆砌(hashtag stuffing)。
- 交付形态:返回可直接审阅、可直接发布的草稿,交由
linkedin_*工具发布。
这条指令的设计特点是"规则少而可执行":它没有规定字数上限,而是用"与用户过往帖子对齐"来做动态校准;没有堆砌写作模板,而是用"一个观点 + 具体开头 + 1–2 行短段 + 轻收尾"给出稳定的结构骨架。这与 content-repurposer 中"为每个平台各写一版,而不是一篇文本到处粘贴"的思路一脉相承——同为 LinkedIn 写作,但前者是"从零起草",后者是"从单一源素材改写"。
三、从 SKILL.md 到会话:技能如何被加载与调用
SKILL.md 不是静态的说明文档,它会经历"解析 → 注入提示词 → 被 Agent 调用"的完整生命周期。
3.1 技能发现:embedded 与 workspace 双来源合并
workspace-skills.ts 的resolveWorkspaceSkills()(第 417–454 行)把两类技能合并为一个列表:
- embedded(内嵌)技能:从
embeddedSkillsRoot()(第 72–88 行)扫描。默认路径按HOLABOSS_RUNTIME_ROOT解析到harnesses/src/embedded-skills或runtime/harnesses/src/embedded-skills,也支持用环境变量HOLABOSS_EMBEDDED_SKILLS_DIR覆盖;每个子目录对应一个技能(含SKILL.md即有效)。 - workspace(工作区)技能:从工作区目录下的
skills目录(WORKSPACE_SKILLS_RELATIVE_PATH = "skills")扫描,且会通过realpath校验技能目录必须落在工作区真实根目录之内(resolveWorkspaceScopedSkills,第 374–405 行),防止路径逃逸。
合并时以技能 id 为 key,工作区技能优先覆盖内嵌技能(第 427–433 行),顺序上内嵌技能在前(第 435–446 行),最终按 id 字典序输出。
3.2 引用与调用:quoted skill block
当用户在会话中提到某个技能(或以/skill-id形式引用)时,系统通过quotedSkillBlock()(第 260–270 行)把 SKILL.md 的正文(剥离 frontmatter)包装成:
<skill name="linkedin-post" location=".../SKILL.md"> References are relative to .../skills/linkedin-post. (SKILL.md 正文) </skill>随后由invokeWorkspaceSkill()(第 481–523 行)或prepareInstructionWithQuotedWorkspaceSkills()(第 525–563 行)将该 block 拼接进指令文本,注入 Agent 的上下文。若请求的技能不存在,会抛出带可用技能列表的错误(第 498–502 行),帮助调用方自查。
3.3 能力安装:SKILL.md 的落地
在 workspace-capabilities.ts 的installCapability()(第 378–431 行)中:
- 对每个
path型技能引用,先经skillIdForPathRef()(第 354–360 行)读取 SKILL.md 原文并解析 frontmatter 得到skillId(frontmattername优先,否则取path的父目录名); - 然后写入工作区
skills/<skillId>/SKILL.md(幂等覆盖,见 materializeSkill 的注释),使 harness 能拾取; - 同时把
capabilityId、技能列表、集成状态等落库为工作区能力记录(第 418–428 行); - 集成状态由
computeIntegrationStatus()(第 363–376 行)通过listConnectionsMerged()按 provider 查询,得到connected或needs_connection。
uninstallCapability()(第 433–466 行)则负责反向清理:仅删除不再被其他能力引用的技能目录,避免误删共享技能。
3.4 集成依赖:为什么linkedin是required
capability.yaml声明了integrations: [{ provider: linkedin, required: true, reason: Publishes the drafted posts }]。结合computeIntegrationStatus的实现可以确认:
- 安装时按
providerId: "linkedin"查询合并后的连接列表,只要存在status === "active"的连接即视为connected,否则为needs_connection; required: true表示该能力没有 LinkedIn 连接就无法完整工作(草稿无法发布);reason 字段把"为什么需要"这一决策依据固化在清单里,供 UI 或 Agent 展示。
另外从 integration-store-catalog.ts 可以看到,linkedin属于tier: "hero"、category: "social"的头部集成,另有linkedin_ads属于supported层——发布路径与广告路径在集成目录中被区分管理。
四、实操参考:如何安装、使用与自查
以下步骤均围绕 holaOS runtime 的能力/技能机制展开(仓库只读,仅说明查看与运行方式):
- 查看能力清单:
capability.yaml是能力的单一事实来源。目录 embedded-capabilities 下每个子目录一份,loadCapabilityCatalog()(workspace-capabilities.ts)会扫描该目录并按 id 排序加载。 - 安装能力:通过
installCapability(内部由工作区/API 层触发)将技能物化到工作区skills/linkedin-post/SKILL.md,并在状态库登记linkedin-ghostwriter记录;安装前请确认 LinkedIn 集成已连接(status: active),否则集成状态为needs_connection。 - 在会话中使用:给 Agent 一个话题、一段笔记或一个粗略想法,Agent 读取
linkedin-post技能后按六步起草;草稿可直接审阅,最终经linkedin_*工具发布。 - 验证技能格式:若技能未被识别,请对照
hasValidSkillFormat的三条硬性要求自查——① SKILL.md 顶部必须有---frontmatter;② frontmattername必须与技能目录名完全一致;③description必须非空。 - 运行测试:仓库在 workspace-capabilities.test.ts 与 workspace-skills.test.ts 中提供了对清单解析、技能发现与格式校验的测试覆盖,可作为行为基准。
五、小结:一条"轻规则、重执行"的技能实践样板
LinkedIn Ghostwriter 的 SKILL.md 是 holaOS 内嵌技能体系的一个典型样本,它展示了三点可复用的工程实践:
- frontmatter 是机器契约:
name与目录强绑定、description驱动发现,决定了技能能否被解析、收录与调用; - 正文是可执行指令:六步规则覆盖"角度 → 开头 → 正文 → 收尾 → 风格对齐 → 交付",既是写作方法论,也是提示词工程;
- 能力清单是生命周期枢纽:capability.yaml 把技能引用、集成依赖、分类与图标统一管理,安装/卸载/状态跟踪全部围绕它展开。
无论你是要在 holaOS 上直接使用"以你之声"发帖,还是要仿照该模式为自己的工作区编写新技能,这条从 SKILL.md 到linkedin_*发布的链路都是可以直接参照的完整闭环。
- 人工智能
- AI Agent
- AI 应用
- 前端
- 后端
- 即时通讯
- 交互助手
- 工具调用
【免费下载链接】holaOS
Open-source agentic workspace enterprises can make their own. Connect the systems you already run — 100+ integrations, MCP, chat tools, apps, browser, local files — with shared memory. Any agent (Claude Code, Codex), any model, or BYOK. Set up in clicks, not months. Local-first: your data never leaves your machines.
相关推荐
holaOS 提案撰写技能(proposal-writer SKILL.md)实战指南:用 Agent 产出能签单的客户提案
holaOS 提案撰写技能(proposal writer SKILL.md)实战指南:用 Agent 产出能签单的客户提案 导读 本文围绕 holaOS 桌面
人工智能AI AgentAI 应用前端后端即时通讯交互助手工具调用MCP ClientsDeepAgents 社媒技能实战:用 SKILL.md 编写“研究先行”的 LinkedIn 与 Twitter 内容工作流
DeepAgents 社媒技能实战:用 SKILL.md 编写“研究先行”的 LinkedIn 与 Twitter 内容工作流 deepagents 的 Con
人工智能大模型AI AgentAgent 框架自主智能体工具调用代码智能体MCP ClientsAI 技能FinRobot Financial Plan 技能实战指南:用 SKILL.md 驱动自动化财富规划工作流
FinRobot Financial Plan 技能实战指南:用 SKILL.md 驱动自动化财富规划工作流 导读 本文围绕 FinRobot 开源 AI Ag
人工智能AI Agent金融科技AI 应用大模型RAG
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考