0Pricing
AI Prompt Engineering · 课时

上下文长度与相关性

在完整的上下文、词元限制和相关性之间取得平衡

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

context 窗口预算

每个模型都有最大的 context 窗口——也就是它在一次 API 调用中能够处理的词元总数。这包括输入(您的提示词和历史记录)以及输出(模型的回复)。

理解这一预算至关重要:超出预算意味着提示词会被截断,或者输出会丢失。如果将预算浪费在无关的 context 上,模型用于推理重要内容的空间就会减少。

context 窗口大小

不同模型的 context 限制不同。截至 2025 年:

  • GPT-4o:128,000 个词元
  • Claude Opus 4.5:200,000 个词元
  • Gemini 1.5 Pro:1,000,000 个词元
  • GPT-3.5 Turbo:16,385 个词元

更大的窗口可以容纳更多 context,但每次调用的成本也更高。对于大多数任务,8,000–16,000 个词元已经足够。如果这意味着包含无关内容,更大并不总是更好。

import tiktoken

def estimate_tokens(text, model='gpt-4o'):
    encoding = tiktoken.encoding_for_model(model)
    return len(encoding.encode(text))

# Quick token budget calculator
models = {
    'GPT-3.5 Turbo':  16385,
    'GPT-4o':        128000,
    'Claude Opus 4.5': 200000,
}

prompt = 'Explain the concept of technical debt in 500 words for a non-technical CEO.'
prompt_tokens = estimate_tokens(prompt)

for model_name, limit in models.items():
    reserved_for_output = 1024
    available = limit - prompt_tokens - reserved_for_output
    print(f'{model_name}: limit={limit:,} | prompt={prompt_tokens} | '
          f'context budget={available:,} tokens')

应包含哪些内容:相关性评分

在加入任何一段 context 之前,请先问自己:这段信息会改变答案吗?

一个简单的思考框架——为每个 context 元素评分:

  • 高相关性(包含):直接影响任务、塑造词汇或限制选项
  • 中等相关性(视情况而定):提供有用的背景信息,但即使没有它,输出也会是 OK
  • 低相关性(排除):虽然真实,却完全不会影响答案
def score_context_element(element, task):
    '''
    Heuristic: does this context element directly constrain or shape the answer?
    Returns: HIGH / MEDIUM / LOW
    '''
    high_signals = ['stack', 'constraint', 'deadline', 'must', 'cannot', 'budget',
                    'audience', 'goal', 'version', 'scale', 'limit']
    low_signals  = ['founded', 'headquartered', 'fun fact', 'history', 'awards',
                    'team building', 'company culture', 'office location']

    el_lower = element.lower()
    if any(s in el_lower for s in high_signals):
        return 'HIGH'
    if any(s in el_lower for s in low_signals):
        return 'LOW'
    return 'MEDIUM'

context_elements = [
    'Our stack is Python FastAPI and PostgreSQL',
    'We cannot use any paid third-party APIs',
    'Our company was founded in Berlin in 2020',
    'We need the solution to handle 1000 requests/second',
    'We won a startup award last year',
]

for el in context_elements:
    score = score_context_element(el, task='optimize our API')
    print(f'[{score:6}] {el}')

中间信息遗失问题

研究表明,大语言模型对放置在超长提示词中间的信息关注较少。放在 50,000 个词元提示词中间的关键 context 可能会被部分忽略。

最佳做法是:将最重要的 context 放在提示词的开头或结尾——模型对这两个位置的关注最强。

import anthropic

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

# Structure: critical constraint at the TOP, then the body, then the task
well_structured_prompt = (
    # Critical constraint FIRST
    'CRITICAL CONSTRAINT: Output must be under 50 words and contain no code.\n\n'
    # Background in the middle
    'Background: we are explaining our API rate limiting policy to non-technical support agents. '
    'They handle billing inquiries and need to explain errors to customers. '
    'Our rate limit is 100 requests per minute per API key.\n\n'
    # Task at the end
    'Task: Write the explanation.'
)

response = client.messages.create(
    model='claude-opus-4-5',
    max_tokens=128,
    messages=[{'role': 'user', 'content': well_structured_prompt}]
)
print(response.content[0].text)

长文档分块

当您需要处理超出词元预算的文档时,有三种选择:

  • 先总结:请模型压缩文档,然后使用总结内容
  • split 并处理:将文档分成多个部分,分别处理,再合并结果
  • 提取并注入:在将内容加入提示词之前,仅提取相关部分

不要试图强行处理超出 context 窗口的文档——超出的内容会被静默截断。

import anthropic

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

def chunk_and_summarize(long_text, chunk_size=2000):
    '''Split text into chunks, summarize each, combine summaries.'''
    words = long_text.split()
    chunks = []
    for i in range(0, len(words), chunk_size):
        chunk = ' '.join(words[i:i + chunk_size])
        chunks.append(chunk)

    summaries = []
    for idx, chunk in enumerate(chunks):
        response = client.messages.create(
            model='claude-opus-4-5',
            max_tokens=256,
            messages=[{
                'role': 'user',
                'content': f'Summarize this section in 3 bullet points:\n\n{chunk}'
            }]
        )
        summaries.append(f'Section {idx+1}:\n{response.content[0].text}')

    return '\n\n'.join(summaries)

