AI GPT系列实践笔记

这次不搞那种"从原理到实践"的标准技术文档,就说说跟GPT打交道这几年踩过的坑、花过的钱、学到的东西。

很多人一上来就讲AI GPT系列的全景图;我更想先把这次卡住的点说清楚。

从GPT-1到GPT-3,到底变了什么

教科书会告诉你:GPT(Generative Pre-trained Transformer)是一种基于Transformer架构的生成式语言模型,通过在大规模文本语料上预训练,获得强大的文本生成能力。

但实际开发的时候,你感受到的变化更像是这样:

# GPT-2时代(2019年)
import openai
openai.api_key = "sk-xxx"

response = openai.Completion.create(
    engine="text-davinci-002",  # 那时候最好的模型
    prompt="写一段Python代码来解析JSON",
    max_tokens=100,
    temperature=0.7
)

print(response.choices[0].text)
# 输出大概这样:
# "这是一个JSON解析的例子,你可以这样写:
# import json
# data = json.loads('{"key": "value"}')
# print(data['key'])"

# 代码能跑,但经常缺参数、有错别字、或者把概念搞混

到了GPT-3时代,情况好了一些:

# GPT-3时代(2022年)
response = openai.Completion.create(
    engine="text-davinci-003",  # 比davinci-002强不少
    prompt="用Python写一个完整的REST API服务,包含用户注册、登录、JWT验证",
    max_tokens=500,
    temperature=0.3  # 降低温度,让输出更确定
)

# 这时候能生成比较完整的代码结构了,
# 但还是会缺imports、缺少必要的错误处理

GPT-3.5出来后,事情开始变得有点不一样了:

# GPT-3.5时代(2023年)
response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",  # Chat模式,对话能力更强
    messages=[
        {"role": "system", "content": "你是一个经验丰富的Python后端开发者"},
        {"role": "user", "content": "用FastAPI写一个完整的用户认证服务,包含注册、登录、JWT验证、密码重置"}
    ],
    temperature=0.1,  # 非常低的温度,确保输出稳定
    max_tokens=1000
)

# 这次生成的代码基本能跑,只需要少量修改

GPT-4就更不用说了,但价格也更贵了。

第一次实战:用GPT生成代码的坑

2022年的时候,公司让我搞一个自动化代码生成工具,用来生成一些重复性的CRUD代码。当时觉得GPT-3应该能搞定,结果踩了一堆坑。

第一个坑是上下文长度限制

# 最初的实现思路
def generate_crud_code(table_schema):
    prompt = f"""
    根据以下数据库表结构生成完整的CRUD代码:
    表名:{table_schema['name']}
    字段:
    {format_fields(table_schema['fields'])}

    要求:
    1. 使用FastAPI框架
    2. 包含SQLAlchemy模型
    3. 包含Pydantic schema
    4. 包含所有CRUD接口
    5. 包含输入验证和错误处理
    """

    response = openai.Completion.create(
        engine="text-davinci-003",
        prompt=prompt,
        max_tokens=2000  # 这里就是问题所在
    )

    return response.choices[0].text

问题在于,稍微复杂一点的表结构,prompt就超过了2000 tokens,GPT直接返回错误。而且生成的代码经常只有一半,后面的被截断了。

解决办法是拆分任务:

def generate_crud_code(table_schema):
    # 分步骤生成
    # 1. 生成数据模型
    model_code = generate_with_retry(
        prompt=f"根据表结构生成SQLAlchemy模型:{format_schema(table_schema)}",
        max_tokens=800
    )

    # 2. 生成Pydantic schema
    schema_code = generate_with_retry(
        prompt=f"根据表结构生成Pydantic schema:{format_schema(table_schema)}",
        max_tokens=600
    )

    # 3. 生成API路由
    route_code = generate_with_retry(
        prompt=f"""
        基于以下模型和schema生成FastAPI CRUD接口:
        模型:{model_code}
        Schema:{schema_code}
        """,
        max_tokens=1200
    )

    return combine_code(model_code, schema_code, route_code)

第二个坑是代码质量不稳定

同样的prompt,有时候生成完美代码,有时候生成一堆bug。测试后发现几个影响因素:

  1. temperature参数:太高会"太有创意",太低会"太死板"
  2. prompt工程:细微的措辞差异会严重影响输出
  3. 随机性:即使temperature=0,OpenAI内部还是有一些随机性

最终我们采用了多重生成+投票的策略:

def generate_with_consensus(prompt, num_attempts=3):
    candidates = []
    for i in range(num_attempts):
        try:
            response = openai.Completion.create(
                engine="text-davinci-003",
                prompt=prompt,
                temperature=0.1 + i * 0.1,  # 尝试不同温度
                max_tokens=1000
            )
            candidates.append(response.choices[0].text)
        except Exception as e:
            log.error(f"生成失败,尝试{i+1}/{num_attempts}", e)
            continue

    if not candidates:
        raise GenerationError("所有尝试都失败了")

    # 简单的投票机制:选择最长且能通过语法检查的
    valid_candidates = [c for c in candidates if is_valid_python(c)]
    if not valid_candidates:
        return candidates[0]  # 回退到第一个

    return max(valid_candidates, key=len)

