Menu

AI 编程提示词:让 AI 写出能运行的代码

编程提示词要写得像一份小型需求说明才管用:语言和版本、输入和输出、边界情况,以及代码必须通过的测试。每次只让 AI 做一小步。

下面的每条提示词都可以编辑:改好后,在 ChatGPT、Claude 或其他 AI 应用中打开。

编程提示词就是一份需求说明。模型没见过你的项目,不知道你用的是哪个版本的语言,也没法问你输入为空时该怎么办。提示词没写的地方,它都会用训练数据中最常见的选择来填补,而最常见的选择往往不是你要的。下面的提示词能让模型少猜一些东西。

先写需求说明,再写代码

下面的提示词要求写一个小的 Python 函数。提示词的每个部分都回答了一个问题,如果不写,模型就会替你回答。把这些部分一个一个关掉,想象一下没有它们的回复会是什么样:没有约束,你可能会拿到一个第三方库;没有上下文,模型只能猜什么算有效输入;没有格式要求,你可能拿不到测试。

根据需求说明写函数
Fill in
Parts
你是一名细心的 Python 开发者,擅长编写小巧且经过测试的函数。
写一个函数 `parse_duration(text)`,把表示时长的字符串转换成秒数。
有效输入形如 "1h30m"、"45m"、"2h" 和 "90s":小时、分钟和秒,每一项都可以省略,但顺序始终不变。"1h30m" 返回 5400。其他任何输入,包括空字符串,都是无效的。
Python 3.11,只用标准库。输入无效时抛出 ValueError,并在错误信息中包含该输入。不接受 "1.5h" 这样的小数。
先给出函数,再给出 pytest 测试,覆盖上面的每个示例以及三个无效输入。除了一句话之外不要做任何解释。
Try it
Example replyReplies vary between models and runs.

这个函数按顺序匹配三个可省略的部分,并拒绝三个部分都为空的匹配。

import re

_PATTERN = re.compile(r"(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?")

def parse_duration(text: str) -> int:
    match = _PATTERN.fullmatch(text)
    if not match or not any(match.groups()):
        raise ValueError(f"invalid duration: {text!r}")
    hours, minutes, seconds = (int(g) if g else 0 for g in match.groups())
    return hours * 3600 + minutes * 60 + seconds
import pytest
from duration import parse_duration

@pytest.mark.parametrize("text, expected", [
    ("1h30m", 5400), ("45m", 2700), ("2h", 7200), ("90s", 90),
])
def test_valid(text, expected):
    assert parse_duration(text) == expected

@pytest.mark.parametrize("text", ["", "1m1h", "1.5h"])
def test_invalid(text):
    with pytest.raises(ValueError):
        parse_duration(text)

这个提示词里有四个细节承担了大部分工作:

  • 带答案的示例。 “1h30m 返回 5400”是一个测试,模型可以拿它来检验自己的代码,同时也消除了对单位的任何疑问。
  • 语言版本和允许使用的库。 不写的话,你可能会拿到一个你没安装的库,或者比你的解释器更新的语法。
  • 什么算无效,以及无效时该怎么办。 没人要求的话,模型很容易漏掉错误处理。
  • 答案里附带测试。 测试把“看起来没问题”变成了可以运行的东西。如果某个测试失败,你可以把失败信息贴回去,这比一句“不能用”好得多。

any(match.groups()) 这个检查也值得注意:单看这个模式,它能匹配空字符串,因为每个部分都是可选的。正是提示词中关于空字符串的那一行,让这种情况出现在了代码和测试里。

写明版本、技术栈和已有的东西

模型倾向于使用训练数据中最常见的写法。对 JavaScript 来说,这可能意味着在使用 ES 模块的项目里写出 CommonJS 的 require;对 Python 来说,可能意味着用了后来已经改变的库 API(Pydantic 1 和 2 就是常见的例子);对任何更新很快的框架来说,可能意味着用的是两个大版本之前的写法。通常一行话就能解决:“Node 22,ES 模块,不用 TypeScript”或者“React 19,函数组件,普通的 CSS 模块”。

在已有项目上添加功能时,模型需要看到新代码会涉及的部分。粘贴它必须调用的函数签名、它会收到的数据结构,以及一个能体现你的代码约定的现有文件。“使用下面文件中的 db.query(sql, params) 辅助函数”能换来与项目契合的代码;不写这句,你可能会得到一段从零写起的新数据库连接。与这次改动无关的文件就不要放进来,因为每一行无关的内容,模型都可能试图拿去复用。

每次只要一小步

