AI Prompt Engineering · 课时

理解聊天界面

了解 LLM 聊天用户界面的工作方式:角色、轮次和会话上下文

第 1 / 4 课13 个步骤

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

三种角色

每次与 LLM 的对话都建立在三种角色之上:系统、用户和助手。

system 角色会在对话开始前设定规则和角色设定。user 角色代表您发送消息。assistant 角色代表模型进行回复。

import anthropic

client = anthropic.Anthropic(api_key='sk-ant-your-key-here')

message = client.messages.create(
    model='claude-opus-4-5',
    max_tokens=256,
    system='You are a helpful cooking assistant.',
    messages=[
        {'role': 'user', 'content': 'What is mise en place?'}
    ]
)
print(message.content[0].text)

系统消息

系统消息是模型的指令手册。它会在第一轮用户发言之前运行,并在整个会话期间保持生效。

您可以使用它来设定角色设定、语气、领域限制或输出格式。在整个对话过程中,模型都会将其视为指导上下文。

import openai

client = openai.OpenAI(api_key='sk-your-key-here')

response = client.chat.completions.create(
    model='gpt-4o',
    messages=[
        {
            'role': 'system',
            'content': 'You are a senior Python engineer. '
                       'Always include type hints and docstrings in your examples.'
        },
        {
            'role': 'user',
            'content': 'Show me a function that parses JSON safely.'
        }
    ]
)
print(response.choices[0].message.content)

轮次与对话流程

对话由一系列轮次组成。每一轮交替进行:用户发言,助手回复,用户再次发言。

模型会在每次请求中看到完整的轮次历史。这使对话感觉像是连续进行的,但从技术上来说,每次应用程序接口调用都是无状态的,并且每次都会接收完整上下文。

import openai

client = openai.OpenAI(api_key='sk-your-key-here')

# Each call sends the FULL conversation history
history = [
    {'role': 'system', 'content': 'You are a geography tutor.'},
    {'role': 'user', 'content': 'What is the capital of France?'},
    {'role': 'assistant', 'content': 'The capital of France is Paris.'},
    {'role': 'user', 'content': 'And its population?'}   # follow-up turn
]

response = client.chat.completions.create(
    model='gpt-4o',
    messages=history
)
print(response.choices[0].message.content)

会话上下文

会话上下文是对话持续累积的记忆。每条用户消息和助手消息都会累积在历史数组中。

模型没有独立的记忆存储,只会根据当前上下文窗口中看到的内容进行推理。如果您开始新的会话,除非重新注入相关信息,否则模型不会记得之前的会话。

import anthropic

client = anthropic.Anthropic(api_key='sk-ant-your-key-here')

# Simulating 3-turn session context
conversation = [
    {'role': 'user', 'content': 'My name is Alex.'},
    {'role': 'assistant', 'content': 'Nice to meet you, Alex!'},
    {'role': 'user', 'content': 'What is 5 times 7?'},
    {'role': 'assistant', 'content': '5 times 7 is 35.'},
    {'role': 'user', 'content': 'Can you repeat my name?'}   # uses session context
]

response = client.messages.create(
    model='claude-opus-4-5',
    max_tokens=128,
    messages=conversation
)
print(response.content[0].text)  # expects: Your name is Alex.

消息历史结构

消息历史其实就是一个字典列表,每个字典都包含一个 role 键和一个 content 键。

您需要在代码中自行管理这个列表。每次助手回复后,您都要 append 它的响应,然后 append 下一条用户消息,并在下次调用时再次发送整个列表。

import openai

client = openai.OpenAI(api_key='sk-your-key-here')

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

history = [{'role': 'system', 'content': 'You are a math tutor.'}]
reply, history = chat(history, 'What is a prime number?')
print(reply)
print('History length:', len(history))

词元限制详解

每个模型都有以词元数量衡量的上下文窗口。一个词元大致相当于 4 个字符,或英语中的 0.75 个单词。

您的输入(系统消息 + 全部历史记录)和模型的输出都会计入此限制。GPT-4o 支持 128k 个词元;Claude Opus 4.5 支持 200k 个词元。达到上限时,必须删除或概括较早的消息。

import tiktoken

# Count tokens before sending to avoid exceeding the limit
encoding = tiktoken.encoding_for_model('gpt-4o')

messages = [
    {'role': 'system', 'content': 'You are a helpful assistant.'},
    {'role': 'user', 'content': 'Explain quantum entanglement in simple terms.'}
]

total_tokens = 0
for msg in messages:
    total_tokens += len(encoding.encode(msg['content']))
    total_tokens += 4  # overhead per message

print(f'Estimated input tokens: {total_tokens}')
print(f'GPT-4o limit: 128,000 tokens')
print(f'Budget remaining: {128000 - total_tokens:,} tokens')

达到词元限制时会发生什么

当对话历史超出上下文窗口时,您有三种选择:

  • 截断 — 丢弃最早的消息
  • 概括 — 请模型将较早的对话轮次压缩成简短摘要
  • 滑动窗口 — 只保留最近的 N 条消息

选择错误的策略可能导致模型丢失关键上下文,并给出不连贯的回复。

def trim_history(history, max_messages=10, keep_system=True):
    '''Keep the system message and the last N non-system messages.'''
    system_msgs = [m for m in history if m['role'] == 'system']
    non_system  = [m for m in history if m['role'] != 'system']

    if len(non_system) > max_messages:
        non_system = non_system[-max_messages:]
        print(f'Trimmed to last {max_messages} messages.')

    return system_msgs + non_system if keep_system else non_system

