点击开始动手实验


ChatGPT写作指令实战指南:从Prompt设计到生产环境部署

背景痛点:为什么“一句话Prompt”总翻车

第一次把需求直接甩给ChatGPT时,我得到的是一篇“看起来对、读起来飘”的软文:品牌调性不对、数据胡编、结尾还自带“作为一款AI语言模型”的免责声明。
训模型不如训自己,问题根源在原始Prompt

  • 没有角色锚点,模型默认“万能助手”口吻,输出风格随机漂移
  • 缺少负样本,幻觉数据无法提前拦截
  • 单轮交互,上下文窗口只有一句话,模型只能“猜”背景
  • 无参数约束,temperature=1 时创意爆棚,事实也跟着放飞

一句话总结:Prompt越短,不确定性越长。要把ChatGPT从“灵感玩具”变成“写作产线”,得先把它当接口而不是聊天框。


技术方案:把Prompt拆成“乐高”再拼回去

1. 单轮 vs 多轮:一次问完≠高效
模式 优点 缺点 适用场景
单轮 代码简单、延迟低 上下文少、风格难控 标题生成、短摘要
多轮 可追加约束、实时纠偏 Token翻倍、工程复杂 品牌故事、白皮书、深度稿

经验:把“多轮”拆成**“三段式”**——System 设角色、User 提需求、Assistant 返草稿,再下一轮 User 给批改,两轮即可把一致性提升 40% 以上。

2. 角色指令设计:System/User/Assistant 的黄金分工
  • System:写“隐形导演脚本”,规定格式、风格、禁区和输出结构
  • User:只放“可变参数”,如主题、受众、字数、关键词
  • Assistant:留空占位,让模型先吐草稿,方便二次修正

示例(System 片段)

你是「极客时间」专栏作者,语言简洁、数据准确、拒绝口语化;  
输出必须包含「导语」「三个段落」「结语」;  
禁止出现“人工智能”“AI”字样,用“模型”指代。

把角色写进 System,可复用且不占每次 Token,比把所有话塞 User 消息省 15% 成本。

3. Python 封装:异步 + 重试,一次写好不用凌晨起床

核心思路:

  • 用 Pydantic 把 Prompt 变量做成类型类,模板与参数解耦
  • 异步调用 aiohttp,超时/速率限制自动退避
  • 返回结构体自带 token 用量,方便写监控

核心代码:Prompt 模板类 + 关键参数

# prompt_builder.py
from __future__ import annotations
import asyncio, backoff, openai
from pydantic import BaseModel, Field
from typing import List, Optional

class WritingVars(BaseModel):
    topic: str
    audience: str = "开发者"
    words: int = Field(1200, ge=800, le=3000)
    tone: str = "技术干货"
    refs: Optional[List[str]] = None

class PromptTemplate:
    SYSTEM = """\
You are a senior technical editor.
Rules:
1. Output in Markdown, use ## for section headers.
2. Data > adjectives; cite sources if numbers appear.
3. Do forbidden to mention "AI" or "人工智能", use "模型".
4. Respond in Chinese unless asked otherwise."""
    
    USER_TPL = """\
Topic: {topic}
Audience: {audience}
Tone: {tone}
Approx {words} words.
{Citations}"""

    @staticmethod
    def render(var: WritingVars) -> List[dict]:
        citations = "\n".join(f"- {r}" for r in var.refs) if var.refs else ""
        user_msg = PromptTemplate.USER_TPL.format(
            topic=var.topic,
            audience=var.audience,
            tone=var.tone,
            words=var.words,
            Citations=citations
        )
        return [
            {"role": "system", "content": PromptTemplate.SYSTEM},
            {"role": "user", "content": user_msg}
        ]

@backoff.on_exception(backoff.expo, openai.RateLimitError, max_time=60)
async def call_chatgpt(messages: List[dict], temp: float = 0.7, stop: List[str] = None):
    stop = stop or ["## 结语"]  # 提前结束,防止乱发散
    res = await openai.ChatCompletion.acreate(
        model="gpt-3.5-turbo",
        messages=messages,
        temperature=temp,
        max_tokens=2000,
        stop=stop
    )
    return res.choices[0].message.content, res.usage

# 使用示例
async def main():
    var = WritingVars(topic="ChatGPT写作指令实战", refs=["openai.com/docs"])
    messages = PromptTemplate.render(var)
    content, usage = await call_chatgpt(messages, temp=0.3)
    print(content, usage)

if __name__ == "__main__":
    asyncio.run(main())

要点解读

  • temperature=0.3 兼顾事实与可读性;创意写作可上调到 0.8
  • stop 序列强制模型在“## 结语”处停,减少尾部车轱辘话
  • 返回 usage,为后续成本监控埋点

生产考量:钱包和内容都要守住

1. 成本控制:实时 Token 监控

在调用层加一层装饰器,把 usage 总数字写到 Prometheus:

# cost_tracker.py
from prometheus_client import Counter, Histogram
TOKEN_COUNTER = Counter("gpt_tokens_total", "Cumulative tokens", ["model"])
async def track_cost(coroutine):
    text, usage = await coroutine
    TOKEN_COUNTER.labels(model=usage.model).inc(usage.total_tokens)
    return text, usage

每日对账:Token 量 × 模型单价 = 实际花费,报警阈值按周预算 80% 触发。

2. 安全防护:先过滤再发布

正则模板拦截常见幻觉句式:

import re
HALLUCINATION_RE = re.compile(
    r"(作为AI语言模型|我无法|我的知识截至|以上内容由AI生成)", flags=re.I)
def safety_filter(text: str) -> str:
    if HALLUCINATION_RE.search(text):
        raise ValueError("Hallucination pattern detected")
    return text

搭配敏感词库 + 百度/火山文本审核 API,双层过滤,比纯规则少误杀 30%。


避坑指南:把“坑”写成文档,后人好乘凉

  1. 长文本截断
    先按 \n\n 分段,chunk 长度 ≤1k token,再顺序调用;每段继承上一段最后 50 token 做 overlap,保证上下文连贯。

  2. 指令冲突
    给变量加命名空间,如 {{brand_tone}}{{seo_keywords}},避免与系统保留字撞车;模板渲染前做双重花括号转义。

  3. 异步并发
    官方默认 3~5 rps,超了会 429;用 asyncio.Semaphore(3) 限流,比官方推荐 tenacity 退避策略更省等待时间。


延伸思考:Prompt 也能“自生长”

  • 动态 few-shot learning:根据用户实时反馈,把高赞段落自动加入下轮示例池,实现“越写越懂你”
  • A/B Prompt:同时跑两条 System 指令,按 CTR 或完读率挑优胜,再灰度上线,持续迭代
  • Prompt 压缩:用微调模型把冗长 System 指令压缩成 100 个隐藏 token,省成本 15% 以上,适合超大并发场景

写在最后:把实验精神带回豆包

写完这篇,我对“角色+变量+监控”三位一体的套路更有信心了。若你也想亲手搭一条实时语音对话产线,不妨换个赛道继续折腾——从0打造个人豆包实时通话AI 这个动手实验,把 ASR→LLM→TTS 串成一条可运行的小程序,本地起服务后,对着笔记本喊一句就能听见“豆包”秒回。代码全开源,步骤带 UI,我这种非语音专业选手也能在一晚上跑通。Prompt 工程的经验同样适用:把 System 人设提前灌好,再让豆包开口,音色和答案一样稳。祝各位写代码、写文字、写对话都能“一句到位”。

点击开始动手实验


Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