首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >万字详解让大模型写出好代码:上下文窗口的工程化实践

万字详解让大模型写出好代码:上下文窗口的工程化实践

作者头像
腾讯云开发者
发布2025-09-11 19:01:18
发布2025-09-11 19:01:18
25800
代码可运行
举报
运行总次数:0
代码可运行

随着大模型在代码生成领域的广泛应用,开发者面临的核心挑战已从"如何让模型生成代码"转向"如何让模型生成高质量的代码"。本文聚焦于大模型代码生成中的关键因素——上下文窗口,通过深入分析Token机制、上下文丢失现象及其对代码质量的影响,提出了一套工程化的上下文管理方法论。文章目标想为开发团队提供了可操作的实践指南,旨在帮助实际的开发工作中提升大模型生成的代码质量,降低开发者对大模型生成的代码的修改次数。

关注腾讯云开发者,一手技术干货提前解锁👇

01、绪论

最近AI辅助编程越来越火了,AI辅助编程的工具也如雨后春笋一般越来越多,例如 CodeBuddy、Cursor、GitHub Copilot 等。根据Google的数据,2025年Q1财报披露,谷歌超过30%的代码在AI辅助下完成(2024年10月为25%),平均每三次代码变更就有一次依赖AI建议。作为开发者,核心工作也开始发生转变。

1.1 大模型生成代码的两类用户群体

大模型的不断发展也催生了许多AI代码生成工具,随着AI代码生成工具的普及,它们的用户可以主要分为两类,两类用户的关注点和需求存在显著差异。

1.1.1 非技术背景用户(代表:产品经理,想要开发小应用来方便自己生活的人等)

AI代码生成工具的出现使得编码的成本被大大降低,即使没有技术背景的用户也可以快速通过AI来实现一个demo甚至是可落地的应用。基于这些的用户场景,这类用户使用AI的目标主要包括以下几点:

图片1.1 非技术背景用户使用AI的主要目标

对于这类用户来说,AI系统需要具备强大的需求理解能力完整解决方案生成能力,上下文窗口主要用于承载业务需求、功能规格和用户交互历史。

举个例子,在纽约时报2月27日的一篇报道中,这篇报道中提到了一个名为“Vibe Coding”的概念,中文翻译过来是氛围编程的意思。这个翻译有点奇怪,结合具体的使用场景来看比较明显:Vibe有氛围的意思,在报道中提到的一个流程为:一位完全不懂编程流程的母亲,仅通过与AI辅助编程的工具来聊天,就实现了名叫LunchBox Buddy的App————一个规划给孩子午餐盒装什么作为午饭的App,它的效果图如下:

图1.2 LunchBox Buddy的示意图

根据其上的介绍(是的,AI不仅完成了使用人提出的诉求,还补充了一些文字说明),这个App的效果是根据对冰箱里面内容拍出的图片,来自动规划可以通过冰箱里的东西能做什么吃的放入孩子们的午餐盒。在AI之前,对于没有技术背景的人来说,完整开发一个这样的App,而且其中的具体逻辑可以根据自己的需求高度自定义(根据效果图,似乎有去掉麸质物质的要求)是几乎不可能的。

1.1.2 技术背景用户(代表:软件开发者、软件架构师等)

有许多AI编程工具是为了方便技术背景用户(大部分是软件开发者)来编写代码而产生的,这可以从承载它们的形态来看。与软件开发者强交互的形态主要有两种:IDE中的插件和IDE本身。

IDE中的插件主要是集成在原有的IDE内部,在IDE的基础上扩展功能,例如Github Copilot、JetBrains的IDE中的AI assistant。

IDE本身的例子也有很多,例如司内的Tico和CodeBuddy,字节的Trae,以及Cursor等。它们本身就是一个可用的完整IDE,相对于插件来说,在与AI交互层面上,能够实现更强大的能力,并提供给AI更强大的接口。

开发者相对而言有更加深厚的技术背景,他们使用AI的目标可以分为以下几点:

对于专业开发者来说,AI系统需要具备深度的代码理解能力和工程实践遵循能力,那么AI就不能从0开始生成没有上下文的文档,需要分析项目中已有的代码,生成风格匹配的代码。以及需要在已有的代码上生成新的代码,这些能力都要求AI本身有一定的存储能力,能够把项目的上下文、代码文件上下文等内容进行存储,并根据拿到的这些信息来生成新的代码。这些要求是可以完全从0生成新代码的非技术背景场景所没有的。

1.2 开发者视角的核心挑战

本文以软件开发者的需求为核心,让我们详细看一下开发者视角中,AI在生成代码的时候可能会遇到什么挑战。

1.2.1 代码库规模挑战

现代软件项目往往包含数万甚至数十万行代码,AI需要拿到足够多的项目场景信息,而直接将项目中的所有文件加载到对话的上下文中显然是不合理的。

1.2.2 技术栈复杂性

企业级项目通常涉及多种技术栈、框架和库,AI需要理解这些技术的使用规范和最佳实践,才能生成符合项目要求的代码。

1.2.3 业务逻辑上下文

除了技术层面,AI还需要理解复杂的业务逻辑、数据模型关系和业务规则约束,这些信息往往散布在多个文件和文档中。

1.2.4 团队协作要求

AI生成的代码需要便于团队其他成员理解、审查和维护,不然生成的代码本身虽然能满足需求,但是会恶化整个项目的代码整洁度。这要求AI不仅要生成正确的代码,还要遵循团队的编码风格和注释规范。

为了解决这些软件开发者使用场景的问题,AI需要有足够大的存储上下文的能力,而这引出了AI的一个能力-上下文窗口(Context Window),它是一种衡量AI能够存储多少上下文的指标,目前常见的AI模型来说,它的单位一般是k token,关于token是什么,下面我们会有比较详细的介绍。司内的 AI 体验平台上,在对话时选择模型的情况下,能看到各个模型的上下文窗口大小。

图1.3 常见AI模型的上下文窗口大小

1.3 上下文窗口的核心作用

在开发者的实际工作场景中,上下文窗口承载着多维度的技术信息,其大小和管理策略将直接影响以下的内容:

  • 代码准确性:是否能够正确理解现有代码的意图,以及项目中对于当前代码的约束。
  • 架构一致性:生成的代码是否符合项目的整体架构设计。
  • 规范遵循:是否遵循团队的编码标准和最佳实践。
  • 可维护性:生成的代码是否便于后续的修改和扩展。

1.4 本文的研究目标

基于对开发者需求的深入理解,本文旨在探讨如何通过工程化的手段优化上下文窗口的使用,从而显著提升大模型在专业开发场景中的代码生成质量。我们将从基础的token机制出发,结合最新的研究成果和实践经验,为开发者和技术团队提供一套完整的方法论指导,重点解决:

  1. 如何在有限的上下文空间内最大化技术信息的利用率。
  2. 如何动态调整上下文内容以适应不同的开发任务。
  3. 如何确保生成代码的工程质量和可维护性。
  4. 如何建立可扩展的上下文管理框架以支持大型项目开发。

通过这些研究,我们期望为专业开发者提供一套实用的工具和方法,让AI真正成为提升开发效率和代码质量的有力助手。

让我们开始吧~

02、token机制

上文提到了用于衡量AI模型上下文窗口大小的单位:token,下面来介绍一下什么是token以及它的相关机制。因为我们现在用到的绝大多数用于生成代码的AI模型都是大语言模型,所以下文以大语言模型LLM的token机制来进行介绍。

2.1 Token化过程详解

token是大语言模型处理文本的基本单位。LLM首先需要将输入的文本(包括代码文件、项目结构、用户输入的Prompt等)进行token化,转成token来进行理解,理解token化过程对于优化上下文窗口至关重要,它是后续所有优化策略的理论基础。

2.1.1 子词分词器(Byte Pair Encoding)

大多数现代LLM使用BPE(Byte Pair Encoding)或SentencePiece等子词分词算法,对于算法本身这里不进行详细介绍,但是我们以一个例子来看一下分词具体都发生了什么。

考虑以下的TypeScript代码:

代码语言:javascript
代码运行次数:0
运行
复制
function calculateSum(a: number, b: number): number { return a + b; }

它经过token化的结果会是:

代码语言:javascript
代码运行次数:0
运行
复制
["function", "Ġcalculate", "Sum", "(", "a", ":", "Ġnumber", ",", "Ġb", ":", "Ġnumber", ")", ":",
 "Ġnumber", "Ġ{", "Ġreturn", "Ġa", "Ġ+", "Ġb", ";", "Ġ}"]

共生成了22个token,可以看到它的分词有点像编译器对高级语言代码进行的词法分析,以“Ġ”开头的内容都是空格等内容。

不过,这个token化的算法是有一定问题的,它需要有一个固定的词汇表,所以如果大模型遇到了一些新技术,或者已有的新框架,那么大模型的分词效果就会比较差,举个例子:

代码语言:javascript
代码运行次数:0
运行
复制
// 新兴技术术语处理困难
"useCallback" // React Hook
"useState"    // 可能被分割为 ["use", "State"] 
"GraphQL"     // 可能被分割为 ["Graph", "QL"]
"TypeScript"  // 可能被分割为 ["Type", "Script"]

并且它对高度自定义的内容,也不会有好的分词效果,例如:

代码语言:javascript
代码运行次数:0
运行
复制
// 项目特定的术语和约定
"MyCompanyUserService"  // 公司特定命名
"handleApiResponse"     // 项目特定模式
"validateUserInput"     // 业务特定逻辑

2.1.2 字节级模型(Byte-level Models))

新兴的字节级模型如MambaByte直接处理原始字节序列,避免了传统token化的问题。它无需预定义词汇表,处理多语言和特殊字符更灵活,不过也有它自己的缺点,在计算序列长度显著增加,计算复杂度提升。

目前来说,我们用到的常见的AI大模型(例如Deepseek、ChatGPT、Claude)都是用的子词分词器来对输入的内容进行token化。不过各大模型可能针对该算法本身有一些自定义的优化。

2.2 代码Token化的特殊性

基于上面token化过程的讲解,我们来看一下代码在token化的过程中与自然语言有哪些不同,与自然语言相比存在哪些独特的特征:

2.2.1 信息密度高

代码的信息密度通常高于自然语言:平均而言,根据OpenAI披露的数据,1个token约对应0.75个英文单词。

图2.1 ChatGPT的官方tokenizer页,里面注明一个token大概是3/4个英文单词

在代码中,1个token可能对应更少的字符,因为包含大量符号和关键字

2.2.2 语法结构更重要

对于自然语言来说,语法结构、语言的顺序重要性并不大。甚至有些文字的顺序发生错误也不会影响阅读,但是代码完全不同。

代码的语法结构(括号、缩进、分号等)对语义至关重要,这些结构元素会占用大量token:

来看一段计算斐波那契数列的递归算法代码:

