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。测试后发现几个影响因素:
- temperature参数:太高会"太有创意",太低会"太死板"
- prompt工程:细微的措辞差异会严重影响输出
- 随机性:即使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的优势:
- 逻辑推理能力更强:复杂架构设计能给出更合理的方案
- 代码质量更稳定:生成的代码更少bug
- 上下文理解更好:能理解更长的prompt和更复杂的需求
但问题也很明显:
- 太贵了:批量生成代码时成本很高
- 速度慢:响应时间比GPT-3.5慢很多
- 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"
)
"""
解决办法:
- 代码验证:生成代码后一定要做语法检查和简单的逻辑验证
- 事实核查:涉及具体库、API、版本号时,要人工核实
- 限制范围:在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的演进思考
这几年用下来,最大的感受是:参数量的增长只是表象,真正的进步在理解和推理能力。
实际开发中的变化:
- prompt工程越来越重要:GPT-1时代prompt几乎无所谓,GPT-4时代prompt好坏决定输出质量
- 成本意识越来越强:从"随便用"到"精打细算"
- 质量要求越来越高:从"能生成就行"到"要能直接用"
- 应用场景越来越广:从文案生成到代码生成、架构设计、debug
一些实用的经验和建议
基于这几年的踩坑经历,给几个实用建议:
- 从简单任务开始:不要一开始就指望GPT解决复杂问题
- 建立验证机制:永远不要相信GPT输出的代码不经验证就上线
- 控制成本:设置预算上限,监控API使用量
- 利用缓存:相似问题的结果可以缓存,避免重复调用
- 人工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会是什么样?老实说,没人知道。但根据这几年的趋势,可以大胆预测一下:
- 上下文窗口会更大:可能直接支持100K+ tokens
- 多模态能力会更强:不只是文本,图像、音频、视频都能处理
- 推理能力会更深:复杂问题不再需要拆解成多个步骤
- 成本会更低:竞争加剧,价格战不可避免
但无论如何,有一个原则不会变: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/) 转载或引用必须申明原指尖魔法屋来源及源地址!
评论
使用 GitHub 账号登录后即可留言,支持 Markdown。