history = [{'role': 'system', 'content': 'You are a tutor.'}]
for i in range(15):
    history.append({'role': 'user',      'content': f'Question {i}'})
    history.append({'role': 'assistant', 'content': f'Answer {i}'})

trimmed = trim_history(history, max_messages=6)
print('Trimmed history length:', len(trimmed))

多轮上下文实践

让我们看看上下文如何发挥作用。在多轮对话中,模型会使用之前的每条消息,正确回答后续问题。

这就是为什么您可以说“把刚才的内容解释得更简单一些”,而不必重复说明“刚才的内容”是什么——模型能看到完整历史记录,并知道您指的是什么。

import openai

client = openai.OpenAI(api_key='sk-your-key-here')

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

# Turn 1
history.append({'role': 'user', 'content': 'What is photosynthesis?'})
r1 = client.chat.completions.create(model='gpt-4o', messages=history)
reply1 = r1.choices[0].message.content
history.append({'role': 'assistant', 'content': reply1})

# Turn 2 — refers to prior answer without repeating it
history.append({'role': 'user', 'content': 'Can you explain that using only 3 bullet points?'})
r2 = client.chat.completions.create(model='gpt-4o', messages=history)
print(r2.choices[0].message.content)

无状态接口,有状态用户体验

这里有一个关键认识:接口是完全无状态的。服务器不会在调用之间记住任何内容。

ChatGPT 这类聊天产品会将对话历史存储在自己的数据库中,并在每次接口调用时将其重新注入,从而营造出拥有记忆的错觉。您也可以自行构建同样的机制。

# Illustration: two isolated API calls vs one with history
import openai

client = openai.OpenAI(api_key='sk-your-key-here')

# ❌ WITHOUT history — model has no memory
r1 = client.chat.completions.create(
    model='gpt-4o',
    messages=[{'role': 'user', 'content': 'My dog is named Biscuit.'}]
)
r2 = client.chat.completions.create(
    model='gpt-4o',
    messages=[{'role': 'user', 'content': "What's my dog's name?"}]
)
print('Without history:', r2.choices[0].message.content)  # will not know

# ✅ WITH history injected
r3 = client.chat.completions.create(
    model='gpt-4o',
    messages=[
        {'role': 'user',      'content': 'My dog is named Biscuit.'},
        {'role': 'assistant', 'content': 'Got it, your dog is named Biscuit!'},
        {'role': 'user',      'content': "What's my dog's name?"}
    ]
)
print('With history:', r3.choices[0].message.content)

使用聊天界面的实用技巧

要充分利用聊天界面:

  • 将持久性指令放在系统消息中,而不要在每个用户对话轮次中重复
  • 让较早的对话轮次保持简洁——冗长的历史记录会迅速消耗词元
  • 切换主题时开始新的会话,以避免上下文受到污染
  • 恢复一个长期项目时,只注入过去上下文中的相关子集
# Good practice: compact system message + focused history
import anthropic

client = anthropic.Anthropic(api_key='sk-ant-your-key-here')

system = (
    'You are a concise Python code reviewer. '
    'Reply with: 1) one-line verdict, 2) top 3 issues, 3) fixed snippet.'
)

response = client.messages.create(
    model='claude-opus-4-5',
    max_tokens=512,
    system=system,
    messages=[
        {'role': 'user', 'content': 'def add(a,b): return a+b\nprint(add(1,2))'}
    ]
)
print(response.content[0].text)

回顾:聊天界面

让我们回顾一下聊天界面工作方式的关键概念:

  • 三种角色:系统设定规则,用户发送提示,助手进行回复
  • 每次接口调用都会发送完整历史记录——服务器是无状态的
  • 词元限制限制了上下文总量;接近上限时请进行裁剪或概括
  • 会话上下文只是由您在自己的代码中管理的一个列表
  • 切换主题时开始全新的会话,以保持上下文整洁
# Summary: minimal chat loop skeleton
import openai

client = openai.OpenAI(api_key='sk-your-key-here')
history = [{'role': 'system', 'content': 'You are a helpful assistant.'}]

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

print(ask('Hello! What can you help me with?'))

知识检查

测试您对聊天界面运行机制的理解。

用户开始一个全新的会话,并向人工智能询问:“我们昨天讨论了什么?”人工智能并不记得昨天的会话。为什么会这样?

您学到的内容

现在,您已经理解了每次人工智能聊天交互的基础:

  • 塑造每次对话的系统/用户/助手角色结构
  • 每次调用都会发送完整消息历史记录,以模拟记忆
  • 接口为何是无状态的,以及聊天产品如何在此基础上构建记忆
  • 词元限制如何约束上下文,以及如何管理这些限制

这个思维模型将帮助您设计更好的提示,并构建更智能的人工智能应用。

免费开始

用 AI 导师学习 AI Prompt Engineering — 免费

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

课程
53
课程
199

常见问题解答

「理解聊天界面」课时是免费的吗?

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

「理解聊天界面」这节课中我会学到什么?

了解 LLM 聊天用户界面的工作方式:角色、轮次和会话上下文 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

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

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

「理解聊天界面」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 理解聊天界面
  2. 人工智能可以处理的请求类型
  3. 人工智能如何生成响应
  4. 人工智能无法完成的事情
← 返回 AI Prompt Engineering