# Example usage
long_doc = 'word ' * 5000  # placeholder for a real document
print('Chunks needed:', len(long_doc.split()) // 2000 + 1)

实践中的相关性筛选

相关性筛选是指在将大型文档加入提示词之前,仅提取其中相关的部分。这对于以下内容尤其重要:

  • 只有一个部分相关的长篇报告
  • 只有一个函数需要审查的代码文件
  • 只有最后 3 条消息重要的电子邮件线程
  • 50 张表中只有 2 张相关的数据库结构
import openai

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

# Step 1: Filter first, then ask
full_schema = (
    'Table: users (id, name, email, created_at, role)\n'
    'Table: products (id, name, price, stock, category_id)\n'
    'Table: orders (id, user_id, total, status, created_at)\n'
    'Table: order_items (id, order_id, product_id, quantity, unit_price)\n'
    'Table: categories (id, name, parent_id)\n'
    'Table: reviews (id, product_id, user_id, rating, body)\n'
    'Table: sessions (id, user_id, token, expires_at)'
)

# Only include relevant tables for the specific question
relevant_context = (
    'Relevant tables for this query:\n'
    'Table: orders (id, user_id, total, status, created_at)\n'
    'Table: order_items (id, order_id, product_id, quantity, unit_price)\n'
)

response = client.chat.completions.create(
    model='gpt-4o',
    messages=[{
        'role': 'user',
        'content': f'{relevant_context}\nWrite SQL to find the top 5 orders by total value this month.'
    }]
)
print(response.choices[0].message.content)

管理对话历史记录

在多轮对话中,历史记录会在每一轮不断增长。智能地管理历史记录,可以保持词元预算处于健康状态:

  • 滑动窗口:只保留最近的 N 轮对话
  • 注入摘要:定期将较早的对话轮次总结成一条消息
  • 提取关键信息:将重要决策记录为项目符号列表,作为系统 context 注入
  • 主题变化时重置:切换到无关主题时开始新的会话
import openai

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

def summarize_history(old_history):
    '''Compress old conversation turns into a brief summary.'''
    history_text = '\n'.join(
        f'{m["role"].upper()}: {m["content"]}' for m in old_history
    )
    response = client.chat.completions.create(
        model='gpt-4o',
        max_tokens=200,
        messages=[{
            'role': 'user',
            'content': (
                'Summarize this conversation history in 3 bullet points. '
                'Focus on decisions made and key information established.\n\n'
                + history_text
            )
        }]
    )
    return response.choices[0].message.content

# Example: compressing old history before continuing
old_turns = [
    {'role': 'user',      'content': 'We are building a Kanban app.'},
    {'role': 'assistant', 'content': 'Great, what is your stack?'},
    {'role': 'user',      'content': 'React + FastAPI + PostgreSQL.'},
    {'role': 'assistant', 'content': 'Good choice for a Kanban app.'}
]
summary = summarize_history(old_turns)
print('Summary of old history:', summary)

context 压缩技术

当您必须包含大量 context、但词元预算紧张时,请使用压缩技术:

  • 使用项目符号而不是散文:项目符号列表比完整句子节省 30–50% 的词元
  • 缩写已知术语:首次使用后,将“PostgreSQL 15”写作“PG15”
  • 删除填充短语:将“值得注意的是……”直接改为陈述事实
  • 使用结构化格式:键值对比完整句子更加紧凑
import tiktoken

def count_tokens(text):
    enc = tiktoken.encoding_for_model('gpt-4o')
    return len(enc.encode(text))

# Same information, different token counts
prose_context = (
    'Our company is a startup that was founded recently and we are building '
    'a data analytics platform. It is worth noting that we use Python for our backend. '
    'Additionally, we have chosen PostgreSQL as our primary database. '
    'Furthermore, we deploy on AWS using ECS containers.'
)

bullet_context = (
    'Company: data analytics startup\n'
    'Stack: Python backend, PostgreSQL, AWS ECS'
)

print('Prose context tokens: ', count_tokens(prose_context))
print('Bullet context tokens:', count_tokens(bullet_context))
print('Tokens saved:', count_tokens(prose_context) - count_tokens(bullet_context))
print('Same information? Yes — same facts, 60% fewer tokens')

动态选择 context

在生产环境中的人工智能应用里,通常会根据当前查询的相关性动态选择 context。这称为检索增强生成(RAG)。

您无需包含所有文档,而是只检索与用户问题在语义上最相似的文档,并将其注入提示词。这样可以使 context 保持精简且高度相关。

# Simplified RAG pattern: retrieve relevant chunks, inject into prompt
import openai

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

# Simulated knowledge base (in production: vector database)
knowledge_base = [
    {'id': 1, 'topic': 'billing',   'text': 'Refunds are processed within 5-7 business days.'},
    {'id': 2, 'topic': 'shipping',  'text': 'Standard shipping takes 3-5 days.'},
    {'id': 3, 'topic': 'returns',   'text': 'Returns accepted within 30 days with receipt.'},
    {'id': 4, 'topic': 'warranty',  'text': 'All products come with a 1-year warranty.'},
]

def get_relevant_docs(user_query, kb, top_k=2):
    '''Simplified relevance: keyword match. Production uses embeddings.'''
    scored = [(doc, sum(w in user_query.lower() for w in doc['topic'].split())) for doc in kb]
    scored.sort(key=lambda x: x[1], reverse=True)
    return [doc['text'] for doc, _ in scored[:top_k]]

query = 'Can I return this and get my money back?'
relevant = get_relevant_docs(query, knowledge_base)
context = '\n'.join(relevant)
print('Injected context:', context)
response = client.chat.completions.create(
    model='gpt-4o', max_tokens=80,
    messages=[{'role': 'user', 'content': f'Context:\n{context}\n\nQuestion: {query}'}]
)
print('Answer:', response.choices[0].message.content.strip())

规划 context 预算

对于生产环境中的应用,请在构建之前明确规划 context 预算:

  • 为输出预留 context 窗口的25%
  • 为系统消息和角色设定分配10%
  • 为最近的对话历史记录分配30%
  • 为动态 context(检索到的文档、注入的数据)预留35%

请将这些分配比例作为代码中的常量记录下来,以便随着使用场景的发展轻松调整。

# Context budget planner
MODEL_LIMIT = 128000  # GPT-4o

BUDGET = {
    'output_reserve':  int(MODEL_LIMIT * 0.25),  # 32,000 tokens
    'system_message':  int(MODEL_LIMIT * 0.05),  # 6,400 tokens
    'recent_history':  int(MODEL_LIMIT * 0.30),  # 38,400 tokens
    'dynamic_context': int(MODEL_LIMIT * 0.35),  # 44,800 tokens
    'task_prompt':     int(MODEL_LIMIT * 0.05),  # 6,400 tokens
}

total_input = sum(v for k, v in BUDGET.items() if k != 'output_reserve')
print('Context budget plan:')
for key, tokens in BUDGET.items():
    pct = round(tokens / MODEL_LIMIT * 100)
    print(f'  {key:<20}: {tokens:>7,} tokens ({pct}%)')
print(f'  {"total input":<20}: {total_input:>7,} tokens')
print(f'  {"+ output reserve":<20}: {BUDGET["output_reserve"]:>7,} tokens')
print(f'  {"= model limit":<20}: {MODEL_LIMIT:>7,} tokens')

相关性胜过长度时

一段 500 个词元、但高度相关的 context,其效果优于一段 5,000 个词元、但相关性较弱的 context。当需要处理的内容更少时,模型能够生成更好的输出。

以下信号表明您的 context 过长且缺乏重点:

  • 模型忽略了您提出的某些限制条件
  • 尽管 context 很长,输出仍然感觉很笼统
  • 模型回答了您问题中错误的部分
  • 延迟和成本高于预期

出现这些迹象时,请精简 context 并重新运行。

import anthropic

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

# Demonstrating: lean context produces sharper output
lean_context = (
    'Task: write a 50-word product tagline.\n'
    'Product: CLI tool that auto-generates Git commit messages from your diff.\n'
    'Audience: senior developers who hate writing commit messages.\n'
    'Tone: dry, witty, technical.'
)

response = client.messages.create(
    model='claude-opus-4-5',
    max_tokens=100,
    messages=[{'role': 'user', 'content': lean_context}]
)
print('Lean context output:')
print(response.content[0].text.strip())

知识检查

一名开发者正在构建一个拥有 20 轮对话历史记录的聊天机器人。20 轮之后,context 窗口即将填满。要在不丢失重要 context 的情况下继续对话,最佳策略是什么?

context 长度与相关性——回顾

有效管理 context 是提示词设计的核心技能,在生产环境中的应用里尤为重要。关键原则包括:

  • 为每个 context 元素评分:相关性分为高/中/低——只包含高相关性的内容
  • 将关键限制条件放在开头或结尾,而不是中间
  • 使用项目符号格式而不是散文,可节省 30–50% 的词元
  • 对超出预算的文档进行总结或分块
  • 在多轮对话中,压缩较早的历史记录,而不是重新开始
  • 将context 预算明确规划为代码常量

常见问题解答

「上下文长度与相关性」课时是免费的吗?

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

「上下文长度与相关性」这节课中我会学到什么?

在完整的上下文、词元限制和相关性之间取得平衡 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

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

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

「上下文长度与相关性」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 理解人工智能提示中的上下文
  2. 提供背景信息
  3. 有效设定场景
  4. 上下文长度与相关性
← 返回 AI Prompt Engineering