跳到主要内容

AI 工具型应用最小项目(结构化输出)

目标:把“会生成内容”升级为“可编辑、可保存、可复用”的工具产品。

目录

目标与边界

这类项目和聊天机器人的区别在于:用户不只“看结果”,还要“继续编辑结果、保存结果、复用结果”。
所以你要把目标从“生成一段话”改成“生成一个结构化对象”。
当你能稳定产出结构化结果时,前端页面、数据库、后续流程才能真正接起来。

  • 必须有:结构化输出、前端可编辑、版本保存
  • 可选有:模板市场、多人协同、导出多格式
  • 先不做:复杂权限与审批流

核心思路

工具型 AI 项目和聊天项目最大的差异:

  • 聊天关注“对话体验”
  • 工具关注“结果可消费”

所以必须优先 JSON(或严格结构)输出,而不是松散段落文本。

最小实现

输出 Schema

先定义 Schema 的原因是:你希望模型输出能被程序稳定消费,而不是每次都靠人工猜格式。 这份 Schema 约束了三个层次:

  • 顶层必须有标题和条目列表
  • 每个条目必须有名称和优先级
  • 优先级只能在固定枚举中取值,避免脏数据

这相当于给模型输出加了一层“合同”,后续前后端都按合同协作。

{
"type": "object",
"properties": {
"title": { "type": "string" },
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"priority": { "type": "string", "enum": ["P0", "P1", "P2"] }
},
"required": ["name", "priority"]
}
}
},
"required": ["title", "items"]
}

后端接口

后端接口的职责不是“把模型结果原样透传”,而是做质量闸门:

  1. 接收用户输入并调用模型
  2. 尝试解析结构化结果
  3. 用 Schema 校验合法性
  4. 只把合法结果返回给前端

这样做的直接收益是:前端编辑器收到的数据结构稳定,不会频繁出现字段缺失导致页面报错。

app.post("/api/tool/generate", async (req, res) => {
const raw = await callLLM(req.body.input);
const parsed = JSON.parse(raw);
const valid = schema.safeParse(parsed);
if (!valid.success) {
return res.status(422).json({ code: "E_SCHEMA", message: "输出格式不合法" });
}
res.json({ result: valid.data });
});

前端编辑与版本

前端这一段要解决“可编辑”和“可回滚”两个产品需求:

  • result 表示当前工作版本
  • versions 保存历史快照,支持误改后回退

structuredClone 的作用是深拷贝,避免历史版本和当前对象共用引用而被意外联动修改。

const [result, setResult] = useState<Result>();
const [versions, setVersions] = useState<Result[]>([]);

function saveVersion() {
if (!result) return;
setVersions((v) => [...v.slice(-4), structuredClone(result)]);
}

预期结果:用户可以放心试改,不满意随时恢复;这比单纯“生成一次文本”更接近真正可用的工具产品。

质量保障

  • 输出失败时:最多自动重试 1 次
  • 仍失败:降级为文本结果 + 手动编辑入口
  • 记录指标:JSON 合格率、用户编辑次数、回滚率

验收标准

  • 输出能稳定通过 Schema 校验
  • 用户可编辑关键字段并保存历史版本
  • 至少保留最近 5 个版本可回滚
  • 出错时有清晰可操作提示