最近在技术社区里,Ethan Mollick 关于 AI 写作的一个判断引发了不少讨论:AI 写作的第一个黄金时代已经结束。
这句话对很多刚接触大模型写作的同学来说可能有些费解。毕竟从 ChatGPT 出现到现在,AI 写文案、写周报、写代码的能力一直在迭代,为什么反而说“黄金时代结束”了?如果你自己批量生成过文章、投放过内容平台,大概会有更直接的体感:早期那种“给一个标题,然后让大模型直接生成一篇完整文章”的做法,正在变得越来越不值钱。输出同质化、内容缺少可信度、读者审美疲劳、平台规则收紧,这些问题叠加起来,让纯靠模型文本“套利”的空间快速变小。
这篇文章不打算只分析趋势,而会结合 AI 工程实践,聊聊 AI 写作到底进入了哪个阶段,以及作为开发者、技术写作者,应该如何把 AI 辅助写作做成一条可控、可复用、可质量把关的工作流。内容会覆盖概念拆解、环境准备、核心代码、常见问题和工程建议,适合正在做 AI 应用开发,或者长期用大模型辅助创作的读者。
1. 一个观察:AI 写作的“套利期”正在结束
1.1 AI 写作 1.0 时代的典型玩法
回看大模型刚被大规模使用的那段时间,AI 写作的典型玩法非常统一:输入一个主题,调用一次模型接口,得到一篇看起来结构完整、语言通顺的长文。整个过程几乎不需要人工参与,也不需要额外的知识库,更不需要对内容进行事实核查。
这种玩法的确带来过一波红利。因为模型相比过去的文本生成技术有了质变,它能模仿博客、新闻、技术教程、短视频脚本等常见文体。对内容平台来说,AI 可以快速生成大量“可被检索”的页面;对普通用户来说,写一封邮件、写一段自我介绍、列一个工作方案,都变得非常简单。可以说,这是 AI 写作的“第一次生产力释放”。
但问题也同时出现。由于所有人都调用类似的基座模型,使用类似的提示词模板,生成的文字开始出现明显的“大模型腔调”。很多文章开头都是“随着人工智能技术的快速发展”,正文喜欢用三段式展开,结尾再来一段“综上所述”。这种结构并不是不能用,而是当大量同质化内容进入平台,读者的注意力和平台的推荐机制都会自动做出筛选。低质量 AI 文本的流量红利,很快就会被稀释。
1.2 为什么会有“黄金时代结束”的体感
Ethan Mollick 所说的“第一个黄金时代结束”,我认为并不是指 AI 不能写作了,而是指靠“一键生成整篇内容”就能获得超额收益的阶段正在结束。这种体感来自几个非常实际的变化:
- 模型输出开始趋同。同一个问题给不同的大模型,得到的答案虽然措辞不同,但背后的逻辑结构和信息密度往往非常接近。
- 读者对模板化内容越来越敏感。纯粹由模型生成的“流水线文章”,很难建立专业信任。
- 平台和搜索引擎开始调整内容策略。低质量 AI 生成内容被降权已经不是新鲜事。
- 企业客户不再满足于“生成一篇文章”,他们更关心内容是否准确、是否符合品牌口径、能否和知识库结合、能不能被持续维护。
换句话说,早期那种“把模型当成自动写作机器”的粗放模式已经走到尽头。接下来拼的是人机协作的工程能力:谁能把素材整理、结构设计、生成、审校、修订这套流程做得更细,谁才能获得高质量、可沉淀的结果。
1.3 结束的不是 AI 写作,而是“无脑生成”
这个概念很重要。如果你只是让模型“随便写一篇 1000 字文章”,那么它大概率不会给你带来太多增量。但如果你把 AI 写作拆解成多个环节,让模型在每一个环节里只负责它擅长的事,情况就会不一样。
比如模型的优势在于:
- 根据素材快速生成多个候选标题;
- 把一篇长文压缩成大纲;
- 将一段口语化的解释改写成正式文档;
- 模拟不同身份和口吻进行改写;
- 对文章做逻辑检查和硬伤扫描。
人的优势则在于:
- 判断选题是否有价值;
- 提供真实项目经验和数据;
- 确认哪些素材可以公开引用;
- 决定内容的最终风格和立场;
- 对涉及安全、法律、利益相关的内容做最终把关。
所以,AI 写作的下半场不再是“谁生成的快”,而是“谁把生成过程管理得好”。这正是从生成式写作转向工程化写作的核心转变。
2. AI 写作的下半场:从生成式写作到工程化写作
2.1 AI 写作 2.0 的完整闭环
如果说 AI 写作 1.0 是“单次请求 + 单次生成”,那么 AI 写作 2.0 更像是“多阶段流水线 + 人在环上决策”。一个比较完整的闭环大致包括六个环节:
- 目标定义:明确文章写给谁、解决什么问题、希望读者做什么。
- 素材准备:收集可靠的资料、内部文档、业务数据,并过滤噪音。
- 结构设计:让模型先生成大纲,不要直接写全文。
- 分步草稿:按章节生成初稿,避免一次输出过长导致内容失控。
- 事实核查:针对数据、引文、产品功能等断言做单独校验。
- 人工修订:由作者整合上下文,加入只有人才知道的细节和判断。
这六步并不需要每次都由 AI 完成,也不需要每次都按同一顺序。但如果没有这个闭环,AI 写作就很容易停留在“生成一段看起来很像样的文字”,而不是“交付一篇可信、可发布、可维护的内容”。
2.2 关键能力拆解
从技术视角看,AI 写作 2.0 依赖几个关键能力,这也是最近 AI 应用开发里的热门方向:
- 提示词工程:不是把提示词写得越长越好,而是把角色、任务、限制条件、输出格式定义清楚。
- 检索增强生成(RAG):把外部知识库作为模型的临时上下文,减少模型凭空发挥的概率。
- 多智能体协作(Agent):让“编辑”“研究助理”“写手”“审核员”分别扮演不同角色,通过多次调用来完成任务。
- 结构化输出:用 JSON、Markdown 等格式约束模型输出,方便下游程序继续处理。
- 评估与护栏:对输出质量做规则检查和模型自评,尤其是事实类内容。
这些能力其实和 AI 编程工具的发展路径很像。早期 AI 编程也是“输入需求生成整个函数”,后来大家发现真正有用的方式是:先理解项目上下文,再生成小段代码,再由程序员 review,并接入测试和 CI。AI 写作也一样,只有把上下文、生成、审查拆开,才有可能在较长时间内稳定产出高质量内容。
2.3 对开发者的启发
如果你是一个正在做 AI 应用开发的工程师,这个趋势带来的启发是:不要只做一个“写作文本生成器”的壳,而是要做“写作基础设施”。
纯生成器很容易被模型迭代淘汰,但“数据管理、权限控制、人工审批、事实核验、格式发布”这些流程性能力,才是企业真正需要的壁垒。越来越多团队会把 AI 写作能力嵌入到编辑器、CMS、知识库、项目管理系统中,而不是单独做一个“输入标题生成文章”的网页。
换句话说,AI 写作已经从“模型能力调用”变成了“AI 工程实践问题”。你不仅要选模型,还要处理素材来源、提示词版本管理、成本控制、模型幻觉、内容审计等问题。这也是本文后续要用代码演示一套最小工作流的原因。
3. 环境准备:搭建一套可控的 AI 写作工作流
3.1 运行环境与依赖
下面我们用一个非常小的项目来演示“分角色 + 多阶段生成”的 AI 写作工作流。示例环境不依赖复杂框架,只需要:
- Python 3.9+;
- OpenAI Python SDK(或任意兼容 OpenAI Chat Completions 协议的 SDK);
- 一个可调用的大模型 API,并提前设置好环境变量。
版本需要根据你的项目实际情况调整。本文示例以常见的 OpenAI 兼容接口为例,重点演示设计思路,而不是绑定某个具体厂商或模型版本。
先创建项目依赖文件:
# requirements.txt openai>=1.0.0安装依赖:
pip install -r requirements.txt代码中读取以下环境变量:
LLM_API_KEY:API Key。LLM_BASE_URL:接口地址,默认使用 OpenAI 官方地址,如果使用其他兼容网关,请改成网关地址。LLM_MODEL:模型名称,默认示例为gpt-4o-mini,实际以你账号可用的模型为准。
在命令行中导出环境变量即可,不需要把密钥写进代码:
export LLM_API_KEY="你的 key" export LLM_BASE_URL="https://api.openai.com/v1" export LLM_MODEL="gpt-4o-mini"3.2 项目结构
为了让思路更清楚,我们把文件拆分为三个部分:
ai_writing_workflow/ ├── requirements.txt ├── llm.py # 封装大模型调用 ├── roles.py # 定义不同角色的系统提示词 └── main.py # 主流程:生成大纲、研究、草稿、复核不一定要使用多智能体框架,先用最直接的多阶段调用来演示。
3.3 统一的大模型客户端
我们没有把 API 调用散落在各个业务函数中,而是统一封装到一个llm.py文件里。这样后续如果要切换模型厂商、增加日志、统一鉴权,只需要改一个文件。
# llm.py import os from typing import Optional from openai import OpenAI _client: Optional[OpenAI] = None def get_client() -> OpenAI: """获取大模型客户端,避免重复创建连接。""" global _client if _client is None: _client = OpenAI( api_key=os.getenv("LLM_API_KEY"), base_url=os.getenv("LLM_BASE_URL", "https://api.openai.com/v1"), ) return _client def chat( system_prompt: str, user_prompt: str, temperature: float = 0.7, max_tokens: Optional[int] = None, ) -> str: """ 统一 chat 调用函数。 :param system_prompt: 系统角色提示词,用来定义行为边界。 :param user_prompt: 用户输入,通常是具体任务。 :param temperature: 控制随机性,事实核查场景可调低。 :param max_tokens: 输出最大 token 数,不传则由模型决定。 :return: 模型返回的文本内容。 """ messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ] response = get_client().chat.completions.create( model=os.getenv("LLM_MODEL", "gpt-4o-mini"), messages=messages, temperature=temperature, max_tokens=max_tokens, ) return response.choices[0].message.content这里有一个容易被忽略的点:temperature 参数不能全程用一个值。生成大纲时需要稳定,temperature 可以低一些;写初稿时希望有一定的词汇变化,可以稍微调高;做事实核查时则希望输出尽量保守,所以要调低。
3.4 角色化提示词定义
角色化提示词的目的是把复杂的写作任务拆给不同身份,让每个模型调用只负责单一职责。这样做有两个好处:一是提示词更短更稳定,二是中间结果更容易被人工检查和干预。
# roles.py SYSTEM_PROMPTS = { "editor": """你是一位严谨的技术编辑。你的任务不是直接写正文,而是把用户需求转成一份可执行的写作计划。 输出要求: 1. 明确读者画像与文章目标; 2. 给出文章大纲,层级不超过三级; 3. 标注哪些章节需要代码示例; 4. 如果存在不确定的事实论据,请标记“待核实”; 5. 不要编造数据、人物言论和版本信息。""", "researcher": """你是一位研究助理。你只能使用用户提供的素材或公认的通用知识来补充背景。 如果遇到无法确认的信息,你必须输出“待核实”,不要用模糊的语言敷衍。 你的输出会被后续写作步骤使用,请保持简洁,用列表组织关键点。""", "writer": """你是一位技术文章主笔。你根据编辑给的大纲和研究资料续写正文。 写作要求: - 多用具体示例解释原理,避免空泛论述; - 代码和配置使用 Markdown 代码块; - 不虚构运行结果,不替产品承诺未验证的特性; - 保留“风险提示”和“适用边界”; - 语言清晰自然,不要堆砌形容词。""", "reviewer": """你是一位事实核查编辑。请检查文章中出现的事实断言。 对每个断言,请输出: - 原文片段 - 类型(数据 / 人物 / 产品功能 / 技术特性) - 结论:SUPPORTED / UNCLEAR / UNSUPPORTED - 判断理由 如果当前上下文无法判断,请直接写“无法从当前上下文确认”,不要猜测。""", }你会发现,“reviewer”这个角色的任务和“writer”是完全相反的。写手要尽量让文章流畅完整,审核员则要逐条挑毛病。这种“对抗式”结构,比单一提示词让模型既写文章又自己检查要更可靠。
4. 实战:从“一键生成”改为“分角色流水线”
4.1 把写作过程拆成多个阶段
下面我们用代码演示一个最小可运行的流水线。它的核心思想是:
- 让模型先写“写作计划”;
- 再补充“研究资料”;
- 然后生成“初稿”;
- 最后做一次“事实核查”。
这种流程比“一次生成全文”多调用几次模型,但它带来了可控性:如果第一步的大纲方向不对,你不需要等全文生成完才发现问题。
4.2 主干流程代码
# main.py import os from llm import chat from roles import SYSTEM_PROMPTS def build_article(topic: str) -> dict: # 第一步:编辑生成文章大纲 outline = chat( SYSTEM_PROMPTS["editor"], f"请为主题《{topic}》创建一份技术文章写作计划。\n" f"读者画像:中高级开发者。\n" f"目标:读者阅读后能理解 AI 辅助写作工作流的核心思路。", temperature=0.3, ) # 第二步:研究助理补充背景和风险 research = chat( SYSTEM_PROMPTS["researcher"], f"下面是文章大纲:\n{outline}\n\n" f"请补充这个话题的行业背景、关键技术风险和常见误区。" f"如果没有可靠数据,请不要编造。", temperature=0.4, ) # 第三步:主笔根据大纲和研究资料写初稿 draft = chat( SYSTEM_PROMPTS["writer"], f"大纲如下:\n{outline}\n\n" f"研究资料如下:\n{research}\n\n" f"请完成一篇完整技术教程初稿,包含必要的代码示例。", temperature=0.6, max_tokens=3000, ) # 第四步:审核员对初稿做事实核查 review = chat( SYSTEM_PROMPTS["reviewer"], f"请审查以下文章初稿中的事实性断言:\n\n{draft}", temperature=0.1, max_tokens=1500, ) return { "topic": topic, "outline": outline, "research": research, "draft": draft, "review": review, } if __name__ == "__main__": result = build_article("AI 辅助写作的工程化工作流") os.makedirs("output", exist_ok=True) with open("output/draft.md", "w", encoding="utf-8") as f: f.write(result["draft"]) with open("output/review.txt", "w", encoding="utf-8") as f: f.write(result["review"]) print("草稿已写入 output/draft.md") print("事实核查意见已写入 output/review.txt")4.3 运行与验证
运行命令非常简单:
python main.py如果环境变量配置正确,目录output/下会生成draft.md和review.txt两个文件。draft.md是主笔生成的初稿,review.txt是审核员对初稿中事实断言的核查意见。
把这四步放在一个流程里,并不代表文章就可以直接发布。它真正的价值在于:模型把“写什么”“为什么写”“怎么写”“哪些地方可能有漏洞”都显性化了。你可以在进入下一步之前人工修正确实偏离的方向,而不是等生成完整篇长文再统一返工。
4.4 结果说明
这个流水线输出的结果有几个特点:
- 大纲和研究资料是分开保存的,方便查看模型是否理解了问题。
- 草稿生成时有明确的
max_tokens限制,防止长文输出中途不稳定。 - 审核结果不会自动修改草稿,而是把问题暴露给人类作者,由作者判断哪些内容保留、哪些删除。
这也是 AI 写作与 AI 编程的相似之处:模型可以先写代码,但最终是否合入主干,仍然需要人来做 code review。所谓“黄金时代结束”,其实是在说:靠初稿直接交付的阶段结束了,接下来是“人机一起做工程”的阶段。
5. 进阶:用本地素材检索降低 AI 幻觉
5.1 为什么需要 RAG 思路
如果只依赖模型内部知识写行业报告或产品文档,很容易出现 AI 幻觉:模型会把一个不存在的论文、API 或版本号写得很具体。解决思路之一,是把可靠的素材提前准备好,在生成之前先做一次检索,把相关片段拼进提示词,让模型“看着素材写”。
这就是 RAG(检索增强生成)的朴素想法。完整 RAG 通常包含向量库、Embedding、相关性召回等环节。本文不展开完整 RAG 架构,而是用一个极简的关键词检索来演示思路:先把素材库建好,再按标题或内容关键词召回片段,最后把它们放入提示词。
5.2 极简本地素材检索
# local_kb.py def build_material_lib(): """ 生产环境中,这个列表应该来自数据库、文档库或 API。 这里用列表只是演示结构。 """ return [ { "title": "人机协作写作模式", "content": "有效的 AI 辅助写作通常包含目标定义、资料检索、结构设计、分步初稿、人工修订和事实核查。模型负责扩展表达,人负责判断和最终决策。", }, { "title": "AI 写作 1.0 到 2.0 的变化", "content": "AI 写作 1.0 强调的是单次生成完整文章;AI 写作 2.0 强调多阶段流程、素材约束、角色拆分和质量审核。", }, ] def collect_context(material_lib, keywords, top_k=2): """ 用简单的关键词命中次数做召回。 真实系统可以使用向量检索或 BM25,这里演示可替换的接口设计。 """ matched = [] for item in material_lib: combined = item["title"] + " " + item["content"] hit_count = sum(1 for kw in keywords if kw and kw in combined) if hit_count > 0: matched.append((hit_count, item)) matched.sort(key=lambda x: x[0], reverse=True) return [item for _, item in matched[:top_k]]调用示例:
from local_kb import build_material_lib, collect_context material_lib = build_material_lib() contexts = collect_context( material_lib, keywords=["AI 写作", "人工修订"], top_k=2, ) for i, item in enumerate(contexts): print(f"素材 {i + 1}: {item['title']}")在真实项目中,使用关键词检索的效果通常不如向量检索,但它的代码逻辑非常简单,适合作为第一版。你可以把collect_context函数替换成“调用向量数据库接口”的实现,后续业务代码不需要大改。
5.3 一致性检查作为辅助护栏
除了检索增强,还可以用“模型自洽性检查”来辅助发现幻觉。思路是:对同一个问题用小温度多次提问,如果模型给出的答案彼此矛盾,就标记为“待人工核验”。
# consistency.py from llm import chat def consistency_check(question: str, times: int = 3) -> dict: answers = [] for _ in range(times): answer = chat( "你是一位严谨的助手,请用一句话回答问题。如果不确定,就回答“不确定”。", question, temperature=0.4, max_tokens=200, ) answers.append(answer.strip()) # 这里只是辅助信号,不能替代人工核验 unique_count = len(set(answers)) if unique_count > 1: return {"status": "needs_review", "answers": answers} return {"status": "preliminary_pass", "answers": answers} if __name__ == "__main__": result = consistency_check("RAG 的中文全称是什么?") print(result)这个检查并不完美:两个答案一致不一定代表正确,不一致也不一定代表错误。但在无法接入搜索引擎或人工专家的情况下,它仍然可以帮助你快速筛出“连模型自己都说不清楚”的内容,避免这类内容直接进入专业文章。
6. 常见问题与排查思路
6.1 常见问题清单
| 问题现象 | 可能原因 | 解决思路 |
|---|---|---|
| 生成文章千篇一律 | 提示词没有提供足够个性化上下文 | 加入素材、案例、写作风格样例;把生成任务拆小 |
| 文章出现事实错误 | 模型幻觉 | 关键数据接入 RAG;让审核角色标注待核实;最后人工核验 |
| API 返回格式不稳定 | 系统提示词没有明确输出格式 | 要求模型按 Markdown/JSON 输出;降低 temperature |
| 长文后半部分内容跑偏 | 一次生成过长 | 按大纲分章节生成,每章单独进入流程 |
| 同一批文章高度相似 | 模型缺少专属角色和素材约束 | 每个生成任务增加业务背景字段和禁止项 |
| 调用 API 报错 | Key、网关地址或模型名错误 | 检查环境变量;确认账号是否有对应模型权限 |
6.2 排查顺序建议
如果你在使用这套工作流时发现输出质量不理想,不要急着换模型,可以先按下面的顺序排查:
- 查看输入素材是否正确。素材缺失是最常见的问题,模型没有上下文时只能靠“脑补”。
- 查看系统提示词是否自相矛盾。比如既让模型“严格引用数据”,又没告诉它“没有数据时怎么办”。
- 查看不同阶段的 temperature。写草稿时可以稍微放飞,但编辑和审核必须稳定。
- 查看是否有中间产物。不要直接看最终长文,先看大纲是否准确、研究资料是否离题。
很多时候,AI 写作质量不高不是模型不够强,而是流程没有给模型足够的“支撑物”。
7. 工程化 AI 写作的最佳实践
7.1 把提示词当作代码来维护
提示词很容易越写越长、越改越乱。推荐做法是把提示词和代码一起纳入版本管理,像维护配置一样维护提示词。每次修改都要记录原因,比如“为了减少语气词,在写手角色中新增了禁止清单”。
如果你有多个写作场景,可以考虑把角色提示词拆成公共部分和业务部分。公共部分规定事实边界、输出格式、风险提示;业务部分规定特定领域的术语和风格,避免每个项目复制一大段相同控制逻辑。
7.2 重视人工审核和安全边界
AI 写作不能取消人工审核,尤其是涉及数据、人物言论、法律条款、业务流程的内容。更好的做法是,把审核从“事后看全文”变成“事前设约束、事中看中间结果、事后看断言清单”。
如果团队中有人负责内容发布,可以要求 AI 工作流把所有引用的事实断言单独输出成一张“待核实清单”。这样人工只需要检查清单,而不是重新理解整篇文章。
7.3 内容和数据的合规意识
在企业或面向公众的写作场景中,要特别注意三点:
- 不要把敏感的业务数据直接放入提示词,先确认是否有权限使用;
- 对外发布的内容要避免“模型编造引用”,所有引文必须有真实来源;
- 模型生成结果不应直接作为法律、医疗、金融等专业决策依据。
对开发者来说,这意味着你不能只关心“生成效果”,还要处理好审计日志、权限控制和数据脱敏。模型用得越多,内容安全治理就越需要提前设计。
7.4 从“工具链”走向“产品闭环”
最后一条建议是:不要停留在“能生成文章”的 demo,而要思考生成的内容如何进入用户的真实工作流。例如:
- 在编辑器里增加“段落改写”而不是“全文生成”;
- 在 CMS 里增加“发布前事实核查”按钮;
- 把常用的写作规范接入提示词,而不是让用户每次手写;
- 给历史生成结果做版本记录,方便回溯和复用。
这些能力会让 AI 写作系统从“一次性玩具”变成可以持续迭代的内容基础设施。
8. 写到最后
Ethan Mollick 所说的“AI 写作的第一个黄金时代已经结束”,更像是一个分水岭:靠模型自动生成整篇文章就能获得关注的时代正在过去,接下来是更考验产品设计、流程编排和内容判断力的阶段。
对内容创作者来说,需要学会把 AI 当成“可以快速产出初稿的协作对象”,而不是“一键生成结果的文字机器”。对开发者来说,则需要把精力放到上下文管理、角色拆分、事实核验、人工审核这些 AI 工程实践上。这些工作不像“写一个生成器”那样直观,但恰恰是长期价值所在。
如果你最近也在做 AI 辅助写作相关应用,不妨先从本文的“编辑—研究—写手—审核”四阶段流水线开始改造,看看把一次长文生成拆成几步之后,输出质量会发生什么变化。若这篇文章对你有帮助,可以先收藏备用;后续我再继续拆解更多 AI Agent 与内容工作流结合的落地方案。