ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Trae实战:半天从0到1搭建AI海龟汤游戏,文生图+推理记忆全流程配置

Trae实战:半天从0到1搭建AI海龟汤游戏,文生图+推理记忆全流程配置 1. 为什么我想用 Trae 做一个会画画的 AI 海龟汤海龟汤这个玩法本质上是一个“信息不对称”的推理游戏出题人手里有完整故事汤底玩家只能通过“是/否/无关”的提问一点点把汤面还原出来。传统玩法靠主持人一旦主持人不在游戏就散了。我一直在想能不能让 AI 当这个主持人而且它还能记住你问过的每一个问题最后根据汤底画一张插画把氛围拉满。这个想法落地需要三块能力一是 AI 能稳定生成汤面和判定提问二是推理过程要落库不能刷新页面就失忆三是文生图接口要能根据汤底出图。如果纯手写光是 Flask 路由、SQLite 表结构、Prompt 编排和文生图调用就够折腾两三天。我这次用 Trae 做主力开发工具把样板代码和调试环节压缩掉半天跑通了从 0 到 1 的雏形。这篇不是“Trae 有多神”的软文而是一份可跟做的配置记录。你会看到 Flask SQLite 的项目骨架、TaoToken 统一 Key 的 config 片段、文生图接口调用、推理历史落库的可复制代码以及本地启动和验证步骤。适合想用 AI 编程工具快速做小项目、又不想在 API 接入上反复踩坑的人。核心检索词就三个Trae、AI 海龟汤、文生图 推理记忆。2. 先解决 API 通道TaoToken 统一 Key 的前置配置做这类小项目最烦的不是业务逻辑而是“这个模型用这家 Key那个模型用那家 Key”。海龟汤里我要调对话模型做提问判定还要调文生图模型出插画如果每家都单独申请、单独配环境变量config 会变得很乱。我这次用 TaoToken 做统一通道一个 Key 走对话和文生图config 里只维护一份 base_url 和 api_key。TaoToken 的官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 注意 API 地址后面不加 UTM 参数。你注册后在控制台创建 API Key然后把它写进项目的.env里不要硬编码进代码。我试过把 Key 直接写在app.py里结果提交 Git 时差点泄露后来改成环境变量才安心。下面是我实际用的 config 片段放在config.py里Flask 启动时加载# config.py import os from dotenv import load_dotenv load_dotenv() class Config: # TaoToken 统一通道 TAOTOKEN_API_KEY os.getenv(TAOTOKEN_API_KEY, ) TAOTOKEN_BASE_URL https://taotoken.net/api # 对话模型用于提问判定和汤面生成 CHAT_MODEL gpt-4o-mini # 文生图模型用于汤底插画 IMAGE_MODEL dall-e-3 # SQLite 配置 SQLALCHEMY_DATABASE_URI sqlite:///haiguitang.db SQLALCHEMY_TRACK_MODIFICATIONS False # 会话密钥 SECRET_KEY os.getenv(SECRET_KEY, dev-secret-change-me)对应的.env文件长这样你只需要填自己的 KeyTAOTOKEN_API_KEYsk-你的TaoTokenKey SECRET_KEY随便一串随机字符这里有个细节TaoToken 的 base_url 是https://taotoken.net/api但不同 SDK 对路径拼接方式不一样。OpenAI 官方 SDK 会在 base_url 后面自动加/v1/chat/completions所以如果你用openai这个包base_url 要写成https://taotoken.net/api/v1才能拼对。我一开始只写到/api结果请求 404排查了十几分钟才反应过来。下面第 3 节的代码里我会用完整路径避免你踩同样的坑。注意API Key 只放在服务端环境变量里前端 HTML/JS 里绝对不能出现。海龟汤是多人玩的一旦 Key 泄露别人可以刷你的额度。3. 可复制配置Flask SQLite 项目骨架与文生图调用项目结构我按“能跑起来”优先来排不搞过度分层。Trae 帮我生成了大部分样板我手动调整了 AI 调用和落库部分。目录如下haiguitang/ ├── app.py ├── config.py ├── models.py ├── ai_service.py ├── image_service.py ├── requirements.txt ├── .env └── templates/ └── index.html先装依赖requirements.txt内容flask flask-sqlalchemy python-dotenv openai requests然后models.py定义三张表游戏记录、问答历史、插画记录。推理记忆的关键就在QAHistory这张表每次玩家提问和 AI 判定都落一条这样刷新页面也能恢复上下文。# models.py from flask_sqlalchemy import SQLAlchemy from datetime import datetime db SQLAlchemy() class Game(db.Model): id db.Column(db.Integer, primary_keyTrue) difficulty db.Column(db.String(20)) # 普通/一般/困难 genre db.Column(db.String(20)) # 清汤/红汤/黑汤 surface db.Column(db.Text) # 汤面 bottom db.Column(db.Text) # 汤底 status db.Column(db.String(20), defaultplaying) created_at db.Column(db.DateTime, defaultdatetime.utcnow) class QAHistory(db.Model): id db.Column(db.Integer, primary_keyTrue) game_id db.Column(db.Integer, db.ForeignKey(game.id)) question db.Column(db.Text) answer db.Column(db.String(20)) # 是/否/无关 created_at db.Column(db.DateTime, defaultdatetime.utcnow) class Illustration(db.Model): id db.Column(db.Integer, primary_keyTrue) game_id db.Column(db.Integer, db.ForeignKey(game.id)) image_url db.Column(db.Text) created_at db.Column(db.DateTime, defaultdatetime.utcnow)ai_service.py负责两件事生成汤面和判定提问。判定时我会把该局所有历史问答拼进 Prompt这就是“记住推理过程”的实现方式。注意 base_url 我写的是https://taotoken.net/api/v1配合 openai SDK 使用。# ai_service.py from openai import OpenAI from config import Config from models import db, QAHistory client OpenAI( api_keyConfig.TAOTOKEN_API_KEY, base_urlhttps://taotoken.net/api/v1 ) def generate_story(difficulty, genre): prompt f生成一个海龟汤故事难度{difficulty}类型{genre}。 prompt 输出格式第一行汤面第二行汤底。汤面要离奇汤底要合理。 resp client.chat.completions.create( modelConfig.CHAT_MODEL, messages[{role: user, content: prompt}], temperature0.9 ) text resp.choices[0].message.content.strip() lines [l for l in text.split(\n) if l.strip()] surface lines[0].replace(汤面, ).strip() bottom lines[1].replace(汤底, ).strip() if len(lines) 1 else return surface, bottom def judge_question(game, question): history QAHistory.query.filter_by(game_idgame.id).all() history_text \n.join([f问{h.question} 答{h.answer} for h in history]) prompt f汤底是{game.bottom}\n已知问答\n{history_text}\n prompt f玩家新问题{question}\n只回答 是/否/无关 三个词之一。 resp client.chat.completions.create( modelConfig.CHAT_MODEL, messages[{role: user, content: prompt}], temperature0.2 ) return resp.choices[0].message.content.strip()image_service.py调文生图。这里我用 TaoToken 的 images 接口同样走统一 Key。注意文生图比对话慢建议加超时和重试。# image_service.py import requests from config import Config def generate_illustration(bottom_text): url https://taotoken.net/api/v1/images/generations headers { Authorization: fBearer {Config.TAOTOKEN_API_KEY}, Content-Type: application/json } payload { model: Config.IMAGE_MODEL, prompt: f悬疑插画风格氛围阴郁主题{bottom_text[:200]}, n: 1, size: 1024x1024 } resp requests.post(url, jsonpayload, headersheaders, timeout60) resp.raise_for_status() data resp.json() return data[data][0][url]app.py把路由串起来核心是/ask接口先落库问题再调 AI 判定再把答案落库最后返回给前端。# app.py from flask import Flask, request, jsonify, render_template from config import Config from models import db, Game, QAHistory, Illustration from ai_service import generate_story, judge_question from image_service import generate_illustration app Flask(__name__) app.config.from_object(Config) db.init_app(app) with app.app_context(): db.create_all() app.route(/) def index(): return render_template(index.html) app.route(/start, methods[POST]) def start(): data request.json surface, bottom generate_story(data[difficulty], data[genre]) game Game(difficultydata[difficulty], genredata[genre], surfacesurface, bottombottom) db.session.add(game) db.session.commit() return jsonify({game_id: game.id, surface: surface}) app.route(/ask, methods[POST]) def ask(): data request.json game Game.query.get(data[game_id]) answer judge_question(game, data[question]) qa QAHistory(game_idgame.id, questiondata[question], answeranswer) db.session.add(qa) db.session.commit() return jsonify({answer: answer}) app.route(/reveal, methods[POST]) def reveal(): data request.json game Game.query.get(data[game_id]) game.status finished db.session.commit() image_url generate_illustration(game.bottom) ill Illustration(game_idgame.id, image_urlimage_url) db.session.add(ill) db.session.commit() return jsonify({bottom: game.bottom, image_url: image_url}) if __name__ __main__: app.run(debugTrue, port5000)前端index.html我写得比较朴素一个开始按钮、一个提问输入框、一个揭晓按钮用 fetch 调上面三个接口。Trae 在这里帮我补了 CSS 和事件绑定省了不少时间。4. 验证请求本地启动与成功结果确认代码写完后先确认环境变量生效。在项目根目录执行python -c from config import Config; print(Config.TAOTOKEN_BASE_URL, bool(Config.TAOTOKEN_API_KEY))如果输出https://taotoken.net/api True说明 Key 读到了。然后启动 Flaskpython app.py看到Running on http://127.0.0.1:5000就说明服务起来了。接下来用 curl 验证三个接口不用等前端写完。先测开始游戏curl -X POST http://127.0.0.1:5000/start \ -H Content-Type: application/json \ -d {difficulty:一般,genre:红汤}成功的话返回类似{game_id:1,surface:一个男人走进酒吧点了一杯水酒保却拔枪指着他男人说了声谢谢就走了。}拿到game_id后测提问判定curl -X POST http://127.0.0.1:5000/ask \ -H Content-Type: application/json \ -d {game_id:1,question:男人是口渴吗}返回{answer:否}就说明对话通道通了。你可以连续问几个问题然后查 SQLite 确认历史落库sqlite3 instance/haiguitang.db select question, answer from qa_history;能看到多条记录说明推理记忆生效。最后测揭晓和文生图curl -X POST http://127.0.0.1:5000/reveal \ -H Content-Type: application/json \ -d {game_id:1}返回里带image_url就成功了。文生图通常要 10 到 30 秒如果 curl 卡住别急着杀等超时设置生效。我实测下来1024x1024 的图大概 15 秒左右返回。5. 本篇常见错排查第一个高频错误是 401 Unauthorized。原因通常是.env没加载或者 Key 前后有空格。检查Config.TAOTOKEN_API_KEY是否为空以及.env文件是否在项目根目录。另外注意load_dotenv()要在读取环境变量之前调用我把它放在config.py顶部就是为了这个。第二个是 404 Not Found路径拼错。如果你用 openai SDKbase_url 写https://taotoken.net/api/v1如果你用 requests 直接调完整路径是https://taotoken.net/api/v1/images/generations。少写/v1或者多写斜杠都会 404。这个坑我在第 2 节提过这里再强调一次。第三个是 SQLite 表不存在。Flask-SQLAlchemy 默认把数据库放在instance/目录下如果你在app.py里没写with app.app_context(): db.create_all()第一次请求就会报no such table。确认这行代码在启动时执行了。第四个是文生图超时。requests.post默认没有超时网络慢时会一直挂起。我在image_service.py里加了timeout60你也可以加到 90。如果还是超时检查 prompt 是否过长我截断到 200 字符就是为了避免这个问题。第五个是推理记忆串局。judge_question里查询历史时一定要带game_id过滤否则会把其他局的问答也拼进 Prompt导致 AI 判定混乱。这个 bug 我在测试时遇到过表现为新开一局后 AI 回答明显受上一局影响加上过滤就好了。提示如果你在 Trae 里让 AI 帮你改代码改完记得重新跑一遍 curl 验证不要只看代码逻辑觉得对就跳过。AI 生成的代码有时会漏掉db.session.commit()导致数据没落库。6. 接下来怎么走从雏形到可玩半天跑通雏形后我建议你先别急着加功能而是把“一局完整流程”走顺开始、提问五到八轮、揭晓、看到插画。这个过程里你会自然发现哪些 Prompt 需要调比如汤面太直白、判定太模糊。调 Prompt 比加功能更影响体验。如果你想把项目继续做下去下一步可以接 Coding Plan 做长期迭代把前端交互和多人房间补上。需要先确认 Key 和通道的可以去 API Keys 页面创建接入细节看接入文档。想先单独验证模型对话效果的用模型对话页面直接试 Prompt不用每次改代码重启 Flask。这几个入口我都放在下面按你的需要选创建和管理 Keyhttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite模型对话验证https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite长期编码与 Agenthttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite最后说一个我踩过的坑Trae 生成代码很快但它不知道你的 Key 额度还剩多少。文生图接口调用几次后如果开始报错先去控制台看用量别一味改代码。把额度监控和错误处理加上这个项目才算真正能给别人玩。
返回列表