从0到1:在Gonka上部署你的第一个AI应用
引言
仅需30分钟,一个能够无限生成练习题、实时智能批改的西班牙语AI助手便成功上线。它的后端并非运行在昂贵的中心云上,而是完全依托于Gonka这个新兴的去中心化AI计算网络。以下是完整的实战记录、核心代码与在线Demo。
去中心化AI计算的新范式
Gonka 是一个基于工作量证明的AI计算网络,通过在经过验证的硬件提供商之间实现类OpenAI推理任务的负载均衡,构建了一个全新的去中心化AI服务生态。Gonka网络采用GNK代币进行支付激励,并通过随机抽查机制有效防范欺诈行为。对于开发者而言,只要掌握OpenAI API的调用方式,就能快速接入Gonka网络部署应用。
实战案例:智能西班牙语学习应用
我们将构建一个持续生成个性化练习的西班牙语学习应用。想象这样一个使用场景:
- 用户点击"开始新练习"后,AI生成包含单个空白处的完形填空句子
- 用户输入答案并点击"检查",AI立即给出评分和个性化解析
- 系统自动进入下一个练习,形成沉浸式学习循环
在线演示: carrera.gonka.ai
技术架构解析
应用采用经典的前后端分离架构:
- React前端:基于Vite构建,完全兼容OpenAI接口标准
- Node代理层:仅50行核心代码,负责请求签名和转发
与传统OpenAI集成的唯一区别在于增加了服务端签名环节,这确保了密钥安全,其他所有操作都保持与标准OpenAI聊天补全调用一致。
快速开始指南
环境要求:Node.js 20+
克隆代码库
git clone git@github.com:product-science/carrera.git
cd carrera
创建 Gonka 账户并设置环境变量
# 使用 inferenced CLI 创建账户
# 查看快速入门文档了解 CLI 下载方式:
# https://gonka.ai/developer/quickstart/#2-create-an-account
# ACCOUNT_NAME 可为任意本地唯一名称,作为账户密钥对的可读标识
ACCOUNT_NAME="carrera-quickstart"
NODE_URL=http://node2.gonka.ai:8000
inferenced create-client "$ACCOUNT_NAME" \
--node-address "$NODE_URL"
# 导出私钥(仅限服务端使用)
export GONKA_PRIVATE_KEY=$(inferenced keys export "$ACCOUNT_NAME" --unarmored-hex --unsafe)
启动代理服务
cd gonka-proxy
npm install && npm run build
NODE_URL=http://node2.gonka.ai:8000 ALLOWED_ORIGINS=http://localhost:5173 PORT=8080 npm start
健康检查
curl http://localhost:8080/healthz
# 预期返回:{"ok":true,"ready":true}
运行前端应用
cd web
npm install
VITE_DEFAULT_API_BASE_URL=http://localhost:8080/v1 npm run dev
在应用中打开"设置"→基础 URL 已预填。选择模型(例如 Qwen/Qwen3-235B-A22B-Instruct-2507-FP8,可访问 https://node1.gonka.ai:8443/api/v1/models 查看当前可用模型列表),点击"测试连接"。
核心技术实现
Gonka 代理服务 是与 Gonka 集成的核心。代理服务使用密钥对请求进行签名,然后将类 OpenAI 调用转发至网络。开发者为自己的应用部署此类代理后,即可开始在 Gonka 上处理推理任务。实际使用时建议添加身份验证机制,确保仅授权用户可请求推理。
代理服务使用的环境变量:
// gonka-proxy/src/env.ts
export const env = {
PORT: num("PORT", 8080),
GONKA_PRIVATE_KEY: str("GONKA_PRIVATE_KEY"),
NODE_URL: str("NODE_URL"),
ALLOWED_ORIGINS: (process.env.ALLOWED_ORIGINS ?? "*")
.split(",")
.map((s) => s.trim())
.filter(Boolean),
};
使用 Gonka OpenAI TypeScript SDK (gonka-openai) 创建客户端 (Go 和 Python 版本也已提供,更多语言支持持续更新中,请关注代码库):
// gonka-proxy/src/gonka.ts
import { GonkaOpenAI, resolveEndpoints } from "gonka-openai";
import { env } from "./env";
export async function createGonkaClient() {
const endpoints = await resolveEndpoints({ sourceUrl: env.NODE_URL });
return new GonkaOpenAI({ gonkaPrivateKey: env.GONKA_PRIVATE_KEY, endpoints });
}
暴露兼容 OpenAI 的聊天补全端点 (/v1/chat/completions):
// gonka-proxy/src/server.ts
app.get("/healthz", (_req, res) => res.json({ ok: true, ready }));
app.post("/v1/chat/completions", async (req, res) => {
if (!ready || !client) return res.status(503).json({ error: { message: "代理未就绪" } });
const body = req.body as ChatCompletionRequest;
if (!body || !body.model || !Array.isArray(body.messages)) {
return res.status(400).json({ error: { message: "必须提供 'model' 和 'messages' 参数" } });
}
try {
const streamRequested = Boolean(body.stream);
const { stream: _ignored, ...rest } = body;
if (!streamRequested) {
const response = await client.chat.completions.create({ ...rest, stream: false });
return res.status(200).json(response);
}
// …
server.ts 中还包含了流式传输(SSE)的透传支持,开发者可以在支持流式处理的客户端中通过设置 stream: true 来启用。Gonka 还提供了 Dockerfile 确保可复现的构建和便捷的部署:
# gonka-proxy/Dockerfile
# ---- 构建阶段 ----
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json tsconfig.json ./
COPY src ./src
RUN npm ci && npm run build
# ---- 运行阶段 ----
FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
EXPOSE 8080
CMD ["node", "dist/server.js"]
技术解析:前端(供应商无关设计)
React 应用始终保持与 OpenAI 的兼容性,无需了解 Gonka 的具体实现细节。它只需调用类 OpenAI 端点并渲染前述的练习循环界面。
所有后端交互均在 web/src/llmClient.ts 中完成,其中对聊天补全端点发起单次调用:
// web/src/llmClient.ts
const url = `${s.baseUrl.replace(/\/+$/, "")}/chat/completions`;
const headers: Record<string, string> = { "Content-Type": "application/json" };
if (s.apiKey) headers.Authorization = `Bearer ${s.apiKey}`; // 可选参数
const res = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify({ model: s.model, messages, temperature }),
signal,
});
if (!res.ok) {
const body = await res.text().catch(() => "");
throw new Error(`LLM 错误 ${res.status}: ${body}`);
}
const data = await res.json();
const text = data?.choices?.[0]?.message?.content ?? "";
return { text, raw: data };
要指定 API 服务提供商,只需在顶部的"设置"弹窗中配置基础 URL,也可以在此设置模型,默认使用 Qwen/Qwen3-235B-A22B-Instruct-2507-FP8。如需在无网络环境下进行本地测试,可将基础 URL 设为 mock:;实际调用时则设置为开发者的代理地址(快速开始中已预填):
// web/src/settings.ts
export function getDefaultSettings(): Settings {
const prodBase = (import.meta as any).env?.VITE_DEFAULT_API_BASE_URL || "";
const baseUrlDefault = prodBase || "mock:";
return { baseUrl: baseUrlDefault, apiKey: "", model: "Qwen/Qwen3-235B-A22B-Instruct-2507-FP8" };
}
应用的提示与评分机制
我们使用两种提示模板:
生成提示: "你是一名西班牙语老师...仅输出严格 JSON 格式...生成包含恰好一个空白(____)的完形填空句子,需包含答案、说明和难度等级"
评分提示: "你是一名批改作业的西班牙语老师...输出严格 JSON 格式,包含通过/未通过状态和解析说明"
生成流程的示例代码段:
// web/src/App.tsx
const sys: ChatMsg = {
role: "system",
content: `你是一名设计互动练习的西班牙语老师。
仅输出严格 JSON 格式(无说明文本,无代码标记)。对象必须包含以下键:
{
"type": "cloze",
"text": "<包含恰好一个用 ____ 标记的空白处的西班牙语句子>",
"answer": "<空白处的唯一正确答案>",
"instructions": "<清晰的说明>",
"difficulty": "beginner|intermediate|advanced"
}
内容规范:
- 使用自然的生活场景
- 仅保留一个空白(在句子中精确使用 ____ 标记)
- 句子长度控制在 8-20 个单词
- 句子部分仅使用西班牙语,说明部分可使用英语
- 多样化练习重点:ser/estar、过去时与未完成时、虚拟语气、por/para、一致性、常用介词、核心词汇`
};
我们添加了几个少样本示例帮助模型理解输出格式,然后解析 JSON 并渲染练习。评分环节同样采用严格的 JSON 模式输出通过/未通过结果及简要解析。
解析机制具备容错性——会自动清理代码标记并在需要时提取首个 JSON 数据块:
// web/src/App.tsx
// 容错 JSON 提取器,适配可能包含说明文本或代码标记的模型输出
function extractJsonObject<TExpected>(raw: string): TExpected {
const trimmed = String(raw ?? "").trim();
const fence = trimmed.match(/```(?:json)?\s*([\s\S]*?)\s*```/i);
const candidate = fence ? fence[1] : trimmed;
const tryParse = (s: string) => {
try {
return JSON.parse(s) as TExpected;
} catch {
return undefined;
}
};
const direct = tryParse(candidate);
if (direct) return direct;
const start = candidate.indexOf("{");
const end = candidate.lastIndexOf("}");
if (start !== -1 && end !== -1 && end > start) {
const block = candidate.slice(start, end + 1);
const parsed = tryParse(block);
if (parsed) return parsed;
}
throw new Error("无法从模型响应中解析 JSON");
}
对开发者的后续建议:
• 添加自定义练习类型和评分规则
• 启用流式 UI(代理已支持 SSE)
• 为 Gonka 代理添加身份验证和速率限制
• 将代理部署至开发者的基础设施,并为 Web 应用构建时设置 VITE_DEFAULT_API_BASE_URL
总结与展望
为什么选择Gonka?
- 成本优势:相比传统云服务,去中心化计算显著降低推理成本
- 隐私保护:请求通过代理签名,密钥永不暴露
- 兼容性:完全兼容OpenAI生态,迁移成本极低
- 可靠性:分布式网络确保服务高可用性
Gonka为AI开发者提供了通往去中心化计算时代的平滑过渡方案。通过本文介绍的集成方式,开发者能够在保持现有开发习惯的同时,享受去中心化网络带来的成本优势和技术红利。随着去中心化AI基础设施的不断完善,这种开发模式有望成为下一代AI应用的标准实践。同时,Gonka也将上线更多实用功能,并和开发者一同探索更多AI应用场景,包括但不限于 智能教育应用、内容生成平台、个性化推荐系统、自动化客服解决方案 等。
原文链接: https://what-is-gonka.hashnode.dev/build-a-productionready-ai-app-on-gonka-endtoend-guide
关于 Gonka.ai
Gonka 是一个旨在提供高效 AI 算力的去中心化网络,其设计目标是最大限度地利用全球 GPU 算力,完成有意义的 AI 工作负载。通过消除中心化守门人,Gonka 为开发者和研究人员提供了无需许可的算力资源访问,同时通过其原生代币 GNK 奖励所有参与者。
Gonka 由美国 AI 开发商 Product Science Inc. 孵化。该公司由 Web 2 行业资深人士、前 Snap Inc. 核心产品总监 Libermans 兄妹创立,并于 2023 年成功融资 1800 万美元,投资者包括 OpenAI 投资方 Coatue Management、Solana 投资方 Slow Ventures、K 5、Insight and Benchmark 合伙人等。项目的早期贡献者包括 6 blocks、Hard Yaka、Gcore 和 Bitfury 等 Web 2-Web 3 领域的知名领军企业。
官网 | Github | X | Discord | 白皮书 | 经济模型 | 用户手册
Why Are Bitcoin, Ethereum, and XRP Prices Falling Ahead of the FOMC Meeting Today?
The post Why Are Bitcoin, Ethereum, and XRP Prices Falling Ahead of the FOMC Meeting Today? appeared...
Why This Analyst Is More Bullish On XRP Over Ethereum For The Short-Term
Technical analyst Charting Guy has shared a new perspective on the relationship between XRP and Ethe...
Antony Turner Shapes BlockDAG’s Architecture with CTO Jeremy Harkness, Blending Leadership Vision & Technical Precision
Explore how Antony Turner and CTO Jeremy Harkness design BlockDAG’s core architecture, blending Proo...