代码语言:javascript
代码运行次数:0
运行
复制
function fibonacci(n: number): number {
    if (n <= 1) {
        return n;
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
}

根据ChatGPT tokenizer的结果,一共会有43个token,可以看到换行符,缩进等信息也成为了token的一部分:

图2.2 斐波那契数列的tokenizer结果

图2.3 每个token对应的token ID

2.3 Token限制对代码生成的影响

代码与自然语言存在客观差异,而且根据上面的分析,代码比自然语言会占用更多的token,而在开发者使用AI大模型辅助编码的时候,AI处理的绝大多数都是代码,自然语言占比并不多。因为AI大模型本身的上下文窗口大小是有限的,所以token限制的存在对代码生成会有很大的影响。

2.3.1 上下文窗口大小的影响

因为上下文窗口实际上是模型能够同时处理的token数量限制,所以这个限制将直接影响:

  1. 可用信息量:决定了模型能够“看到”多少背景信息。
  2. 计算复杂度:O(n²)的注意力计算复杂度随token数量急剧增长。
  3. 生成质量:token不足可能导致信息丢失,影响代码准确性。

2.3.2 代码生成中的Token挑战

因为不同项目的结构、内容量不同,所以在不同的项目中,生成代码、理解代码需要的token数肯定也是不一样的,可以从以下几个方面来体现:

  • 项目规模:大型项目的完整上下文可能需要数十万token。
  • API文档:完整的框架文档可能超过任何现有模型的窗口限制。
  • 历史对话:长期开发过程中的对话历史快速消耗token配额。

03、研究背景

在深入探讨上下文窗口的工程化实践之前,我们需要全面理解这一技术领域的发展背景、面临的核心挑战以及研究的动机。本章将从大语言模型的技术演进出发,分析专业开发者在使用AI代码生成工具时遇到的实际问题,并回顾相关的技术研究工作,为后续的方法论的使用提供坚实的理论基础。

3.1 技术发展背景

近几年AI大模型的发展非常迅速,每隔一段时间就会出现一个新的AI大模型。今年年初Deepseek横空出世给整个AI市场又注入了不少活力,从它出现到现在也仅仅过了半年多,而新模型如雨后春笋般出现:GPT出了5.0,Claude团队推出了Claude4.0,Twitter团队推出了Grok等等,这些大模型都已经有了比较大的上下文窗口。

让我们随着时间来回顾一下上下文窗口的大小发展。

图3.1 大模型上下文窗口大小的发展过程

可以看出,近几年AI大模型的上下文窗口有了大幅度的增长,甚至可以说是指数级的。对比一下,今年8月初,Claude团队宣称Claude4.0 sonnet已经支持了1Mtoken的上下文,而2020年的GPT3只有4k的token上下文大小。

图3.2 Claude团队宣布Claude Sonnet 4模型现在支持1M token的上下文大小

3.2 常见内容占用的token数量

在代码生成的过程中,现在我们知道了token的概念,可以更精确地定义上下文窗口。在代码生成场景中,我们来看一下具体都有哪些内容会产生token的占用,以及它们的占用量大概是多少

3.2.1 系统提示词

这部分内容主要是AI模型的开发者或者向外提供API接口以及调用API接口的接入方提供的,用于规定AI的行为和底层逻辑。同时会限制AI的输出结构和扮演的角色等,典型的系统提示词示例:

代码语言:javascript
代码运行次数:0
运行
复制
const systemPrompt = `
你是一位资深的TypeScript开发专家,精通React、Node.js和现代Web开发技术栈。

你的职责包括:

  • 编写清晰、可维护、文档完善的代码。
  • 遵循TypeScript最佳实践和严格类型检查。
  • 实现合适的错误处理和数据验证。
  • 使用现代ES6+特性和React Hooks。
  • 确保代码达到生产级别标准并符合团队规范。

代码生成要求:

  • 始终包含完整的TypeScript类型定义。
  • 为复杂逻辑添加有意义的注释。
  • 使用描述性的变量名和函数名。
  • 妥善处理边界情况和异常。
  • 遵循既有项目结构和代码模式。

回复格式:提供代码实现和详细解释,突出关键设计决策,并在适当时给出改进建议。

这部分内容根据系统提示词的语言、内容长度可能会有不同,一般是100-500token。

3.2.2 历史对话内容

既然我们与AI大模型的对话是以一种一问一答的“回合制”进行的,那么我们很容易就会认为AI能够对对话的上下文进行记忆,并且应用到要输出的内容中。

所以,历史的对话内容也会占用token。它包括包含之前的用户输入、模型回复和生成的代码,以提供上下文连续性。

对于AI大模型来说,这可能是这样的一个结构:

代码语言:javascript
代码运行次数:0
运行
复制
const context = {
      turn1: {
        user: "创建一个用户登录组件",
        tokens: 8,
        assistant: "这里是React登录组件的实现...",
        tokens: 245,
        totalSoFar: 253
      },

      turn2: {
      user: "请添加表单验证和错误处理",
      tokens: 12,
      assistant: "我来为登录组件添加验证逻辑...",
      tokens: 180,
      totalSoFar: 445
      },

      turn3: {
      user: "能否改为使用React Hook Form?",
      tokens: 15,
      assistant: "当然,我来重构为使用React Hook Form...",
      tokens: 220,
      totalSoFar: 680
      },

      // 历史对话随轮次增长,需要智能裁剪
      tokenManagementStrategy: {
      fullHistory: "保留完整对话历史",
      summarized: "对早期对话进行摘要压缩",
      contextual: "只保留与当前任务相关的历史",
      sliding: "使用滑动窗口保留最近N轮对话"
      }
};

因为上下文窗口的总大小是有限的,所以AI不会无限制的存储上下文,随着对话轮数的增长,AI会选择性地舍弃一些上文对话内容,只保留与任务相关的部分,对话轮数也会有裁剪。

3.2.3 用户的当前输入

这部分就是我们在对话框中输入的部分,根据输入内容的大小而变动。我们可能直接询问AI一个问题,也可能把一段代码的报错扔给AI来问它具体发生了什么问题,也可能把代码的上下文扔给他让他找BUG或者扩充内容。

3.2.4 相关文档

这部分一般来说是最占用上下文窗口空间的,它包括项目文档、API规范、代码库结构等背景信息。这些内容可能非常巨大

例如对于一个TypeScript+React仓库来说,AI在分析仓库中的代码逻辑或者在生成代码时需要寻找代码规范时。

我们以这样的一个Prompt为例:帮我给仓库中的会员中心页添加一个轮播图,AI可能要找以下文件来进行参考:

类别

示例文件

Token占用范围(预估)

重要性评级

页面组件

member-center/index.tsx

800-1500

⭐⭐⭐⭐⭐

通用组件

Carousel/index.tsx

600-1200

⭐⭐⭐⭐⭐

类型定义

types/member.ts

200-600

⭐⭐⭐⭐⭐

API服务

services/banner.ts

400-800

⭐⭐⭐⭐

样式系统

styles/variables.less

300-600

⭐⭐⭐⭐

Hook函数

hooks/useSwiper.ts

200-500

⭐⭐⭐

工具函数

utils/image.ts

150-400

⭐⭐⭐

业务文档

docs/requirements/

500-1500

⭐⭐⭐⭐

配置文件

package.json、eslint.js等

100-300

⭐⭐

当然,这只是乐观情况下,AI能直接知道每个文件具体是做什么的,它们之间有什么关系,并且精确定位到了每个文件的内容。在实际场景中,AI可能要先读取整个项目的结构信息来确认项目都有哪些文件夹,每部分是做什么的,然后搜索代码内容来获取相关的代码具体在哪些文件里,并且读取文件的依赖来获取其他需要读入的文件。所以,一般来说这部分是占用token最多的。

3.3 开发者遇到的痛点

基于对专业开发者工作场景的深入调研,我们发现当前AI代码生成工具在实际工程应用中存在以下关键问题:

3.3.1 代码质量与工程规范的矛盾

现状分析:

  • AI生成的代码往往能够"运行",但距离"生产就绪"还有很大差距。
  • 缺乏对团队编码规范、设计模式、架构约束的理解。
  • 生成代码的命名、注释、结构可能会不符合项目标准。

3.3.2 上下文信息出现结构化缺失

技术挑战:

  • 现有项目的架构信息、业务规则、技术约束无法有效传达给AI。
  • token限制导致无法包含足够的项目背景信息。
  • 缺乏智能的信息优先级排序算法和动态上下文调整机制。

具体表现:

  • 生成的代码不遵循现有的错误处理模式。
  • 忽略项目中已有的工具函数和公共组件。
  • 无法理解复杂的数据流和状态管理逻辑。

3.3.3 AI可能会忽略项目代码的长期维护性

工程实践痛点:

  • AI生成的代码往往"一次性"特征明显,扩展性差。
  • 缺乏对未来需求变化的考虑。
  • 技术债务累积,将影响项目长期健康度。

3.3.4 影响团队协作效率

协作层面问题:

  • 生成的代码风格与团队其他成员差异较大。
  • 缺乏必要的文档和注释,影响知识传递。
  • Code Review过程中需要大量的解释和修改工作。

3.4 成本与性能的权衡

上面提到的许多与AI丢失内容、上下文被忽略的问题,都是因为大模型的上下文窗口有限产生的。上下文窗口目前来看肯定不是无限的,那么是不是我们选择有最大上下文窗口的模型就可以?这也是不可以的,因为不同模型之间有价格的区别,参考Claude官方网站对于不同token情况下的计价:

图片3.3 Claude官网对于不同模型的价格

可以看到,虽然Claude sonnet 4支持1M的token,但是在大于200k上下文的情况下,价格会暴涨。而且Claude4的价格也比Claude3.5来的高。

04、业界相关工作

业界近几年在为了提升模型上下文窗口上做了许多工作,例如:

4.1 长上下文模型的发展

4.1.1 Transformer架构的改进

现在的大模型基本都是基于Transformer架构的,开发者对大模型通过优化编码结构来增强其处理长序列和长上下文的能力,用到的技术可以包括:

  • 相对位置编码(Relative Position Encoding):更好地处理长序列中的位置关系。
  • 旋转位置编码(RoPE):在LLaMA等模型中广泛采用,支持更长的序列。

对于Transformer架构来说,其核心就是注意力机制。模型的开发者们通过稀疏化注意力矩阵降低计算复杂度,引入滑动窗口注意力的方式来进行局部注意力与全局注意力的结合,以及使用分层注意力的方案来使得模型可以对不同层级采用不同的注意力范围等方式,改进了Transformer算法,增强了模型处理长上下文的能力,从而提高了模型的上下文窗口大小。

4.1.2 业界突破性进展

Google Gemini 1.5

采用混合专家(Mixture of Experts, MoE)架构,实现了以下技术突破:

  • 百万级token窗口:最高支持1,000,000 tokens。
  • 混合稀疏注意力机制:显著降低计算复杂度。
  • 动态上下文分块策略:根据内容重要性动态分配模型的注意力。

OpenAI的技术路线

  • GPT-4 Turbo:扩展至128,000 tokens。
  • 采用更高效的注意力机制和内存管理策略。

4.2 上下文工程

4.2.1 概念提出

IBM苏黎世研究院在2024年提出了"上下文工程"的概念,将其定义为一种系统性的优化模式,它们使用了结构化的方法设计用来管理LLM的输入上下文。

4.2.2 核心技术:结构化认知工具

  • 动态上下文管理技术,包括:
  • 上下文压缩:使用小模型对长文本进行摘要压缩。
  • 检索增强生成(RAG):动态检索相关信息片段,这个方法现在在各大线上的AI系统中(尤其是涉及检索和客制化AI模型的场合)使用很广泛。
  • 分层记忆机制:短期记忆和长期记忆的结合。
  • 以及:
  • 思维链模式:引导模型进行逐步推理。
  • 工具增强推理:用于集成外部工具和API。
  • 多模态上下文:结合文本、代码和图像信息。

4.3 工程实践中的技术方案

4.3.1 SelfExtend方法

2024年1月提出的SelfExtend方法通过构建双层注意力机制,在无需微调的情况下扩展模型的上下文窗口:

技术原理

  • 动态权重分配:根据任务类型调整两层的权重比例。
  • 局部注意力层:处理近距离的token关系。
  • 全局注意力层:处理远距离的重要信息。

实验结果

  • 在LLaMA-2-7B上将有效上下文长度从4K扩展至16K。
  • 在代码补全任务上准确率提升23.5%。
  • 推理速度仅下降12.3%。

4.3.2 分页注意力机制

针对长上下文的显存优化技术:

核心思想,这部分很像操作系统的内存分配算法

  • 使用CUDA流式处理技术实现异步计算。
  • 通过显存池管理减少显存碎片,并且对显存碎片进行回收。
  • 将长序列分割成固定大小的页,类似操作系统的内存分配。

4.3.3 多尺度语义校验

确保长文本生成的语义连贯性:

技术框架

  • 句法层校验:检查语法错误和结构问题。
  • 语义层校验:验证逻辑一致性和语义合理性。
  • 上下文层校验:确保前后文的连贯性。

05、实际场景的方法论指导

在前面的章节,我们对专业开发者需求进行了深入分析,本章着重提出一套可以复用的方法论,针对于有关上下文窗口有限的问题着手进行解决。

5.1 以Cursor与Claude4.0 sonnet的交互为例,如何分析一个大的项目

从其他优秀的产品中学习经验是一种很好的方式,Cursor是一个已经有比较完整商业化能力,并且经过市场验证的IDE,而Claude又是一个强大的且比较新的AI大模型(其实GPT5更加新,但是它的写作能力比较差,而且输出的内容GPT味严重,不太容易看懂),那么我们就以它们的结合,在React官方项目中作为例子来看一下它们是怎么做的。

我这里用到的Prompt是,大家如果感兴趣的话也可以试试:

代码语言:javascript
代码运行次数:0
运行
复制
我正在编写一篇技术文章,主题聚焦于模型上下文窗口的大小对于AI生成代码或者分析结果的质量。
这篇文章将会包含如何降低模型上下文大小占用的方法论。
该项目是React官方项目,异常庞大,如果我提出问题,你是否是通过将整个项目的所有代码文件来读取进行分析的?
如果不是,你和CursorIDE之间进行了哪些交互?分别读取了什么文件?这些交互阶段分别占用了多少token?
下面是我的问题,以你针对这个问题的分析来回答我上面的要求:
帮我看一下useState这个Hook是怎么实现的

首先可以看到,Claude把我的问题,在要输出的内容上分成了4个部分:

图5.1 Claude针对输出的分步处理

在整个完整的调用过程中,如果是涉及和Cursor的交互,输出页面中会以不同的字体显示,所以在Claude执行完所有的to-do之前,我们可以看到它和Cursor做了哪些交互(调用了哪些Cursor提供的API)

图5.2 Claude与Cursor的交互过程,小字即为与Cursor的交互过程(Searched、Read开头的部分)

那么根据Claude输出的最终结果,与我们的猜测一致,它并没有完全将整个项目都进行了读取,而是只读取了部分代码。

它首先会对整个项目进行初始的搜索,确定相关内容所在的文件和位置:

图5.3 与Cursor进行交互的初始语义搜索阶段

在这个过程中会得到与我的输入预期相关的代码片段。演示中的例子是只进行了一轮搜索就得到了结果,但是实际上AI对于拿到的搜索结果会进行二次检查,如果拿到的结果不合适,那么AI会进行第二轮甚至更多轮的搜索。

基于拿到的代码片段,Claude会进一步搜索具体的实现函数:

图5.4 Claude搜索具体的实现方法,并且进行读取

可以看到,通过这种方式,避免了读取整个React项目代码,节省了许多token,而且读取整个项目可能需要花费大量时间,也可能会导致Claude的上下文窗口溢出。

基于对以上交互流程的分析,我们可以得到以下如何节省token的二级结论:

  1. 使用比较语义化的搜索进行描述性查询,不直接进行关键词搜索。因为关键词搜索可能搜索到与最终问题结果无关的内容
  2. 将搜索进行分层,搜索策略从宽泛到具体,先找到入口点和接口定义,再深入核心实现,最后查看具体的算法细节。进一步降低读取的代码量
  3. 只选择性读取代码的实际内容,只读取特定文件的关键部分,避免读取整个大文件,并且限制每个文件能够读取的内容量,防止将超大文件直接读入从而降低内容生成速度和增加token占用量
  4. 对于拿到的搜索发现,及时进行记录,并且确认搜索结果是否合法/是否符合需求。在每次拿到搜索结果后与之前的搜索结果进行确认和关联,以此来保持搜索结果的相关性,建立代码之间的关联关系。

同时,我让Claude以HTML的结构生成了一个层级的架构图来描述这个结构

图5.5 Claude与Cursor进行交互的分层架构

整个查询的时序图可以以以下的方式呈现:

图5.6 “useState是如何实现的”,查询处理时序图

5.2 如何更好地编写Prompt,生成更好的代码

根据上面的例子,我们在使用Curosr以外,想要对deepseek进行对话获取信息,或者想要开发自己有关AI模型进行对话的应用时,可以分场景讨论来看我们应该怎么撰写Prompt。

5.2.1 可能会在多轮对话中让AI的上下文窗口容量被打爆的场景

虽然例如Cursor一样的IDE会为我们做很多工作,来尽可能地防止上下文窗口空间被打爆,但是我们不是所有情况下都在使用Cursor进行代码生成。

考虑这样的一个场景:我们可能在排查一个线上bug,可能会不断的在对话的多轮中输入我得到的报错信息。如果问题一直没解决,那么总会有一次超出上下文窗口的限制。那么这个时候模型可能会因为上下文窗口的限制,舍弃一部分内容。我们并不想让我们认为重要的内容被舍弃。根据上面提到的流程,我们可以采取以下的方案:

1. 主动要求AI对关键信息进行记忆:每当我们有重要发现时,我们可以对AI说:

代码语言:javascript
代码运行次数:0
运行
复制
请记忆以下重要内容:xxx

2. 既然AI本身由于上下文窗口大小的限制,记忆能力并不是无限的,所以我们可以每间隔几轮或者十几轮,对AI说:

代码语言:javascript
代码运行次数:0
运行
复制
"请总结当前调试状态,包括:
- 核心问题
- 已排除的可能性  
- 下一步方向"

3. 我们可以针对遇到的新的错误,主动要求AI删掉某些比较旧的无用上文,来让它有更多的空间来对新的内容进行存储,例如我们要求:

代码语言:javascript
代码运行次数:0
运行
复制
## 更新 #[序号] - [时间戳]

### 新发现 [P0/P1/P2]
[具体发现内容]

### 验证结果 [P1]
- 假设: [具体假设]
- 验证方法: [如何验证]
- 结果: [成功/失败/部分成功]
- 结论: [从结果得出的结论]

### 新的错误信息 [P0]

5.2.2 可能在一轮对话中就让AI的上下文窗口被打爆的场景

这种场景我们也可能会遇到,因为有一些模型的上下文窗口不大,例如比较老的模型或者我们在本地通过OLLAMA 部署的参数较少的模型(比如参数量较小的deepseek)。在ai.woa.com中的deepseek就与huggingFace网站中deepseek宣称的上下文窗口大小有出入,这可能与部署流程有关?如果个人本地部署其他deepseek,可能表现会更差。

图5.7 ai.woa.com中deepseek-v3.1的上下文长度大小

图5.8 Deepseek-V3.1在HuggingFace上的Context Length标识

在这种情况下,我们可以复用上面Claude与Cursor进行交互的逻辑,将输入进行分段处理。

例如:

1. 将问题进行分段处理

代码语言:javascript
代码运行次数:0
运行
复制
# 原始复杂问题 → 分解为多个子问题

## 子问题1:错误定位
"React应用在生产环境出现白屏,错误信息是:[核心错误信息],请帮我分析可能的原因"

## 子问题2:环境差异
"开发环境正常,生产环境白屏,这种情况通常是什么原因?我的环境配置是:[关键配置]"

## 子问题3:具体解决
"确认是polyfill问题,如何在webpack配置中添加Object.entries的polyfill?"

2. 不要在对话中粘贴大段代码,而是:使用代码摘要,或者提醒模型哪部分更加重要,更加值得关注。

代码语言:javascript
代码运行次数:0
运行
复制
# 对话1结束时
"请生成一个50字以内的问题摘要,包含:1)核心问题 2)主要发现 3)下一步建议,我将用于开启新对话"

# AI回复示例"SUMMARY: React生产环境TypeError,Safari特有,缺少polyfill。FOUND: Object.entries不支持。NEXT: 检查babel配置和browserlist设置。"
 
或者:
 
# 不要这样:[粘贴100行代码]
 
# 而是这样:
CODE: OrderForm.jsx:45, handleSubmit function
ISSUE: Accessing user.data.id where user might be undefined
CONTEXT: After async API call, before setState

06

结论

本文通过明确区分AI代码生成的两类用户群体,并以专业开发者的需求为核心,从技术背景和技术的发展历史,首先系统性地介绍了什么是大模型的上下文窗口,以及开发者在使用AI大模型进行辅助的时候可能会遇到什么问题。之后通过一个使用Claude、Cursor在React项目中实际操作的例子,提出了开发者如何在复杂的开发场景中利用好AI有限的上下文窗口,并对可能遇到的问题进行分类讨论、提供解决方案。

未来,随着技术的不断完善和开发者对AI工具理解的加深,我们相信AI将真正成为软件开发团队不可或缺的智能伙伴,推动开发者的编码向更高效、更高质量的方向发展。

希望这篇文章能够帮助到想了解什么是上下文窗口的开发者/非开发者,并且对开发者在日常使用AI辅助编程时的方案提供指导和方法论。

-End-

原创作者|齐炜林

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云开发者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01、绪论
  • 02、token机制
  • 03、研究背景
  • 04、业界相关工作
  • 05、实际场景的方法论指导
  • 06
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档