开发

不写后端,也能做 AI 应用

写一个网页应用,通过 SDK 调用任意模型,打包成 zip 上传。用户用 RunApps 账号登录并为自己的 AI 用量付费——你不用管服务器,也不用管 API Key。

发布免费 · 用户为自己的用量付费

上传之前

应用一创建就有 slug,不需要先传 zip。在自己电脑上对着这个 slug 开发,发布后的应用用的是同一个身份。

  1. 1

    先把应用建成草稿

    控制台 → 创作者 → 发布。填名称和描述,包留空,保存。草稿只有你自己可见,不会进入审核。

  2. 2

    把开发服务器指向它

    把 slug 作为 SDK 的 project 选项传入。从 http://localhost 登录可用,调用走真实网关、从你自己的余额扣费,文件落在应用的真实命名空间。

  3. 3

    做好了再上传

    构建、打 zip、上传到同一个应用。slug、文件、提示词都已就位,本地跑通的代码就是上线的代码。

main.jshttp://localhost:5173
// The slug from your draft app — the same one the published
// app will have, so nothing changes at upload time.
const client = new RunApps.Client({
  authProvider: "runapps",
  project: "my-tool",
});

const resp = await client.chat.create({
  model: "Claude Sonnet 4.6",
  messages: [{ role: "user", content: "Hello!" }],
  // While developing, send a prompt inline; ship it as
  // .runapps/prompts/outline.md and use { id: "outline" } later.
  prompt: import.meta.env.DEV
    ? { template: "You write outlines in five acts." }
    : { id: "outline" },
});

三步发布

  1. 1

    用 SDK 调用 AI

    加一行 script 标签,或 npm i @runjobsai/sdk。用户用 RunApps 账号登录,代码里不需要 API Key。

  2. 2

    上传 zip

    上传构建好的静态文件,应用自动上线到专属的 runapps.dev 链接。

  3. 3

    上架

    直接分享链接,或提交审核后上架到应用库。

index.html@runjobsai/sdk
<script src="https://cdn.jsdelivr.net/npm/@runjobsai/sdk/dist/sdk.umd.js"></script>
<script>
  const client = new RunApps.Client({ authProvider: "runapps" });

  const resp = await client.chat.create({
    model: "Claude Sonnet 4.6",
    messages: [{ role: "user", content: "Hello!" }],
  });
  console.log(resp.choices[0].message.content);
</script>

把提示词留在服务端

前端代码里的任何东西都能在浏览器里看到。把提示词作为文件放进 zip,在 bundle.json 里登记:RunApps 从不对外提供这个文件和它登记的任何文件,应用只按 id 调用。

  1. 1

    写提示词文件

    每个提示词一个 Markdown 文件,放在项目任意位置,比如 prompts/outline.md,再在 zip 根目录的 bundle.json 里把 id 指向它。调用时才填的内容写成 {{genre}} 这样的占位符。

  2. 2

    按名字调用

    调用 chat.create 时,用 prompt 参数传入提示词的名字和变量值(见右侧代码)。服务端把提示词作为系统消息加进去,网络上只传名字。

  3. 3

    和构建产物一起打包

    把 bundle.json 和提示词文件复制进构建产物一起打 zip。发布页会列出识别到的提示词。(放在 .runapps/prompts/<id>.md 的文件不登记也能用。)

本地开发时

在自己的开发服务器上还没有上传的包,所以把提示词原文作为 prompt.template 一起发。服务端只接受应用创作者这样做;import.meta.env.DEV 保证正式构建里不会带上原文。

平台会要求模型对提示词保密,回复里一旦原样复述提示词就会被拦截。但有心人仍可能让模型换个说法透露出来,所以不要把密钥、密码写进提示词。

bundle.json不会发给浏览器
{
  "prompts": {
    "outline": "prompts/outline.md",
    "rewrite": "prompts/rewrite.md"
  }
}
prompts/outline.md不会发给浏览器
You are the outline writer for this studio.
Every story has five acts, with a twist in act four.
Genre: {{genre}}
src/ai.js@runjobsai/sdk
async function privatePrompt(id, vars) {
  const prompt = { id, vars };
  // Your dev server only: send the text along. Vite drops
  // this branch (and the file) from production builds.
  if (import.meta.env.DEV) {
    prompt.template = (await import(
      `../prompts/${id}.md?raw`)).default;
  }
  return prompt;
}

const resp = await client.chat.create({
  model: "Claude Sonnet 4.6",
  prompt: await privatePrompt("outline", { genre: "mystery" }),
  messages: [{ role: "user", content: idea }],
});
打包shell
npm run build
cp -r bundle.json prompts dist/
cd dist && zip -r ../app.zip .

准备好了吗?

发布你的第一个应用,或者创建 API Key 开始调用模型。

发布应用

发布免费 · 用户为自己的用量付费