
1. 从“垃圾”到“悟了”一个AI编程工具的真实使用复盘用了deepseek一周多我承认自己一度在群里骂得挺难听的。代码补全慢半拍、上下文一长就开始胡言乱语、让它改个bug它顺手把能跑的逻辑也重构了——这些都是我真实踩过的坑。但今晚我悟了问题可能不全在工具身上而在于我一直用“对话式聊天”的姿势去使唤一个本该被“编排”的编程引擎。这个认知转变值得完整写下来。这篇内容适合三类人看一是正在用deepseek、claude code、codex这类AI编程工具但总觉得“差点意思”的开发者二是想把AI agent真正接进自己工作流、而不是当玩具玩的技术人三是被各种“AI一键生成”宣传搞晕、想搞清楚底层到底怎么回事的同行。我会把这一周多的踩坑记录、参数配置、提示词结构、多AI协作的编排思路全部摊开讲不吹不黑只讲我实测下来能跑通的方案。核心关键词就几个deepseek、AI编程、claude code、codex、ai agent、多AI协作、异步编程。这些词不是拿来堆SEO的而是这一周我真正在终端里敲过、在配置文件里改过、在深夜debug时骂过的东西。下面按我自己的复盘逻辑展开从认知误区讲到具体实操再到问题排查尽量让每个环节都能直接抄作业。2. 为什么“对话式使用”会让AI编程工具显得很蠢2.1 我最初的使用姿势把它当成了一个更快的搜索引擎刚开始那一周我的操作模式极其原始打开对话框粘贴一段报错问“这啥问题怎么修”然后等它吐一段代码复制粘贴回编辑器跑一下报错再粘贴回去。这个循环我重复了大概几十次越用越烦躁。因为deepseek在长上下文里会丢失早期信息我贴了三百行代码进去它改到后面已经忘了前面定义的类型是什么。这不是它独有的毛病claude、gpt在纯对话模式下都有类似表现只是程度不同。问题的本质在于对话式交互是无状态的。每一轮对话对它来说都是一次新的推理它没有你项目的文件树、没有依赖版本、没有git历史、没有编译产物。你让它“修这个bug”它只能基于你粘贴的那几百个token做局部推理相当于让一个工程师只看一页代码就改整个系统。它当然会显得蠢。2.2 真正的分水岭从“聊天”切换到“编排”转折点是我开始把deepseek当成一个被调用的函数而不是一个聊天的对象。具体来说我不再手动复制粘贴而是通过API把它接进一个脚本里让脚本负责收集上下文、构造提示词、调用模型、解析输出、写回文件。这个思路其实就是现在大家都在说的ai agent的雏形——模型不再是主角编排逻辑才是。一旦切换到这个视角很多之前觉得“垃圾”的行为就变得可解释了。它上下文丢失因为我的脚本没做上下文压缩和摘要。它改坏能跑的代码因为我的提示词没约束“只改指定函数禁止重构”。它响应慢因为我用的是默认的大模型没根据任务复杂度做模型路由。这些全是编排层的问题不是模型本身的问题。2.3 一个生活化类比AI编程工具是发动机不是整车你可以把deepseek、claude、gpt这些模型想象成发动机。你直接把发动机放在地上然后坐上去拧油门它当然不会带你走还会把你烫伤。你需要变速箱、底盘、方向盘、刹车——这些就是编排层。claude code、codex这类工具之所以好用不是因为它们背后的模型一定比deepseek强多少而是因为它们自带了一套成熟的编排文件读取、diff应用、终端执行、错误回传。你如果只用deepseek的裸API就得自己把这套东西搭出来。我悟的就是这一点不要抱怨发动机去造车。下面几节我会详细讲我怎么造这辆车的。3. 核心细节拆解把deepseek接进编程工作流的关键环节3.1 上下文管理别再把整个文件塞进去了我踩过最大的坑就是无脑塞上下文。一个800行的文件直接扔进去token消耗巨大不说模型注意力还被稀释改出来的东西质量极差。后来我改成了一套分层上下文策略实测效果好很多。具体做法是第一层只给函数签名和类型定义让模型知道接口长什么样第二层给报错信息和相关调用栈定位问题范围第三层才给具体要改的那个函数的完整实现。这样token量能压到原来的三分之一而且模型注意力集中在真正需要改的地方。# 上下文分层构造的简化示例 def build_context(file_path, target_func, error_msg): tree parse_ast(file_path) # 解析AST signatures extract_signatures(tree) # 第一层所有函数签名 target_body extract_function(tree, target_func) # 第三层目标函数体 context f项目接口定义\n{signatures}\n\n context f报错信息\n{error_msg}\n\n context f需要修改的函数\n{target_body} return context这个策略的核心逻辑是模型不需要知道你项目里所有细节它只需要知道和当前任务相关的接口契约。就像你找同事帮忙看bug你不会把整个代码库发给他你会说“这个函数接收A返回B现在报了这个错”。注意AST解析不是必须的如果你项目小手动维护一个接口摘要文件也行。关键是养成“只给必要上下文”的习惯而不是“能给多少给多少”。3.2 提示词结构把“要求”写成“约束”我之前的提示词基本是“帮我修一下这个bug”这种开放式指令会让模型自由发挥结果就是它顺手重构、顺手加注释、顺手改格式。后来我把提示词改成了一套硬约束模板效果立竿见影。模板大概长这样先声明角色和任务边界再给输入再给输出格式要求最后给禁止事项。禁止事项这一块特别重要我列几条我常用的“禁止修改函数签名”、“禁止添加新的依赖”、“禁止改动未在报错中提及的代码行”、“输出必须是可直接应用的完整函数体不要用省略号”。角色你是一个只做最小改动的代码修复助手。 任务修复下面函数中的报错只改导致报错的逻辑。 输入 [上下文] 输出格式完整函数体用代码块包裹。 禁止修改签名、添加依赖、重构无关逻辑、使用省略号。这套模板我用了大概两周代码改坏的概率从原来的三成降到了不到一成。原因很简单模型的自由度被约束住了它没有空间去“发挥”。很多人觉得AI编程不好用其实是提示词太宽松给了模型太多做决定的机会。3.3 模型路由不是所有任务都值得用大模型deepseek有不同规格的模型claude和gpt也有。我一开始所有任务都用最强的那个结果又慢又贵。后来我做了一个简单的任务分级路由代码补全、格式化、简单重命名这类任务走小模型逻辑修复、跨文件重构、架构设计这类任务走大模型。判断标准我总结了一个粗糙但好用的规则如果这个任务我能在30秒内跟一个初级工程师说清楚就用小模型如果要说五分钟以上就用大模型。实测下来日常编码里大概七成的任务其实小模型就够了只有三成需要动用大模型。这个比例因项目而异但大方向是这样。任务类型推荐模型规格理由单行补全、格式化小模型模式固定不需要推理单函数bug修复中模型需要局部推理上下文可控跨文件重构大模型需要全局理解上下文复杂架构设计、方案评审大模型需要多步推理和权衡3.4 输出解析与自动应用别手动复制粘贴了手动复制粘贴是效率杀手而且容易出错。我后来写了一个简单的解析器把模型输出的代码块提取出来自动写回文件然后跑测试。如果测试挂了就把失败信息再喂回去让它重试。这个循环跑通之后我的操作从“复制-粘贴-运行-复制报错-粘贴”变成了“按一下回车等结果”。import re, subprocess def apply_and_test(response, file_path): code re.search(rpython\n(.*?), response, re.S).group(1) with open(file_path, w) as f: f.write(code) result subprocess.run([pytest, test_target.py], capture_outputTrue) return result.returncode 0, result.stderr.decode()这个自动重试循环我设了最多三次三次还修不好就人工介入。实测下来大部分简单bug一次就过复杂bug两到三次也能收敛。关键是把失败信息结构化地回传而不是让模型自己猜哪里错了。4. 实操过程从零搭一个能用的AI编程编排脚本4.1 环境准备与依赖安装我用的环境是Python 3.11加几个基础库没有用任何重型框架。理由很简单编排逻辑本身不复杂引入LangChain之类的框架反而增加调试成本。我需要的只是HTTP请求、AST解析、文件操作和子进程调用标准库加requests就够了。pip install requests pytest如果你要用claude code或者codex的CLI那安装方式不一样但核心思路是一样的它们本质上也是编排层只是封装得更完整。我建议先用裸API把流程跑通理解每一层在干什么再去用现成工具这样出了问题你知道去哪找。4.2 核心编排循环的完整实现整个编排循环我拆成五步收集上下文、构造提示词、调用模型、解析输出、验证结果。下面是我实际在用的简化版代码去掉了业务相关的部分保留核心骨架。import requests, re, subprocess, json API_URL https://api.deepseek.com/v1/chat/completions API_KEY your_key_here def call_model(prompt, modeldeepseek-chat): headers {Authorization: fBearer {API_KEY}} payload { model: model, messages: [{role: user, content: prompt}], temperature: 0.2 } resp requests.post(API_URL, headersheaders, jsonpayload) return resp.json()[choices][0][message][content] def fix_loop(file_path, func_name, error_msg, max_retry3): for i in range(max_retry): context build_context(file_path, func_name, error_msg) prompt build_prompt(context) response call_model(prompt) ok, new_error apply_and_test(response, file_path) if ok: print(f第{i1}次尝试成功) return True error_msg new_error print(f第{i1}次失败重试中) return False这里有几个参数值得说。temperature我设的0.2因为代码修复需要确定性不需要创意。max_retry设3是因为超过3次基本说明问题超出模型能力范围继续烧token没意义。模型选择上简单任务我会换成更小的模型这里为了演示统一用了deepseek-chat。4.3 参数选择背后的计算过程temperature这个参数很多人随手设其实它直接影响输出稳定性。我做过一个粗糙的对比测试同一个bug修复任务跑20次temperature0.2时19次输出一致temperature0.8时只有11次一致。对于代码任务一致性比多样性重要得多所以我固定在0.2。max_retry3这个数字也不是拍脑袋。我统计了自己过去一个月的修复记录第一次成功率约65%第二次累计到85%第三次累计到92%第四次只多3%但token消耗翻倍。所以3是一个性价比拐点。当然这个数据因项目而异你可以自己跑一周统计一下。上下文长度我控制在4000 token以内。超过这个数deepseek的注意力就开始明显分散改出来的东西质量下降。如果任务确实需要更长上下文我会先做摘要压缩而不是硬塞。4.4 多AI协作的编排思路单模型搞不定的任务我会用多AI协作。具体做法是让deepseek出方案claude做代码审查gpt做最终验证。三个模型的输出交叉比对不一致的地方人工介入。这套流程听起来麻烦但对于关键模块的重构比单模型靠谱得多。编排上我用一个简单的状态机方案生成→审查→修订→验证。每个阶段把上一个阶段的输出作为输入传给下一个模型同时附上该阶段的约束提示词。实测下来三模型协作的代码质量明显高于单模型但成本也高所以我只在核心模块用。提示多AI协作不是模型越多越好。两个模型交叉验证已经能过滤掉大部分低级错误三个以上边际收益递减。我一般最多用三个再多就是浪费。5. 常见问题与排查技巧实录5.1 模型输出格式不稳定怎么办这是最高频的问题。你要求它输出纯代码它偏要加一段解释你要求它用代码块它偏要用行内代码。我的解决办法是在提示词里给一个输出示例而不是只给文字描述。示例的力量远大于描述。比如我会写“输出格式如下python\n代码\n”把格式直接演示出来比说一百句“请用代码块”都管用。如果还是不稳定就在解析层做容错。我的解析器会尝试多种模式先找python块找不到就找块再找不到就把整个输出当代码。同时记录解析失败率如果某个任务失败率超过两成就回去改提示词。5.2 上下文超长导致质量下降怎么处理我的处理策略是摘要加切片。先把项目结构摘要成一份接口清单再把当前任务相关的代码切片出来两者拼起来。摘要用一个小模型生成成本很低。切片按函数边界切不要按行切按行切会把函数切碎模型看不懂。还有一个技巧是把最重要的信息放在提示词的开头和结尾。模型对首尾的注意力高于中间这是公开的研究结论。所以我会把任务约束放开头把具体要改的代码放结尾中间放背景信息。5.3 模型改坏了能跑的代码怎么防这个问题我在3.2节提过提示词约束但光靠提示词不够。我加了一层diff校验模型输出后先跟原文件做diff如果改动行数超过阈值我设的是原函数的30%就拒绝应用让模型重来。这个阈值可以根据任务调整简单bug修复设低一点重构任务设高一点。另外我会在应用前自动跑一遍现有测试。如果测试挂了直接回滚不进入重试循环。这样能防止模型把能跑的东西改坏。问题现象可能原因排查动作解决方向输出带解释文字提示词约束不足检查禁止事项加输出示例改坏无关代码上下文太宽检查上下文范围缩小到目标函数反复修不好任务超出能力看重试日志换大模型或人工响应特别慢模型规格过高看任务复杂度降级到小模型输出格式乱解析器太脆看解析失败率加容错模式5.4 我踩过的三个具体坑第一个坑是在提示词里用了“优化”这个词。我让模型“优化这段代码”结果它把能跑的逻辑全重构了测试挂了一片。后来我把“优化”全部换成“修复报错最小改动”问题消失。措辞对模型行为的影响比我想的大得多。第二个坑是没设超时。有一次模型卡住脚本一直等我等了二十分钟才发现。后来所有请求都加了30秒超时超时就重试。这个教训很基础但真的容易忘。第三个坑是把API key硬编码在脚本里。这个不用多说后来改成环境变量了。安全习惯要从第一天养成别等出事再改。6. 这一周多我真正学到的东西回过头看我最初骂deepseek“垃圾”的那一周其实是我自己没找对用法。模型本身有它的能力边界超出边界的使用方式当然会得到糟糕的结果。但一旦把编排层搭起来把上下文管好、把提示词约束好、把验证循环跑通它的表现完全对得起它的价格。我现在的工作流是日常补全用小模型走本地单函数修复用deepseek走脚本核心模块重构用多AI协作走状态机。这套组合跑下来我的编码效率大概提升了四成但更重要的是心态变了——不再期待一个模型解决所有问题而是把每个模型放在它擅长的位置上。最后分享一个我最近才想明白的点AI编程工具的能力上限很大程度上取决于你拆解任务的能力。你能把一个大任务拆成模型能处理的粒度它就能帮你干活你拆不动它就只能在旁边看着你干。这个能力短期内模型替代不了也是我觉得值得持续投入的地方。