project-builder

project-builder

端到端项目工程:设计、增量构建、验证、系统化调试。 在构建用户要求的软件、仪表盘、定时任务或 Web 应用时使用(例如构建价格监控器、每日摘要任务、发布 API)。

18Star
9Fork
更新于 2026/7/17
SKILL.md
readonly只读
name
project-builder
description

端到端项目工程:设计、增量构建、验证、系统化调试。 在构建用户要求的软件、仪表盘、定时任务或 Web 应用时使用(例如构建价格监控器、每日摘要任务、发布 API)。

version
1.6.2

阶段 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:设计

将模糊的请求转化为具体的规格。 如果意图不明确,问一个问题。

架构决策树:

周期性警报/报告?  → 定时任务
实时可视化界面?    → 预览服务器(仪表盘)
一次性分析?        → 内联(无需构建)
可重用工具?        → 工作区中的脚本

对于中等以上项目,在编写代码之前向用户展示:

  1. 数据流 — 来源 → 处理 → 输出
  2. 架构选择及原因
  3. 成本估算 — (每次运行成本) × 频率 × 30 = 月费用
  4. 已知限制

UI 设计门(必需,阻塞 — 针对视觉项目):
如果架构选择是预览服务器或任何输出用户可见 HTML 的项目:

  1. read_file ui-design 技能的 SKILL.md 现在(如果本次会话尚未完成)并选择一个轨道(手写 vs 组件库)。
  2. 对于手写 UI,运行设计拨盘(在 ui-design 的 references/design-process.md 中)以确定表面色、强调色、排版和美学家族。
  3. 在下面的阶段计划中包含设计拨盘输出行。
    如果跳过此步骤,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_fileSKILL.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-publishpublish_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)

调试: ☐ 日志已检查 ☐ 已复现(或跳过 — 日志足够)☐ 已隔离层 ☐ 已找到根本原因 ☐ 修复已验证 ☐ 回归已检查