1. 项目概述
如果你正在尝试构建一个自主智能体,无论是用于个人助理、客服机器人还是团队协作,你可能会发现一个令人头疼的问题:市面上有太多不同的运行时(Runtime)了。OpenClaw、PicoClaw、TinyClaw……每个运行时都有自己的配置文件格式、目录结构和部署方式。今天为OpenClaw写好的智能体,明天想迁移到TinyClaw上,几乎等于重写一遍。这种“供应商锁定”不仅浪费精力,也让智能体资产难以复用和移植。Spawnfile 正是为了解决这个痛点而生的。它是一个规范(Spec)和一套工具链,旨在让你用一套统一的、与运行时无关的格式来定义你的智能体或智能体团队,然后通过编译器将其“编译”成目标运行时所需的原生配置和文件。简单来说,Spawnfile 让你“一次编写,到处运行”,将智能体的核心定义(身份、技能、团队结构)与具体的运行时实现解耦。
这个项目的核心价值在于“标准化”和“可移植性”。它识别并抽象了当前主流自主智能体运行时之间共通的“最大公约数”,比如基于Markdown的身份文档、技能文件夹、MCP(Model Context Protocol)连接、执行意图(模型、工作空间)和团队结构。通过定义一个名为Spawnfile的YAML清单文件,配合一系列约定俗成的Markdown文档(如IDENTITY.md,SOUL.md,SKILL.md),你可以完整地描述一个智能体。随后,spawnfile compile命令会像一个编译器一样,读取你的源项目,并根据你指定的目标运行时,调用对应的“适配器”(Adapter),生成该运行时能直接识别的配置和工作空间文件。更棒的是,它还会生成完整的Docker构建上下文(包括Dockerfile,entrypoint.sh),让你能一键构建出可运行的容器镜像。
无论你是一个想快速尝试不同运行时特性的开发者,还是一个需要为不同环境(开发、测试、生产)部署同一智能体但使用不同后端的技术负责人,亦或是一个希望智能体资产能长期保值、不因技术栈变迁而报废的团队,Spawnfile 都能为你提供一套优雅的解决方案。它不是一个运行时,而是一个位于运行时之上的“元工具”,致力于让智能体的创建和管理变得更像传统的软件开发——模块化、版本可控、易于协作。
2. 核心设计理念与架构解析
2.1 设计哲学:规范先行,适配在后
Spawnfile 的核心设计哲学是“规范(Spec)驱动”。它首先定义了一套规范化的源格式(Canonical Source Format),这套格式力求简洁、通用,只描述智能体“是什么”和“要做什么”,而不涉及“怎么做”。例如,它规定用IDENTITY.md来描述智能体的基本身份,用SKILL.md来描述一个技能,用surfaces字段来声明通信渠道(如Discord、Slack)。这些定义是抽象的、声明式的。
然后,针对每一个支持的运行时(如openclaw,picoclaw,tinyclaw),Spawnfile 项目会提供一个适配器(Adapter)。适配器的职责非常明确:将规范化的源格式“翻译”(或称为“Lowering”)成目标运行时原生的、可执行的配置。如果某个运行时原生不支持规范中的某个特性(比如某个特定的访问控制模式),适配器会如实报告这个特性是“完全支持(supported)”、“降级支持(degraded)”还是“不支持(unsupported)”。这种设计确保了透明性,让你在编译阶段就能清楚知道移植的成本和限制。
这种架构带来了几个关键优势。首先,关注点分离:作为智能体的作者,你只需要关心业务逻辑和智能体设计,无需深入每个运行时的配置细节。其次,未来兼容性:当有新的运行时出现时,只需要为其编写一个新的适配器,你现有的Spawnfile源项目理论上就能编译到新运行时上,保护了你的投资。最后,工具链统一:无论背后是哪个运行时,你都可以使用同一套CLI命令(init,validate,compile,build,run)来管理你的智能体项目,极大降低了学习成本。
2.2 版本策略:聚焦核心,渐进标准化
Spawnfile v0.1 的版本范围是经过深思熟虑的。它明确聚焦于自主智能体运行时,即那些将智能体作为长期运行服务、并采用Markdown工作空间身份模型的系统。这意味着它暂时不试图标准化一切,而是专注于那些已经被多个运行时共同实践、相对稳定的“便携层(Portable Surface)”。
这个便携层包括:
- 身份与人格文档:
SOUL.md,IDENTITY.md,AGENTS.md。这些Markdown文件定义了智能体是谁、如何思考、如何与其他智能体互动。 - 记忆与心跳意图文档:
MEMORY.md,HEARTBEAT.md。描述了智能体的记忆策略和周期性自检行为。 - 技能:通过
SKILL.md文件定义的、可复用的能力模块。 - MCP连接:声明智能体需要连接哪些外部数据源或工具(通过Model Context Protocol)。
- 运行时绑定:在
Spawnfile中指定目标运行时(如runtime: openclaw)。 - 执行意图:指定使用的AI模型、工作空间配置、沙箱环境等。
- 团队结构:定义多个智能体如何组织成团队,包括成员、层级和共享资源。
- 通信表面:标准化了Discord、Telegram、WhatsApp、Slack和HTTP这几种常见交互渠道的声明方式。
对于超出这个范围的功能,如特定运行时的内存引擎、任务调度器、自定义UI等,v0.1 选择保持开放。它们可以通过适配器以运行时特定的方式扩展,而不强制纳入规范。这是一种务实的做法,既保证了核心的可移植性,又为运行时的创新留出了空间。随着生态发展,更多特性可能会被吸纳进未来的规范版本中。
2.3 项目结构:两种形态,清晰界定
Spawnfile 源项目有两种基本形态:智能体(Agent)和团队(Team)。理解它们的区别对于正确组织项目至关重要。
一个智能体项目的典型结构如下:
my-personal-assistant/ ├── Spawnfile # 主清单,定义运行时、模型、表面等 ├── IDENTITY.md # 我是谁:名称、角色、核心指令 ├── SOUL.md # 我如何思考:价值观、沟通风格、决策原则 ├── AGENTS.md # 我如何看其他智能体:对团队中其他成员的认识 ├── MEMORY.md # 我的记忆策略:记住什么,如何组织 ├── HEARTBEAT.md # 我的心跳:定期自检任务或状态报告 ├── subagents/ # (可选)内部子智能体 │ └── fact-checker/ │ └── Spawnfile # 子智能体有自己的配置 └── skills/ # 技能库 ├── web_search/ │ └── SKILL.md # 技能描述:目的、输入、输出、使用示例 └── summarize/ └── SKILL.md这里的关键是subagents/目录。它用于定义内部子智能体,这些是主智能体内部使用的、功能特定的助手。它们的编译和运行方式取决于父智能体所在运行时的内部机制,对外部而言不是一个独立的服务。
一个团队项目的典型结构则不同:
customer-support-team/ ├── Spawnfile # 团队清单,定义团队结构和共享资源 ├── TEAM.md # 团队使命、协作规则 ├── shared/ # 团队共享资源 │ └── skills/ │ └── kb_lookup/ │ └── SKILL.md # 所有成员可用的共享技能 └── agents/ # 团队成员(独立的智能体项目) ├── receptionist/ │ ├── Spawnfile # 成员A的独立配置,可指定不同运行时 │ └── SOUL.md ├── specialist/ │ ├── Spawnfile # 成员B的独立配置 │ └── SOUL.md └── manager/ ├── Spawnfile # 成员C的独立配置 └── SOUL.md团队项目的核心是agents/目录,它包含的是第一类智能体(First-class Agents),每个都是可以独立运行和编译的实体。团队清单 (Spawnfile) 主要描述这些成员之间的关系和层级。一个团队中的不同成员甚至可以声明使用不同的运行时(例如,receptionist用tinyclaw以节省资源,specialist用openclaw以获得强大功能),Spawnfile 编译器会分别处理它们。
注意:区分
subagents/和agents/是理解Spawnfile项目组织的关键。前者是“内部组件”,后者是“独立个体”。错误地将一个本应是独立智能体的实体放在subagents/下,可能会导致它无法被正确编译和部署为一个独立的服务。
3. 核心工作流程与实操详解
3.1 初始化与项目搭建
开始一个Spawnfile项目最快捷的方式是使用CLI。打开终端,进入你打算创建项目的目录。
创建单个智能体项目:
# 在当前目录创建一个默认使用 openclaw 运行时的智能体项目骨架 spawnfile init # 或者,指定运行时和项目路径 spawnfile init --runtime picoclaw ./my-ai-assistant执行init命令后,你会看到一个新的目录(或当前目录下新增的文件),里面包含了Spawnfile、IDENTITY.md、SOUL.md等模板文件。.spawn/目录也会被创建,并自动添加到.gitignore中,用于存放编译生成的临时文件。
创建团队项目:
# 创建一个团队项目骨架 spawnfile init --team ./support-team团队项目的初始结构不绑定特定运行时,因为运行时是在每个成员智能体的Spawnfile中单独声明的。
向现有项目添加成员:
# 假设当前在 support-team 目录下,它是一个团队项目 # 添加一个名为 `translator` 的智能体成员,默认使用 openclaw 运行时 spawnfile add agent translator # 添加一个名为 `analyst` 的智能体成员,并指定使用 tinyclaw 运行时 spawnfile add agent analyst --runtime tinyclaw # 假设当前在 my-ai-assistant 目录下,它是一个智能体项目 # 添加一个名为 `grammar-checker` 的内部子智能体 spawnfile add subagent grammar-checkeradd命令会智能地根据当前项目的类型(agent或team)来创建正确的目录结构。它会拒绝无效操作,例如尝试向一个智能体项目add agent。
3.2 编写核心清单与文档
项目骨架创建好后,下一步是填充内容。核心是Spawnfile这个YAML文件。一个典型的智能体Spawnfile如下:
# Spawnfile kind: agent runtime: openclaw version: 1 execution: model: primary: provider: anthropic name: claude-3-5-sonnet-20241022 auth: method: claude-code # 使用 Claude CLI 的认证方式 workspace: root: /app/workspace sandbox: enabled surfaces: discord: access: mode: allowlist users: - "987654321098765432" # 你的 Discord 用户 ID bot_token_secret: DISCORD_BOT_TOKEN # 对应环境变量名 telegram: access: mode: open # 对所有人开放(谨慎使用) bot_token_secret: TELEGRAM_BOT_TOKEN http: access: mode: open policy: mode: strict on_degrade: error关键字段解析:
kind: 必须是agent或team。runtime: 指定目标运行时。这决定了编译时使用哪个适配器。execution.model: 定义AI模型。auth.method支持claude-code(Claude CLI)、codex、api_key或none。对于本地模型,可以添加endpoint字段指定兼容的API端点。surfaces: 声明智能体对外暴露的通信接口。v0.1 支持 Discord, Telegram, WhatsApp, Slack, HTTP。access字段控制访问权限,mode可以是pairing(配对模式)、allowlist(白名单)或open(开放)。强烈建议在生产环境中避免使用open模式,除非你完全清楚其安全风险。policy: 控制编译时的严格程度。strict模式下,任何能力降级(degraded)都会导致编译错误,这有助于保证跨运行时行为的一致性。
除了Spawnfile,Markdown文档是智能体的“灵魂”。IDENTITY.md应清晰定义智能体的名称、核心职责和系统指令。SOUL.md则更侧重于描述其性格、沟通偏好和决策框架。SKILL.md文件需要详细描述技能的触发条件、输入参数、输出格式以及使用示例。这些文档的质量直接决定了编译后智能体的行为表现。
3.3 编译、构建与运行
编写完源文件后,就可以进行编译了。
1. 验证项目结构:在编译前,最好先验证一下项目格式是否正确。
spawnfile validate .这个命令会检查Spawnfile的语法、必需文件是否存在以及结构是否符合规范,能提前发现一些配置错误。
2. 编译项目:
# 默认编译,输出到项目根目录的 .spawn/ 下 spawnfile compile . # 指定输出目录 spawnfile compile . --out ./build-output编译过程是Spawnfile的核心魔法。CLI会读取你的源项目,解析依赖关系图(对于团队项目,会遍历所有成员),然后为每个智能体调用其声明的运行时对应的适配器。适配器会生成:
- 目标运行时原生的配置文件(如OpenClaw的
config.yaml)。 - 对应的工作空间文件和目录结构。
- 一个完整的容器构建上下文,包括
Dockerfile、entrypoint.sh和.env.example。 - 一份详细的编译报告
spawnfile-report.json,里面列出了每个特性的支持状态。
3. 管理认证信息:智能体运行通常需要API密钥或令牌。Spawnfile提供了安全的认证管理。
# 将项目所需的认证信息同步到名为“dev”的本地配置文件中 spawnfile auth sync . --profile dev --env-file ./.env这个命令会读取你Spawnfile中声明的认证方式(如claude-code),并引导你将相应的密钥(如从环境文件.env中)导入到本地的Spawnfile认证配置中。密钥本身不会被写入到编译输出或镜像里,而是在运行时动态注入,这比硬编码在镜像中安全得多。
4. 构建Docker镜像:
# 一键编译并构建镜像,打上标签 my-agent:v1 spawnfile build . --tag my-agent:v1build命令封装了compile和docker build。它使用编译生成的Dockerfile,该文件会从官方源拉取已编译好的、版本固定的运行时二进制文件(版本在runtimes.yaml中锁定),而不是在镜像构建过程中从源码编译运行时,这保证了构建速度和环境的一致性。
5. 运行智能体:
# 使用之前配置的“dev”认证配置文件来运行镜像 spawnfile run . --tag my-agent:v1 --auth-profile devrun命令是一个便捷的包装器,它在背后执行docker run,并自动将你在--auth-profile中指定的认证信息(如API密钥)作为环境变量或卷挂载的方式注入到容器中。你也可以选择手动运行:
docker run --env-file .env -p 8080:8080 my-agent:v13.4 模型与通信表面管理
Spawnfile CLI 提供了便捷的命令来修改项目配置,而无需手动编辑YAML文件。
管理模型配置:
# 为当前智能体设置主模型为 Claude Opus,使用 Claude CLI 认证 spawnfile model set anthropic claude-opus-4-6 --auth claude-code # 为当前智能体添加一个本地 Qwen 模型作为后备,使用 OpenAI 兼容接口 spawnfile model add-fallback local qwen2.5:14b --auth none --compat openai --base-url http://localhost:11434/v1 # 递归地为团队项目中的所有智能体成员设置模型 spawnfile model set anthropic claude-3-5-sonnet ./my-team --auth claude-code --recursive这些命令会直接修改Spawnfile中execution.model部分,并确保格式符合规范。
管理通信表面:
# 为智能体添加一个 Discord 表面,采用白名单模式 spawnfile surface add discord . --mode allowlist # 设置 Discord 表面的访问用户列表(需先存在该表面配置) spawnfile surface set-access discord . --mode allowlist --users "123456789,987654321" # 显示当前已声明的所有表面 spawnfile surface show . # 移除 Telegram 表面 spawnfile surface remove telegram .重要提示:不同运行时对通信表面的支持程度不同。例如,在v0.1中,
tinyclaw仅支持 Discord 和 Telegram 的pairing模式,且不支持 Slack;而openclaw和picoclaw则支持更丰富的模式但不支持便携的 HTTP 表面。在添加表面时,务必查阅spawnfile compile生成的报告,或对应运行时的适配器文档,以确认支持情况。
4. 高级特性与实战经验
4.1 策略(Policy)与能力降级处理
在跨平台编译中,一个无法避免的问题是:目标运行时可能无法完全实现源格式中声明的所有能力。Spawnfile 通过明确的策略(Policy)和能力报告机制来优雅地处理这个问题。
在你的Spawnfile中,可以这样设置策略:
policy: mode: strict # 或 `loose` on_degrade: error # 或 `warn`, `ignore`strict模式:编译器会尽可能严格地检查。如果适配器报告某个声明的能力被“降级(degraded)”支持(例如,你声明了surfaces.slack.access.mode: pairing,但目标运行时只支持allowlist,因此适配器将其降级为allowlist实现),编译器会根据on_degrade的设置采取行动。设为error会直接终止编译,这能确保你的智能体在所有目标环境中的行为高度一致。loose模式:编译器会更宽容。它仍然会报告降级和不受支持的特性,但除非是“不受支持(unsupported)”,否则不会失败。这适用于探索性项目或当你明确接受某些功能在不同运行时上有差异时。
编译完成后,务必查看生成的spawnfile-report.json文件。它会详细列出:
- 项目解析出的依赖图。
- 每个智能体使用的运行时和适配器。
- 每个声明的能力(如某个Surface的某种访问模式)的最终状态:
supported、degraded或unsupported。 - 输出文件的位置。
实战经验:对于生产环境的关键智能体,建议始终使用policy: {mode: strict, on_degrade: error}。这相当于在CI/CD流水线中增加了一道质量关卡,防止因运行时兼容性问题导致线上服务出现非预期行为。在开发初期探索阶段,可以先用loose模式快速验证核心功能,然后再逐步收紧策略。
4.2 团队项目的多运行时编排
Spawnfile 最强大的特性之一是对异构运行时团队的支持。在一个团队项目中,不同的成员智能体可以指定不同的runtime。
考虑这样一个客服团队场景:
- 接待员(Receptionist):处理高并发、简单的问答,对响应速度要求高,但对功能要求相对简单。可以指定
runtime: tinyclaw,因为它可能更轻量、启动更快。 - 专家(Specialist):处理复杂、需要深度推理的客户问题。需要强大的模型和技能支持。指定
runtime: openclaw。 - 经理(Manager):负责监控、汇总报告和协调。可能也需要较强的能力,同样使用
runtime: openclaw。
在团队项目的根Spawnfile中,你主要定义团队结构和共享资源,而不指定运行时:
# 团队项目根目录的 Spawnfile kind: team version: 1 # 注意:团队清单本身没有 `runtime` 和 `execution` 字段然后在每个成员的目录下,它们有自己的Spawnfile来声明各自的运行时和配置。
当你对团队项目执行spawnfile compile时,编译器会进行图解析:
- 读取团队根清单,发现成员
receptionist,specialist,manager。 - 进入每个成员的目录,读取其独立的
Spawnfile,获取其声明的runtime(分别是tinyclaw,openclaw,openclaw)。 - 为每个成员调用对应的适配器进行编译。
- 最终输出目录中,会为每个运行时生成独立的子目录(如
.spawn/runtimes/tinyclaw/,.spawn/runtimes/openclaw/),里面包含了对应成员的运行时特定配置。
部署考量:编译后,你会得到多个独立的部署单元(Docker镜像)。你需要分别部署和运行它们。团队间的协作(例如,接待员将复杂问题转交给专家)需要通过运行时间通信机制(如通过共享数据库、消息队列或HTTP API调用)来实现,这部分逻辑需要你在智能体的技能或工作流中自行实现。Spawnfile 目前标准化的是静态的团队结构声明,而非动态的运行时通信协议。
4.3 认证(Auth)系统深度解析
Spawnfile 的认证系统设计得非常巧妙,旨在平衡安全性与便利性。其核心思想是将秘密(Secrets)与配置(Configuration)分离。
1. 认证声明(在 Spawnfile 中):你在Spawnfile的execution.model.auth或surfaces.xxx.bot_token_secret中声明的,不是密钥本身,而是密钥的“引用”。
execution: model: primary: provider: openai name: gpt-4 auth: method: api_key # 这里指向一个环境变量名,而不是真实的密钥 key: OPENAI_API_KEY surfaces: discord: bot_token_secret: DISCORD_BOT_TOKEN # 这是一个环境变量名2. 认证资料管理(通过spawnfile auth命令):你本地的认证资料(真实的API密钥、令牌)存储在~/.spawn/auth.json(或类似位置)中,按配置文件(Profile)组织。
# 创建一个名为“prod”的配置,并从 .env.prod 文件中导入所有环境变量 spawnfile auth sync . --profile prod --env-file ./.env.prod # 查看“prod”配置中存储了哪些认证信息 spawnfile auth show --profile prodsync命令是智能的:它会解析当前项目的Spawnfile,找出所有需要认证的地方(如OPENAI_API_KEY,DISCORD_BOT_TOKEN),然后检查--env-file指定的文件或当前Shell环境,将这些变量的值导入到指定的profile中。
3. 认证注入(在spawnfile run时):当你运行容器时,spawnfile run --auth-profile prod会做以下事情:
- 读取本地
prodprofile 中存储的密钥。 - 将这些密钥通过 Docker 的
--env参数或一个临时环境文件注入到容器运行时环境中。 - 容器内的智能体运行时(如OpenClaw)会读取这些环境变量,完成认证。
这样做的好处:
- 安全:密钥永远不会被硬编码到镜像或编译输出的配置文件中。镜像可以公开分享,而不用担心泄露密钥。
- 灵活:你可以为不同环境(开发、测试、生产)创建不同的profile,轻松切换。
- 兼容:支持多种认证方式,包括
claude-code和codex,它们直接利用你本地已登录的CLI工具的认证状态,无需再次输入密钥。
手动管理认证(高级):你也可以不使用sync,而是手动管理profile:
# 手动设置一个环境变量到profile中 spawnfile auth import env --profile dev --name OPENAI_API_KEY --value sk-xxx... # 导入本地 Claude CLI 的认证状态 spawnfile auth import claude-code --profile dev # 然后运行容器时指定这个profile即可 spawnfile run . --auth-profile dev4.4 自定义与扩展
虽然Spawnfile v0.1提供了开箱即用的支持,但你可能需要适配内部运行时或调整编译输出。
理解适配器(Adapter)结构:适配器位于Spawnfile项目的src/adapters/目录下。每个运行时一个目录(如openclaw/)。适配器的主要工作是实现一个compile函数,它接收规范化的源项目数据,并输出目标运行时的文件树。 关键文件通常包括:
adapter.ts:主适配器逻辑,实现Adapter接口。schemas.ts:定义该运行时特有的配置模式(如果有)。templates/:存放用于生成配置文件的模板(如Handlebars模板)。
添加对新运行时的支持(高级):
- 研究运行时:在
specs/research/下创建笔记,分析该运行时的配置格式、启动方式、能力矩阵。 - 创建适配器骨架:在
src/adapters/下创建新目录,实现compile、getCapabilities等方法。 - 实现编译逻辑:将Spawnfile规范中的字段映射到该运行时的配置文件。处理能力降级报告。
- 注册适配器:在运行时注册表(
src/runtimes.ts)中添加新适配器。 - 更新
runtimes.yaml:添加新运行时的版本锁定和下载信息。 - 编写测试:使用
fixtures/下的示例项目进行集成测试。
调整编译输出:编译生成的Dockerfile和entrypoint.sh是模板化的。如果你需要统一的监控、日志收集或初始化脚本,可以修改这些模板(位于src/container/templates/)。但要注意,对核心模板的修改会影响所有使用该运行时的项目,这可能不是你想要的效果。更常见的做法是在你自己的Spawnfile源项目中,通过skills/或自定义启动脚本来添加这些运维功能。
5. 常见问题、排查技巧与最佳实践
5.1 编译与验证问题
问题1:执行spawnfile compile时报错Unsupported runtime: XYZ
- 原因:你在
Spawnfile中指定的runtime字段(如runtime: myinternalclaw)在Spawnfile的运行时注册表中不存在。 - 排查:
- 运行
spawnfile --help,查看当前支持的运行时列表。 - 检查
Spawnfile中runtime的拼写是否正确。目前官方支持的通常包括openclaw,picoclaw,tinyclaw等。 - 如果你确实在使用一个自定义或内部运行时,你需要为其编写适配器并注册,或者联系该运行时的维护者提供Spawnfile适配器。
- 运行
问题2:编译报告显示大量能力为unsupported或degraded
- 原因:你使用的目标运行时功能较旧或设计不同,无法完全实现Spawnfile规范中声明的所有特性。
- 排查与解决:
- 仔细阅读
spawnfile-report.json文件,找到具体哪些特性不被支持。 - 如果是在
strict模式下,编译会失败。你需要调整源项目:- 方案A(修改源):移除或修改目标运行时不支持的特性。例如,如果目标运行时不支持Slack的
pairing模式,将其改为allowlist或移除Slack表面。 - 方案B(切换运行时):换用一个功能更全面的运行时(如从
tinyclaw切换到openclaw)。 - 方案C(放宽策略):将
policy.mode改为loose,并设置on_degrade: warn。但这意味着你需要接受不同环境下的行为差异。
- 方案A(修改源):移除或修改目标运行时不支持的特性。例如,如果目标运行时不支持Slack的
- 查阅目标运行时的官方文档,确认其能力边界,以便在项目设计初期就做出合适的选择。
- 仔细阅读
问题3:spawnfile validate通过,但spawnfile compile失败,提示YAML解析错误
- 原因:
validate只做基础的结构和语法检查。compile过程会进行更深入的语义分析,并且适配器可能会对字段值有更严格的约束。 - 排查:
- 检查错误信息指向的字段。常见问题包括:枚举值错误(如
mode写了allowlist但运行时只支持whitelist,不过Spawnfile规范会做转换)、字段类型不匹配(期望是数组却给了字符串)。 - 查看对应运行时适配器的源码或文档,了解其对
Spawnfile各字段的具体期望。 - 尝试使用一个最简单的
fixtures/示例项目进行编译,以排除项目特定文件的问题。
- 检查错误信息指向的字段。常见问题包括:枚举值错误(如
5.2 容器构建与运行问题
问题4:spawnfile build成功,但spawnfile run失败,容器立即退出
- 原因:这通常是容器内启动命令失败导致的。可能的原因包括:认证信息缺失、运行时二进制无法执行、端口冲突、配置文件错误。
- 排查步骤:
- 查看容器日志:先不用
spawnfile run,手动运行docker run -it --rm your-image:tag sh进入容器shell,检查文件是否存在,权限是否正确。然后尝试手动执行entrypoint.sh看看报错信息。 - 检查认证:确保
spawnfile auth sync已正确执行,并且--auth-profile参数与sync时使用的profile名称一致。运行spawnfile auth show --profile your-profile确认密钥已存在。 - 检查环境变量:手动运行容器并传递环境变量:
docker run -e OPENAI_API_KEY=sk-... -e DISCORD_BOT_TOKEN=... your-image:tag。如果这样能运行,问题就在Spawnfile的auth注入环节。 - 检查端口:确认
Spawnfile中或运行时默认的端口没有被主机其他进程占用。修改spawnfile run或docker run的端口映射参数试试。
- 查看容器日志:先不用
问题5:镜像构建缓慢,每次都要下载很大的基础镜像或编译运行时
- 原因:Spawnfile 生成的
Dockerfile默认会从网络拉取运行时官方镜像或二进制包。 - 优化:
- 利用构建缓存:确保你的Docker守护进程有足够的缓存空间。在CI/CD中,可以利用Docker的
--cache-from参数复用之前的缓存层。 - 自定义基础镜像:如果你有内部镜像仓库,可以基于Spawnfile生成的
Dockerfile创建一个包含了常用运行时的基础镜像,然后修改你的项目,使用FROM your-internal-base:tag作为基础镜像,避免每次都从公网拉取。 - 离线部署:对于无外网环境,可以事先在有网的环境中将运行时二进制和所有依赖下载好,打包进一个离线镜像,然后推送到内网仓库。
- 利用构建缓存:确保你的Docker守护进程有足够的缓存空间。在CI/CD中,可以利用Docker的
5.3 通信与集成问题
问题6:智能体在Discord/Telegram上无响应
- 原因:表面配置或认证问题。
- 排查清单:
- Token/Secret是否正确:通过
spawnfile auth show确认DISCORD_BOT_TOKEN等环境变量的值是正确的、未过期的。 - Bot权限:确认你在Discord开发者门户为机器人添加了必要的权限(如读取消息、发送消息、读取频道)。对于Telegram,确保你已通过
@BotFather正确创建了机器人并获取了token。 - 访问模式(Access Mode):检查
Spawnfile中surfaces.discord.access.mode和users列表。如果你设置了allowlist,确保你的用户ID在列表中。ID必须是字符串格式。 - 运行时支持:确认你选择的运行时支持该通信表面及你设置的访问模式。例如,
tinyclawv0.1可能不支持Slack。 - 网络与防火墙:确保运行容器的服务器可以访问Discord/Telegram的API服务器。如果使用代理,需要在容器或运行时配置中设置。
- Token/Secret是否正确:通过
问题7:HTTP表面可以访问,但返回错误或超时
- 原因:HTTP服务配置或模型调用问题。
- 排查:
- 检查端口:确认容器内HTTP服务监听的端口与
docker run -p映射的端口一致。查看运行时日志。 - 检查模型调用:如果HTTP请求最终需要调用AI模型,而模型调用失败(如认证失败、额度不足、网络超时),HTTP接口也可能返回错误。查看容器日志中关于模型调用的部分。
- 检查端点路径:Spawnfile v0.1 标准化的HTTP表面通常提供简单的
POST /api/message接口。确认你请求的路径和方法是否正确。参考对应运行时的HTTP API文档。
- 检查端口:确认容器内HTTP服务监听的端口与
5.4 最佳实践总结
- 版本控制你的源项目:将包含
Spawnfile和所有.md文件的目录完整地纳入Git管理。编译输出的.spawn/目录和Dockerfile等是衍生文件,应该被.gitignore忽略。 - 使用策略(Policy)保障一致性:在团队协作和CI/CD流水线中,为生产环境项目设置
policy: {mode: strict, on_degrade: error}。这能强制要求所有目标运行时必须完全支持所声明的特性,避免环境差异导致的问题。 - 分离配置与密钥:始终坚持使用
spawnfile auth管理密钥,绝不将真实密钥写入Spawnfile或提交到代码库。为不同环境(开发、预发、生产)使用不同的auth profile。 - 从简单开始,逐步复杂化:先创建一个单智能体、单表面的简单项目,确保能成功编译、构建和运行。然后再逐步添加技能、MCP连接、复杂的表面配置,最后再尝试多智能体的团队项目。
- 善用
spawnfile-report.json:每次编译后,花一分钟浏览这份报告。它能帮你快速了解跨运行时的兼容性状况,是排查问题的重要依据。 - 为团队项目设计清晰的接口:当使用多运行时团队时,提前规划好智能体之间的通信方式(例如,通过一个共享的HTTP API、消息队列或数据库)。将通信逻辑封装成明确的技能(Skill),并在
SKILL.md中定义好接口契约。 - 关注运行时生态更新:Spawnfile 和底层的运行时都在快速迭代。定期关注
runtimes.yaml中锁定版本的更新,以及新版本运行时对Spawnfile规范的支持情况,适时升级以获得新特性和性能改进。