Skip to content

GPTGenDesk - OpenAI Completions API 实现指南

概述

GPTGenDesk 是基于 OpenAI Completions API 的 DeskLLM 实现,提供纯文本生成能力。Completions API 是 OpenAI 的传统接口,支持停止词(stop words),但不支持指令(instructions)字段。

模型支持

可用模型

模型名称 上下文窗口 特点
gpt-3.5-turbo-instruct 4K 唯一可用的 Completions 模型

⚠️ 重要说明:OpenAI 已不再推出新的 Completions 模型,gpt-3.5-turbo-instruct 是目前唯一可用的模型。

GPTDesk vs GPTGenDesk

特性 GPTDesk GPTGenDesk
API 类型 Responses API Completions API
Instructions ✅ 支持 ❌ 不支持
停止词 ❌ 不支持 ✅ 支持(最多 4 个)
模型支持 最新模型(gpt-4o 等) 旧版模型(gpt-3.5-turbo-instruct)
结构化输出 ✅ 支持 ❌ 不支持
多模态 ✅ 支持 ❌ 不支持

选择建议

# ✅ 大多数情况下,推荐使用 GPTDesk
from tfrobot.brain.chain.llms.generation_llms.desk_llm.openai_desk import GPTDesk

desk_llm = GPTDesk(name="gpt-4o")

# ⚠️ 仅在需要停止词时使用 GPTGenDesk
from tfrobot.brain.chain.llms.generation_llms.desk_llm.openai_gen_desk import GPTGenDesk

desk_llm = GPTGenDesk(name="gpt-3.5-turbo-instruct")

快速开始

基本使用

from tfrobot.brain.chain.llms.generation_llms.desk_llm.openai_gen_desk import GPTGenDesk
from tfrobot.brain.chain.prompt.memo_prompt import MemoPrompt
from tfrobot.schema.message.conversation.message_dto import TextMessage

# 创建 GPTGenDesk 实例
desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    openai_api_key="your_api_key"
)

# 配置系统提示
desk_llm.system_prompt = [
    MemoPrompt(template="你是一个专业的代码助手,擅长 Python 开发。")
]

# 调用
result = desk_llm.complete(
    current_input=TextMessage(content="帮我写一个快速排序函数")
)
print(result.generations[0].text)

配置 API 密钥

通过环境变量配置(推荐):

export OPENAI_API_KEY="your_api_key"

或直接传入:

desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    openai_api_key="your_api_key"
)

核心参数

模型参数

参数 类型 默认值 说明
name str gpt-3.5-turbo-instruct 模型名称
max_tokens int - 最大生成 tokens 数
temperature float 1.0 采样温度(0-2)
top_p float 1.0 核采样参数
stop str\|list[str] - 停止词列表(最多 4 个)
stream bool False 是否流式处理
timeout int 180 请求超时时间(秒)
user str - 用户 ID,用于监控和检测滥用

网络配置

参数 类型 默认值 说明
openai_api_key str 环境变量 OpenAI API 密钥
proxy_host str - 代理地址
proxy_port int - 代理端口
proxy_user str - 代理用户名
proxy_pass str - 代理密码

特殊功能

停止词支持

GPTGenDesk 支持最多 4 个停止词

from tfrobot.brain.chain.llms.generation_llms.desk_llm.openai_gen_desk import GPTGenDesk

desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["```", "END", "\n\n"]  # 最多 4 个
)

desk_llm.purpose_prompt = [
    MemoPrompt(template="生成一个 Python 快速排序函数。")
]

result = desk_llm.complete(current_input=TextMessage(content="开始"))
# 模型在遇到 "```" 或 "END" 或 "\n\n" 时会停止生成

ToolPrompt 停止词整合

GPTGenDesk 会自动整合 ToolPrompt 的停止词:

from tfrobot.brain.chain.prompt.tool_prompt import ToolPrompt

desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["```"]  # 用户定义的停止词
)

# ToolPrompt 也有停止词
tool_prompt = ToolPrompt()
tool_prompt.stop_words = ["END", "STOP"]

desk_llm.system_prompt = [tool_prompt]

# 最终的停止词会整合用户定义的和 ToolPrompt 的
# 最终:["```", "END", "STOP"]

使用场景

使用停止词控制输出

desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["```"]
)

# 生成代码块
desk_llm.purpose_prompt = [
    MemoPrompt(template="生成一个 Python 快速排序函数。")
]

desk_llm.prefix_prompt = [
    MemoPrompt(template="```python\n")
]

result = desk_llm.complete(current_input=TextMessage(content="开始"))
# 输出会在遇到 "```" 时停止,自动闭合代码块

多个停止词

desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["```", "END", "DONE", "\n\n"]  # 最多 4 个
)

# 模型会在遇到任何一个停止词时停止生成

代码生成

desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["```"],
    temperature=0.0  # 确定性输出
)

desk_llm.system_prompt = [
    MemoPrompt(template="你是一个 Python 专家,编写高质量、有文档的代码。")
]

desk_llm.purpose_prompt = [
    MemoPrompt(template="创建一个 Person 数据类,包含 name 和 age 属性。")
]

desk_llm.prefix_prompt = [
    MemoPrompt(template="```python\nfrom dataclasses import dataclass\n\n")
]

result = desk_llm.complete(current_input=TextMessage(content="开始生成"))
print(result.generations[0].text)

代理配置

HTTP 代理

desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    proxy_host="127.0.0.1",
    proxy_port=7890
)

带认证的代理

desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    proxy_host="proxy.company.com",
    proxy_port=8080,
    proxy_user="username",
    proxy_pass="password"
)

错误处理

