正在学习
第三步:添加结构和评估指令
14.3 后端与 API 提示
后端和 API 开发是 Claude Code 最强的应用场景之一。与专注于生成样板代码的传统代码生成器不同,Claude 能够理解意图、逻辑流程和架构设计。它可以生成完整的后端模块、RESTful 端点和中间件管道,同时保持业务逻辑的清晰和可维护性。
本节重点介绍如何编写有效的后端提示——能够生成可运行的 API 服务器、处理数据验证、集成数据库并管理错误处理的提示。无论你使用 FastAPI、Express.js、Flask 还是 Django,目标都是展示 Claude 如何通过结构良好、上下文丰富的请求来协助构建生产级的后端系统。
概念阐述
后端提示与前端提示在一个关键方面有所不同:它们要求的是结构和功能上的精确性,而不是美学上的精致。当你提供以下信息时,Claude 的表现最佳:
- 框架和编程语言(例如,"Python + FastAPI")
- API 的用途(例如,"用户认证"或"任务管理")
- 需求,如身份验证、数据验证或数据库连接
- 预期输出的格式——单个模块、多个路由或整个服务
- 环境约束——是否应使用异步函数、遵循 REST 原则,或与 CI/CD 工具集成
通过明确定义这些要素,你将引导 Claude 生成结构化、可测试且可部署的后端系统,而不是通用的代码片段。
动手示例 1:FastAPI CRUD 应用
提示:
你是一名资深 Python 后端工程师。
构建一个用于管理任务的 FastAPI 应用程序,包含以下端点:
任务的创建、读取、更新和删除
使用 Pydantic 验证请求体
包含针对缺失任务的异常处理
返回完整可运行的 Python 文件。
Claude 输出(示例):
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List
app = FastAPI()
class Task(BaseModel):
id: int
title: str
completed: bool = False
tasks: List[Task] = []
@app.post("/tasks", response_model=Task)
def create_task(task: Task):
tasks.append(task)
return task
@app.get("/tasks", response_model=List[Task])
def get_tasks():
return tasks
@app.get("/tasks/{task_id}", response_model=Task)
def get_task(task_id: int):
for task in tasks:
if task.id == task_id:
return task
raise HTTPException(status_code=404, detail="Task not found")
@app.put("/tasks/{task_id}", response_model=Task)
def update_task(task_id: int, updated_task: Task):
for i, task in enumerate(tasks):
if task.id == task_id:
tasks[i] = updated_task
return updated_task
raise HTTPException(status_code=404, detail="Task not found")
@app.delete("/tasks/{task_id}")
def delete_task(task_id: int):
for i, task in enumerate(tasks):
if task.id == task_id:
tasks.pop(i)
return {"detail": "Task deleted"}
raise HTTPException(status_code=404, detail="Task not found")
为什么有效:提示明确指定了框架、数据验证和错误处理,使 Claude 能够生成一个完整且功能可用的 FastAPI 应用程序——没有不完整的占位符,也没有遗漏的导入语句。生成的结果可以直接通过 uvicorn main:app --reload 运行。
动手示例 2:带中间件的 Node.js Express API
提示:
创建一个用于管理用户身份验证的 Node.js Express API。
包含以下内容:
注册和登录的端点
使用 bcrypt 进行密码哈希
使用 JWT 生成令牌
用于保护私有路由的中间件
返回一个完整可运行的文件。
Claude 输出(示例):
import express from "express";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
const app = express();
app.use(express.json());
const users = [];
const SECRET = "mysecretkey";
app.post("/register", async (req, res) => {
const { username, password } = req.body;
const hashed = await bcrypt.hash(password, 10);
users.push({ username, password: hashed });
res.status(201).json({ message: "User registered successfully" });
});
app.post("/login", async (req, res) => {
const { username, password } = req.body;
const user = users.find((u) => u.username === username);
if (!user) return res.status(404).json({ message: "User not found" });
const valid = await bcrypt.compare(password, user.password);
if (!valid) return res.status(401).json({ message: "Invalid credentials" });
const token = jwt.sign({ username }, SECRET, { expiresIn: "1h" });
res.json({ token });
});
function auth(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader) return res.status(401).json({ message: "Missing token" });
try {
const decoded = jwt.verify(authHeader.split(" ")[1], SECRET);
req.user = decoded;
next();
} catch {
res.status(401).json({ message: "Invalid token" });
}
}
app.get("/profile", auth, (req, res) => {
res.json({ message: `Welcome ${req.user.username}!` });
});
app.listen(4000, () => console.log("Server running on port 4000"));
关键要点:
- 提示明确定义了安全机制(JWT、bcrypt)和具体的路由,确保了输出的完整性。
- Claude 正确地包含了中间件和身份验证逻辑,而这些在通用 AI 代码中经常被遗漏。
- 输出无需修改即可运行,使用
node app.js(在安装依赖项之后)。
动手示例 3:带数据库集成的 Flask API
提示:
构建一个图书目录的 Flask REST API。
包含以下内容:
SQLite 数据库集成
SQLAlchemy ORM 模型
图书的 CRUD 路由
针对无效操作的错误处理
返回一个完整可运行的 Python 脚本。
Claude 输出(示例):
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///books.db"
db = SQLAlchemy(app)
class Book(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
author = db.Column(db.String(100), nullable=False)
@app.before_first_request
def create_tables():
db.create_all()
@app.route("/books", methods=["POST"])
def add_book():
data = request.get_json()
book = Book(title=data["title"], author=data["author"])
db.session.add(book)
db.session.commit()
{
"code": "return jsonify({\"message\": \"Book added successfully\"}), 201\n\n@app.route(\"/books\", methods=[\"GET\"])\ndef get_books():\n books = Book.query.all()\n return jsonify([{\"id\": b.id, \"title\": b.title, \"author\": b.author} for b in books])\n\n@app.route(\"/books/<int:book_id>\", methods=[\"GET\"])\ndef get_book(book_id):\n book = Book.query.get(book_id)\n if not book:\n return jsonify({\"error\": \"Book not found\"}), 404\n return jsonify({\"id\": book.id, \"title\": book.title, \"author\": book.author})\n\n@app.route(\"/books/<int:book_id>\", methods=[\"DELETE\"])\ndef delete_book(book_id):\n book = Book.query.get(book_id)\n if not book:\n return jsonify({\"error\": \"Book not found\"}), 404\n db.session.delete(book)\n db.session.commit()\n return jsonify({\"message\": \"Book deleted\"})\n\nif __name__ == \"__main__\":\n app.run(debug=True)\n\n## 14.4 测试与调试提示\n\n测试与调试是 Claude Code 从编码助手转变为软件质量合作伙伴的关键环节。编写良好的提示不仅可以帮助 Claude 生成测试用例,还能帮助诊断逻辑错误、解读堆栈跟踪,甚至解释如何修复 bug。本节重点介绍如何编写结构化、可复现的测试与调试提示,以获得高质量、可验证的结果。\n\nClaude 的优势在于其上下文推理能力——理解函数应有的功能、检测失败原因,并在单一工作流中同时生成测试和修复方案。通过合适的提示结构,你可以将 Claude 视为灵活的测试工程师,补充你的直觉判断,节省大量人工检查时间。\n\n### 概念阐述\n\n在使用 Claude 进行测试与调试时,清晰性和范围控制至关重要。与人类测试人员不同,Claude 无法很好地推断未明确说明的需求——你必须明确指定范围、框架和预期行为。以下关键提示要素能够持续产出优质结果:\n\n- **框架指定**——例如"使用 pytest"、"使用 Jest"或"使用 unittest"。\n- **覆盖范围**——定义要测试的函数、模块或边界情况。\n- **预期格式**——要求返回可运行的测试文件,而非代码片段。\n- **错误处理**——提供供 Claude 分析的示例堆栈跟踪。\n- **验证意图**——指示 Claude 确认修复方案能通过所有测试。\n\n结构良好的调试提示不仅请求修复,还会解释观察到的行为,并引导 Claude 逐步进行推理。\n\n### 动手示例 1:使用 Pytest 编写单元测试\n\n**提示**:\n你是一名 Python 质量保证工程师。\n请为以下函数编写 pytest 测试用例。\n确保覆盖有效输入、无效输入和边界情况。\n返回一个完整可运行的测试文件。\n\n```python\ndef divide(a, b):\n return a / b\n```\n\n**Claude 输出(示例)**:\n```python\nimport pytest\nfrom main import divide\n\ndef test_divide_valid():\n assert divide(10, 2) == 5\n assert divide(-6, 3) == -2\n\ndef test_divide_zero_division():\n with pytest.raises(ZeroDivisionError):\n divide(5, 0)\n\ndef test_divide_floats():\n assert pytest.approx(divide(5.0, 2.0), 0.001) == 2.5\n\ndef test_divide_large_numbers():\n assert divide(1_000_000, 10) == 100_000\n```\n\n**说明**:Claude 创建了一个结构清晰的测试文件,覆盖了边界情况——包括浮点精度和错误处理。得益于精心设计的提示,它在没有明确指示具体测试内容的情况下,自动推断出了边界条件。\n\n### 动手示例 2:通过错误跟踪分析进行调试\n\n**提示**:\n你是一名调试助手。\n请分析以下 Python 跟踪回溯并找出根本原因。\n然后,重写存在缺陷的代码并附上说明。\n\n```\nTraceback (most recent call last):\n File \"app.py\", line 10, in <module>\n result = calculate_area(5)\nTypeError: calculate_area() missing 1 required positional argument: 'height'\n\n```python\ndef calculate_area(width, height=2):\n return width * height\n```\n\n**Claude 输出(示例)**:\n```python\n# 修复后的代码\ndef calculate_area(width, height=2):\n return width * height\n\n# 正确的调用方式\nresult = calculate_area(5, 4)\nprint(result) # 输出:20\n```\n\n**说明**:Claude 准确识别出问题——函数调用缺少必需的位置参数。它不仅提供了修正后的代码,还在上下文中解释了修复方案,将调试过程转变为学习过程,而非凭直觉猜测。\n\n### 动手示例 3:JavaScript Jest 测试自动化\n\n**提示**:\n请为以下 Express.js 路由编写 Jest 测试用例。\n覆盖成功、失败和验证场景。\n\n```javascript\napp.post(\"/users\", (req, res) => {\n const { name, email } = req.body;\n if (!name || !email) return res.status(400).json({ message: \"Invalid input\" });\n res.status(201).json({ message: \"User created\" });\n});\n```\n\n**Claude 输出(示例)**:\n```javascript\nimport request from \"supertest\";\nimport express from \"express\";\n\nconst app = express();\napp.use(express.json());\n\napp.post(\"/users\", (req, res) => {\n const { name, email } = req.body;\n if (!name || !email) return res.status(400).json({ message: \"Invalid input\" });\n```
```markdown
res.status(201).json({ message: "用户已创建" });
});
describe("POST /users", () => {
it("应成功创建用户", async () => {
const res = await request(app)
.post("/users")
.send({ name: "Alice", email: "alice@example.com" });
expect(res.statusCode).toBe(201);
expect(res.body.message).toBe("用户已创建");
});
it("对于无效输入应返回 400", async () => {
const res = await request(app).post("/users").send({});
expect(res.statusCode).toBe(400);
});
});
为什么有效:提示定义了三个预期——框架、测试覆盖率和验证行为。Claude 响应提供了一个可用的测试套件,该套件使用 Supertest,处理有效和无效输入,并可在 Node.js 中立即运行。
动手示例 4:调试循环中的逻辑错误
提示:
分析这段产生不正确结果的 Python 代码。
解释逻辑错误并提供修正后的版本。
def calculate_sum(numbers):
total = 0
for num in numbers:
total = num # 错误在这里
return total
print(calculate_sum([1, 2, 3]))
Claude 输出(示例):
练习题
在为 Claude Code 编写后端提示时,以下哪项不是关键要求?
在 FastAPI CRUD 应用程序提示示例中,提示的主要目标是什么?
以下哪些是 Claude Code 有效后端提示的特征?(选择所有适用的)
在 Claude Code 的后端提示中包含环境约束有哪些好处?(选择所有适用的)
Claude Code 的后端提示应关注美学而非结构和功能。
FastAPI CRUD 应用程序提示示例之所以成功,是因为它指定了数据验证和错误处理要求。
在后端提示中,提供___和编程语言(例如 'Python + FastAPI')有助于 Claude 生成与您的技术栈一致的代码。
API的___(例如"用户认证"或"任务管理")是在为Claude Code编写后端提示时需要定义的一个重要方面。
解释为什么在 Claude Code 的后端提示中指定预期输出格式很重要。
从用于用户身份验证的 Node.js Express API 提示示例中可以得出哪些关键要点?
以下哪一项是在 Claude Code 开发中使用可复用提示库的好处?
Claude Code 提示词开发中迭代调优的三大原则是什么?(选择所有适用项)
在为带有用户认证的 Node.js Express API 编写后端提示时,以下哪项不是为让 Claude 生成完整且可运行应用程序而需要在提示中指定的关键要求?
以下哪些是在 FastAPI CRUD 应用程序提示中必须包含的基本组件,以确保 Claude 生成完整且功能齐全的应用程序?(请选择所有适用的选项)
在带有数据库集成的 Flask API 的后端提示中,指定数据库类型(例如 SQLite)和 ORM(例如 SQLAlchemy)对于 Claude 生成完整且功能正常的应用程序是必要的。
解释为什么在后端提示中包含错误处理要求对于生成功能性 API 很重要。
登录后解锁笔记、知识点解析、AI 问答
立即登录