GPT-4时代:更聪明但也更贵

2023年GPT-4发布后,我们第一时间试用。效果确实好很多,但价格也涨了10倍。

# GPT-4调用示例
def generate_complex_solution(problem_description):
    response = openai.ChatCompletion.create(
        model="gpt-4",  # 比gpt-3.5-turbo贵10倍
        messages=[
            {
                "role": "system",
                "content": "你是一个资深软件架构师,擅长解决复杂的系统设计问题"
            },
            {
                "role": "user",
                "content": f"""
                设计一个高并发的订单系统,要求:
                1. 支持每秒10万订单
                2. 保证数据一致性
                3. 支持水平扩展
                4. 包含完整的监控和告警

                具体需求:{problem_description}
                """
            }
        ],
        temperature=0.2,
        max_tokens=2000
    )

    return response.choices[0].message['content']

GPT-4的优势:

  1. 逻辑推理能力更强:复杂架构设计能给出更合理的方案
  2. 代码质量更稳定:生成的代码更少bug
  3. 上下文理解更好:能理解更长的prompt和更复杂的需求

但问题也很明显:

  1. 太贵了:批量生成代码时成本很高
  2. 速度慢:响应时间比GPT-3.5慢很多
  3. quota限制:免费账户的调用次数有限

我们最终采用的策略是混合使用:

def smart_generate(prompt, complexity="medium"):
    """
    根据任务复杂度选择模型
    complexity: simple -> gpt-3.5-turbo
                 medium -> gpt-3.5-turbo + 重试
                 complex -> gpt-4
    """
    if complexity == "simple":
        model = "gpt-3.5-turbo"
        retries = 1
    elif complexity == "medium":
        model = "gpt-3.5-turbo"
        retries = 3
    else:  # complex
        model = "gpt-4"
        retries = 2

    for attempt in range(retries):
        try:
            response = openai.ChatCompletion.create(
                model=model,
                messages=[{"role": "user", "content": prompt}],
                temperature=0.1 if model == "gpt-4" else 0.2,
                max_tokens=1500
            )
            return response.choices[0].message['content']
        except RateLimitError:
            if attempt < retries - 1:
                time.sleep(2 ** attempt)  # 指数退避
            else:
                raise
        except Exception as e:
            log.error(f"生成失败,尝试{attempt+1}/{retries}", e)
            if attempt == retries - 1:
                raise

实际项目中的踩坑记录

坑1:GPT会"产生幻觉"

这是最危险的问题。GPT会一本正经地胡说八道。

# 错误示例
prompt = "用Python写一个连接到 nonexistent_database_driver 的代码"
response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": prompt}]
)

# GPT可能会生成这样的代码:
"""
import nonexistent_database_driver  # 这个库根本不存在!

conn = nonexistent_database_driver.connect(
    host="localhost",
    port=5432,
    database="mydb"
)
"""

解决办法:

  1. 代码验证:生成代码后一定要做语法检查和简单的逻辑验证
  2. 事实核查:涉及具体库、API、版本号时,要人工核实
  3. 限制范围:在prompt中明确限制使用已验证的库和框架
def safe_generate_code(prompt, allowed_libraries=None):
    if allowed_libraries is None:
        allowed_libraries = ["fastapi", "sqlalchemy", "pydantic", "requests"]

    constrained_prompt = f"""
    {prompt}

    重要约束:
    1. 只能使用这些Python库:{', '.join(allowed_libraries)}
    2. 不要引入任何其他第三方库
    3. 如果需要标准库外的功能,明确说明并给出替代方案
    """

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": constrained_prompt}]
    )

    code = response.choices[0].message['content']

    # 验证生成的代码
    if not validate_code_libraries(code, allowed_libraries):
        raise ValueError("生成的代码包含不允许的库")

    return code

坑2:上下文窗口的限制

即使GPT-4支持32K tokens,实际项目中还是经常不够用。

# 尝试分析大型代码库
def analyze_large_codebase(file_paths):
    all_code = ""
    for path in file_paths:
        with open(path, 'r') as f:
            all_code += f.read() + "\n"

    # 这里大概率会超token限制
    response = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[{
            "role": "user",
            "content": f"分析以下代码的架构问题:\n{all_code}"
        }]
    )

解决办法是分块处理:

def analyze_large_codebase(file_paths):
    # 1. 先生成代码摘要
    summaries = []
    for path in file_paths:
        with open(path, 'r') as f:
            code = f.read()
            summary = generate_summary(f"文件:{path}\n代码:{code[:2000]}")
            summaries.append(f"{path}: {summary}")

    # 2. 基于摘要进行分析
    combined_summary = "\n".join(summaries)
    analysis = analyze_architecture(f"代码库摘要:\n{combined_summary}")

    return analysis

坑3:成本控制失控

一开始没注意成本控制,结果一个月下来API账单吓人。

