端到端项目工程:设计、增量构建、验证、系统化调试。 在构建用户要求的软件、仪表盘、定时任务或 Web 应用时使用(例如构建价格监控器、每日摘要任务、发布 API)。
阶段 0:技能发现与必读文档
⚠️ 关键 — UI 设计质量门: 如果项目生成任何可视的 HTML 输出(仪表盘、Web 应用、落地页、作品集、用户会看到的任何页面),你必须在编写任何 HTML/CSS 之前 read_file ui-design 技能的 SKILL.md 并遵循它。这不是可选的。project-builder 负责工程;ui-design 负责视觉质量(并告诉你何时使用组件库如 shadcn/ui、HeroUI 或 coss ui 而不是手写)。跳过 ui-design 会产生通用的 AI 垃圾。
A. 选择技能。 收集项目所需的每个数据源。对于每个数据源,优先使用技能:检查 <available_skills>,如果没有合适的,尝试 search_skills(query) 查找官方和社区覆盖。技能是最可靠的层——它们提供经过测试的客户端、认证和速率限制处理。Web 搜索是最后的手段。只有当没有技能可以覆盖数据源时才编写原始 HTTP/SDK 代码。
B. 阅读项目涉及的平台规则。 这些规则存在于参考资料中(不在你的系统提示中),因此你必须在编写代码之前 read_file 它们。跳过这是导致 401、路径错误和“本地工作,预览失败”错误的头号原因。
| 如果项目包含... | 在阶段 2 之前 read_file |
|---|---|
| 任何外部 API 调用 | config/context/references/sc-proxy.md |
| 预览/仪表盘/Web 应用 | config/context/references/preview-guide.md |
| 定时任务 | config/context/references/scheduled-tasks-guide.md |
| 长时间运行的后台任务 | config/context/references/background-tasks.md |
| 文件写入超过 300 行 | config/context/references/tool-writing-guide.md |
| 任何可视的 HTML 输出(仪表盘、Web 应用、落地页、作品集) | ui-design 技能 SKILL.md — 加载并遵循它进行所有视觉决策(跟踪选择、颜色、排版、布局、动画以及何时使用组件库)。此技能是 UI 质量门;跳过它会产生通用的 AI 垃圾。 |
阶段 1:设计
将模糊的请求转化为具体的规格。 如果意图不明确,问一个问题。
架构决策树:
周期性警报/报告? → 定时任务
实时可视化界面? → 预览服务器(仪表盘)
一次性分析? → 内联(无需构建)
可重用工具? → 工作区中的脚本
对于中等以上项目,在编写代码之前向用户展示:
- 数据流 — 来源 → 处理 → 输出
- 架构选择及原因
- 成本估算 — (每次运行成本) × 频率 × 30 = 月费用
- 已知限制
UI 设计门(必需,阻塞 — 针对视觉项目):
如果架构选择是预览服务器或任何输出用户可见 HTML 的项目:
read_fileui-design技能的 SKILL.md 现在(如果本次会话尚未完成)并选择一个轨道(手写 vs 组件库)。- 对于手写 UI,运行设计拨盘(在 ui-design 的
references/design-process.md中)以确定表面色、强调色、排版和美学家族。 - 在下面的阶段计划中包含设计拨盘输出行。
如果跳过此步骤,UI 看起来会像通用的 AI 输出。此门是阻塞的 — 在完成之前不要进入阶段 2。
设计门(必需,阻塞):
阶段 1 之后,停止并展示一个简短的阶段计划(设计/构建/调试的里程碑)。明确询问:“批准此计划并进入阶段 2 构建?” 提问时使用用户的语言 — 绝不注入硬编码的非英文字符串。
- 如果用户确认:进入阶段 2。
- 如果用户要求更改:修改设计并重新确认。
- 如果没有确认:不要编写/修改代码。
阶段 1.5:脚手架(可共享项目必需)
设计确认后,在编写任何代码之前,在标准布局下搭建项目。这使得项目从第一天起就可以通过 community-publish 技能共享 — 无需后续迁移。
标准项目位置: output/projects/{slug}/
output/projects/{slug}/
├── project.yaml # 名称、版本(从 0.1.0 开始)、类型、描述、许可证、入口、env_required
├── PROJECT.md # 4 个必需部分:是什么 / 所需环境 / 如何启动 / 输出 / 故障排除
├── .env.example # 代码读取的每个环境变量,带有占位值
├── .gitignore # 至少包含:.env, *.key, *.pem, __pycache__, node_modules
└── src/ # 所有代码都放在这里,不要分散
├── run.py # type=task — 第一行必须是: # -*- task-system: v3 -*-
├── server.py # type=service
├── main.py # type=script
└── index.html / app.py + frontend # type=preview
项目类型 → 入口映射:
| 架构选择 | type | 入口路径 |
|---|---|---|
| 定时任务 | task |
src/run.py |
| 预览服务器 | preview |
src/index.html(静态)或 src/app.py |
| 后台守护进程 | service |
src/server.py |
| 一次性工具 | script |
src/main.py |
仅在以下情况跳过脚手架:
- 纯内联分析,无持久代码
- 修改现有的
output/projects/...项目(保持其布局) - 用户明确说“只需在 /tmp 中放一个脚本”或类似
在阶段 2 构建期间,维护脚手架:
- 代码读取的每个新环境变量 → 在同一编辑中添加到
.env.example - 每个行为变更 → 更新 PROJECT.md
- 永远不要在
src/之外编写代码(配置文件、固定数据:项目根目录或src/data/)
为什么这很重要: 已经处于标准布局的项目可以通过一条命令发布。分散在 tasks/、output/scripts/、dashboards/ 等中的项目需要 tidy_project() 迁移才能共享,而用户通常不想从记忆中重建 PROJECT.md。
对于现有的分散代码: 调用 community-publish 技能 → tidy_project(any_dir) 在发布前重新组织。
API 成本与速率限制:
所有外部 API 调用都通过 sc-proxy,它按请求计费并强制执行速率限制。
在设计之前,阅读 config/context/references/sc-proxy.md 了解定价表和限制。
- 估算成本:
credits_per_request × requests_per_run × runs_per_day × 30 - 遵守速率限制:例如 CoinGecko 60 请求/分钟 — 每分钟轮询 10 个币的任务没问题;100 个币则不行
- 优先使用批量端点而不是 N 次单独调用(例如使用多个 id 的
coin_price而不是 N 次单独调用) - 纯脚本任务(无 API):约 0 积分/次运行
- LLM 成本警告: 高端模型单次调用可能超过 $0.10。不同模型层级的定价差异巨大;昂贵模型对于相同工作流的成本可能是预算模型的 100 倍以上。
- 需要按模型估算: 按模型分解 LLM 成本(
model_price_per_call × expected_calls_per_run × runs_per_day × 30),而不是使用单个通用数字。 - 仪表盘自动刷新消耗积分 — 默认手动刷新,除非用户另有要求
- 支出保护: 如果预计月 LLM 成本较高,明确询问是否在实施前强制执行每个调用者的限制。
- 每个调用者跟踪(必需): 每个代理请求必须包含
SC-CALLER-ID(例如job:{JOB_ID}、preview:{preview_id}、chat:{thread_id}),以便使用情况可追踪和限制。详情见config/context/references/sc-proxy.md§ 调用者信用限制
数据可靠性: 原生工具 > 代理 API > 直接请求 > 网页抓取 > LLM 数字(永远不要)。
铁律:脚本获取数据。LLM 分析文本。最终输出 = 脚本变量 + LLM 散文。
任务脚本可以直接导入技能函数:
from core.skill_tools import coingecko, coinglass # 自动发现 skills/*/exports.py
prices = coingecko.coin_price(coin_ids=["bitcoin"], timestamps=["now"])
工具名称 = SKILL.md 前置元数据 tools: 列表。参见 build-patterns.md § Using Skill Functions。
阶段 2:构建
每个部分遵循以下循环:
构建一个小部分 → 运行它 → 验证输出 → ✅ 下一部分 / ❌ 先修复
| 构建内容 | 验证方式 | 通过条件 |
|---|---|---|
| 数据获取器 | 运行,打印原始响应 | 非空、最近、合理 |
| API 端点 | curl localhost:{port}/api/... |
正确的 JSON |
| HTML 页面 | preview_serve + preview_check |
ok = true |
| 任务脚本 | python3 tasks/{id}/run.py |
数字与来源匹配 |
| LLM 分析 | 数字来自脚本变量,而非 LLM 文本 | 使用模板模式 |
验证分层:
- 关键(必须在预览/激活前通过):数据正确性、核心逻辑、无崩溃
- 信息性(可在交付后修复):样式、边缘情况消息、次要 UX 优化
反模式:
- ❌ 未运行任何内容就说“完成!”
- ❌ 编写 200 多行然后第一次测试
- ❌ “应该能工作”
→ 详细模式:阅读 references/build-patterns.md
代码实践
- 在
edit_file之前read_file— 了解现有内容 - 修改时
edit_file>write_file - 在
write_file之前检查ls— 避免重复现有文件 - 大文件(超过 300 行):拆分为多个文件,或先骨架后 bash 注入
- 环境变量:
os.environ["KEY"],将安装持久化到setup.sh
仪表盘 UX 默认值(type=preview)
自行决定合理的默认值,并在首次加载时渲染真实数据。将过滤器视为用户稍后可调整的可选优化 — 永远不要将其作为限制初始视图的先决条件。在合理的间隔内自动刷新。在显示任何内容之前,不要出现“点击加载”/“输入地址”/“选择符号”。
视觉设计质量(所有 HTML 输出必需): 如果安装了 ui-design 技能,你必须在编写任何 HTML/CSS 之前 read_file 其 SKILL.md 并遵循它。project-builder 负责工程工作流;ui-design 负责视觉质量。仅使用 project-builder 会产生功能正常但视觉上通用的输出。
平台规则
- 代理工具仅是工具调用 — 不可在脚本中导入
- 预览路径必须是相对路径(
./path而不是/path) - 在代码中硬编码预览端口,不要从环境变量读取。 每个预览运行在自己的 pod 中,环境变量端口契约在不同 pod 间不可靠。选择任何空闲端口(例如
8765),直接写入应用,并将相同数字传递给preview(action="serve", port=...)。两者必须完全匹配。 - 并发预览需要不同的 ID。 如果两个预览共享相同的
dir,较新的会自动杀死较旧的(同目录替换规则)。迭代时,重用相同的 ID 而不是发明变体,或使用不同的目录。 - 全栈 = 一个端口(后端提供 API + 静态文件)
- Cron 时间为 UTC — 从用户时区转换
- 预览服务与发布 → 阅读平台参考
config/context/references/preview-guide.md - localhost API → 阅读
config/context/references/localhost-api.md- 任务脚本决定何时调用代理、传递什么数据/上下文、使用哪个模型
- 模式:脚本获取数据 → 评估是否值得注意 → 仅在需要时调用 LLM → 打印结果
- 脚本中的 LLM — 两个选项(详情见
references/build-patterns.md):- OpenRouter(通过 sc-proxy):轻量级,用于摘要/翻译/格式化文本。直接 API 调用,无代理开销。
- localhost /chat/stream:带工具的完整代理。仅在 LLM 需要工具访问时使用。
- 数据模板规则: 脚本拥有数字,LLM 拥有文字。最终输出组装来自脚本变量的数据 + 来自 LLM 的分析。永远不要让 LLM 输出成为用户看到的数字的唯一来源。
- API 成本与速率限制 → 阅读平台参考
config/context/references/sc-proxy.md - 货币化(可选): 你构建的任何 HTTP 服务都可以通过
x402技能转变为付费服务 — 一个反向代理网关,位于未修改的应用之前,按调用/订阅(周-年)/终身/预付费余额收取 Base 上的 USDC,支持多计划。如果用户提到为项目收费、出售 API 访问或代理间支付,在构建阶段后阅读skills/x402/SKILL.md并使用scripts/monetize.py包装服务(暴露 GATEWAY 端口,而不是上游)。
包装后的完整付费服务链:preview(serve)网关 →community-publish→publish_preview()(公共 URL)→create_paid_service(..., pricing_options=[...])→submit_for_review()(多计划服务:审查通过X-Pricing-Model头探测每个计划的 402 金额)→publish_service()→ 在服务市场上线。详情:community-publish SKILL.md § 付费服务列表。 - 始终在线的服务(长时间运行/已发布/付费): 代理机器在空闲时自动挂起,自动更新重启会杀死服务进程。任何必须保持 24/7 可达的服务需要:① 一个保活看门狗(重启服务的定时任务 — 参见
skills/x402/SKILL.md“始终在线可用性”),② 将机器切换到手动更新模式(Web 仪表盘切换;代理只能在机器内读取模式 — 如果读取到“自动”,提醒用户切换开关,否则下一次平台更新将使服务下线)。
阶段 3:调试
检查日志 → 复现 → 隔离 → 诊断 → 修复 → 验证 → 回归
- 首先检查日志 — 任务日志、预览诊断、stderr。如果日志揭示了明确原因,直接跳到修复。
- 仅在日志不足时复现 — 亲自查看失败
- 隔离哪个层出了问题(数据?逻辑?LLM?输出?前端?后端?)
- 修复根本原因,然后验证使用相同的复现步骤。不要只修复 — 修复并确认。
三击规则: 相同方法失败两次 → 停止 → 重新思考 → 向用户解释 → 不同方法。
→ 完整调试流程:阅读 references/debug-handbook.md
快速检查清单
启动: ☐ 澄清意图 ☐ 提出架构 ☐ 估算成本 ☐ 用户确认(阶段 2 前必需)
构建: ☐ 每个组件已测试 ☐ 数字与来源匹配 ☐ 错误已处理 ☐ 预览健康(Web)
调试: ☐ 日志已检查 ☐ 已复现(或跳过 — 日志足够)☐ 已隔离层 ☐ 已找到根本原因 ☐ 修复已验证 ☐ 回归已检查






