01 学习交流群
知识库之外,我们还建了「工程化专题交流群」。
进群和大家一起交流 AI 应用从 Demo 到生产落地的工程实践,包括开发流程、架构设计、效果评估、性能优化与稳定性保障,也会同步专题最新更新和实战资料。
扫码加入,一起聊聊怎样把 AI 应用真正做成、上线并稳定运行。

02 00|先看这里:为什么训练判断力,比学会搭建 Agent 更重要
这是这门课的课前材料。我们希望向你介绍它训练什么、怎么训练,再由你自己决定值不值得投入 8 周。
这门课与常见教学材料最大的区别,是它强调工程意识、训练判断力,而不是单纯堆砌技术名词,图个「量大管饱」。
多数教程会讲清「RAG 是什么、Agent 怎么搭建」,却很少回答更前面的问题:眼前这个需求该不该引入 RAG?单个 Agent 够不够用?对应的成本如何计算、划不划算?这类问题不会有现成答案,只能靠一次次在项目中的真实取舍练出来——这正是课程每周实践任务与结业答辩着重训练的。
开篇先建立两个共识:01 用五道判断,简单展示判断力是如何表现出来的;02 说明模型越来越强之后,判断力为什么反而更值钱——通用能力会不断被模型吸纳走,留在你手里的只有在特定领域下的判断。
本页和 01、02 同属第一组「开篇」;之后按顺序分四组,从不同角度认识这门课:
- 为什么学——AI 都能写代码了,还要不要学开发?(03-04)
- 怎么用 AI——个人怎么用它干活,企业为什么做不好?(05-06)
- 高手怎么练——怎么学,才算真的有效?(07-11)
- 进阶学习——如果跟这门课走,8 周能做出什么?(12-13)
结业只有一个标准,加深多少按需选
结业不分等级,标准只有一个:做出一个能公网访问、并且你讲得清怎么做的 Agent 服务。答辩时提交四项成果(项目仓库、可访问服务、演示录屏、答辩材料),按实现、判断、验证、复盘四条标准审核。基础代码课程提供,往哪个方向加深按需选:
- 先把服务跑起来:在基础代码上修改提示词、调整配置项(模型、key、温度、人设),按自己挑选的应用场景发布一个能被公开访问、使用的服务,并讲清自己修改了什么。
- 增加一个能力:挑选一个自己的场景,定向增加 1 个能力(记忆 / 工具 / RAG / 循环,四选一),做出属于自己的场景服务,并借鉴课程的路演框架讲清它的应用价值。
- 往工程深处走:调用课程的选修 / 拓宽内容,在成本计算、安全护栏、效果数据对比上深入,上线一个「能扛住追问」的服务。
这三条只是可选清单,不用先给自己归一类;具体怎么选,报名前对照课程详情页的说明即可。
这门课默认你掌握至少一门编程语言、愿意用 Python 完成参考路径:能读懂一段代码在做什么、愿意在 AI 辅助下把代码改到能跑、看到报错不慌。
14 页地图(每篇一句)
开篇(含本页,共 3 页)
- 01《判断:成熟工程师怎么做技术选型》——这门课最大的不同,建议先读这一页
- 02《模型越来越强,我学的东西会不会白学?》「会不会白学」——通用能力正被模型收走,剩下的是你的领域
为什么学
- 03《AI 普及后,还需要学习编程吗?》「还要不要学」——最底层的疑虑,先解答这个
- 04《程序员的 AI 三重境界》「你在哪一层」——2023 年提出的分层框架,今天依然成立
怎么用 AI
- 05《程序员如何利用 AI 开发工具辅助开发?》「具体怎么干」——把 AI 当实习生带,方法比工具重要
- 06《企业 AI 做不好,可能不是技术问题》「企业为何失败」——老师的判断力从哪来:企业一线
高手怎么练(选自专栏《10x 程序员工作法》加餐「通向高手之路」)
AI 可以帮助我们提高工作效率,但它并不能替代一个会工作的人。
- 07《知识体系:你与高手之间到底差在哪?》——高手学新东西为什么快:他们学的是增量
- 08《ASK 模型:为什么有些东西“学”不会?》——态度、技能、知识是三件事
- 09《刻意练习:为什么我努力了很长时间水平却没有提升?》——努力很久没提升?缺的是目标、学习区与反馈
- 10《教练:我该如何向高手学习?》——自学能到什么高度,为什么需要教练
- 11《通才:我该如何不断拓宽自己的边界?》——别把自己做成「工具人」
进阶学习
- 12《Agent 开发到底在开发什么:五个要素讲清楚》——先消除「名词堆砌」的顾虑
- 13《8 周,三条路径,一个公网可访问的服务》——每周你能做出、说清什么,一条时间线读完
四种读法
- 时间紧,只判断要不要学:阅读 01(判断力)→ 02 → 03 → 09 四篇
- 快速浏览:阅读每篇开头与结尾各一段,另加 01、12、13 三篇
- 完整通读:按 01—13 顺序通读全文
- 只了解课程交付:阅读 12 → 13,判断这门课适不适合你
读完之后
- 想了解课程具体安排 → 课程详情页(附每周课程安排与常见问答)
- 还有疑问 → 课程详情页 FAQ(持续更新)
03 01|判断:成熟工程师怎么做技术选型
很多人报名前的顾虑是「会不会又是一堆框架名词」。区别在于:网上教程教你「有什么」,这门课练你「选哪个」。下面五道判断题,相信你能直接对到自己工作上的情况。
判断 1 | 提示词能解决,还上 RAG 吗?
- 判断问题:这个需求,提示词就能解决,还要上 RAG 吗?
- 老师的判断:提示词能解决的不上 RAG,规则能解决的不上 Agent;确定性需求,可以用传统的方式做,不一定非要开发成 Agent。
- 课程哪里练:最后两周的工坊——对给定需求做「提示词足够 / 该上 RAG / 该上 Agent」的分层选型判断,并算出月成本账。
- 一句点睛:怎么搭 RAG 是知识点,什么时候不搭才是判断力——少加一层,复杂度、成本和不可控性全省下。
判断 2 | 单 Agent 还是多 Agent?
- 判断问题:这个系统,一个 Agent 够不够,什么时候才该拆成多个?
- 老师的判断:即便要开发 Agent,优选单 Agent 系统,而不是复杂的多 Agent;真要拆,前提是在具体开发之前做好职责分配、画出 Agent 之间调用图,并做好抽象,让它们拥有一个公共接口。
- 课程哪里练:第五周——能描述主从委派的多 Agent 模式,并说出何时需要它。
- 一句点睛:多 Agent 是手段不是勋章。判断力是先问「一个够不够」,再问「拆开的职责说清了吗」。
判断 3 | AI 原生还是 AI 增强?
- 判断问题:已有系统的 AI 化改造,要不要推倒重来做成「AI 原生」?
- 老师的判断:除非有新产品要开发,否则,AI 增强才是一个企业应该选择的道路。
- 课程哪里练:最后两周的工坊——技术成熟度与成本估算,算一笔你的服务的月账单。
- 一句点睛:「性感」的方案和省钱的方案往往是对立的;成熟工程师先问现实约束,再选技术路线。
判断 4 | 哪些事别让 AI 做?
- 判断问题:AI 什么都能试一试,那哪些事干脆别交给它?
- 老师的判断:像重构这样的工作最好还是交给成熟的 IDE 去完成;如果用到的东西比较新,最好还是自己去查文档看代码,找到恰当的解决方案。
- 课程哪里练:第六周——人机分工:人负责架构决策、验收标准、安全边界,AI 负责写代码。
- 一句点睛:知道 AI 的边界在哪,比知道 AI 能做什么更值钱——分工错了,效率反而倒退。
判断 5 | 要不要打开「深度思考」?
- 判断问题:这次任务,是打开「深度思考」让模型自己推理,还是自己写推理步骤?
- 老师的判断:深度思考已经是大模型标配,多数情况下,提问前打开开关即可,不必再手写 CoT。唯一的例外是业务本身有特定的推理步骤:这时 CoT 仍有价值,该由你把步骤写清楚。但自己写了步骤,就别再开深度思考——两套推理容易打架,token 花得更多,效果未必更好。
- 课程哪里练:第七周(大作业工坊 I)——模型分层:什么任务用免费档就够、什么任务值得用推理模型,并把它算进你服务的月账单。
- 一句点睛:开关谁都会按;判断力在于哪一次该按、哪一次该自己写步骤。
这五道题只是样本。这类判断的完整版本,在课程最后两周的选型判断与成本账里练。上面引用的判断,均出自郑晔老师已发表的文章,课程里每一道都有对应的动手练习。
想看判断的依据原文,往后翻《模型越来越强,我学的东西会不会白学?》(02)、《程序员如何利用 AI 开发工具辅助开发?》(05)和《企业 AI 做不好,可能不是技术问题》(06);想知道这门课 8 周到底做什么,看《8 周,三条路径,一个公网可访问的服务》(13)。
04 02|模型越来越强,我学的东西会不会白学?
一些曾经的 Agent 设计模式,正逐渐内化到大模型服务之中,于是,Agent 开发呈现出“一边建设新功能,一边拆除旧用法”的现象。
从 CoT 到深度思考
我们以很多人知道的“深度思考”为例来说明这个过程。
思维链(Chain of Thought,CoT),是 Google 研究者于 2022 年提出的一项提示词技术,他们发现,在给大模型的示例中加入推理过程,模型在算术、常识、符号等推理任务上的表现会大幅提升——模型不是不会推理,只是没人提醒的话,它会急着给出答案,跳过了中间的推理。
随后有人发现,甚至不用构造示例,只要在提示词里加一句“Let's think step by step”,就能激发出类似的效果。一句大白话,胜过千行工程,CoT 就此出圈,会不会写思维链提示词,一度是用好 AI 的分水岭。
之后几年,这门手艺越做越精细:手工雕琢推理步骤、思维树(Tree of Thought)分叉探索、自洽性(Self-Consistency)采样投票,各种技巧被框架封装起来,成了 AI 应用的标配。
转折发生在 2024 年 9 月,OpenAI 发布 o1,用强化学习训练模型“先想后答”,推理不再依靠提示词引导,而是模型内部自发生成。2025 年初,DeepSeek-R1 开源,推理能力不再是少数厂商的专利,各家模型纷纷跟进。
如今,深度思考已经是大模型的标配,我们所需要做的是,在向大模型提问之前,打开一个叫“深度思考”的开关。
内化,不止是 CoT
CoT 不是孤例,环顾 Agent 开发,同样的故事在各个角落上演:
- 基于 ReAct 模式的工具调用,演变成向大模型传递工具参数。解析模型输出,从纯文本解析变成了读取结构化结果,出错的概率大幅度降低;
- JSON 结构化输出,演变成通过参数指定应答格式,输出格式稳定,省掉了解析失败重试处理;
- 联网搜索和图像识别,直接内置进了大模型服务,无需自行集成搜索 API 与视觉模型服务;
- 模型的上下文正在变得越来越长,在某些场景下,我们甚至可以把整个文档直接交给模型:长文总结不必分段处理,简单的知识检索也不必引入 RAG;
- 针对 Agent 开发中最通用的路由决策,甚至出现了专门优化的决策模型,显著降低决策成本。
这些方案诞生时,都是实实在在的工程能力,都曾在应用开发中扮演关键角色。而如今,它们都成了大模型服务的一部分:有的变成一个参数,有的变成一个开关,有的干脆成了服务内置的能力。
大模型服务的不断改进,带来的可能是坏消息,你辛苦构建的模块,也许会在某次升级后失去存在的价值;当然,也可能是好消息,原本要费力解决的问题,如今一个参数就搞定了。
趋势从何而来
为什么大模型服务会把越来越多的能力揽到自己身上?要理解这个趋势,我们得回到起点。大模型的核心原理是下一个词预测(Next Token Prediction,简称 NTP),本质上这是个文字接龙引擎,光靠它做不出复杂的应用。
于是,应用开发者们在模型外面想办法,用工程方案补齐能力,CoT、ReAct、结构化输出等等,都是这么来的。这些方案在大量的实践中被反复验证。渐渐地,大家发现,它们并非某个应用的特殊需求,而是几乎所有应用的通用需求。
既然是通用需求,模型厂商自然会把它们沉淀到大模型服务中,交互更少,延迟更低,成本更小,还能变成产品卖点。所以,这个趋势的本质是一次自然的能力演化:应用层是大模型的试验田,在试验田里验证过的通用能力,最终会内化到大模型服务之中。
我们可以做些什么?
趋势之下,我们看到 Agent 建设呈现出“一边建设新功能,一边拆除旧用法”的现象。我们建设的,是自己应用必不可少的能力;而拆除的,是被大模型服务内化的能力。大模型服务内化的是什么?是通用的能力。这给了我们一个启发。
开发者要有意识地区分自己构建的能力:
- 通用能力,就是换一个模型、换一个场景依然需要的,比如推理增强、格式化输出、工具调用。这部分大概率会被内化,它们很可能只是临时的脚手架,我们可以做好隔离,必要时,该拆就拆。
- 领域特有的能力,就是只在你的业务里成立的能力,比如对业务规则的理解、领域数据的积累、工作流的编排。这部分模型给不了,这才是一个 Agent 存在的核心价值。
内化不定期发生,如果有什么是我们立即可以做的,就是看看自己的模型服务支持哪些能力。比如,支持工具参数的话,你的 ReAct 模式就可以调整一下;支持 JSON 输出,输出处理的代码就可以简化。当然,如果不支持,原本的逻辑还得继续留着。
当然,用大模型服务代替工程,也不是处处适用。比如深度思考模式,如果你的业务有特定的推理步骤,CoT 就还是有价值的。顺带说一个实践细节:自己定制了推理步骤,就不要再开启深度思考模式,两套推理互相打架,token 花得更多,效果未必更好。
小结
说来说去,你会发现,能力内化的趋势,重塑了 Agent 开发的基本盘:推理、解析、检索、路由,这些曾经要亲手构建的工程,正一个个变成大模型服务的一部分;而你的业务、你的领域,这些模型给不了的东西,才是一个 Agent 存在的核心价值。
这一切还没有到头。大模型服务还会继续演化,能提供给我们的能力会越来越多,我们的开发方式也要跟着调整。但无论怎么变,有一个基本动作不会变:把通用的交给模型,把精力留给自己的领域。
这篇不是课程内容,是课程的前提:既然通用能力会被内化,要学的就不是把 CoT、ReAct、RAG 一个个搭起来,而是在具体需求面前判断——哪些该交给模型、哪些必须自己建。课程第 3 周划职责边界,第 4 周讲知识库,第 7 周算成本,练的都是这件事。
内化不会停在今天。想先看这种判断长什么样,回到最前面的 01。
原文:郑晔,公众号「郑大晔校」《趋势:大模型服务能力内化》
05 03|AI 普及后,还需要学习编程吗?
我在知乎上回答了一个问题,关于 AI 之后,是否还要学习编程。下面是我的回答。
在我写下这个回答的时候,答案是需要。
当下,世界还需要程序员
使用 AI 进行开发经过了一个快速演化的过程,从 AI 的聊天窗口,到 Github Copilot 类的插件在 IDE 中聊天/补全,再到 Cursor/Windsurf/Trae/Cline 直接让 AI 写代码。配合上大模型的快速进化,现在用 AI 写代码已经越来越方便。这确实会给人一种错觉,有了 AI 工具,人人都能写代码。
但实际情况是,现在 AI 的能力还很有限。AI 擅长的完成一段功能,但前提条件是,你能够把需求描述得非常清晰。但只要干过开发,你就知道,大部分人是没有办法把需求一下子描述清楚的。我们看到的各种一键生成的应用,其实都是非常简单的。至于复杂的逻辑,让人把描述清楚都很困难,何况是让 AI 写出来。
还有一个实际的问题是,这些 AI 工具并不能完整地掌握整个代码仓库,所以,我们提出的需求,AI 很可能不能完整地修改整个代码仓库里相应的代码,代码仓库规模只要稍微大一点,就有可能出现遗漏。如果你是一个程序员,你可能会想到「高内聚、低耦合」之类的设计原则,减少模块之间的依赖,但不幸的是,这不是 AI 的强项,一个不懂开发的人更不会想到这个问题。
你看到了,即便我们用上了目前最好的工具,很多时候,AI 写出来的代码还是会有很多的问题。我们能怎么办?AI 写的代码出了问题,还是需要程序员来改好,至少当下,世界还是需要程序员的。
程序员,与 AI 协作
有了 AI,程序员的工作模式会发生很大的转变。如果还把主要的时间花在敲代码上,肯定是落伍的。有了 AI,程序员的工作模式应该转成:
- 告诉 AI 写什么
- 看看 AI 写得对不对
- 如果不对,告诉 AI 怎么改
- 如果 AI 实在改不对,自己上手改
在这里,重点是学会告诉 AI 怎么写。显然,在这种工作模式下,学会把需求描述清楚就非常重要了,这就要求程序员好好学学提示词怎么写,以及提升一下自己的语言表达能力。
基于目前的 AI 自身的能力以及我们与 AI 协作的能力,最好让 AI 一次写一个小需求。这就非常考验程序员的任务分解能力。任务分解本就应该是程序员的必备能力,在 AI 时代,这个能力的价值更加凸显出来。
与 AI 协作,另外一个应该受到重视的能力是编写测试的习惯。一旦 AI 改的代码比较多,它改的代码是否影响了已有代码,我们只能通过测试来判断修改的正确性。好消息是,我们可以让 AI 帮助我们写单元测试。
近未来,写代码还有价值
随着 AI 的发展,AI 工具能力的增强,写代码会变得越来越容易,这个趋势是确定的。这也就意味着,开发同样多的功能,所需的程序员会减少。但也同样意味着,用同样多的程序员,会完成更多的功能。
在可见的未来,程序员群体会经历一个洗牌的过程,不会使用 AI 的程序员会逐渐被时代淘汰,会使用 AI 的程序员效率大幅度提升。
只要世界上还有要自动化的东西,就依然需要程序员。指望一个完全不懂编程的人用 AI 写出一个小工具,这是可能的,写出有复杂逻辑的系统,基本不可能。所以,老板还是缺一个写代码的。
如果你是一个已经具备编程技能的程序员,要做的是学会与 AI 协作;如果你是一个普通人,完全可以借助 AI 工具,上手开发一个小工具,过一把创造的瘾(这是程序员最大的乐趣),大概率,你也不会以此为职业。
如果你有一个孩子,要不要培养他写代码呢?这取决于孩子的兴趣,毕竟不是所有人都适合学编程,但只要孩子是那块料,学编程还是值得的,编程还是很能锻炼一个人的思维。以后,即便 AI 再发展,还需要有人让 AI 更强大。
至于通用人工智能实现以后,还要不要编程,谁知道呢!也许还是需要编程,只不过,已经不是今天这种方式的编程了。
读完这篇,如果你认同「会写代码的人会留下来」,接下来自然会问:那具体该怎么学?这篇只回答了「要不要」,没回答「怎么学」——后者正是这门课在做的事:8 周,每周一个动手产出,最后做出一个公网可访问的个性化 Agent 服务。想看路线,翻到《8 周,三条路径,一个公网可访问的服务》。
原文:郑晔,公众号「郑大晔校」
06 04|程序员的 AI 三重境界(删节版)
从 ChatGPT 的火爆开始,AI 这个已经存在了好几十年的东西终于一步一步地走进了普通程序员的日常工作。不同的程序员涉及到 AI 的程度不同,这里我将程序员在工作中使用 AI 分成了三个境界:
- 作为用户的程序员
- 作为 API 调用者的程序员
- 作为模型调教者的程序员
用户
作为用户的程序员,应该是最常见的。程序员本身就是一个对新技术比较敏感的群体,所以,像 ChatGPT 这样的新应用,很多人都会在第一时间尝试使用。程序员会如何使用 ChatGPT 呢?
最初接触时,我们会和其他人一样,只把 ChatGPT 当做一个聊天机器人。但是,作为一个专业人士,我们应该很快就会了解到提示词的概念,也应该应该知道提示词更好的写法。
一个好的提示词要符合下面的公式:
提示词=定义角色+背景信息+任务目标+输出要求
作为 ChatGPT 的技术基础,**大语言模型(Large Language Model,简称 LLM)**做的主要工作是基于上下文信息推断下一段要输出的内容,也就是说,信息越充分,推断出来的内容越精准,反之,则内容越通用。所以,当我们给 ChatGPT 足够的信息,它就会越来越接近我们希望达到的目标。比如,同样是回答医学问题,如果让 ChatGPT 扮演医生的角色,那么它输出的内容就会与诊断治疗相关,而如果让它扮演医学论文写作者的角色,那么它生成的内容就会更加专业。
事实上,这个公式不仅仅适用于普通用户,作为更高级的玩法,它也是是适用的。比如,许多 AI Agent 也是依赖于写出适当的提示词完成的。
有了对于提示词结构的了解,我们就能更好地利用 ChatGPT 去完成自己的目标,也就是进入到程序员的专业领域。
程序员常见的利用 ChatGPT 的方式有
- 让 ChatGPT 协助解决问题
- 利用 ChatGPT 学习相应的知识
原本,搜索引擎在程序员的工作中扮演着重要的角色:
- 在程序中遇到异常,就扔给搜索引擎
- 遇到没用过的工具或框架,扔给搜索引擎
- 一段代码该怎么写,扔给搜索引擎
- ……
当 ChatGPT 出现后,搜索引擎的很大一部分工作被替代了。如果说扔给搜索引擎之后,我们还要做人工筛选,扔给 ChatGPT 很容易直接得到答案。面对 AI 的应答。我们要做的是,识别真伪。程序员的工作识别真伪最容易,就是代码能否运行成功。当然,在解决一些具体问题上,有比 ChatGPT 更好的选择,比如,Github Copilot[1],它甚至可以帮我们写代码。
利用 ChatGPT 学习,尤其是经典知识的学习是很方便的。比如,我要学习 Python,我完全可以告诉 ChatGPT 我是一个经验丰富的程序员,让他帮我规划一条学习路线。这样,它就会避免让我从基础知识开始学。我甚至可以有针对性地问一些我希望了解的话题,比如,Python 项目做自动化有哪些选择。几个问题下来,我就会某个领域有一个初步的了解。
至此,AI 算是开始进入了一个程序员的工作环节。不过,作为一个有追求的程序员,我们可以再进一步了。
API 调用者
在大多数人眼里,ChatGPT 是一个聊天机器人的面貌呈现于使人面前,实际上,它是 GPT 这个大语言模型的一个应用,而 GPT 本身就是作为一个基础设施打造的,所以,GPT 的标准用法就是调用 API。
在 ChatGPT 火爆之后,最早的一批出现的 AI 应用就是复刻 ChatGPT,这几乎是调用 API 最简单的方式。用程序员的话说,就是给 API 加上一些聊天历史:GPT API 本身是无状态的,所以,它不会保留对话历史,要想让 GPT 看上去有一些智商,就需要把聊天的历史作为请求的一部分传给 GPT。
随着人们对于 GPT 能力认识的加深,紧接着就出现了一批用好提示词就能做出的应用,比如,让 GPT 总结文本的内容、续写文字、翻译文字等等。这些应用甚至不用考虑聊天历史,只要直接调用 API,传入相应的提示词即可。
在度过了最初的兴奋,人们发现开始意识到 GPT 并非无所不知。一个典型的问题是,它知道的内容是通用的,换言之,它并不了解特定的知识。虽然 GPT 的 API 提供了微调接口,让我们可以训练出属于自己的 GPT,但对于普通人来说,他们并不会直接调用 API,而能够调用 API 接口的程序员,又不会轻易地把数据交给别人。所以,一个常见的解决方案就是引入向量数据库。
具体做法就是,把训练素材做向量化,存储到本地的向量数据库中。调用 API 之前,先在向量数据库中进行检索,再把检索到的内容结合到请求里,让 GPT 能够根据这些内容进行回答,这样一来,回答就是根据训练素材来的,看上去,我们就拥有了专属于自己的 GPT。这种做法在行业里有个名字:RAG(Retrieval-augmented generation,检索增强生成),其核心是通过引入一个信息检索的组件,在不微调模型的情况下,对检索进行增强。这种方案同样催生出一大批的 AI 应用。
基于 LLM 的应用不断产生,一个将所有这些统一起来的框架诞生了,这就是大名鼎鼎的 LangChain。LangChain 提供了 LLM 应用开发所需的组件,以及一些预制好的应用模版。有了 LangChain,今天的开发者要想开发一个应用比起之前容易许多,其中的一些组件已经成为了行业里事实标准,换言之,它为 LLM 应用开发提供了原语(Primitive)。
如果说最初的 AI 应用几乎都是围绕 LLM 本身能力构建的,在基础设施不变的情况下,程序员开始进行了更多的探索,一个叫 AI Agent 的方向开始逐渐兴起。
一些经过验证的能力本身会下沉到作为基础设施的大模型层面,比如,OpenAI 就可以通过让用户上传文件了做 RAG,实现自己的 GPT。当然,作为基础设施,在具体做法上会有所差异,减少了应用与大模型之间的交互,执行效率上会得到提升。
无论是直接调用 LLM 的 API,还是调用 LangChain 封装的原语,程序员们正在积极地推动着 AI 应用的落地,但所有这些能力一定还是在 LLM 本身的能力范围之内做事情,模型的局限也就成了 AI 应用的局限,想要突破这层限制,就需要再进一步,到达模型本身。
模型调教者
大语言模型与的核心在于大。之前,AI 模型之所以很长一段时间无法突破,很大程度上是不够大。如果不是 OpenAI 出手,谁也想不到「大」到一定规模之后,会产生如此神奇的效果。所以,很多大厂也纷纷入局,训练自己的模型。
但「大」也同样意味着其它的问题,首当其冲的就是资金投入。因为模型很大,所以,训练一次的成本就是少则百万,多则千万,还是美元。这也就决定了这不是小玩家可以随便入局的赛道。即便是舍得投入,也并不一定会有良好的效果。
回到程序员的视角,如果不在资金雄厚且舍得投入的公司,训练大模型必然不是普通程序员的选项,一个现实的选项是模型微调。
LLM 自身的一个限制是有很多东西它不知道,前面说过,RAG 在一定程度上解决了这个问题,但这种做法的准确性不太理想,更好的做法就是基于大模型进行微调,也就是把训练素材喂给模型。之所以叫微调,因为相对于模型整体的素材量,我们提供的素材量可以说是微不足道。
但如果微调是基于像 GPT 这样的模型,就意味着我们需要把数据提供给 OpenAI,这也是很多人宁愿用效果差一些的向量数据库,也不愿意去做模型微调的原因。显然,更多的人需要是一个能够在本地微调的大模型。于是,就出现了一个新的赛道:能够在本地微调的大模型。
如果说以 OpenAI 为首的厂商选择了成为 AI 时代的 iOS,提供强大而封闭的模型,那能成为 AI 时代的 Android 显然也是一个不错的选择,虽然能力略逊一筹,但胜在可定制性上。于是,我们看到的不同厂商的选择:
- 认为自己有能力直接挣钱的,选择走提供服务的路线;
- 认为开放更重要的,选择了走公开模型的路线。
其实,真正的问题出现在选择了一个大模型之后,并不是那些具体的操作,而是微调本身。想要获得良好的微调效果,就需要准备良好的数据。行业里有句名言「垃圾进,垃圾出(Garbage in Garbage out)」,而准备良好的训练素材是一件费时费力的工作。
如果只是把原始素材直接扔给模型,效果不见得会比 RAG 好。你现在应该明白了,之所以微调能够取得比 RAG 更好地效果,完全是因为大量的精心准备。所以有人调侃「人工智能是有多少人工才有多少智能」。
不过,相比于训练一个模型,微调一个模型的成本要低很多,所以,如果面对特定场景,从工程的角度看,微调一个模型对大多数团队来说,是一条更可行的路。
小结
这里所谓的「三重境界」,只是不同的 AI 使用方法,没有境界之间有优劣之分。一个程序员要完成好自己的工作,三重境界可能会在不同的阶段接触到。
如果说,现阶段有什么能力是最重要的,那就是写好提示词。无论是自己使用 AI,还是要开发 AI 应用,关键点都是提示词。一些眼花缭乱的 AI 应用背后都是提示词。一个学习方式就是打开 LangChain 的源码,找到那些提示词模板,了解不同的功能是如何实现。
虽然软件开发领域常常被人认为是高速发展的,新技术层出不穷,但作为一个在行业里沉浸二十多年的老兵,我认为,真正的需要认真学习和理解的东西并不多,今天的 AI 绝对算一个。每次新技术的出现,就是一个抹平高手与新手之间差距的机会,如今,在 AI 面前,我们又站到了同一起跑线上。
参考资料
[1] Github Copilot: https://github.com/features/copilot
这张分层图最有价值的地方,不在名次,而在它指的方向:会调 API 只是第二重,是入门,不是终点。课程就从这一重起步,练的是把一次调用变成有记忆、有工具、有知识、会自己规划的服务。想看清这一步要补哪几样东西,看《Agent 开发到底在开发什么:五个要素讲清楚》。
07 05|程序员如何利用 AI 开发工具辅助开发?
随着 AI 日益普及,各行各业都在积极探索如何在实际的工作中运用 AI,这其中,已经被验证有效地一条路径就是利用 AI 辅助开发,尤其是在编码的这个环节。
AI 开发工具的发展
程序员早期的使用基本集中在向各种大模型提问,帮忙解决开发中遇到的各种问题。从 Github Copilot[1] 开始,新一代的 AI 开发工具开始真正进入到程序员的日常工作中。Github Copilot 的能力集中在自动代码补全以及让 AI 根据提示词辅助生成一些代码片段上。即便如此,这也大幅度地提升了程序员的开发体验,至少一些简单问题无需再做额外的搜索。Github Copilot 的出现引发了很多追随者的出现,比如,智谱的 CodeGeeX[2]、阿里的通义灵码[3]。不过,这些工具基本上还是集中在开发者圈子里。
真正带来更大有影响力的开发工具是 Cursor[4]。Cursor 第一个显著的不同是,它是一个独立的 IDE,之前的很多 AI 开发工具都以 IDE 插件形式存在的。Cursor 最大的优势在于,它可以根据用户的需求编写大规模的代码。在一些需求明确的情形下,它甚至可以完成整个项目,这种展示是激动人心的。也是因为有这样的能力,Cursor 的出圈了。在一个宣传视频中,一个 8 岁小女孩很快就构建了一个聊天机器人。这让很多不懂开发的人看到自己编写代码创建应用的可能性。Cursor 的成功同样也带来了一批追随者,比如,Windsurf[5]、Trae[6]、Cline[7] 等。
除此之外,还有一些其它的方案也有人在尝试,比如,基于命令行的 Aider[8],用于生成 UI 的 v0[9],总之,这是一个快速发展的领域,各种新鲜工具层出不穷。
以目前的趋势来看,Cursor 类工具的用法越来越受到更多人的欢迎,其主要的优势在于 相比于其它使用方式,IDE 的使用方式更接近于传统开发人员的工作习惯,相比于生成代码片段,生成大规模的代码能极大地解放生产力。即便是一些早期的 Copilot 类工具,也在朝着这个方向前进,比如,通义灵码。可以想见,未来二者会逐渐融合。所以,如果你决定采用 AI 辅助开发,学习 Cursor 类工具的用法是现阶段比较好的选择。
注意:这里说的是 Cursor 类工具,不见得一定要选择 Cursor。你完全可以根据自己的需要进行选择,比如,可以选择当前免费的 Trae,也可以选择开源的 Cline。
以这些工具当前的成熟度而言,没有哪个工具可以让人放心大胆地把所有工作都交给它。所以,我们更现实的选择是,利用好这些工具提升我们的工作效率。
接下来,我们就来聊聊如何利用 Cursor 类开发工具进行开发。
如何利用 AI 工具辅助开发
前面说了,Cursor 类工具的最大优势在于它们能够完成相对完整的代码。在不同的工具里,名字或许略有不同,但本质上说,它们都是 Agent。这些 Agent 最大的优点是,它们是半自动的,也就是需要人类参与到它们的编码过程中。
基础原则
行业里有不少全自动的编码 Agent,这反而很多人先探索的领域,一些工具也支持全自动的 Agent,比如,Cursor 的 Yolo 模式,但其表现往往是差强人意。其中的关键点在于,大模型的编码能力和人类的表达能力都是有限的。通过半自动的方式,Cursor 类的工具让人类在 Agent 的执行过程中发现问题,及时止损。所以,在目前的阶段,AI 工具最好的角色还是辅助人进行开发,主导权还是要在人的手上。
利用 AI 工具辅助开发,有一个重要的视角是,把 AI 当做一个需要指导的实习生。它会很多东西,但是,要让它完成你的工作,你需要给予它耐心地指导,各种细节都需要指导,比如:需求是什么、代码风格是什么、工程上有哪些要注意。
任务分解
有了这样的视角,我们推导出指导 AI 的一个重要原则就是,一次给 AI 一个小任务。站在人的角度理解,给一个实习生过多的任务,一方面,他很难一次性消化,另一方面,你作为布置工作的人,也很难一次性说清楚。站在技术的角度看,AI 目前在处理大规模任务时,完成度还比较低。
给 AI 布置任务,难点在于把问题描述清楚。在各个工具的演示视频中,我们看到的是通常是一段非常长的提示词。但在实际工作中,我们很难一下子写出这么复杂的提示词。正常与 AI 沟通的方式往往是在多轮沟通中,不断地向其中补充更多的上下文。越是具体的小任务,也就越容易描述清楚。
规则
在开发的过程中,我们会发现有些要求是反复需要提给 AI 的,比如,因为希望函数要简洁,所以,要求 AI 进行函数提取。如同经常通用的程序要提取成程序库一样,经常提的要求,我们也可以把它提取出来,成为公共的部分。
很多 AI 开发工具都支持一个概念:规则(rule)。规则就是通用的提示词,可以在每次向 AI 发起请求带过去,这样就省去了我们每次去设置。规则更有价值的用法是在一个团队内部,许多刚刚加入团队的人,并不能很好地意识到一些团队内部风格的存在,把通用的规则文件作为项目的基础设施是非常有必要的。所以,一个好的实践是把规则文件提交到代码仓库中。
代码评审和测试
AI 写代码确实很快,但随之而来的一个问题是,我们怎么知道 AI 写得对不对。如果是一个实习生,我们会怎么做?通常的解决方案是代码评审以及测试。对于 AI,我们同样需要这么做。一方面,我们需要人工审核 AI 的代码。好消息是读代码比写代码快,而且不理解的地方还可以让 AI 进一步解释。另一方面,我们需要测试 AI 编写的代码。很多团队缺少编写测试的习惯,尤其是单元测试,好消息是,现在 AI 可以帮助我们写测试,一般来说,测试代码的理解难度要低于产品代码。我们不光是用 AI 编写新代码,还会用 AI 改写老代码,这时,测试的价值会变得异常重要。
模型
采用 AI 编程,一个很现实的问题就是模型。虽然主流大模型的基础能力已经比较接近了,但在编程这个领域模型之间表现还是存在差异。比如,我写下这段文字的当下,公认最好的编程是 Claude Sonnet,国内的 DeepSeek 最新版本也不错。鉴于这个领域正在快速发展,各个大模型都在快速演化,我们很难有一个决定性的结论。好在大部分工具都支持切换模型,所以,我们可以在不同的模型之间多多尝试,找到适合自己的模型。
具体的提示词
与大模型沟通,其关键点就是给大模型更多的上下文。同样,想让发挥 AI 开发工具的能力发挥到最大,我们最好也能提供充足的上下文,越具体越好,比如一个具体的函数,如果能够给它函数签名,就比一段话的描述得到的效果要好。很多 AI 开发工具都有提供更多上下文的能力,比如,我们可以在对话中引用文件、引用目录,甚至引用具体的函数,这样,我们就可以把 AI 的注意力限制在恰当的部分。
不要用 AI 做不擅长的事情
AI 很强,但有些事情它们不擅长,比如:重构。改个类名,提取个函数之类的操作,对很多程序员来说,已经是习以为常的事情,让 AI 去做效果不见得好,因为 AI 的上下文有限,它的修改可能会遗漏很多地方。像重构这样的工作最好还是交给成熟的 IDE 去完成,比如,IntelliJ IDEA、PyCharm 等,它们的重构能力很强,用它们做这些工作更合适。
如果你的工作比较传统,AI 给你的助力会比较大,但如果你的工作比较新,AI 可能就爱莫能助了。比如,你用到了最新的程序库,或是某个程序库的新用法,AI 很有可能帮不上你。因为它的训练数据是有截止日期的,即便有联网功能,搜索出来的结果也可能并不令人满意。所以,如果用到的东西比较新,最好还是自己去查文档看代码,找到恰当的解决方案,然后,用 AI 去编码。
除了功能,代码结构也是很重要的,但这并不是 AI 的强项。如果是通用的结构,比如,Java 程序的 Controller、Service、Repository,我们可以写在规则文件中。但是,在实际的开发中,有不少结构是在编码过程中涌现出来的。发现新的代码结构,还需要人来完成。当然,在结构发现之后,我们可以让 AI 把这些结构提取出来。
自己保底
AI 很好,但还没好到能够解决所有的问题。很有可能出现的情况是,AI 改了几次,依然无法达到我们想要的效果,甚至可能出现很大的偏差,这个时候,我们就需要自己动手把这段代码写好,因为最终要为这段代码负责的人是我们。所以,有了 AI,一个程序员的工作模式应该转成:
- 告诉 AI 写什么
- 看看 AI 写得对不对
- 如果不对,告诉 AI 怎么改
- 如果 AI 实在改不对,自己上手改
小结
说来说去,你会发现,如果想在一个实际的项目中用好 AI,对人的要求还是很高的。无论是任务分解的能力,还是提取通用信息的能力,抑或是发掘代码结构的能力,这些都是一个程序员原本应该具备的技能,而且越是高手,这些方面的能力越强。AI 只会放大一个人原本的能力,所以,作为一个程序员,在这个 AI 时代,修炼内功依然是一件不可或缺的事情。
参考资料
[1] Github Copilot: https://github.com/features/copilot
[2] CodeGeeX: https://codegeex.cn
[3] 通义灵码: https://lingma.aliyun.com/
[4] Cursor: https://www.cursor.com/
[5] Windsurf: https://windsurf.com/
[6] Trae: https://www.trae.com.cn
[7] Cline: https://cline.bot/
[8] Aider: https://aider.chat/
[9] v0: https://v0.dev
本文实践清单(全部从正文提炼):
- 把规则文件提交到代码仓库,作为项目基础设施;
- 提问时引用具体文件、目录、函数,把 AI 的注意力限制在恰当部分;
- 一次只给 AI 一个小任务,上下文在多轮沟通中补充;
- 重构交给成熟 IDE;用到新库,先自己查文档再让 AI 编码;
- 人工评审 + 测试为 AI 的代码兜底;改不对,就自己上手。
文里这套「一次一个小任务、评审测试兜底」的做法,正是这门课工程化训练的核心。课程把「把 AI 当实习生带」变成一条具体的工作流:把需求写成 AI 能执行的规格,小步迭代、逐条验收。读这篇你会看到,这门课练的不是某个工具,而是一套能被工程规范兜底的方法。想往下走,看《8 周,三条路径,一个公网可访问的服务》。
08 06|企业 AI 做不好,可能不是技术问题
这周受邀到一个企业讲AI,这次课主要讲了大模型技术演化、Agent和RAG开发,以及大模型应用开发的工程实践。每次出去讲课,于我而言,更有收获的部分是,与听课小伙伴们的交流,这次也不例外。这次的团队与其说是听我讲课,不如说就是想找一个外部视角交流一下,因为他们已经在AI领域中做了很多探索。
这个团队是一个大集团下的研发团队,集团的主营业务相对比较传统,一些高层领导已经深刻地认识到了AI的重要性,于是,要大力地推动AI在各个业务线里落地。研发团队自然是这次AI落地的主角。研发团队的小伙伴确实很给力,从RAG到Agent,他们都有过一些落地实践。所以,他们这次就是带着问题来的。
如何做好知识库
一个很典型的问题是,他们做了知识库,但效果不好。如果站在技术的角度理解,我们直觉上想到的解决方案是
- 如何做数据清洗
- 如何做好文档分块
- 如何找一个靠谱的Embedding模型
- 如何选一个好的检索方式
- 如何通过重写,让用户提示词更适合在系统中做查询
这些技术点都很重要,但团队遇到的真实问题是,他们没有可以很好放到知识库里的知识。因为他们想要的不是简单的文档,而是优秀员工的技能。卡住研发团队的一个关键点就是如何把这些技能变成可以放到知识库里的知识。
这不是一个技术问题,而是一个典型的知识管理的问题:如何将隐性知识变成显性知识。只有成了显性知识,才可能放到知识库里。这个问题的答案就是知识萃取,通过各种方式把知识从优秀员工身上拿出来。
和一些小伙伴交流,我发现,这个问题是一个可以进一步泛化的问题:AI化改造暴露出的一些问题,可能不是AI的问题,而是企业中存在已久的问题,只是因为AI改造暴露出来了而已。比如,他们想做的员工技能梳理,这和建不建知识库没关系,因为有了AI,他们才觉得这件事或许可行。
对企业来说,这可能是一个好的契机,借助AI化改造,把这些问题暴露出来,推动它在企业内部逐步去解决,站在企业发展的角度,这可能是一件好事。
全盘改造 vs 渐进增强
还有一个问题是,既然要AI化,要不要把现在的系统都改成聊天界面。这个看上去很AI的问题,实际上和AI也没有关系,一个运行良好的系统,为什么要改它呢?
现在的AI产品有两种常见的思路,AI原生和AI增强。看上去AI原生要性感一些,AI增强会显得土一些,因为它只是在现有系统上增加一些AI能力。但除非有新产品要开发,否则,AI增强才是一个企业应该选择的道路。毕竟,对企业来说,稳健发展是更重要的。
秉承这样的思路,我们怎样改造一个已有产品,答案就是渐进式调整。有新功能要开发,用新方式,对于老功能,如果有机会,就逐步改造。
即便是改造老功能,也不用一下子把后端的业务逻辑都改成Agent。我们可以根据用户查询内容做一个路由,如果是老功能,跳转到老功能上。还可以把老功能做成一个工具或是MCP,给新的Agent使用。这个思路就是传统的遗留系统改造的思路,和AI也没啥关系。
如何开发Agent系统
讲Agent开发流程时,我的建议就是确定性需求,可以用传统的方式做,不一定非要开发成Agent。即便要开发Agent,优选单Agent系统,而不是复杂的多Agent。这背后的道理就是程序员们熟知的简单性原则,是不是AI系统都要这么做。
讲到多Agent系统时,我提到了在具体开发之前,一定要做好职责分配,画出Agent之间调用图,一些同学从中听出了软件设计的味道。没错,Agent也是软件,它也是需要考虑职责的,不能让一个Agent承担过于复杂的职责。
谈到Agent和工作流的设计时,我强调的点是要做好抽象,让它们拥有一个公共的接口,这样一来,Agent和工作流可以形成组合模式。Agent就成了一个独立的、可以用来组合的元素,而工作流做的事情就是组合各种Agent。再进一步,一个传统过程也可以实现Agent的接口,人机交互也可以是Agent的接口,这样,它们就融入一个工作流里。这里的重点是,我讨论的设计是传统的软件设计,与AI没有关系。
小结
这次交流的很多小伙伴都是工作了很多年的,经验都很丰富,这也是他们可以做出很多优秀探索的基础。只不过,新东西的出现可能会让人迷失,忘了自己也是很厉害的,但是,自己掌握的很多东西并不会一夜之间清零。
AI来了,但很多问题没变。《10x程序员工作法》的开篇词标题是《程序员解决的问题,大多不是程序问题》,同样,我们在AI这里遇到的很多问题,往往与AI无关。我在专栏里提到的很多问题,现在换了一层AI的皮肤,又重新呈现了出来。好消息是,我在《10x程序员工作法》里讨论的很多内容依然是成立的,我们的基本功依然有价值。
这篇文章里的三个判断——确定性需求用传统方式做、优选单 Agent、AI 增强优先——正是这门课反复强调的「判断力」。课程最后两周的工坊,会让你对着自己的大作业,把「该不该上 RAG、一个 Agent 够不够、要不要推倒重来」这些判断亲手做一遍。想先看判断力长什么样,回到最前面的 01。
原文:郑晔,公众号「郑大晔校」
09 07|知识体系:你与高手之间到底差在哪?
你好,我是郑晔!
对于大部分程序员来说,无论在真实工作中职务是什么,在内心里,他都更希望成为一个高手,一个能够不断精进的高手!
然而,很多人不知道自己和高手的差距在哪里,只会埋头努力,结果,常常是效率极低,进展有限。
你与高手之间的差距
我们来看一个小故事:
程序员小李已经工作了三年,在同龄人中,他已经很优秀了,能够解决工作中的大部分问题,但他从未满足过,因为在他心中,一直有一个让他不停追赶的高手:技术负责人老赵。
老赵也挺欣赏这个优秀的苗子,愿意时不时提点他一下。有一次大家在一起闲聊,小李对老赵聊起了心中的疑问:我怎么觉得你什么都知道。
- 老赵:我工作这么多年了,知道一些基础的东西很正常吧。
- 小李:不光是基础的东西,很多新东西你也知道,比如,大模型。
- 老赵:我们当程序员的,不能停了学习。AI 一出来,我觉得这是个好东西,就花了点时间看看。
- 小李:我也是在大模型一出来就花时间看了,但显然我理解的深度远远不如你。
- 老赵:你学习新东西怎么学?
- 小李:不是找各种文档,从头开始学吗?
- 老赵:你这么学东西会不会觉得很累?
- 小李:确实很累,每次学个新东西,我都要看大量文档,陷入到很多细枝末节中,花费大量的时间。
- 老赵:你为啥要花那么多时间看文档呢?
- 小李:不然我怎么学会呢?
- 老赵:我知道我们的差别在哪了?你看的是全量,我看的是增量。
- 小李:全量?增量?什么意思?
- 老赵:我学新东西,只看这里面对我来说哪些东西是新的。其实一个新东西出来,真正的新东西没有多少。
- 小李:为啥我觉得都是新东西呢?
- 老赵:你可能还没有建立起你的知识体系。
- 小李:知识体系?
- 老赵:对,当你建立起知识体系之后,任何新东西都会在这个体系上找到自己的位置,它和我已有的知识都能关联起来,所以,我才说我学东西都是增量。而缺少知识体系的话,任何东西都是全新的,学起来就是全量。
- 小李:你这么说,我有点懂了。如果新东西和我已有的知识有一些关联,确实学起来会轻松一些。
- 老赵:想成为一个优秀的程序员,必须要有一个良好的知识体系,否则,往后走会很难的。
从上面这个小故事,我们不难知道,在外人看来,高手知道很多东西,且上手新东西很快,但这些高手并非多么天赋异禀,他们也需要为了新东西付出极大的努力。
但同样是学习,高手往往都有强大的知识体系做支撑,学起新东西是很快的,因为他很清楚学到的东西应该放在自己的知识体系中哪个地方,而已有的知识可以帮助他更好地学习。
你现在已经知道知识体系的重要性,但接下来的问题就是:我该怎么建立起自己的知识体系?
构建知识体系
在构建自己的知识体系之前,我们首先应该知道,每个人的知识体系都是不同的,因为我们各自从事的工作方向不一,所以,我们先要对构建知识体系这件事本身有个了解。
对于程序员来说,我们要掌握的知识分成三大类:
基础通用的知识:这是所有程序员都需掌握的,是程序员的必备知识,比如网络、操作系统等,无论你做的是前端,还是后端,都应该有所了解。
专业特定的知识:这是程序员在选定职业方向后,要深入学习的该方向的知识。前端程序员需熟悉前端框架、构建工具;后端程序员要掌握各种中间件,还可以再进一步细分,Java 后端程序员还需了解 JVM。这是在选定方向立足的关键。
行业领域的知识:这是程序员进入到某个具体的行业需要了解的领域知识,比如,进入到安全领域,就需要了解安全领域的知识,进入到金融领域,就需要知道金融的知识。
从基础通用知识,到专业特定知识,再到行业领域知识,知识范围由广变窄,内容由浅入深,相应地,掌握相关内容的人也会人数也递减。
从我们构建知识体系的角度看,基础通用的知识是我们无论如何都应该掌握的,是从事程序员这个行业必备的基础知识;而专业特定的知识是我们在选择了一个大方向之后,必须要掌握的内容,这也是我们在一个行业立足的根本,因为我们可能会换公司,但换大方向的概率就低多了。
至于行业领域的知识,往往和我们在一个公司从事的具体工作是相关的。所以,从策略上讲,通用的知识和特定的知识是我们要先建立的基础。有了这样的认知,才是考虑如何具体地去构建知识体系。
下面就以基础通用的知识为例,看看构成程序员知识体系有哪些必需的内容。
**对一个程序员来说,其最核心的能力一定是技术能力。**技术能力,指的是程序员解决问题的能力,这是程序员最基础、最核心的能力,包括但不限于:
- 实现能力
- 设计能力
- 解决问题能力
- ……
其中,实现能力是程序员最基础的能力,也就是把一个软件 / 系统实现出来的能力。
这里要强调一点,**我们不应该把实现能力理解为使用框架写代码。**在 AI 已经普遍流行的今天,像单纯地使用框架这种套路性的工作,已经可以很好地由 AI 完成了。一个不是特别懂编程的人也可以用 AI 写代码了,我们和他们的区别是什么呢?
**作为专职程序员,我们需要理解技术原理,掌握相关的基础知识。**这样,我们才能提出和定位一些更有价值且深层次的问题。
我们先来看看基础知识。按道理说,基础知识是一个程序员必须要具备的,但实际情况是,我经常会遇到我以为常识的东西,一些人根本不知道。出现这种情况的一个重要原因就是,很多程序员并非科班出身,在基础知识上往往有所欠缺。
**基础知识的欠缺也让很多程序员难以在技术路上走远。**当然,我也认识很多优秀的非科班出身的程序员,他们无一例外地都通过各种途径将基础知识补齐了。
程序员的基础知识有哪些呢?
- 算法数据结构
- 计算机体系结构
- 操作系统
- 程序设计语言与编译器
- 数据库
- 网络
- 分布式系统
- ……
如果你被这个列表吓到,证明你确实有很多欠缺的东西,因为这些内容都是计算机的专业课。
当然,你并不需要真的坐到大学的课堂中去学习这些东西。作为一个专业的程序员,最强大的能力一定是自学。好在有人已经把如何自学这些内容整理出来了,你可以看看《自学计算机科学》。
相比于我当年学习这些内容之时,今天的学习资料更容易理解了。很多学习资料不仅仅是单纯地讲原理,而是动手做了实现,比如实现一个编译器。大多数程序员的自我定位是一个工程师,而非计算机科学家,只要能够跟着一些资料实现一遍,我们的理解就可以向前大幅度地迈进一步。
关于实现能力,还有一点也很关键,就是要有端到端的实现能力。很多程序员脑子里只有写代码,对于代码是如何在生产环境中运行起来的知之甚少。
在面试前端程序员的时候,我曾经问过一个问题,我写好的代码部署之后无法访问,该如何排查。结果很多人都不知道从何下手,他们对于 DNS、Web 服务器(比如 Nginx)之类的一无所知,只会在本地把程序启动起来调试代码。
今天一个普通的 Web 应用通常会有域名、负载均衡、Web 服务器、数据库、缓存、消息队列等等,最后才是我们写的前后端代码。所以,一个程序员如果不能了解从前到后这些内容,知识面确实就非常局限了。
通用知识还包括设计能力。这里的设计主要指的是软件设计,软件设计并不与具体的程序设计语言紧密相关,所以,它是一种通用的知识。
**软件设计是一门应对软件长期变化的学问。**很多人对于软件设计的理解属于盲人摸象,缺少结构,而学习软件设计的一个关键点就是建立起关于软件设计的知识结构:
- 程序设计语言:软件设计的实现载体。
- 编程范式:可以使用的设计元素。
- 设计原则:设计元素的组合原则。
- 设计模式:在具体场景下的设计元素组合方式。
- 设计方法:识别设计元素的方式。
其实,这些内容是我在《软件设计之美》专栏里讨论的内容,如果希望了解更多,不妨去那个专栏里学习。
至于解决问题的能力,就是发现问题解决问题的能力。这里面既包含了技术问题,也包含了非技术问题。
其实,解决技术问题是程序员特别擅长的,而非技术问题在真实的软件开发过程中常常是很大的阻碍,而这恰恰是《10x 程序员工作法》这个专栏里讨论的问题,这里就不过多赘述了。
总结时刻
这一讲,我们讨论了普通程序员和高手程序员之间的差距。一个高手看上去是知道得多,学东西快,其实背后是有一个强大的知识体系在作为支撑。有了一个强大的知识体系,新的内容只是这个知识体系上的增量,已有的知识会帮助新知识更好地融入其中。
知识体系很重要,每个人的知识体系也不尽相同,但我们可以知识分成三大类:基础通用的知识、专业特定的知识和行业领域的知识。
基础通用的知识,是所有程序员都应该掌握的,专业特定的知识是某个专业方向的程序员应该了解的知识,而行业领域的知识是某个特定领域程序员应该了解的知识。
基础通用知识是所有程序员都应该掌握的最核心的部分,包括但不限于实现能力、设计能力和解决问题能力。
其中,实现能力是最核心的,对于程序员来说,最重要的就是基础知识,本来这部分应该是常识,但由于很多程序员是非科班出身,造成的结果就是基础知识的欠缺,难以在技术的路上走远。
设计能力是《软件设计之美》专栏里讨论的内容,而解决问题的能力之中很大一部分内容则是在《10x 程序员工作法》这个专栏里讨论过了。
如果今天的内容你只能记住一件事,那请记住,想要成为高手程序员,需要构建一个强大的知识体系。
思考题
在这一讲里,我讨论了基础通用的知识包含了哪些内容。请你结合自己的实际情况,列举一下你专业特定的知识和行业领域的知识包含了哪些需要掌握的内容。
期待在课程作业和学员群中看到你的思考,我们课上见~
「学的是增量」这句话,正好是这门课的设计思路:8 周按周递进,每周只练 Agent 的一个要素。你已有的工程经验是底子,每周新增的只是一块。
原文:郑晔,极客时间专栏《10x 程序员工作法》加餐「通向高手之路」
10 08|ASK 模型:为什么有些东西「学」不会?
你好,我是郑晔!
通过上一讲的讲解,我们已经知道了,每个高手都有一个强大的知识体系支撑着自己不断向前。但即便知道我们知道该学什么东西,也不见得能够取得很好的学习效果。
有些东西“学”不会
我们再来看看小李的故事。
在理解了知识体系的重要性之后,非科班出身的小李决定补一下自己欠缺的基础知识。但是,真正学起来,他发现,任何一本专业教科书读起来都让人头疼,学了一段时间,收效甚微。于是,他又一次把困惑抛给了老赵。
- 小李:我这段时间都在看各种基础知识,但真的很让人头疼,比如,编译原理一上来就给我讲了一大堆各种范式,我都学晕了。
- 老赵:你是怎么学的?
- 小李:我买了很多教科书,然后,就开始读。
- 老赵:你在读教科书?
- 小李:学习知识不需要读书吗?
- 老赵:确实需要读书,但有些东西你想仅仅依靠读书可能是学不会的,编译原理就是其中一个。
- 小李:学不会?为什么?
- 老赵:因为它需要练习。
- 小李:练习?
- 老赵:没错,有些东西是知识,你知道了就好,但还有一部分东西属于技能,需要练习,计算机相关的东西里,有相当一部分属于知识与技能的结合,所以,除了要知道,更需要练习。
- 小李:这又是知识,又是技能,又是知道,又是练习的,这到底是个啥?
- 老赵:你可能需要了解一下 ASK 模型。
ASK 是什么?
ASK 模型是一个教育领域常见的模型,这三个字母分别代表了 Attitude(态度)、Skill(技能) 和 Knowledge(知识),其核心想法把不同的学习内容做了一个分类。
**态度就是你的选择,你用什么样的有色眼镜看待一个事物。**比如,作为一个 Java 程序员,面对不断升级的 Java 版本,你是选择不断追新,还是视而不见,这就是你的态度。
**技能就是你以为你知道,但如果没做过,就永远不会真正知道的东西。**比如,骑自行车,你可以去学习自行车的运作原理,但如果你不去骑一下,你就永远不会骑车。
**知识就是那些已经被发现和验证过的规律,是确定的,不需要你再通过个人的成功或失败验证的东西。**比如,1+1=2,那它不会等于 3,别抬杠,这不是脑筋急转弯。
知道了这些有什么用呢?我们需要知道,不同类型的学习内容要有不同的学习方法。
关于态度,我能给你提供的只有各种信息,比如,别人是怎么做的,这么做有哪些好处等等,尽可能地摆事实讲道理,至于最终的结果,那就是学习者自己决定的了。
假如你认为 Java 8 就是 Java 世界的全部,别人再说新版本有哪些新特性,都是无济于事的。然而,当你打开了心扉,那就有无数的新东西,等着你去学习。
技能的东西,只能通过实践掌握,无他,唯有不断地练习,才能真正地习得。就像是骑自行车,只有不断地骑,才能真正的学会。最好的练习是要有反馈的,骑车最初的反馈特别直接,骑不好,就会摔倒。
至于知识,既然是已经验证过有效的东西,我们只需要把它记住就好。对于简单的东西,比如 1+1=2,直接记忆就好。对于有一些复杂度的东西,就需要一些记忆的方法,比如,面向对象软件有五个设计原则,名字很难记,但如果我们用 SOLID 来记就简单多了。
我们常说的学习,其实是两件事,学和习。
学要有一个理解的过程,理解是帮助我们记忆的,什么样的东西可以“学”呢?知识是可以学的。而“习”则是一个大量练习的过程,什么样的东西要靠“习”呢?没错,技能是要习出来的。
理解了这一点,我们回过头看一开始的问题。
正如老赵所说,计算机相关的东西里有一部分是知识和技能的结合,也就是说,有的需要“学”,有的需要“练”。
就以前面提到的编译原理为例,无论你去看书,还是听老师讲知识点,你会很快地对其知识点有个大概地了解,但是,你依然会觉得这些东西不属于你,其中,一个关键的因素就是,我们缺少了练习。想要更好地理解编译原理,写一个编译器是最有效的方式。
估计很多人听到这个想法会吓一跳,写一个编译器太难了吧!其实,相比于过去,现在写一个编译器的门槛大幅度降低了。
一方面,现在有很多不错的资料可以参考,像上一讲提到的《自学计算机科学》,关于编译器,它推荐的材料是《Crafting Interpreters》,其中就是完整地实现了一个编译器,跟着走一遍就可以对编译器有一个完整的了解。
另一方面,我们可以借助现有的工具,无论是前端的 Antlr、Flex,还是后端的 LLVM、JVM,都可以拿过来使用,此外,在 AI 的帮助下,我们把这些工具串联起来的难度也大幅度降低了,比如让 AI 帮助实现前端的语法表达式。
应用 ASK
现在,我们已经理解 ASK 模型,那我们该如何应用 ASK 模型呢?
首先,区分学习的内容属于什么。
我们常说,算法和数据结构是程序员的基本功。我们要学习各种算法和数据结构,然而你会发现,有些内容很容易学,比如:理解各种数据结构的特性、链表是什么样子、树是什么样子,但有些东西却不是那么容易,比如:动态规划算法。
究其原因,因为它们是两种不同的东西。
数据结构和一些算法,都是已经成型的东西,是知识。我们只要了解了它的特性,就可以把这些东西拿过来用。
而且,在真实的项目中,我们通常也很少写一个数据结构,大多数情况下,都是把标准库中已有的数据结构拿过来用,偶尔需要找一些开源项目,解决一下特定的数据结构。所以,通常来说,数据结构我们是可以学会的。
**而像动态规划,它其实不是一个特定的算法,而是一种算法设计的思想。**即便你能够理解这种思想, 也不意味着你能写出代码来,动态规划能告诉你的是“解决一个问题的步骤”,想要写出代码来,只能靠练习。
没错,看上去动态规划是一种知识,实际上,它的知识部分很简单,而想要掌握它,需要大量的练习,这是它的技能部分。
其次,要规避学习的误区。
一个误区是把知识当技能。有一些“实战派”,总是愿意相信自己感悟的东西,拒绝接受新的事物,忽视别人已经总结出来的知识。
这一点在有一定经验的程序员中尤为常见,很多人总愿意相信自己已经掌握了编程真谛,拒绝学习新东西,比如,谈及设计就会说“高内聚、低耦合”,殊不知,这种闭塞会让他们费尽心力去解决一个别人早已解决好的问题。
另一个与之相对的误区是把技能当知识。**有一些“理论主义者”,喜欢通过阅读来学习。**VI 编辑器怎么用,找本书看看,IntelliJ IDEA 的快捷键是怎么回事,找篇文章读读。但是,这些内容能够给你提供的,其实只是一个练习的方法。不去打开编辑器,一点一点地练习,形成肌肉记忆,这些内容是不可能真正掌握的。
最后,**态度决定一切。**我们前面讨论的重点是区分知识和技能,采用不同的方式,对待不同的学习内容。但这一切的前提是,态度。
态度,是最难学的,每个人心中都有一扇门,这扇门只能从里面打开,没有人可以真正的教你。
对于一个程序员来说,新东西是层出不穷的,唯有保持开放的态度才能够不断地吸收新的营养,一个人只有这样做,才能不断地前进,不畏时代的进步。
当然,我并不建议大包大揽地学习所有新东西,没有人有那么大的精力。对于一个程序员来说,最好的做法是,秉持一个开放的态度,构建自己的知识体系,并定期地更新。
**对于一个新东西,如果它能够带来新的思想冲击,多花些时间深入它,这会让你对很多事情的理解上一个大台阶。**放心,这样的东西并不多。如果它是一个新的工具 / 框架,就看它与现有工作的互补程度,关系不大的话,知道有这个东西就好了。
学习其实只有三件事:**用心学习态度,用脑学习知识,用手学习技能。**用一个开放的态度,把知识学以致用,把技能练成艺术。
总结时刻
这一讲,我们讨论了很多人即便很努力地在学习了,依然收效甚微,其中的关键点是缺少对 ASK 模型的理解。
ASK 模型是 Attitude(态度)、Skill(技能) 和 Knowledge(知识)三个单词的缩写,其核心想法把不同的学习内容做了一个分类。
态度就是你的选择,技能就是你以为你知道,但如果没做过,就永远不会真正知道的东西,知识就是那些已经被发现和验证过的规律,是确定的,不需要你再通过个人的成功或失败验证的东西。
不同的内容需要有不同的学习方法。态度由自己决定,技能需要练习,知识需要学习。计算机领域很多的东西看上去是知识,其实有很大一部分是技能,所以,大量的练习是不可避免的。
应用 ASK 模型,首先,要区分学习的内容是什么类型,其次,要规避一些常见的误区,最后是态度决定一切。
如果今天的内容你只能记住一件事,那请记住,用心学习态度,用脑学习知识,用手学习技能。
思考题
我在这一讲里给你介绍了 ASK 模型,我想让你借助这个模型做一个回顾,看看自己在学习过程中,是否有把不同类型的学习内容混淆的情况,以致于影响了自己的进步。期待在课程作业和学员群中看到你的思考,我们课上见~
技能只能「用手学」。这门课就是照这个来的:8 周每周一个动手产出,从能跑的 Agent 到公网可访问的服务。
原文:郑晔,极客时间专栏《10x 程序员工作法》加餐「通向高手之路」
11 09|刻意练习:为什么我努力了很长时间水平却没有提升?
你好,我是郑晔!
上一讲我们说了学习要区分不同的内容,根据不同的内容安排不同的学习方式。从大多数程序员的工作内容上看,大部分所需的是技能,也就是说,程序员需要的更多的是练习。
那么是不是只要练习了,我们就一定能有提高呢?答案是不尽然。
我们还是从小李的故事开始。
小李已经工作五年了,他感觉自己的提高明显不像从前那么快了。前几年,每个项目他都能有所收获,这让他很快地从一个初出茅庐的新人成长为一个独当一面的成手。
但是,最近一两年,他做事情越来越驾轻就熟,但只有他自己清楚,他进步有限,因为在做的事情都是他熟悉的。他又想起了总是帮助自己的老赵。
- 小李:你遇到过瓶颈吗?我总觉得自己最近一两年没什么提高。
- 老赵:当然了,我也遇到过。你是不是觉得现在做的事都是在重复?
- 小李:对,前些年做这些事情,我会很开心,现在觉得有些无聊了。
- 老赵:之前这些东西你不会,你是在学习。现在你会了,你就觉得无聊了。
- 小李:嗯,是这样的。
- 老赵:小伙子,你是有上进心的。很多人到了这个程度,他会习惯,所以,水平就会停滞不前了。
- 小李:这就是有些人说的,一年的工作经验重复了十年。
- 老赵:没错,就是这样的。
- 小李:那我想突破,该怎么办呢?
- 老赵:你听说过刻意练习吗?
本质上说,我们无论做什么都是在练习,但练习与练习是不同的。大部分练习都是无意识的、自动的。一个人在经过最初的提高之后,通常就会陷入低水平重复,这样的练习无论做多少,都很难有真正的提高。
而与之相对应的就是,刻意练习。
刻意练习的特点
刻意练习,也是练习,但它不同于常规的练习方式,刻意练习是一种有目的且系统的练习方式。它有哪些特点呢?
**刻意练习要有一个明确的目标。**目标的重要性,我在这个专栏里已经强调无数次了。大部分人无法有效提高,根本原因是缺乏一个清晰的目标。
你可能会说,我日常做项目都有目标,但请明确一点,这是公司的目标,并不是你个人的目标,完成这个工作,并不能帮助你提升。
**刻意练习需要在学习区练习。**我在《40 | 我们应该如何保持竞争力?》讲过学习区,不清楚的同学可以回顾一下。
为什么大部分程序员在刚开始入行时提升很快,因为他们会的东西有限,大部分工作内容都是新东西,处于学习区。为什么几年之后就陷入瓶颈,因为一旦熟练掌握基础技能之后,他们就进入了舒适区,在舒适区反复练习,是不会有提高的。
**刻意练习需要反馈。**没有反馈,你不知道自己做的怎么样,提高也就无从谈起。反馈不是自以为是的标准,它可能是一个具体的测量,也来自别人的反馈。
想当年,我带过一帮毕业生,为了让他们练习快捷键,就让他们用秒表计时,看看多长时间完成一段代码。有了明确的反馈,大家的提高都很快,同样的一段代码,从最开始的 20 分钟写完,到最后 5 分钟写完,最快的同学甚至可以在 2 分半写完。
**刻意练习需要保持专注。**每个程序员都知道专注的价值,都有过时间飞速流过的心流体验,这是专注带给我们的价值。当我们进行某一项特定训练时,最好能够全神关注。
哪来的天才?
刻意练习原本是研究卓越表现从何而来。研究发现,一个人在某项技能上的精通程度,与他的练习方式息息相关,我们可以把刻意练习理解为顶尖人才为提升其专业技能所才采用的练习方式。
对刻意练习的研究,同时破解了一个“迷思”:你以为某些人是天赋异禀,实际上是他们进行了大量的刻意练习。与之相伴的一个说法是,一万小时定律。一个人要想在一个领域取得世界级的成就,需要进行一万个小时的练习,而这里练习并不是常规的练习,而是刻意练习。
现在我们知道了,“以大多数人努力程度之低,根本轮不到拼天赋”这句话是很道理的,因为大部分人都还没经过刻意练习,何谈天赋。
当然,并不是所有人的目标都是成为世界级的人才,所以,不见得每个人都需要一万个小时的刻意练习,但我们只要把刻意练习的理念引进到我们日常的工作学习中,也足以让我们在短时间内,有很大的提升。
最后,我们也要知道,刻意练习并非万能,它对于单一技能的训练更有价值,比如,体育项目、各种乐器等等。程序员有很多专业技能也是需要训练的,所以我们也可以采用刻意练习。
对刻意练习有了一个初步的理解之后,我们再回到小李的故事。
小李在初入职场时技能提高很快,因为他有一个明确的目标:生存下去,所以,他会尽快掌握那些他不熟悉的东西,这就是在学习区里刻意练习。上级交给的任务能否完成,是非常直观的反馈。所以这个阶段的技能提高是很快的。
一旦过了最初的阶段,大部分人都能够很好地应对自己的工作了。从个人技能上该如何继续提升,这是很多人都没有想过的,所以,自然而然地就陷入了瓶颈期。更有甚者,某些人是“一年的工作经验重复了十年”。
程序员的刻意练习
程序员如何进行刻意练习?如果你有一项正在学习的内容,你可以针对着这项内容设计相应的练习。
正如我们上一讲说的,计算机领域有很多东西属于技能,需要大量的练习。
比如,学了某个算法,我们就可以找一批算法题,进行有针对性的练习。现在有很多平台让我们完成这样的练习,比如,LeetCode。我们可以在一段时间内,连续地完成这些练习,让我们在短时间内快速地对这个知识点有一个完整的理解。
不过,并非所有内容都像算法那样有大量现成的问题等着我们。我们就不妨给自己设计一些练习题。我在上一讲就说过,学习编译原理就去实现一个编译器,这也是一种针对性的练习。我自己就在学习 DSL 之后,为了练习,编写了我的开源软件 Moco。
还有一些内容,需要的是我们理解现有的一些做法,比如,JVM 的实现。我们同样也可以给自己设计练习,比如,把自己的理解写成文章。我曾经因为一个项目的缘故,要了解 Lambda 的具体实现,我就把自己的理解写成一系列的文章发在自己的公众号上,算是自己学习的阶段性总结。
**给自己设计练习也是有一定挑战的,因为自己学习的是新东西,往往缺乏对它的理解,很容易设计的练习让自己无法完成。**比如,实现一个编译器就是一个很劝退的想法,但实现一个表达式求值器就要简单很多。
现在有了 AI,我们也完全可以让 AI 提供一些能够逐步提升难度的练习,这样,更有利于我们一步一步地去完成,这也是任务分解思想的体现。
其实,对大多数人来说,最难的并不是练习过程本身,而是缺乏目标。很多人都有一颗要提高的心,但实际情况是,光靠自己,你很难再有更大的提升:虽然在做的是不同的项目,但本质上,在做的事情是一样的;虽然努力地在学着各种知识,但实际上,却很难在真实项目中用到。在这种情况下,单单依靠自己是难以破局的,我们需要的是一个“教练”。在刻意练习里,最好有一个“教练”,相比于你,他更知道这个高水平的特征是什么样的,可以根据你的情况给你一些高质量反馈。如果我们想在职业生涯中不断提升,最好也能有一个“教练”,他能够给我们引导,让我们找到自己突破的方向。当然,我们不太可能像运动员一样找到一个时刻在身边的教练,但我们可以找一个定期给于我们指导的人,这个角色更类似于我们传统中的“师父”。下一讲,我们就来聊聊如何做“师父”的好弟子。
总结时刻
这一讲我们讲的是刻意练习,这是一种有目的且系统的练习方式,可以让我们摆脱日常盲目的练习,有效地帮助我们进行提升。刻意练习有一些特点:要有明确的目标,要在学习区学习,要有反馈,还有保持专注。
对程序员来说,我们可以在日常学习工作中进行刻意练习,其关键就是为自己找到练习。有现成的练习是最好,如果没有,就自己设计一些练习,无论是编写一个软件,还是写一些文章,做一些输出,都可以。
现在,有了 AI 的加持,我们可以让 AI 帮我们设计一些逐步提升的小练习,这样,可以更好地降低练习的门槛。
在自我提升的道路上,我们最好还是要找到“教练”,让他帮我们破开思维迷雾,帮自己能够窥见更高的水准。
如果今天的内容你只能记住一件事,那请记住,刻意练习,才能真正地提升。
思考题
我在这一讲里给你介绍了刻意练习,其实,每个人应该有过“刻意”地进行练习的过程。你可以回想一下自己的职业生涯中,做过哪些练习让你在短时间内有过很大的提升。期待在课程作业和学员群中看到你的思考,我们课上见~
目标、学习区、反馈这三样,课程里都有对应的安排:每周一个明确的交付物,内容在你现在的能力之外,做完了有验收,卡住了有人答。
原文:郑晔,极客时间专栏《10x 程序员工作法》加餐「通向高手之路」
12 10|教练:我该如何向高手学习?
你好,我是郑晔!
上一讲我们讲到了刻意练习,最后,我们强调了教练在刻意练习中的作用。虽然在成年人的世界里,自学是最主要的学习方式,但如果有一个教练能够给予我们帮助,这将大幅度提升我们的学习效率。
不过,道理是没错,但别人凭什么给我们提供帮助呢?小李也有同样的疑问,于是,他又找到了老赵。
- 小李:老赵,多谢你这段时间给予了我很大的帮助。
- 老赵:没什么,举手之劳。
- 小李:我其实还有一个疑问。
- 老赵:说来听听。
- 小李:你这么资深,而且工作这么忙,可是你为什么愿意帮助我呢?
- 老赵:因为和你交流很有意思啊!
- 小李:有意思?
- 老赵:年轻人有很多,想提升的也有很多,但大部分人都缺乏深入思考。你很热爱编程,也很愿意思考。你问的很多问题都是经过深思熟虑的。
- 小李:我不好意思总麻烦你,所以,我会先探索,实在解决不了再来问你。
- 老赵:我愿意回答问题,但不愿意回答那种不过脑子,搜一下就有答案的傻问题。而你从来不问傻问题,所以我愿意与你交流,这能激发我进一步思考。
小李是幸运的,有一个愿意帮助他的老赵,但正如老赵所说,他愿意帮助小李,因为帮助小李对他也有促进。从某种程度上,二者是相互促进的,形成了一个正向反馈。
每个人都想有这样的教练,不过,有两个问题是我们需要解决的:如何找到一个教练,以及如何让教练愿意帮助我们。
身边的教练
如果想要找到一个教练,我们可以在身边找,也可以远处找。我们先来看看怎样在身边找教练。
很多有点规模的公司都有导师制度,他们会为新员工配置一个导师,其目的是帮助新员工更好地融入公司。对我们而言,这个导师就是我们这个阶段的教练。即便公司没有这样的制度安排,加入一个团队,我们也会很快发现团队里哪些人适合成为自己的教练,比如,项目的技术负责人或是经验丰富的同事。
当然,这里同样有一个问题,如果公司没有这样的人事安排,人家凭什么要来帮助你。这就需要我们自己积极主动,先和这个人建立起良好的私人关系,一旦建立起私人关系,剩下的事情就水到渠成了。
对很多程序员来说,解决技术问题是很简单的,与人打交道往往是更有挑战的一件事。
一方面,有很多经验丰富的人并一定适合做教练,他更擅长的是单打独斗,而且,很多程序员并不善于表达,自己可能身怀绝技,但并不一定能够给予他人很大的帮助。另一方面,“不好意思”往往是阻碍经验浅的程序员前进的一个重要因素。没有人有义务主动帮助你,你能从别人身上获得怎样的收获,完全取决于你有多积极主动。
其实,大多数程序员还是很愿意聊技术、开发相关的各种东西,多找机会聊聊,你就会有所收获。
我初入职场的时候,刚好有机会和当时的项目负责人聊天,一开始我也没什么功利的目的,只是觉得和他聊天挺有收获的,也就经常问他一些问题。一来二去,他也觉得和我聊天挺有意思,我们俩就越聊越多。
我从他身上学到了很多东西,他也找到了一个能与他深入聊编程的人。与他的沟通,让我少走了很多弯路,那段时间成了我职业生涯中成长最快的一段时间,也为后面的职业发展奠定了一个非常好的基础。
身边的人给予我们的帮助,通常是眼前的事情。如果我们想进一步扩展视野,有时候,身边的人可能就不够了。随着成长,我们也必须把视野打开,远方的人一样可以成为我们的教练。
远方的教练
在我起步的那个年代,接触远方的人主要是通过一些论坛或是邮件列表,不过,这种沟通方式效率并不算高,因为论坛或邮件列表并不能让一个人有完整的表达,所以,我们只能从这些高手的只言片语中学习。
现在则有了更方便的途径。最常见的就是很多在线的课程,而这些课程的作者本身就已经在扮演老师的角色,一方面,他们已经把自己的思想做了一个完整的总结,另一方面,很多人也乐见有更多的反馈回来。所以,通过在线的课程,我们就有机会结识到更多水平不错的老师。
还有一个找到远方高手的途径是参与开源项目。相比于课程,开源项目的实践性更强。
一个稍微流行的开源项目都会有不少的参与者,而且一般来说,开源项目参与者的平均水平是高于通常的公司团队的平均水平。所以,如果有机会参与到这些项目中,我们的代码将得到这个高水平团队成员的评审,这对于提升个人的编程水平大有助益。
现在参与到一个开源项目的门槛已经大幅度降低了,找一个自己喜欢的项目,从给这个项目提 Issue 开始,慢慢地熟悉代码、提 PR,逐渐参与其中。
如果我们把眼光再放开阔一些,我们甚至可以向行业中的顶级大牛学习。当然,让他们近距离指导我们并不容易,但我们依然可以从他们的故事中学到很多东西。
在编程领域,有很多传奇故事。通过阅读一些书,我们有机会看到这些行业大牛是怎样一步一步成长起来的。对我来说,正是这些大牛的事迹,让我看到了什么叫热爱。
推荐两本当年让我看得热血沸腾的书,一本是 Linus Torvalds 的《只是为了好玩》,它讲了 Linus 打造 Linux 操作系统的故事,其中最打动我的是 Linus 讲述了自己打造初始版本 Linux 的过程,那是一个纯粹程序员的热爱。
还有一本是《DOOM 启世录》,它讲述了 ID Software 的发展历程,这个公司打造了 DOOM 和 Quake 两款影响力极大的游戏,深刻地影响了今天的软件开发。其中的关键人物是约翰·卡马克,一个天才程序员,书中有一段他打造引擎时的工作日志,其中他回顾了自己的成长过程,把一个遥不可及的大牛还原成了一个追求进步的普通人。
向高手学习
我们希望向高手学习,不过,**没有人平白无故地就会帮助你,人家帮助你是因为他觉得帮助你有价值。**此外,我们还要知道,大部分程序员都有着一些内心的骄傲,如果一个人不能在他们欣赏的领域内证明自己的价值,他们在内心里会低看这个人,这也是很多程序员与产品经理产生矛盾的重要原因。
向高手学习,一个前提条件是我们先要竭尽全力。**没有高手愿意回答浅白问题,如果一个问题上网搜索一下就能得到答案,就不要浪费别人的时间了。**所以,我们最好先在一个问题上竭尽全力去探寻一个答案:可能是在网络上搜索,可能是阅读相关的技术手册,可能是问问身边的朋友,也可能是阅读一下相关的源码。
或许你会说,如果我竭尽全力,结果把问题解决了呢?那不就是最好的答案了,我们本质上需要的自我提升,向其他人学习只是一种手段,如果我们已经把问题解决了,已经完成了自我提升,是不是向别人请教就不那么重要了。
想向别人提出高质量的问题也是需要一定技巧的。关于如何向别人提问,让我受益量多的是 Eric Raymond 写的《提问的智慧》,我强烈推荐每个程序员读读这篇文章。
Eric Raymond 是 Open Source 这个概念的提出者,也是著名的开源运动文集《大教堂与市集》一书的作者。他在职业生涯中,看到过各种人在各种渠道的讨论问题,所以,他才写了这篇《提问的智慧》,教新手如何提问。
《提问的智慧》属于跨越时间的文章,作者会根据一些情况进行更新,所以,在这篇文章里,我们会看到 IRC 这种久远的沟通方式,也能够看到 Stack Overflow 这种常见的问答网站,重点是其中的沟通技巧是跨越时间的存在,至于是邮件,还是问答网站,只是沟通的途径而已。
**无论是身边的教练,还是远方的高手,我们都很难一上来就向他们提出有深度的问题。**大家的关系都是随着合作次数的增多而深入起来,而建立深入的关系需要我们长期去维护。
如果有一个可以帮到自己的教练,那么我们需要多付出一些去维系这种关系,相比于得到的回报,这是一件非常划算的事情。
总结时刻
这一讲我们讲了教练在一个人成长过程中的重要性。在成年人的世界里,别人不会无缘无故地帮助你。想要拥有一个可以帮助自身成长的教练,我们需要证明自身的价值,形成与教练之间互相促进。
我们可以在身边找到教练,无论是公司安排的导师,抑或是项目中资深的同事,都可能成为我们的教练。但想要从他们身上学习到更多,需要我们积极主动,与教练建立起良好的私人关系。
我们也可以在远方寻找高手成为我们的教练,可以是课程的老师,也可以是开源项目的成员,同样,也需要我们积极参与,从他们身上学习更多。当然,我们还可以向行业中的顶级大牛学习,现在有很多讲述他们成长经历的书,可以让我们从中汲取营养。
想从高手身上学到东西,重点还是要自己积极主动,证明自身价值。向高手提问之前,我们需要竭尽全力自己去找寻答案。关于如何提问,我推荐你去读读《提问的智慧》。
如果今天的内容你只能记住一件事,那请记住,积极主动地向教练学习。
思考题
这一讲我们讲了如何向教练学习。回想一下你一路走来的职业经历,有哪个“教练”对你提供了很大的帮助?期待在课程作业和学员群中看到你的思考,我们课上见~
找个好教练并不容易,这门课把教练配好了:讲师直播答疑、结业答辩逐一点评。带上你竭尽全力后仍卡住的地方来,就是一次高质量提问。
原文:郑晔,极客时间专栏《10x 程序员工作法》加餐「通向高手之路」
13 11|通才:我该如何不断拓宽自己的边界?
你好,我是郑晔!
前面我们讲了很多东西,本质上都是在说如何在自己的专业技能上不断精进。不过,**到底哪些东西算是自己的专业技能呢?**这个问题的答案往往是随着一个人的不断成长而逐渐变化的。
我们再从小李的故事开始。
在小李的眼中,技术负责人老赵不仅仅是技术厉害,而且知识面非常广,很多自己没有太听说过的东西,老赵都能够有很深刻的理解。他就好奇地问起了老赵。
- 小李:老赵,我觉得一个人做到技术牛已经很厉害了,但你不光是技术厉害,像什么历史、商业、金融等等,很多东西你都知道,而且都有很深的理解。
- 老赵:工作时间长,你的边界自然会扩展。
- 小李:你在技术牛,我很容易理解,你这都扩展到技术之外去了。
- 老赵:很正常,我们都要工作在现实世界里,随着工作职责的拓宽,必然要和很多非技术人打交道。不懂点技术之外的东西,和人家聊不到一起啊。而且,我也不想只是做一个实现功能的工具人,我也想贡献更多的价值,所以,我必须不断地拓展自己的边界。
“工具人”说法显然触动了小李。随着近期 AI 的兴起,一些基础工作用 AI 来完成,质量可以接受,关键是速度极快。尽管小李的能力还不错,但他知道,仅凭自己现有的技术能力,并没有足够的说服力证明自己就一定比 AI 强。
- 小李:我是不是也该学点技术之外的东西呢?
- 老赵:当然了,以我对你的了解,你的技术底子已经算打得比较扎实了,可以去做一些扩展了。
- 小李:那我该学什么呢?
- 老赵:就是学点技术之外的东西。
**一个程序员的成长过程,就是一个边界不断拓展的过程,从解决代码问题,到解决软件开发过程中的问题,再到解决现实生活中的各种问题。**在这个过程中,我们所掌握的知识也需要不断的拓展。
刚开始的时候,我们追求的只是写出满足需求的程序,然后拓展到我们这个专栏提到的关于软件工程方面的各种内容,随着我们的继续成长,边界还会继续拓展。
打开视野
我们的工作基本上就是一个“发现问题 - 解决问题”的循环。作为程序员,我们的主要精力都在解决问题上,但你是否想过,我们解决的问题是从何而来呢?如果只是扮演解决问题的角色,我们就会产生“工具人”的感受。所以,在工作中,我们一定要学会发现问题。
不同的问题价值是不同的。大部分程序员能够发现的就是日常工作中的问题,即便解决了这个问题,影响力也是极其有限的。优秀的程序员能够发现通用的问题,比如,你开发了一个通用的框架或是搭建了一套基础设施,其影响力可以扩展到公司,甚至研发社区的层面,但这也仅限于程序员范围之内。
一个公司要想要运营起来,往往需要解决更大的问题,比如,即时通信或是电子商务。我们不难发现,一些公司,甚至是技术公司,其创始人也不是技术出身,但偏偏他们就能发现一些好的问题去解决。
能够发现怎样的问题,往往是由一个人的经历和视野决定的。
如果有机会近距离接触这些人,你会发现,他们可能不是某个方面的专家,却是一个通才,具备很多方面的知识。这样的知识结构,让他们有机会把一些看似不相干的事情联系起来,找到一些创造性的解决方案。最广为人知的故事就是乔布斯把他在书法课上学到的设计应用到了 Mac 的字体设计上。
对比之下,程序员的思考通常会局限在技术维度上。我在《40 | 我们应该如何保持竞争力?》中说过,我们要成为 T 型人才,也就是“一专多能”。对于很多程序员来说,前面几讲所谈到的内容都是在说如何精进,具备“一专”,成为专才。而在“一专”之后,我们就要打开自己,让自己变得“多能”,成为通才。
传统教育体系的关注点常常在单一技能上,欠缺一些打通多学科知识的培养。这种思路延续到工作中就是,作为个体的我们更擅长的是自己的专业技能,具体的表现就是擅长解决问题,而非发现问题。
在工作中,有很多“好”员工,他只负责执行,却很少思考这个东西为什么是这样的。造成的结果是,工作中常常有不合理的地方,却很少有人会质疑。因为这些东西是“上边”的人提出来的,我们自己就会把他们的行为合理化,认为他们一定有自己的道理。为什么不质疑?有时候是不敢,但很多时候,我们无法判断很多决定的合理性,其原因就在于,我们缺少了一些思考的维度。
碎片学习
现在,我们已经意识到了,自己在思考上缺少一些维度,那该怎样让自己的思考维度丰富起来呢?最简单的答案就是学一些技术之外的东西,学习什么不重要,重要的是需要大量地学。
至于具体学什么东西,我们完全可以根据自己的喜好入手,有人喜欢历史,有人喜欢经济,有人喜欢商业,有人喜欢科学。其实在今天的社会上来说,这些都是应该知道的东西。我在这里强调的是从你喜欢的东西入手,也就是说,别的东西也要学,只不过优先级可以稍稍往后放一些。
一说到要学技术之外的东西,还要大量地学,很多人恐怕要打怵了。然而我们需要知道,这里所谓的学,不是为了考试,而是为了扩展自己的知识面。所以,我们的学习并不需要像在学校一样正襟危坐,认认真真地记笔记、答卷子。知道了这一点,我们就学得轻松了。只要找一些资料,把其中的内容过一遍,有一个大概了解就好。只要积累的量足够,这些知识自然会在你的头脑中产生连接。
你可能会想,即便我只是大概过一遍,也需要投入足够多的时间才可以。现在每天工作那么忙,我哪有时间去大块地投入呢?且不说我们每天浪费了大量的时间在游戏、短视频上,成年人也确实很难有整块的时间投入到一件事上,但我们有的是碎片时间:上下班通勤路上、写码之余的放松时间、中午午休的时间,都是我们可以利用起来的。
现在有了许多知识服务平台,让我们有机会实现用碎片时间进行学习。
就我个人而言,最重要的学习平台是《得到》和《极客时间》,我在这两个平台都订阅了大量的专栏,通过碎片时间的学习,了解了很多我之前不知道的东西。既然这里主要讨论的是技术之外的内容,我就以《得到》为例来谈谈如何学习。
**首先是学习什么。**如果一个程序员没接触过《得到》,那么其中的大部分内容都是新东西,我的建议是从一些通识类的课程学起,比如:经济学、金融学、历史、心理学、医学、法律、商业等等。
如果看课程列表,你会发现同一品类下有很多类似的课,我们可以从一些能帮助我们形成整体认识的课程开始,比如:
- 薛兆丰的经济学课
- 香帅的北大金融学课
- 施展·中国史纲·时间篇
- 李筠·西方史纲 50 讲
- 李松蔚·心理学通识
- 薄世宁·医学通识 50 讲
- 刘晗·法律思维 30 讲
- 5 分钟商学院
- ……
这些课程可以帮我们快速地形成对某个领域的初步认识,然后再想学什么,就可以根据自己的需要进一步展开了。
就我个人来说,除了这些知识性的内容,我还喜欢学习一些相对前沿的,所以,我个人会学习万维刚、吴军和卓克几位老师的课程,他们的课会给我打开一些不一样的视角,让我知道世界顶级大脑在思考哪些内容。
**再来说说怎么学。**可能光看我列出这么多内容,很多人已经打退堂鼓了。实际上,我当年学习这些课程的时候,都是利用碎片时间进行学习的。之所以我能够用碎片时间进行学习,这是因为音频的崛起。
我们需要理解的一点是,所有的学习方式都是建立在一定的技术条件下。比如,我们一直说要好好读书,“读”这个行为是建立书面呈现的基础上,而现在的一些小朋友从小习惯的方式是“看”视频学习。而随着智能手机的兴起,“听”也变成了一种重要的学习方式。
音频最大的优点就是它可以不过分占据人们的注意力,这使它可以成为碎片时间学习的利器。
《得到》也是很早就意识到音频的重要性,大部分专栏内容都是有音频的。于是,通勤路上听《得到》就成了我的日常习惯。《得到》的内容还有一个非常适合碎片学习的特点是,每篇内容都很短,大约在 10 分钟左右,文字稿也就是三千字上下,这让我们可以随时随地选取一个主题进行了解,而不会占用大把的时间。
听音频还有一个好处,就是可以开启倍速播放。相比于人类接收信息的速度,人的语言表达是很慢的。有人曾经做过一个试验,采用 1.2 倍速播放,大多数人根本听不出来,所以,你至少可以采用 1.2 倍速来听音频。如果你习惯了 1.2 倍速,把速度调到 1.5 倍速,你可能也不会觉得有什么大不了的。接下来,你很可能会进化到 2 倍速。不知不觉中,你吸收信息的速度就会大幅度提升了。
事实上,不仅是专栏,现在很多电子书都提供了听书的能力。我曾在自己的公众号上写过一篇《书一定要“读”吗?》分享过自己的“听”书心得,有兴趣不妨了解一下。
正是因为改变了学习方式,相比于从前,我的信息摄入量大了好多。每年我都可以学习很多的专栏、听几十本书。因为知识面的扩大,视野也比从前宽阔了许多:原本我的思维只局限在技术范围内,而如今我能从更宏观的视角去看待许多问题,对世界的理解也更深刻了,这反过来也会让我更好地理解自己所写的每一行代码。
总结时刻
这一讲,我们把目光从技术思维扩展开来,一个高手可不仅仅局限在技术之内。程序员应该跳脱“工具人”思维,从单纯的问题解决者,变成问题的发现者,从发现身边问题,到发现更大的问题。当一个程序员已经具备相当的技术基础之后,他可以尝试拓展自己的能力边界,由一个专才向一个通才转变。从一个程序员的职业发展来看,更宽广的视野也有助于得到更多的机会。
程序员想要拓展自己,关键是要拓展自己的思考维度,而想要拓展思考维度,最简单的答案是学习一些技术之外的东西,而且是要大量地去学。
对于专业技能之外的学习,我们可以不求甚解,利用碎片时间完成大量的知识输入。我们可以通过很多音频课程学习,或者通过“听”书的方式学习。这个过程不是一蹴而就的,日积月累,我们就会发现自己一点点地在进步。
如果今天的内容你只能记住一件事,那请记住,利用碎片时间,大量地学习一些技术之外的东西。
思考题
这一讲,我们讲了一个程序员在奠定技术基础之后,应该积极地拓展自己。你在技术之外,有哪些感兴趣的主题,系统地学习过什么东西吗?期待在课程作业和学员群中看到你的思考,我们课上见~
到这里,这次课程迭代的内容就告一段落了。如果以后有机会,我会再来与你分享我对软件开发的理解,再见!
不当「工具人」,靠的是判断力。这门课面向有几年经验的程序员,把你踩过的坑变成对 Agent 技术选型与成本的判断——拓宽的正是技术之外的维度。
原文:郑晔,极客时间专栏《10x 程序员工作法》加餐「通向高手之路」
14 12|Agent 开发到底在开发什么:五个要素讲清楚
随便打开一个大模型对话框,你都有一个会聊天的 AI。但会聊天和能干活是两件事,中间差的那一截,就是 Agent 开发。
8 周下来要交的东西只有一个:一个能公网访问的 Agent 服务。别人点开就能聊,它有自己的资料和工具,花掉多少钱也记在账上。这样一套服务拆开看是五个要素,课程一周练一个。
模型:一次思考的智力(第一周)
Agent 的「大脑」,是一次又一次的模型调用。而调用质量的分水岭在提示词——郑晔老师在《程序员的 AI 三重境界》里给过一个公式:提示词 = 定义角色 + 背景信息 + 任务目标 + 输出要求。
第一周你从写一篇 System Prompt 开始,做一个文章总结器:粘贴长文,流式输出结构化总结。同时搞清楚一件反直觉的事:这个系统里哪些是确定性的(你的代码),哪些是概率性的(模型的输出)——这个区分,会贯穿你后面所有的设计决定。
记忆:会记,也要会忘(第二周)
模型本身没有记忆,每次调用都是初见。聊天机器人之所以「记得你」,是工程师把对话历史塞回请求里的结果。但上下文窗口既贵又有限——第二周你会先亲手触发一次超出上下文的报错,再实现两种记忆策略(滑动窗口、摘要记忆),并用 SQLite 把会话持久化。验收标准很直白:连续 20 轮对话人设不崩、重启历史不丢。记忆从玄学变成工程。
工具:从「会说」到「会做」(第三周)
只会输出文字的模型,什么也改变不了。给 Agent 接上工具——查文件、算数字、调接口——它才开始做事。第三周你设计自己的工具 Schema,跑通完整的工具循环,同时上一道闸:权限白名单与危险操作确认。能干活,但不越权。你也会搞清楚 MCP 与 Skill 各自解决什么问题——今天接工具,已经比一年前规范得多。
知识:让服务懂你的资料(第四周)
模型知道的是通用世界,不知道你的文档、你的业务。RAG 的思路很朴素:提问时,先把相关资料检索出来,连同问题一起交给模型。第四周你独立实现索引与检索两条流程,并且用 10 个测试问题度量命中率:答对 8 个以上、答案带出处,才算过。做知识库不难,难的是知道它什么时候答错、为什么答错。
循环:给目标,不给步骤(第五周)
单次调用是「问一句答一句」;Agent Loop 是「给个目标,它自己规划、调用工具、检查结果、决定下一步」。第五周你只给目标不给步骤,让服务自主完成一个至少 3 步的任务——同时装好三道护栏:最大循环次数、成本闸、计划批准。自主,不等于放任。
比实现更重要的:判断
五个要素学下来,比「都会做」更重要的是「知道该用哪几个」。课程里有一句贯穿始终的话:
提示词能解决的不上 RAG,规则能解决的不上 Agent。
每加一层,能力在涨,复杂度、成本和不可控性也在涨。成熟工程师的标志不是五层全用上,而是说得出「这个需求为什么到提示词就够了」。郑晔老师在企业里讲 AI 落地时给的是同一个判断:确定性需求用传统方式做,即便要做 Agent,也优选单 Agent。最后两周的工坊,你会对着自己的大作业做一次完整的分层选型判断,并算出月成本账。
8 周之后
五个要素各练一周,第六周部署上线(公网可访问、重启不丢、密钥不入库),最后两周是你的大作业工坊——中期检查、集中辅导,最后做展示答辩。最终它们组装成你的个性化 Agent 服务。至于这个服务做成什么样,取决于你走哪条路:见《先看这里:为什么训练判断力,比学会搭建 Agent 更重要》;每周你能做出什么、说清什么,见《8 周,三条路径,一个公网可访问的服务》。
15 13|8 周,三条路径,一个公网可访问的服务
8 周下来的成品是一个能公网访问的 Agent 服务。它不是第八周才开始赶的东西:从开营前的预习算起,每周的主线项目都在给它添一块。
8 周分成两个阶段:前六周做主线,每周给你的服务加一个能力;最后两周是你的大作业工坊,把它做成你自己想要的样子。
每周你能做出什么
- 开营前:完成预习与准备——跑通环境自检、完成第一次 LLM API 调用,登记大作业选题意向。
- 第一周:一个文章总结器——粘贴一篇长文,流式输出结构化总结,并能说出本任务中确定性/概率性的拆分。
- 第二周:一个记得住你的聊天机器人——连续 20 轮人设不崩、重启历史不丢、/clear 生效,人设为可配置模板。
- 第三周:一个带工具的助手——一句话完成建文件,外加至少一个你自选的新工具可演示。
- 第四周:一个自己的资料库——10 个测试问题命中率 ≥ 8/10、答案带出处,附命中率记录表。
- 第五周:一个会自己干的 Agent——只给目标不给步骤,自主完成 ≥3 步任务,附轨迹与花费报告。
- 第六周:一个上线的服务——公网可访问、流式对话、重启不丢、key 不在代码库。
- 第七周(工坊):说清自己的方案——通过中期检查三件套(可访问地址、演示录屏、成本预估),并对大作业做分层选型判断、算出月成本账。
- 第八周(工坊):讲清自己的作品——按「场景一句话 → live demo → 亮点 → 成本账」完成 5 分钟展示,答好三类标准问题(为什么这方案、成本怎么算、出错怎么办)。
每一周都在为大作业攒模块
大作业和每周练习不是两件事。课程主线只有一条:从开营前登记选题起,每周给你的服务加一个模块——
- 信息处理
- 人设与个性化
- 功能扩展
- 知识与出处
- 自主执行
- 公网上线
前五周每周练一个能力,第六周把它部署成公网服务,最后两周围绕你自己的大作业做中期检查、集中辅导与展示答辩。
往哪儿加深,按需选
结业只有一个标准:8 周后你手上有一个能公网访问的 Agent 服务,并且讲得清它怎么做的、成本怎么算。答辩按四项成果(项目仓库、可访问服务、演示录屏、答辩材料)与四条标准(实现、判断、验证、复盘)逐一对照。
至于往哪个方向加深,不用先给自己归一类:想先把服务跑起来,就改提示词与配置项;想练动手,就在基础代码上定向加一个能力(记忆、工具、RAG、循环,四选一);想练工程判断,就往成本、安全护栏、效果数据里扎。这三条只是可选清单,具体怎么选,报名前对照课程详情页的说明即可。
下一步
- 不确定加深到哪一步 → 看课程详情页的按需选择;也可以先读《先看这里:为什么训练判断力,比学会搭建 Agent 更重要》
- 想知道这个服务拆开由什么构成 → 读《Agent 开发到底在开发什么:五个要素讲清楚》
- 想看更细的周安排、验收标准与报名信息 → 课程详情页