上下文超长

GPTGenDesk 会自动检测并处理上下文超长错误:

from tfrobot.schema.exceptions import ContextTooLargeError

try:
    result = desk_llm.complete(current_input=very_long_input)
except ContextTooLargeError as e:
    print(f"当前大小: {e.current_size} tokens")
    print(f"目标大小: {e.target_size} tokens")
    print(f"模型: {e.model_name}")
    # 由 Chain 层自动处理上下文压缩

速率限制(TPM)

GPTGenDesk 还会检测 TPM(Tokens Per Minute)速率限制:

try:
    result = desk_llm.complete(current_input=large_input)
except ContextTooLargeError as e:
    # 如果是 TPM 限制
    if "rate limit exceeded (TPM)" in str(e):
        print("TPM 速率限制,请减少请求频率或降低 token 数量")

重试机制

GPTGenDesk 使用 tenacity 实现自动重试:

  • 重试条件:APITimeoutError, APIConnectionError
  • 重试次数:3 次
  • 重试策略:指数退避(4s, 8s, 10s)
import logging

# 配置日志记录重试
logging.basicConfig(level=logging.WARNING)

高级用法

多轮编辑

desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["```"]
)

# 初始代码
original_code = """
def add(a, b):
    return a + b
"""

desk_llm.original_desk_screenshot_prompt = [
    MemoPrompt(template=f"原始代码:\n```python\n{original_code}\n```")
]

# 第一轮:添加类型注解
desk_llm.purpose_prompt = [
    MemoPrompt(template="添加类型注解。")
]

result1 = desk_llm.complete(current_input=TextMessage(content="开始编辑"))
current_code = result1.generations[0].text

# 第二轮:添加文档字符串
desk_llm.current_desk_screenshot_prompt = [
    MemoPrompt(template=f"当前代码:\n```python\n{current_code}\n```")
]

desk_llm.intermediate_prompt = [
    MemoPrompt(template="已添加类型注解。")
]

desk_llm.purpose_prompt = [
    MemoPrompt(template="添加文档字符串。")
]

result2 = desk_llm.complete(current_input=TextMessage(content="继续编辑"))
print(result2.generations[0].text)

使用停止词提取 JSON

desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["}"]  # 在遇到 } 时停止
)

desk_llm.purpose_prompt = [
    MemoPrompt(template="生成一个 JSON 对象,包含 name 和 age 字段。")
]

desk_llm.prefix_prompt = [
    MemoPrompt(template="{")
]

result = desk_llm.complete(current_input=TextMessage(content="开始"))

# 手动添加停止词
json_str = result.generations[0].text + "}"

import json
data = json.loads(json_str)
print(data)

异步调用

import asyncio

async def generate():
    desk_llm = GPTGenDesk(name="gpt-3.5-turbo-instruct")
    result = await desk_llm.async_complete(
        current_input=TextMessage(content="生成代码")
    )
    return result.generations[0].text

result = asyncio.run(generate())

最佳实践

1. 合理使用停止词

# ✅ 好的做法:使用明确的停止词
desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["```"]
)

# ❌ 不好的做法:使用太多停止词(最多 4 个)
desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["```", "END", "DONE", "STOP", "FINISH"]  # 超过 4 个会被截断
)

2. 控制温度

# 确定性输出(代码生成)
desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    temperature=0.0
)

# 创造性输出(文案创作)
desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    temperature=1.2
)

3. 限制上下文长度

# gpt-3.5-turbo-instruct 的上下文窗口只有 4K
desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    max_tokens=1024  # 留出足够空间给输入
)

4. 考虑使用 GPTDesk

# 如果不需要停止词,推荐使用 GPTDesk
from tfrobot.brain.chain.llms.generation_llms.desk_llm.openai_desk import GPTDesk

desk_llm = GPTDesk(name="gpt-4o")

性能优化

1. 减少 Token 消耗

# 限制输出长度
desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    max_tokens=512
)

2. 使用低温度

# 低温度可以减少无效输出
desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    temperature=0.0
)

3. 异步调用

# 使用异步调用提高吞吐量
async def batch_generate():
    desk_llm = GPTGenDesk(name="gpt-3.5-turbo-instruct")
    tasks = [
        desk_llm.async_complete(current_input=TextMessage(content=f"任务 {i}"))
        for i in range(10)
    ]
    results = await asyncio.gather(*tasks)
    return results

注意事项

1. 模型限制

# ⚠️ gpt-3.5-turbo-instruct 是唯一可用的 Completions 模型
desk_llm = GPTGenDesk(name="gpt-3.5-turbo-instruct")

# ❌ 以下模型不支持 Completions API
# desk_llm = GPTGenDesk(name="gpt-4o")  # 会报错
# desk_llm = GPTGenDesk(name="gpt-4-turbo")  # 会报错

2. 上下文窗口小

# gpt-3.5-turbo-instruct 的上下文窗口只有 4K
# 如果输入过长,会抛出 ContextTooLargeError

from tfrobot.schema.exceptions import ContextTooLargeError

try:
    result = desk_llm.complete(current_input=long_input)
except ContextTooLargeError as e:
    print(f"上下文超长:{e.target_size} tokens")
    # 由 Chain 层自动处理压缩

3. 停止词限制

# 最多 4 个停止词
desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["stop1", "stop2", "stop3", "stop4"]  # ✅ 最多 4 个
)

# 超过 4 个会被截断
desk_llm = GPTGenDesk(
    name="gpt-3.5-turbo-instruct",
    stop=["stop1", "stop2", "stop3", "stop4", "stop5"]  # ⚠️ 第 5 个会被忽略
)

相关文档