AI Engineering Academy · 课时

聊天补全端点

理解包含系统、用户和助手角色的消息数组,编写您的第一个提示词,并解读 API 返回的响应对象。

第 2 / 4 课13 个步骤

聊天补全端点 是 CoddyKit 上的免费 AI Engineering Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Engineering Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Engineering Academy 课程共包含 4 节课。

消息数组架构

聊天补全接口基于消息数组运行:这是一个由多轮对话组成的列表,每一轮都带有角色(系统、用户或助手)。模型没有状态,因此您每次都必须发送完整的历史记录。

from openai import OpenAI

client = OpenAI()

response = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[
        {'role': 'system', 'content': 'You are a concise Python tutor.'},
        {'role': 'user', 'content': 'What is a list comprehension?'}
    ]
)

print(response.choices[0].message.content)

系统角色:定义行为

系统消息是您最重要的控制手段。它会在用户输入任何内容之前设定模型的角色、规则和格式。请在这里投入时间,因为它会影响后续的一切。请查看代码。

system_prompt = '''You are a customer support agent for TechShop.
You help customers with: order tracking, returns, and product questions.
You do NOT discuss pricing changes or competitor products.
Always respond in 2-3 sentences maximum.
If you cannot help, say: 'Let me connect you with a human agent.'
'''

response = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[
        {'role': 'system', 'content': system_prompt},
        {'role': 'user', 'content': 'Where is my order #12345?'}
    ]
)

管理多轮对话

要让对话持续下去,您需要将每一轮追加到消息数组中,然后重新发送全部消息。模型之所以看起来像是记得之前的内容,是因为您每次都把完整历史记录提供给它。

history = [
    {'role': 'system', 'content': 'You are a helpful assistant.'}
]

def chat(user_message):
    history.append({'role': 'user', 'content': user_message})
    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=history
    )
    assistant_reply = response.choices[0].message.content
    history.append({'role': 'assistant', 'content': assistant_reply})
    return assistant_reply

print(chat('My name is Alice.'))
print(chat('What is my name?'))  # model remembers 'Alice'

API 响应的构成

响应是一个对象,而不只是文本。选项保存回复,结束原因说明它为何停止,使用情况则统计令牌数,也就是您的成本。在生产环境中请记录这些信息。

response = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': 'Say hello in one word.'}]
)

# Accessing response fields
print('Content:', response.choices[0].message.content)
print('Finish reason:', response.choices[0].finish_reason)  # 'stop'
print('Model:', response.model)  # exact version like gpt-4o-mini-2024-07-18
print('Prompt tokens:', response.usage.prompt_tokens)
print('Completion tokens:', response.usage.completion_tokens)
print('Total tokens:', response.usage.total_tokens)

理解结束原因

结束原因会告诉您生成为何停止。'stop' 表示生成完成;'length' 表示达到 max_tokens 上限,答案在中途被截断。请始终检查它,因为截断是一种不易察觉的错误。

def safe_completion(messages, max_tokens=500):
    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=messages,
        max_tokens=max_tokens
    )
    choice = response.choices[0]
    
    if choice.finish_reason == 'length':
        print(f'WARNING: Response was truncated at {max_tokens} tokens!')
    elif choice.finish_reason == 'content_filter':
        print('WARNING: Response blocked by content filter!')
        return None
    
    return choice.message.content

选择合适的模型

请根据任务选择合适的模型。gpt-4o 擅长处理困难的推理任务;gpt-4o-mini 便宜得多,也能很好地完成大多数任务。在认定模型越大越好之前,请先进行基准测试。

# Model comparison guidance
models = {
    'gpt-4o': {
        'use_for': 'Complex reasoning, code generation, nuanced analysis',
        'input_cost_per_1M': 2.50,  # USD
        'output_cost_per_1M': 10.00
    },
    'gpt-4o-mini': {
        'use_for': 'Classification, extraction, summarization, Q&A',
        'input_cost_per_1M': 0.15,
        'output_cost_per_1M': 0.60
    }
}
# gpt-4o is ~17x more expensive on input tokens

消息中的内容类型

消息的内容不一定只有文本。对于 gpt-4o 这类视觉模型,您可以传入一个混合文本和图片的列表,从而询问有关图表或屏幕截图的问题。