# 成本监控中间件
class CostMonitor:
    def __init__(self, budget_limit=100):
        self.daily_cost = 0
        self.budget_limit = budget_limit  # 美元
        self.reset_time = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

    def track_api_call(self, model, tokens_used):
        # 价格表(每1K tokens的价格,美元)
        prices = {
            "gpt-3.5-turbo": 0.002,
            "gpt-4": 0.03,
            "gpt-4-32k": 0.06
        }

        cost = (tokens_used / 1000) * prices.get(model, 0.01)
        self.daily_cost += cost

        # 检查是否超预算
        if self.daily_cost > self.budget_limit:
            raise BudgetExceededError(
                f"日预算已超限:${self.daily_cost:.2f} > ${self.budget_limit}"
            )

        return cost

    def reset_if_new_day(self):
        now = datetime.now()
        if now > self.reset_time + timedelta(days=1):
            self.daily_cost = 0
            self.reset_time = now.replace(hour=0, minute=0, second=0, microsecond=0)

# 使用
cost_monitor = CostMonitor(budget_limit=50)

def safe_api_call(model, messages):
    cost_monitor.reset_if_new_day()

    try:
        response = openai.ChatCompletion.create(
            model=model,
            messages=messages
        )

        # 计算token使用量
        tokens_used = response['usage']['total_tokens']
        cost = cost_monitor.track_api_call(model, tokens_used)

        log.info(f"API调用成功,花费:${cost:.4f}")

        return response.choices[0].message['content']

    except BudgetExceededError as e:
        log.error(f"预算超限:{e}")
        raise

从GPT-1到GPT-4的演进思考

这几年用下来,最大的感受是:参数量的增长只是表象,真正的进步在理解和推理能力

graph LR A[GPT-1] -->|1.17亿参数| B[GPT-2] B -->|15亿参数| C[GPT-3] C -->|1750亿参数| D[GPT-3.5] D -->|估计1.8万亿参数| E[GPT-4] A -.->|基础文本生成| F[能力演进] B -.->|少样本学习| F C -.->|零样本学习| F D -.->|对话能力| F E -.->|复杂推理| F

实际开发中的变化:

  1. prompt工程越来越重要:GPT-1时代prompt几乎无所谓,GPT-4时代prompt好坏决定输出质量
  2. 成本意识越来越强:从"随便用"到"精打细算"
  3. 质量要求越来越高:从"能生成就行"到"要能直接用"
  4. 应用场景越来越广:从文案生成到代码生成、架构设计、debug

一些实用的经验和建议

基于这几年的踩坑经历,给几个实用建议:

  1. 从简单任务开始:不要一开始就指望GPT解决复杂问题
  2. 建立验证机制:永远不要相信GPT输出的代码不经验证就上线
  3. 控制成本:设置预算上限,监控API使用量
  4. 利用缓存:相似问题的结果可以缓存,避免重复调用
  5. 人工review:GPT是助手,不是替代品
# 带缓存的智能代码生成
from functools import lru_cache
import hashlib

class CachedCodeGenerator:
    def __init__(self):
        self.cache = {}

    def _get_cache_key(self, prompt):
        return hashlib.md5(prompt.encode()).hexdigest()

    @lru_cache(maxsize=100)
    def generate(self, prompt, complexity="medium"):
        cache_key = self._get_cache_key(prompt)

        if cache_key in self.cache:
            log.info("命中缓存")
            return self.cache[cache_key]

        try:
            result = smart_generate(prompt, complexity)
            self.cache[cache_key] = result
            return result
        except Exception as e:
            log.error(f"生成失败:{e}")
            raise

# 使用
generator = CachedCodeGenerator()
code = generator.generate("写一个FastAPI的JWT认证中间件", "medium")

未来的一些思考

GPT-5会是什么样?老实说,没人知道。但根据这几年的趋势,可以大胆预测一下:

  1. 上下文窗口会更大:可能直接支持100K+ tokens
  2. 多模态能力会更强:不只是文本,图像、音频、视频都能处理
  3. 推理能力会更深:复杂问题不再需要拆解成多个步骤
  4. 成本会更低:竞争加剧,价格战不可避免

但无论如何,有一个原则不会变:AI是工具,不是目的

技术最终要解决实际问题。GPT再强大,如果只是用来写博客、聊天、生成一些没用的代码,那它就只是一个昂贵的玩具。真正有价值的是把AI的能力融入到实际的工作流程中,提高效率、降低成本、解决问题。

就像这次写这篇文章,我用GPT帮我整理了一些思路、生成了一些代码示例,但最终的内容还是我自己的判断、自己的经验、自己的表达风格。AI可以辅助,但不能替代。


跟GPT打交道这几年,花了不少钱,也踩了不少坑。但总体来说,这个技术确实改变了工作方式。以前写代码要自己想、自己写、自己debug,现在是让GPT想、让GPT写、自己review和debug。效率确实提高了,但也带来了新的挑战:如何更好地利用AI、如何控制成本、如何保证质量。这些都是需要在实践中不断摸索的。

版权声明: 本文首发于 指尖魔法屋-AI GPT系列实践笔记https://blog.thinkmoon.cn/post/252-ai-gpt-series-evolution-gpt1-to-gpt4/) 转载或引用必须申明原指尖魔法屋来源及源地址!