AI Web 应用 — 跨过脚本与应用之间那条线¶
这一章讲什么: 每个开发者都会跨过一条线:线这边,你写脚本——有用, 但基本只服务你自己;线那边,你建应用——别人能点、能刷新、能依赖。 这一章带你跨过去,而且是用 AI 当脚手架。你将搭出一个最小但完整的闭环: 浏览器里一个输入框 → JavaScript 把文字发给你的 Flask 后端 → 后端问 OpenAI 的模型 → 回答回到页面上。 读完你会理解每一个现代 Web 应用的骨架:请求-响应循环。
1. 这一章讲什么¶
前八章的产物都有一个共同点:它们活在你的机器上、你的终端里。 这一章的产物第一次有了用户。书里给这个转变的定义很准: 它不在于复杂度增加多少,而在于心态——从「我写了个有用的 Python 脚本」 到「我建了一个别人能用的 Web 应用」3。
同时书里先澄清一个用词:「AI 驱动的 Web 应用」不是 AI 包办一切的应用, 而是 AI 在开发的特定环节、有意为之地点上帮忙的应用——决定仍然由你做, 只是不再独自一人、不再靠猜4。
为什么值得跨?Web 应用给你四样脚本给不了的东西5:
| 触达(Reach) | 代码为任何有浏览器的人运行 |
| 持久(Persistence) | 数据可以存、可以改、可以复用 |
| 交互(Interactivity) | 用户不是读输出,而是与输出互动 |
| 可信度(Credibility) | 交付一个应用,改变别人对你技能的看法 |
本章的边界也先说死:没有账户、没有数据库。 一个窄而清晰的目标—— 一个收文本、返回处理结果的端点——因为 AI 在请求具体的时候表现最好6。 这一章在全书链条里是落点:第一章的 key 纪律、第三章的 CCG、第四章的防御式错误处理、 第八章的管道,全部在这里合龙。
2. 顶层全景:请求-响应循环¶
浏览器(用户视角) Flask 后端(开发者视角) 模型(API)
───────────────── ────────────────────── ──────────
输入框 textarea
│ 点击按钮
▼
fetch(POST /api/process, {text}) → @app.route("/api/process")
校验输入(非 JSON?缺字段?)
│ 合法
▼
client.chat.completions.create()
→ AI 回复
组装 JSON 响应 ◀──────────────
▼ 回传 JSON
页面更新 result 区域
(404/CORS/JSON 错 → 各自的排查路径)
图说:每一方只做一件事——浏览器发问,Flask 校验与转述,模型作答;全章就是给这三方接线的过程。
3. 核心原理¶
3.1 设计先于编码:API 契约¶
大多数人卡在第一行后端代码之前。 书里列了新手最常见的四个迷思: 先建哪个文件?路由放哪?逻辑怎么组织才能两周后不乱?小应用什么程度算「结构过多」?7
答案是一个反直觉的顺序:先让 AI 帮你设计,再让它写码。 第一条约好的提示:「我想用 Flask 建一个小型 Python 后端:一个 POST 端点收文本、返回 JSON。 请给一个初学者友好的项目结构,并解释每个文件干什么。」8 这条提示做了三件要紧的事:定了框架(Flask)、定了范围(单端点)、要解释而不只是要代码—— 最后一点比多数人想的更重要9。
AI 会给出两种常见结构:极简版 app.py + requirements.txt + README.md;
进阶版 app/(routes.py、services.py) + run.py + requirements.txt。
书里选了极简版起步——概念清晰之后随时重构10。
装 Flask 并固化依赖:pip install flask,然后 pip freeze > requirements.txt
(把当前环境所有库及版本写进清单文件——重装环境时照单抓药)11。
3.2 最小端点:让 AI 写第一版,你逐行读懂¶
提示:「写一个最小的 Flask 应用:一个 POST 端点 /api/process,收 JSON、返回 JSON,初学者友好。」12
from flask import Flask, request, jsonify
app = Flask(__name__) # ① 创建应用
@app.route("/api/process", methods=["POST"]) # ② 声明:我只听这里的 POST
def process_text():
data = request.get_json() # ③ 取请求里的 JSON
user_text = data.get("text", "")
return jsonify({ # ④ 组装 JSON 响应
"original_text": user_text,
"message": "Text received successfully"
})
if __name__ == "__main__":
app.run(debug=True) # ⑤ 启动开发服务器
逐行读懂(书里的要求:slow down and read it line by line13):
Flask(__name__) 创建应用本体;request 是进来的请求,get_json() 把请求体解析成字典;
jsonify 保证回出去的是干净的 JSON;@app.route(...) 那行装饰器(decorator,
贴在函数上方、给函数加功能的语法)的意思是「我在这个地址监听,且只听 POST」。
到此为止,你建的是一个标准 API——还没接 AI14。
3.3 接入 AI:密钥进环境变量,模型进端点¶
装 OpenAI 官方库:pip install openai,再 freeze 一次15。
密钥纪律(第一章的复述,本章升级为铁律):绝不把密钥硬编码(直接写死在代码里)进源码。
用环境变量:macOS/Linux export OPENAI_API_KEY=你的key,
Windows PowerShell setx OPENAI_API_KEY 你的key——让密钥离开代码库和版本控制16。
改造端点:
from flask import Flask, request, jsonify
import os
from openai import OpenAI
app = Flask(__name__)
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) # 从环境变量读 key
@app.route("/api/process", methods=["POST"])
def process_text():
data = request.get_json()
user_text = data.get("text", "")
if not user_text:
return jsonify({"error": "No text provided"}), 400
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": user_text},
],
)
ai_reply = response.choices[0].message.content
return jsonify({"input": user_text, "ai_response": ai_reply})
if __name__ == "__main__":
app.run(debug=True)
三个技术点:os.getenv("OPENAI_API_KEY") 从环境变量取密钥;
messages 是对话的角色列表(system 定人设、user 放输入);
response.choices[0].message.content 从模型响应里剥出文本。
跑起来 python app.py,看到 Running on http://127.0.0.1:5000,你的 AI 后端就活了17。
测试端点的标准姿势 curl(在终端里直接发请求的工具):
curl -X POST http://127.0.0.1:5000/api/process \
-H "Content-Type: application/json" \
-d '{"text": "Explain AI in simple terms"}'
回的是一段 JSON:输入原样返回 + AI 的解答18。这个回包意味着三件事同时成立: 后端通了、端点通了、结构稳了19。
3.4 REST API:一套干净的四方法约定¶
REST API 听起来重,书里给了一个轻定义:它是你的后端与任何对话方(浏览器、 移动应用、别的服务、未来的你)之间的一份干净协议20。 四个要点:每个端点代表一种资源;用 HTTP 方法表达意图;响应可预测、结构化;错误显式处理21。 最常用的四个方法22:
| 方法 | 意图 |
|---|---|
| GET | 取数据 |
| POST | 创建或处理数据 |
| PUT | 更新已有数据 |
| DELETE | 删除数据 |
扩展端点前,先问 AI 要命名建议——这是本章第二个「设计先于编码」:
「我有一个 Flask 应用、一个 POST 端点。想扩成带清晰路由和错误处理的小 REST API。
先别写码,给端点名与职责的建议。」23
合理的回答:POST /api/process 处理文本;GET /api/status 健康检查。
健康检查端点(三行,日后监控与部署排障全靠它):
@app.route("/api/status", methods=["GET"])
def status():
return jsonify({"status": "running", "message": "API is up and responding"})
浏览器直接访问 http://127.0.0.1:5000/api/status 就能看到 JSON24。
书里说它「看起来微不足道,日后无比有用」——监控、部署检查、调试,全靠这一口25。
让 POST 端点抗造。 它现在默认输入合法——太乐观,真实用户会搞坏一切。 提示:「改进这个 Flask POST 端点:优雅处理非 JSON、缺字段,返回有意义的错误。」26
@app.route("/api/process", methods=["POST"])
def process_text():
if not request.is_json:
return jsonify({"error": "Request must be JSON"}), 400
data = request.get_json()
text = data.get("text")
if not text:
return jsonify({"error": "Missing text field"}), 400
return jsonify({"original_text": text, "length": len(text),
"message": "Text processed successfully"})
状态码是协议的一部分:400 表示「你的请求有问题」(而非服务器崩了)。 现在你的 API 会校验输入、说清楚话、可预测地失败——演示与可用品的分界就在这里27。 书里给了一个反常识的练习:故意发坏请求——不带 JSON、JSON 里不给 text 字段, 看返回的错误消息;测试坏情况比测试好情况教你的更多28。
路由的可读性纪律:端点变多,杂乱是真敌人。保持路由短、命名清、一个函数别塞太多; 路由一长,就是该让 AI 帮你重构的信号:「重构这个路由:把校验逻辑与处理逻辑分开,别加不必要的复杂度。」29
3.5 接上前端:浏览器怎么问到你的后端¶
后端藏在幕后,用户不跟 API 打交道,用户跟界面打交道。前后端的关系一句话30:
项目结构按 Flask 的约定摆(约定省配置):templates/ 放 HTML、static/ 放 JS/CSS31。
后端开一个页面路由:
HTML 三件套(一个输入区、一个按钮、一块结果显示区):
<h1>Text Processor</h1>
<textarea id="userInput" rows="6" cols="50" placeholder="Type or paste text here…"></textarea>
<br><br>
<button id="submitBtn">Process Text</button>
<pre id="result"></pre>
<script src="/static/script.js"></script>
JavaScript 的核心是 fetch(浏览器里发 HTTP 请求的函数):
document.getElementById("submitBtn").addEventListener("click", async () => {
const text = document.getElementById("userInput").value;
const resultBox = document.getElementById("result");
if (!text) { resultBox.textContent = "Please enter some text."; return; }
resultBox.textContent = "Processing…";
try {
const response = await fetch("/api/process", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text })
});
if (!response.ok) throw new Error(`Server error: ${response.status}`);
const data = await response.json();
resultBox.textContent = JSON.stringify(data, null, 2);
} catch (error) {
console.error("Request failed:", error);
resultBox.textContent = `Something went wrong: ${error.message}`;
}
});
这段脚本的骨架:读输入 → 发请求 → 显示响应,外加两条失败路径(网络层、HTTP 层)。 书里建议对流程本身再追问 AI:「逐步解释这个 fetch 调用怎么和我的 Flask 后端通信, 包括请求失败时会发生什么」——用它强化理解,而不是跳过理解32。
全链路测试四步:起 Flask → 开浏览器 → 输文字 → 点按钮。 看到回包的那一刻,书里的话是:浏览器、JavaScript、后端、逻辑、响应——全部连上了, 这就是每个现代 Web 应用的地基33。
前端出错三剑客(书里把每个错误都标成教材):
| 症状 | 病根 | 排查起点 |
|---|---|---|
| 404 (NOT FOUND) | 路由不匹配——fetch 的地址和后端声明的地址对不上 | 核对两边路径逐字符 |
| CORS 错误 | 前后端不同源(不同域名或端口) | 本章 setup 不会遇到(见下注) |
| JSON 解析错 | 请求头缺 Content-Type 或请求体不是合法 JSON | 查 headers 与 body |
CORS 为什么本章遇不到:Flask 同时从同一个源(同域名同端口)伺服 HTML、JS 和 API, 跨源问题不存在;一旦前后端分开部署,它必然出现(补充:CORS 是浏览器的跨源安全机制, 需要后端额外放行)34。
3.6 错误处理:从「终端红字」到「接口语言」¶
脚本里的错误和 Web 应用里的错误是两个物种。 脚本崩了,终端给你红字,清清楚楚; 应用里的错误会躲——后端失败显示为白屏,前端 bug 表现为「点了没反应」35。 所以错误处理与测试在跨线之后不再是可选项36。
错误的四分类(书里给的全景):输入错误(用户数据缺失或非法)、逻辑错误(跑通但结果错)、 运行时错误(执行中抛异常)、集成错误(前后端没谈拢)。 修任何东西之前,先判断是哪一类——这一步本身就该问 AI: 「这是我的 Flask 应用的一个报错。帮我判断它属于哪一类,通常什么原因引起。」37
故意打破再修复的练习(本章的调试教学):
- 把路由里
data.get("text")改成data["text"],发空 JSON → 终端KeyError: 'text'。 书里的解读:这不是 Flask 的问题,是 Python 在告诉你发生了什么38。 好提示:「这个路由在缺 text 字段时抛 KeyError。解释为什么,并给一个不掩盖错误的防御写法。」39 - 防御版:先
if not request.is_json: return ..., 400,再if "text" not in data: return ..., 400, 最后才取data["text"]。既保护应用,也告诉用户哪错了40。 - 前端版:把 fetch 的 URL 改错 → 点按钮没反应 → 打开浏览器开发者控制台,看到 404。 这不是 JavaScript 的 bug,是路由不匹配。问 AI:「我的前端 fetch 返回 404。 Flask + JavaScript 设置里我先查什么?」41
调试提示的好与坏(书里的对照,与第三章同源):
- 坏:「我的 Flask 应用不工作。」——AI 只能猜;
- 好:「这个路由用 curl 测能过,但从 JavaScript 调就失败。这是路由、fetch 调用和报错信息。」42
基础测试四习惯(不需要任何框架):curl/Postman 测端点;后端改了刷新浏览器; 开发期 print 中间值;故意搞坏东西。再配一句:「这个端点该测哪些边界情况?」43
何时不该信 AI 的建议(本章的清醒剂):AI 会建议让错误静音而不解决的修复、 加不必要的复杂度、掩盖更深的逻辑问题。每次采纳前问自己:我懂这个修复为什么有效吗? 它让代码更清楚吗?下次我自己会这么写吗?——有一个答不上,就慢下来44。
3.7 动手项目:迷你 AI 应用(书里的完整作业)¶
本章的练习是一道没有标准答案的大题:从文本摘要器、聊天机器人、情感分析器里挑一个, 用 Flask + HTML/JS + ChatGPT 提示,独立做出一个能给别人用的小应用45。 书里给的不是答案,是七步脚手架,每步一条「问自己的问题 + 问 AI 的提示」:
- 定义目的——「输入是什么?用户该看到什么输出?」先写下来,再碰代码;
- 搭后端骨架——一个 GET(状态或首页)+ 一个 POST(处理输入);
- 设计接口契约——「请求和响应的 JSON 长什么样?」字段、错误、成功三种形状先定死;
- 建前端——输入区 + 提交按钮 + 结果区,让 AI 写最小的 HTML/JS;
- 接入 AI——把模型调用塞进 POST 路由,聚焦校验、清晰输出、优雅失败;
- 制造并处理错误——空输入、非法 JSON、网络失败,故意各来一遍,只采纳你懂的修复;
- 改进结构——「怎么重构才能更可读、职责更清,又不过度设计?」收尾。
书里的验收标准只有一句:如果一个真实用户能毫无困惑地用你的应用,你就做完了46。 注意这条标准里没有「代码漂亮」——用户视角是这一章的总法官。
3.8 章末 Key Terms 七词与收尾判断¶
| 术语 | 含义 |
|---|---|
| REST API | 系统间用可预测的 URL 与请求类型通信的结构化方式 |
| Endpoint(端点) | Web 应用里做一件具体事的 URL(处理输入或返回数据) |
| HTTP Methods | 描述请求意图的标准动作(GET、POST 等),不描述怎么做 |
| Request–Response Cycle | 数据的全旅程:请求 → 服务器处理 → 响应 |
| Frontend–Backend Integration | 用户所见(HTML/JS)与幕后逻辑(Python)的连接 |
| Error Handling | 预期失败,用清晰有意义的消息回应,而不是崩溃或沉默47 |
本章结语里有一句值得原文带走: 工具会变(今天 Flask、明天别的), 但你在这里练的思考——请求怎么流动、逻辑怎么安全地暴露、AI 怎么在不夺权的前提下 支持设计与调试——会留下来48。
3.9 章末 Points to Remember 五条(书里的原话收拢)¶
原书收尾五条,照录——每一条都能指回本章的某一节:
- Web 应用是对话,不是脚本:每个动作都是输入 → 处理 → 反馈;理解这个流,调试才容易;
- 好的 API 在编码前设计好:早想路由、输入、输出,项目长大后不迷路;
- 错误消息是界面的一部分:一条清楚的错误同时帮用户与未来的开发者;
- AI 在你已有上下文时最有用:你的提示与解释越好,它的输出越准;
- 简洁胜过后端的小聪明:直白的代码好测、好修、好扩展49。
第五条是本章的隐藏纪律:Flask 不强制结构,这是它的优点也是危险—— 「route 里塞六个职责」在 Flask 里没有任何东西拦你。书里给的约束是自觉的: 路由短、命名清、一个函数别贪多;route 变长就是重构信号50。 外加那句收尾格言:「如果你能大声把你的应用讲出来,你就懂它了」—— 讲不清楚的地方,就是结构模糊的地方51。
3.10 从本地到别人的电脑:一个没写进书里的下一步¶
本章的应用跑在 127.0.0.1——只你自己能访问。书里到此为止,
但「别人能用」只差一步,值得点破(补充,不在书里,来自通用知识):
把 app.run(debug=True) 换成 app.run(host="0.0.0.0"),
同一局域网的人就能用你电脑的 IP 访问;要全世界能访问,需要部署到服务器
(书中未覆盖,见书卡 notCovered)。不要在 debug 模式下对外暴露——
详细报错页会把你的代码结构透给任何访问者。这一步之险与这一步之近,
是本章留给读者的最后一个功课。
3.11 章节的暗线:一切始于「设计先于编码」¶
回看全章,九节内容其实只讲了一个习惯的两次应用:
习惯:先设计,后编码——接口的形状先于实现存在
│
├─ 应用一(§3.1):先要「项目结构 + 每个文件干什么」,再写码
└─ 应用二(§3.4):先要「端点名与职责」,再写码
│
▼
同样的习惯在第四章是「先写失败测试」,
在第三章是「先要结构不要代码」——全书是同一个主张的多次变奏。
这个习惯为什么如此重要?因为 AI 编码的引入把「写」变便宜了, 「想清楚」成了唯一的瓶颈——你设计的接口越清楚,AI 填空越准;你设计的接口含糊, AI 就替你瞎猜,而猜错的重构成本远高于想清的成本。 第九章把这个道理讲到了 Web 上。
3.12 全章的一句话验收¶
收一张验收卡——做完本章的动手项目后逐条自问:
□ 我能画出浏览器 → JS → Flask → OpenAI → 原路返回 的箭头图吗?
□ 我能不看代码说出 /api/process 收什么、回什么、哪几种错吗?
□ curl 测过三个坏请求(无 JSON / 缺字段 / 错路径),返回都符合预期吗?
□ 密钥在任何 .py 文件里都搜不到吗?(grep 自查)
□ 换一个没看过代码的人,能不看解释就用这个应用吗?
五条全勾,本章达标;勾不满的那条,回到对应的小节。 书里的验收标准是最后一条46——其余四条是我们加的脚手架, 为的是让「别人能用」这个软标准有硬支撑。52
3.13 部署之外的两个「差一点」(书里没写、从缺口推的)¶
第九章把应用跑在本地之后,离「别人能用」还差两件事,书里停下了,我们补上 (通用知识,不改变书中任何结论):
第一件:持久化。 本章的端点把用户输入问完就忘——刷新页面,对话历史归零。 让应用「记住」需要数据库(书卡 notCovered 已列):最小可行方案是 SQLite—— 单文件、零安装、够用到几千用户。Flask 与之对接只需一个库(SQLAlchemy 或 sqlite3), 但「表怎么设计」是全新的思考维度,值得单独一章。
第二件:并发。 app.run(debug=True) 的开发服务器一次只处理一个请求;
两个人同时点按钮,第二个就排队。生产服务器(gunicorn/uwsgi)用多进程或协程解决,
但那引入「全局状态不能乱用」「请求之间怎么隔离」的新纪律。
这两条缺口正好是「下一步学什么」的答案——书末的未来方向里,
「学基础后端架构」一项说的就是把这两条补上53。
3.14 前端代码的读法(本章的「读懂」回合)¶
第九章也是第二章读法的一次实战:那 30 行 fetch 代码,按第二章的问法走一遍——
问「是什么」: 给按钮挂了一个点击监听器;点击后读输入框文本,POST 给 /api/process; 把返回的 JSON 格式化显示;出错时在结果区显示错误消息。
问「为什么」: 为什么先 if (!text) 再发请求?——空输入发过去也是 400,
本地拦下省一轮往返,体验更快;为什么 try/catch 里还查 response.ok?——
HTTP 层的错(404、500)不抛异常,网络层的错(断网)才抛,两层都要接54。
问「怎么办」: 「怎么在请求期间禁用按钮防重复提交?」「怎么把 JSON 显示换成漂亮的格式化?」 ——全是让 AI 给变体的标准句式。
走完这一圈,前端代码不再是「浏览器里的魔法」:它就是第二章的代码, 只是宿主从 Python 换成了 JavaScript。语言换了,读法没换——这正是第二章 「读法总谱」跨语言的证据。
3.15 好错误的三性质:书里给错误处理定的验收标准¶
§3.6 讲了错误处理怎么写,这一节讲写完了怎么验收——书里在错误处理的结尾 给了三条性质,作为「这个 API 的错误处理算不算合格」的判据1:
| 性质 | 含义 | 本章的对应实现 |
|---|---|---|
| 校验输入 | 不合法的东西进不来,或进来就挡下 | 检查 request.is_json、用 .get() 取字段 |
| 说得清 | 错误信息人读得懂,不是一坨 traceback | 回 {"error": "..."} 带一句人话 |
| 败得可预期 | 同样错输入,永远同样错输出 | 每种坏请求都有固定状态码与固定 JSON 形状 |
书里紧跟一句判语:「这就是 demo(演示)与「能用的东西」之间的差别」2。 这句话值得当成本章的门槛——跑通一次成功请求只证明它是 demo; 故意发三种坏请求(空 JSON、缺字段、错路径)都得到预期响应,才证明它能用。 §3.12 验收卡里「curl 测过三个坏请求」一条,源头就在这里。
判断(我们的,不是书里的): 三性质里「败得可预期」是最容易被新手跳过、 又最值钱的一条——它的本质是「错误也是接口契约的一部分」: 前端(或任何调用方)能靠稳定的错误形状做分支,而不是每次解析一坨未知文本。 如果错,会错在: 对内部脚本,三性质是过度设计(脚本的用户是你自己, 错误形状稳定与否无所谓);本章是 Web 应用,调用方是别人,所以成立。
4. 作者的判断与证据¶
有演示支撑的判断:
经验之谈:
- 「健康检查端点日后无比有用」——运维常识,可信25;
- 「curl 先行、浏览器殿后」的调试顺序——好习惯,但复杂前端状态(登录态、依赖前端路由)时 curl 覆盖不全。
推测:
- 「把 AI 集成进端点就是『真正 AI 驱动』的时刻」——修辞性表述,技术上是把 API 调用包进路由而已17。
5. 边界与局限¶
- 没有数据库与用户系统:书里明说「没有账户、没有数据库」——持久化、登录、会话全靠你自己后续补;
- debug=True 不能上生产:开发模式的自动重载与详细报错页会泄露代码;部署要换生产服务器(gunicorn 等),本章未涉;
- 没有鉴权与限流:端点裸露在公网会被刷爆;真实应用要加 API key/登录与速率限制;
- 模型调用无重试与超时:网络抖动时端点会挂;生产要加超时、重试、降级;
- 前端极简:一个 textarea 的静态页;真实产品的前端复杂度高几个数量级,本章只是打通链路。
6. 可带走的¶
本章主线例子,一行写完: pip install flask openai → app.py 里 POST /api/process
(校验 JSON→取 text→调 OpenAI→回 JSON)→ GET /api/status 健康检查 →
templates/index.html + static/script.js(fetch POST→渲染)→ curl 测 → 浏览器测 → 故意发坏请求 → 防御式改版。
- 应用与脚本的差别在人:别人能用、能依赖;
- 设计先于编码:先要结构、先要端点命名,先写「请求/响应长什么样」再写实现;
- 密钥永远走环境变量:os.getenv,不进代码、不进仓库;
- 端点三件套:POST 处理、GET 查健康、400 说人话;
- 请求-响应循环是地基:浏览器问、后端转述、模型答、页面更新;
- Flask 的 templates/static 约定省配置;fetch 是前端的发报机;
- 错误四分类先判型再修;「脚本红字 vs 应用沉默」是两个物种;
- 故意搞坏是必修课:空 JSON、错 URL、缺字段,坏请求教得比好请求多;
- 调试提示带三样:代码、报错、你怎么触发的——「不工作」三个字值零;
- 采纳 AI 修复前三问:懂为什么吗?更清楚吗?下次自己会写吗?44
7. 原文地图¶
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 脚本与应用的线 | Building an AI-Powered Web Application | text/21-ch09-9-building-an-ai-powered-web-application.txt:18(搜「line most developers cross」) |
| AI 驱动≠AI 包办 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:33(搜「specific, intentional points」) |
| Web 应用四样 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:46(搜「Reach」) |
| 没有账户没有数据库 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:148(搜「No accounts」) |
| 先要结构提示 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:163(搜「beginner-friendly project structure」) |
| 最小端点与逐行读懂 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:276(搜「minimal Flask app」) · text/21-ch09-9-building-an-ai-powered-web-application.txt:318(搜「line by line」) |
| 密钥走环境变量 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:375(搜「Never hardcode」) · text/21-ch09-9-building-an-ai-powered-web-application.txt:385(搜「export OPENAI_API_KEY」) |
| 接入 AI 与运行 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:415(搜「OpenAI(api_key」) · text/21-ch09-9-building-an-ai-powered-web-application.txt:496(搜「Running on http」) |
| curl 测试 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:508(搜「curl -X POST」) |
| REST 四方法 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:594(搜「Method」) |
| 先要端点命名 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:693(搜「suggest endpoint names」) |
| 健康检查端点 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:719(搜「api/status」) |
| 防御式 POST 与故意发坏 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:800(搜「Request must be JSON」) · text/21-ch09-9-building-an-ai-powered-web-application.txt:850(搜「Try sending bad requests」) |
| 前后端接线五步行 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:972(搜「types something」) |
| templates/static 约定 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:1025(搜「templates folder」) |
| fetch 脚本 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:1142(搜「addEventListener」) |
| 404/CORS/JSON 三剑客 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:1311(搜「404 errors」) |
| 错误四分类 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:1388(搜「Input Errors」) |
| KeyError 与防御版 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:1452(搜「KeyError」) · text/21-ch09-9-building-an-ai-powered-web-application.txt:1505(搜「Expected JSON input」) |
| 不信 AI 建议三问 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:1655(搜「Silence errors」) · text/21-ch09-9-building-an-ai-powered-web-application.txt:1669(搜「understand why」) |
| 七步动手项目 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:1694(搜「Build a Mini」) |
| 用户验收标准 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:1865(搜「without confusion」) |
| Key Terms 六词 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:1872(搜「REST API」) |
| 工具会变思考会留下 | 同上 | text/21-ch09-9-building-an-ai-powered-web-application.txt:1688(搜「remain relevant」) |
-
出处:「Building an AI-Powered Web Application」第 834–840 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:834,搜「Validates input」;:837,搜「Communicates clearly」;:840,搜「Fails predictably」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 844 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:844,搜「demo and something usable」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 18 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:18,搜「line most developers cross」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 33 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:33,搜「specific, intentional points」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 46 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:46,搜「Reach」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 148 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:148,搜「No accounts」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 92 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:92,搜「Which file do I create first」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 163 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:163,搜「beginner-friendly project structure」)。 ↩↩ -
出处:「Building an AI-Powered Web Application」第 180 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:180,搜「matters more」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 228 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:228,搜「simpler version」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 255 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:255,搜「pip freeze」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 276 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:276,搜「minimal Flask app」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 318 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:318,搜「line by line」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 344 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:344,搜「standard API」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 362 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:362,搜「pip install openai」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 375 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:375,搜「Never hardcode」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 481 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:481,搜「genuinely AI-powered」)。 ↩↩ -
出处:「Building an AI-Powered Web Application」第 508 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:508,搜「curl -X POST」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 542 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:542,搜「structure is sound」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 555 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:555,搜「clean agreement」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 568 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:568,搜「Each endpoint」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 594 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:594,搜「Method」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 693 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:693,搜「suggest endpoint names」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 719 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:719,搜「api/status」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 767 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:767,搜「incredibly useful later」)。 ↩↩ -
出处:「Building an AI-Powered Web Application」第 785 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:785,搜「gracefully handles」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 844 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:844,搜「demo and something usable」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 895 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:895,搜「more than the successful ones」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 40–41 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:927,搜「separate validation」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 972 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:972,搜「types something」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1025 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1025,搜「templates folder」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1301 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1301,搜「step by step」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1292 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1292,搜「foundation of every modern web app」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1311 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1311,搜「404 errors」)与第 1332 段(text/21-ch09-9-building-an-ai-powered-web-application.txt:1332,搜「same origin」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1371 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1371,搜「backend failure may show up」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1378 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1378,搜「not optional」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1410 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1410,搜「category of error」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1452 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1452,搜「KeyError」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1467 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1467,搜「without hiding the error」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1532 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1532,搜「protects your app」)。 ↩↩ -
出处:「Building an AI-Powered Web Application」第 1571 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1571,搜「404 (NOT FOUND)」)与第 1586 段(text/21-ch09-9-building-an-ai-powered-web-application.txt:1586,搜「should I check first」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1607 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1607,搜「works when tested with curl」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1626 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1626,搜「curl or Postman」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 1655 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1655,搜「Silence errors」)与第 1669 段(text/21-ch09-9-building-an-ai-powered-web-application.txt:1669,搜「understand why」)。 ↩↩ -
出处:「Building an AI-Powered Web Application」Hands-on Project(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1694,搜「Build a Mini」)。 ↩ -
出处:「Building an AI-Powered Web Application」Hands-on Project 收尾(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1865,搜「without confusion」)。 ↩↩ -
出处:「Building an AI-Powered Web Application」Key Terms(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1872,搜「REST API」)。 ↩ -
出处:「Building an AI-Powered Web Application」结论段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1688,搜「remain relevant」)。 ↩ -
出处:「Building an AI-Powered Web Application」Points to Remember(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1895,搜「Conversations, Not Scripts」至:1911,搜「Beats Cleverness」)。 ↩ -
出处:「Building an AI-Powered Web Application」第 918 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:918,搜「signal」)。 ↩ -
出处:「Building an AI-Powered Web Application」Points to Remember(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1915,搜「Explain Your App out Loud」)。 ↩ -
(我们的验收清单;用户标准一条出自原书,见
text/21-ch09-9-building-an-ai-powered-web-application.txt:1865。) ↩ -
出处:「Best Practices and Optimization」第 737 段(
text/22-ch10-10-best-practices-and-optimization.txt:737,搜「Learn Basic Backend Architecture」)。持久化与并发的具体机制是通用知识,不在书里。 ↩ -
出处:「Building an AI-Powered Web Application」第 1190 段(
text/21-ch09-9-building-an-ai-powered-web-application.txt:1190,搜「response.ok」)与第 1311 段(text/21-ch09-9-building-an-ai-powered-web-application.txt:1311,搜「404 errors」)。 ↩