# Sending an image to a vision-capable model
response = client.chat.completions.create(
    model='gpt-4o',
    messages=[
        {
            'role': 'user',
            'content': [
                {
                    'type': 'text',
                    'text': 'What is in this image? Describe in one sentence.'
                },
                {
                    'type': 'image_url',
                    'image_url': {'url': 'https://example.com/photo.jpg'}
                }
            ]
        }
    ]
)

n 参数:多个补全结果

n 参数会针对一个提示返回多个补全结果。您可以借此挑选最佳结果,或评估模型的信心:如果所有 n 个结果都一致,说明模型比较确定;如果结果相互冲突,就应当保持警惕。

response = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': 'Name the capital of Germany.'}],
    n=3,  # generate 3 independent completions
    temperature=0.5
)

for i, choice in enumerate(response.choices):
    print(f'Completion {i+1}: {choice.message.content}')

# Check if all completions agree (confidence signal)
answers = [c.message.content.strip() for c in response.choices]
print('All agree:', len(set(answers)) == 1)

将响应作为字符串处理

要以文本形式获取回复,路径始终是 response.choices[0].message.content。请将其封装到辅助函数中,并处理 None 的情况,因为工具调用或过滤器可能导致该值出现。

def get_completion(prompt, system='You are a helpful assistant.', model='gpt-4o-mini'):
    '''Simple helper that returns the response text as a string.'''
    response = client.chat.completions.create(
        model=model,
        messages=[
            {'role': 'system', 'content': system},
            {'role': 'user', 'content': prompt}
        ]
    )
    content = response.choices[0].message.content
    if content is None:
        raise ValueError(f'No content in response. Finish reason: {response.choices[0].finish_reason}')
    return content

result = get_completion('Explain recursion in one sentence.')
print(result)

检查原始请求和响应

遇到异常回复,需要调试吗?请检查原始请求和响应。设置 OPENAI_LOG=debug 后,完整请求体会打印到终端,这是查看实际传输内容的最快方法。

import json
import httpx

# Enable debug logging (shows full request/response)
import os
os.environ['OPENAI_LOG'] = 'debug'

# Or use a custom logging client:
class LoggingClient(httpx.Client):
    def send(self, request, *args, **kwargs):
        print('REQUEST:', request.method, request.url)
        print('BODY:', json.loads(request.content))
        response = super().send(request, *args, **kwargs)
        print('STATUS:', response.status_code)
        return response

构建最小聊天循环

现在您可以构建一个最小的聊天循环:维护一个消息列表,追加每一轮消息,发送全部内容,然后重复执行。API 上的每个聊天应用都基于这一简单模式。代码中展示了具体实现。

import openai

client = openai.OpenAI()

SYSTEM_PROMPT = 'You are a helpful assistant. Be concise.'

def simple_chat_loop():
    messages = [{'role': 'system', 'content': SYSTEM_PROMPT}]
    print('Chat started. Type "quit" to exit.')

    while True:
        user_input = input('You: ').strip()
        if user_input.lower() == 'quit':
            break
        if not user_input:
            continue

        messages.append({'role': 'user', 'content': user_input})

        response = client.chat.completions.create(
            model='gpt-4o-mini',
            messages=messages,
            max_tokens=500
        )

        assistant_reply = response.choices[0].message.content
        messages.append({'role': 'assistant', 'content': assistant_reply})
        print(f'Assistant: {assistant_reply}\n')

print('Example chat loop defined. Run simple_chat_loop() to start.')

快速检查

测试您对本课 AI 工程概念的理解。

课程回顾

您已经学会了聊天的核心:消息数组控制对话,响应则包含内容、结束原因和令牌数量。接下来学习参数。

免费开始

用 AI 导师学习 Python — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
30
课程
120

常见问题解答

「聊天补全端点」课时是免费的吗?

是的 — 「聊天补全端点」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Engineering Academy 课程的其余内容,请升级到 CoddyKit PRO。 AI Engineering Academy 课程共包含 4 节课。

「聊天补全端点」这节课中我会学到什么?

理解包含系统、用户和助手角色的消息数组,编写您的第一个提示词,并解读 API 返回的响应对象。 你通过在浏览器中直接运行的动手代码来练习 AI Engineering Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Engineering Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Engineering Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「聊天补全端点」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Engineering Academy 课中编写并运行代码吗?

能。每节 AI Engineering Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 设置 Python 环境
  2. 聊天补全端点
  3. 使用参数控制模型行为
  4. 错误处理与速率限制
← 返回 AI Engineering Academy