在“vibe coding”(通过向 AI 描述来开发应用)中,最常见的失败是一次就要整个应用。模型必须在一个回复里选好框架、数据库、文件夹结构和十几个功能,而一个回复很少能装下全部能运行的代码,所以常常得到的只是一个大纲。对比下面两个标签页。

帮我做一个待办事项应用,要有用户账号、数据库、提醒功能和深色模式。
Try it
Example replyReplies vary between models and runs.

下面是一个使用 React、Node.js + Express 和 MongoDB 的全栈待办事项应用。

项目结构

todo-app/
  client/   (React front end)
  server/   (Express API, auth, reminders)

server/index.js

const express = require("express");
const mongoose = require("mongoose");
const app = express();
app.use(express.json());
// ... auth routes, todo routes and the reminder scheduler go here

身份验证可以用 jsonwebtoken 加上 JWT,提醒功能可以用 node-cron 这样的定时任务库。如果需要我把其中某个部分补全,告诉我就行。

第一个回复不算错,但它只是一个骨架:它替你选了三种技术,又把真正要做的工作留在了注释里。第二个回复短到可以读完,打开文件就能运行,还给了你一个可以用来做第 2 步的基础(“现在把列表保存到 localStorage,让它在刷新后还在”)。每一步都足够小,出问题时你就知道是哪处改动导致的。

这就是手动进行的提示词链:一次请求的输出成为下一次请求的起点。每做新的一步,都把文件的当前版本粘贴进去,这样模型修改的是你手上真实的代码,而不是它记忆中自己写过的那份。

大改动之前先要计划

只要比一个函数大,就先要计划,再要代码:“列出你要修改的文件,以及每处修改做什么。先不要写代码。”计划读起来快,改起来也快。如果它提出要加一个你不想要的依赖,或者漏掉了你知道会涉及的文件,你用一句话就能纠正,而不必在三百行代码里才发现问题。

检查返回的结果

生成的代码出错的方式有几种是可以预见的,每一种都有对应的提示词习惯可以防住:

  • 编造的 API。 模型可能调用一个并不存在的函数或导入一个并不存在的包,只因为这个名字听起来很合理。安装不熟悉的导入之前先查一查;AI 幻觉解释了为什么会这样。
  • 被忽略的边界情况。 代码在正常情况下能跑,遇到空列表就崩溃。在提示词里列出边界情况并要求写测试,是成本最低的解决办法。
  • 悄悄的改动。 当你要求修复一个长文件时,模型可能还会顺手重命名一些东西,或重新组织你没提到的代码。加上一句“只改必要的地方,并列出你做的每一处改动”。

如果代码能运行但行为不对,就换成调试用的提示词:调试提示词讲了该粘贴些什么。合并任何重要的代码之前,再用代码审查提示词过一遍,能发现写代码的提示词没想到要问的问题。

常见问题

用 ChatGPT 或 Claude 写代码,最好的提示词是什么?

没有一个万能的提示词。管用的提示词读起来像一份简短的需求说明:语言和版本、代码接收什么、返回什么、两三个示例输入及其输出、边界情况,以及代码不能使用的东西。最后加一句“同时为这些情况写测试”,你就有办法检验答案,而不是只能相信它。

vibe coding 提示词是什么?

“Vibe coding”指的是主要靠向 AI 描述你想要的东西来开发软件,并直接接受它写出的代码,往往不仔细阅读。能让 vibe coding 项目一直保持可用的提示词都很小:每次请求只做一个功能,清楚说明已经有哪些东西,并要求先运行或测试结果再继续。一次要求做完一大堆,正是这类项目最容易出问题的地方。

要不要告诉 AI 使用哪个版本的编程语言?

要。语言和库在不同版本之间会变化,不写明的话,模型会采用训练数据中最常见的写法,而它可能比你的环境更旧。写明版本(“Python 3.12”“React 19,使用函数组件”“Node 22,ES 模块”)可以避免回答用到你根本没有的 API。

AI 写的代码可以信任吗?

把它当作新同事写的代码来对待:大概率八九不离十,有时却错得看上去很对。运行它,用你关心的边界情况测试它,并仔细阅读涉及金钱、安全或用户数据的部分。模型还可能编造不存在的函数或包,所以安装任何东西之前,先查一查不熟悉的导入。

为什么项目变大以后,AI 生成的代码就容易出问题?

模型只能看到对话里的内容。项目变大后,它看不到你没给它看的文件,只能靠猜来补上名称、结构和之前的决定。粘贴相关的文件,说明项目遵循的约定,并让每次请求只做一处改动。

Coddy 编程语言插图

和 Coddy 一起学编程

开始