LLM辅助编程下Python、TypeScript、Go的协作效能对比
1. 项目概述:这不是一场语言“擂台赛”,而是一次开发效率的精准测绘
最近在带一个AI原生应用团队,我们每天要写大量胶水代码、工具脚本、API服务和本地Agent调度逻辑——不是在调用LLM API,就是在把LLM输出转成可执行的结构化动作。某天晨会,后端同学说:“我用Go写了个RAG路由分发器,300行,编译完8MB,启动200ms”;前端同学立刻接话:“我用TypeScript写了个IDE插件,实时解析用户自然语言指令生成VS Code命令,热更不重启,改完保存就生效”;而数据工程同事默默打开Jupyter,贴了段Python代码:“我让LLM帮我把17个SQL方言的ETL逻辑自动转成Spark DataFrame操作,5分钟跑通,改了3次prompt就对了。”没人争论谁“更强”,但所有人都在问同一个问题: 当LLM成为你的“副驾驶”,哪种语言能让它真正飞起来? 这不是比谁语法糖多、谁生态库全,而是比谁最能承接LLM的“认知输出”——它的思维链是否容易被语言结构捕获?它的错误推理是否能被类型系统或运行时快速拦截?它的增量修改是否能被开发环境零摩擦消化?Go的确定性、Python的表达力、TypeScript的渐进式约束,三者在LLM辅助编程这个新范式下,呈现出完全不同的“适配曲线”。本文不提供“终极答案”,而是基于6个月、12个真实项目(含生产级LLM Router、本地代码补全引擎、自动化测试生成器)的实测数据,拆解三门语言在 提示词理解保真度、错误反馈闭环速度、上下文感知重构能力、以及人机协作熵值 四个维度的真实表现。适合正在选型AI原生工具链的工程师、想提升Copilot使用效率的日常开发者,以及对“AI如何改变编程本质”有技术好奇心的技术负责人。
2. 核心设计思路:为什么必须放弃“性能基准测试”的旧框架?
2.1 LLM-Assisted Programming 的本质是“人机协同工作流”,不是“纯计算任务”
传统语言对比常陷入两个陷阱:一是拿微基准(如JSON解析吞吐量)说话,二是用“Hello World”式代码量做判断。但在LLM辅助场景下,决定效率的从来不是单次函数执行快慢,而是整个 人机反馈环的耗时总和 。我把它拆成四个可测量环节:
-
Prompt to Code 转换保真度 :LLM输出的代码,是否能被语言环境“原样接受”?比如LLM生成
for i in range(len(arr)):,Python直接跑;但若生成for (let i = 0; i < arr.length; i++) { },TypeScript需手动补const和类型注解,Go则根本无法识别let关键字——这里损失的不是毫秒,而是开发者中断心流去纠错的15秒。 -
Error to Fix 修复速度 :当LLM代码报错,语言能否提供 指向性极强的错误信息 ?Python的
TypeError: 'str' object is not callable常让人懵圈;TypeScript的Argument of type 'string' is not assignable to parameter of type 'number'直接标出变量名和行号;Go的cannot use "hello" (type string) as type int in assignment则连类型名都给你框出来。实测显示,TypeScript平均修复时间比Python快42%,因为错误信息本身已包含90%的修正方案。 -
Context-Aware Refactor 感知重构能力 :当LLM建议“把这个函数拆成两个,一个处理验证,一个处理存储”,TypeScript的VS Code能一键提取方法并自动更新所有调用点;Python的PyCharm需手动确认每个引用;Go的gopls虽支持,但对未显式声明接口的代码重构保守。这决定了LLM提出的架构优化建议,有多少能被“秒级落地”。
-
Human-AI Entropy 人机协作熵值 :这是最关键的隐性指标——指开发者为“驯服”LLM输出所付出的额外认知负荷。比如Python中LLM常生成
import pandas as pd; df = pd.read_csv(...),但实际项目用的是Polars,开发者得手动替换;TypeScript中LLM默认用any类型,但团队规范要求unknown加校验;Go中LLM爱写fmt.Println调试,但日志规范强制用log.Printf。这些“规范对齐成本”在Python中靠约定,在TS中靠ESLint规则,在Go中靠go vet静态检查——三者拦截时机和严格度天差地别。
提示:不要用“我的项目用Python跑得飞快”来反驳。LLM辅助编程的瓶颈从来不在CPU,而在开发者大脑的上下文切换频率。你每手动修正一次LLM的类型错误,就消耗一次短期记忆带宽;每重读一遍报错堆栈,就延长一次注意力恢复周期。真正的效率,是让LLM的“不完美输出”尽可能靠近“开箱即用”。
2.2 为什么选这三门语言?它们代表三种人机协作范式
-
Python :代表“ 表达优先范式 ”。它的设计哲学是“可读性即正义”,LLM天然倾向生成符合PEP 8的代码。但代价是:类型模糊性放大了LLM的幻觉风险。比如LLM生成
def process(data): return data.upper(),它既可处理字符串,也可被误用于字典——Python运行时才报错,而此时开发者已写了5个调用方。 -
TypeScript :代表“ 契约优先范式 ”。它强制LLM在生成代码前,先“想清楚接口”。当你让Copilot写一个HTTP客户端,它必须先定义
interface ApiResponse<T>,再实现fetchData<T>(url: string): Promise<ApiResponse<T>>。这种“契约前置”极大压缩了LLM的自由发挥空间,但也让它的输出更可靠。实测中,TS项目LLM首次生成通过率(无需修改即可编译)达68%,Python仅31%。 -
Go :代表“ 确定性优先范式 ”。没有类、没有继承、没有泛型推导(早期版本),一切行为由语言规范明确定义。LLM生成
bytes.Buffer用法时,几乎不会出错,因为Go标准库API极其稳定。但它的短板在于“表达贫瘠”——LLM想生成一个带缓存的异步任务队列,Python可用asyncio.Queue+functools.lru_cache组合,TS可用Promise.allSettled+Map,而Go必须手写sync.Map+chan+select,LLM常因过度简化逻辑而出错。
这三种范式没有高下,只有匹配度。就像给不同性格的副驾驶配车:Python适合“创意型驾驶员”(需要快速试错),TS适合“流程型驾驶员”(需要步骤清晰),Go适合“可靠性驾驶员”(需要结果确定)。
2.3 实验设计:我们到底在测什么?(附真实项目对照表)
我们拒绝人造benchmark,全部基于真实项目脱敏数据:
| 项目类型 | Python代表项目 | TypeScript代表项目 | Go代表项目 | 核心LLM任务 |
|---|---|---|---|---|
| 本地开发工具 | llm-testgen :自动生成单元测试用例 |
copilot-cli :VS Code插件,解析自然语言生成命令 |
go-lsp-ext :扩展gopls,添加LLM驱动的代码解释功能 |
将用户描述(如“测试用户登录失败场景”)转为可执行代码 |
| API服务层 | rag-router :动态路由请求到不同LLM模型 |
ai-gateway :统一API网关,处理鉴权/限流/审计 |
llm-proxy :轻量代理,转发请求并注入trace ID |
解析用户prompt,选择最优模型并构造请求体 |
| 数据处理管道 | sql-translator :将自然语言SQL需求转为Pandas/Polars操作 |
json-schema-gen :根据LLM描述生成TS接口定义 |
log-parser :实时解析日志流,提取结构化字段 |
将非结构化文本(如“找出所有status=500的请求”)转为可执行过滤逻辑 |
所有项目均满足:
- 使用同一套LLM(GPT-4-turbo,temperature=0.3)
- 同一Prompt模板(Role + Task + Input Format + Output Format + Examples)
- 同一评估人(我本人,12年全栈经验,熟悉三门语言)
- 同一衡量标准: 首次生成可用率 (FGR)、 平均修复轮次 (ARL)、 上下文重构成功率 (CRS)
关键发现:Python在FGR上垫底,但在CRS上意外领先——因为它的动态性允许LLM用 getattr(obj, method_name)() 绕过类型检查,快速实现原型;TS在FGR和ARL上双优,但CRS依赖编辑器智能,遇到复杂泛型推导时会卡住;Go在ARL上最稳(错误信息直击要害),但FGR最低,因为LLM常忽略 error 返回值处理。
3. 核心细节解析:三门语言在LLM协作中的“隐藏机制”
3.1 Python:动态性是双刃剑,类型提示是LLM的“缰绳”
Python的 duck typing 让LLM可以天马行空,但也埋下巨大隐患。举个真实案例:在 sql-translator 项目中,LLM生成如下代码:
def translate_natural_query(query: str) -> pd.DataFrame:
# LLM生成的伪代码,实际用了正则提取关键词
if "average" in query.lower():
return df.groupby("category").mean()
elif "top" in query.lower():
return df.nlargest(10, "score")
else:
return df # 这里df未定义!
这段代码在Jupyter里能跑(因为 df 在上一个cell定义了),但作为独立模块会直接 NameError 。LLM没意识到 df 是外部依赖,它的“思维链”停留在“我要返回DataFrame”,而非“这个DataFrame从哪来”。
解决方案不是禁用动态特性,而是给LLM装上“类型缰绳” :
-
强制启用
--enable-preview的typing.Annotated:让LLM明确知道参数来源。例如,Prompt中要求:“所有输入DataFrame必须标注为Annotated[pd.DataFrame, 'source: user_upload'],所有输出必须标注Annotated[pd.DataFrame, 'transform: groupby_mean']”。这样LLM生成代码时,会主动思考数据血缘。 -
用
pydantic.BaseModel替代裸dict :LLM生成{"user_id": 123, "score": 95.5}时,Python不报错,但后续user_id + 1会崩。改为class UserScore(BaseModel): user_id: int; score: float,LLM必须生成符合Schema的字典,且user_id自动转为int。 -
mypy配置必须开启--disallow-untyped-defs和--disallow-incomplete-defs:这是最关键的。当LLM生成def process(x): ...(无类型注解),mypy立刻报错,逼迫开发者(或LLM)补全。实测开启后,FGR从31%升至52%。
注意:别迷信
@dataclass。LLM生成@dataclass时,常漏掉init=False或frozen=True,导致运行时意外修改。我们团队规定:所有LLM生成的dataclass,必须手动添加__post_init__做字段校验,哪怕只有一行assert self.score >= 0。
3.2 TypeScript:类型系统是LLM的“导航地图”,但过度依赖会迷路
TypeScript的强类型是LLM的福音,但也是陷阱。LLM最爱生成 any ,因为它最省事。在 copilot-cli 项目中,我们抓取了1000次LLM生成的函数签名, any 出现率高达67%。这不是LLM懒,而是它在“不确定用户意图”时的理性选择——用 any 规避类型错误,把决策权交给开发者。
真正的高效,是让LLM“不得不”思考类型 :
-
Prompt中嵌入TypeScript编译器错误示例 :在Few-shot示例里,放一段LLM生成的
any代码,然后紧跟$ tsc --noEmit的报错截图:“error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.”。LLM看到这个,下次生成就会倾向Record<string, unknown>。 -
用
const assertion锁定字面量类型 :LLM生成const status = ["pending", "done"];,TypeScript推导为string[],失去枚举语义。改为const status = ["pending", "done"] as const;,类型变为readonly ["pending", "done"],LLM后续生成if (s === "pendng")(拼错)时,TS立刻报错。 -
satisfies操作符是LLM的“类型锚点” :当LLM生成配置对象时,用satisfies强制校验。例如:const config = { timeout: 5000, retries: 3, endpoint: "https://api.example.com" } satisfies ApiConfig; // 即使ApiConfig有更多字段,这里也只校验存在的这比
as ApiConfig安全得多,LLM不会因字段缺失而静默失败。
实操心得:在VS Code里,把
"typescript.preferences.includePackageJsonAutoImports": "auto"关掉。LLM常生成import { createClient } from "@supabase/supabase-js",但实际项目用的是@supabase/auth-helpers-nextjs。自动导入会污染依赖,而手动Ctrl+Space触发的智能导入,会结合当前tsconfig.json路径映射,准确率高3倍。
3.3 Go:确定性是护城河,但“少即是多”原则让LLM束手束脚
Go的简洁性是双刃剑。LLM生成 http.HandleFunc("/api", handler) 时,几乎不会出错,因为 http.Handler 接口就一个 ServeHTTP 方法。但当任务变复杂,比如“实现一个带熔断的HTTP客户端”,LLM就容易翻车:
// LLM生成的伪代码(错误!)
client := &http.Client{
Transport: &circuitbreaker.Transport{ // Go标准库根本没有这个类型!
RoundTripper: http.DefaultTransport,
},
}
LLM混淆了社区库(如 sony/gobreaker )和标准库,因为Go官方文档里从不提“熔断器”。
让Go与LLM协作的关键,在于“标准化LLM的认知边界” :
-
构建
go.mod专属Prompt上下文 :在每次请求LLM前,自动注入当前项目的go list -m all输出。例如:你只能使用以下包: - net/http (std) - github.com/sony/gobreaker (v1.0.0) - golang.org/x/exp/slices (v0.0.0-20230228193153-1455a3b4e5b5) 禁止使用任何未列出的包,包括"google.golang.org/api"。这比让LLM“自己查文档”可靠10倍。
-
用
go:generate固化LLM输出模式 :对于重复性任务(如从OpenAPI spec生成Go client),我们写了一个//go:generate go run llm-gen.go --spec=api.yaml,内部调用LLM并校验输出格式。LLM只负责“内容生成”,不负责“代码结构”,结构由llm-gen.go模板保证。 -
errors.Is和errors.As是LLM的“错误指南针” :LLM常生成if err != nil { log.Fatal(err) },粗暴终止程序。我们强制Prompt要求:“所有错误处理必须用errors.Is(err, context.DeadlineExceeded)或errors.As(err, &target),禁止裸比较err == xxx”。这迫使LLM学习Go的错误哲学。
踩过的坑:别让LLM生成
goroutine调度逻辑。我们曾让LLM写一个“并发处理100个URL”的函数,它生成了for _, url := range urls { go fetch(url) },但忘了sync.WaitGroup或channel同步,导致主函数退出时goroutine被杀。后来改成固定模板:func fetchAll(urls []string) []Result { ch := make(chan Result, len(urls)); for _, u := range urls { go func(u string) { ch <- fetch(u) }(u) }; close(ch); return collect(ch) },LLM只填fetch函数体。
4. 实操过程:从Prompt设计到CI/CD的完整流水线
4.1 Prompt工程:不是写得越长越好,而是让LLM“知道自己的无知”
所有失败的LLM协作,根源都在Prompt没管理好LLM的“知识边界”。我们总结出三类必加Prompt组件:
-
Role Definition with Constraints(角色定义+约束) :
你是一个资深[Python/TypeScript/Go]工程师,专注AI原生应用开发。 你必须遵守: - Python:使用PEP 8,类型注解用`typing`模块,禁用`eval()`和`exec()`。 - TypeScript:所有函数必须有完整类型签名,禁用`any`,`unknown`必须校验。 - Go:所有错误必须显式处理,禁用`panic()`,`goroutine`必须有同步机制。 -
Input/Output Schema with Examples(输入输出Schema+示例) : 不是给LLM看“例子”,而是给它一个 可验证的契约 。例如:
输入:用户自然语言描述(字符串) 输出:严格JSON格式,包含: - "code": 字符串,可直接写入文件的代码 - "imports": 字符串数组,所需import语句(不含package声明) - "explanation": 字符串,用1句话解释核心逻辑 示例输入:"把列表里所有字符串转大写" 示例输出:{"code": "def to_upper(strings: List[str]) -> List[str]:\n return [s.upper() for s in strings]", "imports": ["from typing import List"], "explanation": "使用列表推导式遍历并调用upper()"} -
Failure Mode Injection(失败模式注入) : 主动告诉LLM“哪些错你常犯,这次不准犯”。例如:
常见错误: - Python:忘记`import`,用`pd`但没`import pandas as pd` - TypeScript:用`let`声明但未赋值,导致`undefined`参与运算 - Go:`http.Get`返回`*http.Response`,但忘记`defer resp.Body.Close()` 本次生成必须规避以上所有错误。
实测表明,加入Failure Mode Injection后,ARL(平均修复轮次)下降57%。因为LLM不是“不知道怎么改”,而是“不知道自己哪里会错”。
4.2 开发环境配置:让编辑器成为LLM的“协作者”,而非“翻译器”
LLM输出只是起点,编辑器才是最终执行者。三门语言的配置差异极大:
-
Python(VS Code + Pylance) :
- 关键设置:
"python.defaultInterpreterPath": "./venv/bin/python"(确保LLM生成的import与当前venv一致) - 必装插件:
Pylance(提供# type: ignore智能提示)、Black Formatter(自动格式化,避免LLM生成的缩进混乱) - 隐藏技巧:在
settings.json中加"python.analysis.extraPaths": ["./src"],让LLM生成的from src.utils import helper能被Pylance索引,否则它会建议import utils(错误路径)。
- 关键设置:
-
TypeScript(VS Code + TypeScript Server) :
- 关键设置:
"typescript.preferences.includePackageJsonAutoImports": "off"(如前所述,防污染) - 必配
tsconfig.json:开启"strict": true,"noImplicitAny": true,"exactOptionalPropertyTypes": true。LLM生成interface User { name?: string }时,name类型是string | undefined,而非string | undefined | null,减少歧义。 - 隐藏技巧:用
// @ts-expect-error代替// @ts-ignore。前者要求LLM必须写出预期错误(如// @ts-expect-error Argument of type 'string' is not assignable to...),倒逼它理解类型系统。
- 关键设置:
-
Go(VS Code + gopls) :
- 关键设置:
"go.toolsManagement.autoUpdate": true(确保gopls始终用最新版,LLM生成的Go 1.21特性如try语句能被识别) - 必配
gopls设置:"gopls": { "staticcheck": true }(启用staticcheck,LLM生成if err != nil { return err }后,会提示“error returned from function call is not handled”) - 隐藏技巧:在
go.mod同目录建.gopls文件,写入{"buildFlags": ["-tags=dev"]}。LLM生成//go:build dev时,gopls能正确识别构建标签。
- 关键设置:
实操心得:所有项目都配
pre-commit钩子,但作用不同。Python用pre-commit run --all-files跑black+isort+mypy;TS用pre-commit run --all-files跑eslint --fix+tsc --noEmit;Go用pre-commit run --all-files跑gofmt -w+go vet+staticcheck。关键是: 让CI/CD的检查项,和本地编辑器提示完全一致 。否则LLM在本地生成的“绿色代码”,推到CI就红,信任感瞬间崩塌。
4.3 CI/CD流水线:把LLM协作纳入质量门禁,而非放任自流
我们绝不让LLM生成的代码“裸奔”进主干。流水线设计原则: 越早拦截,成本越低 。
-
Stage 1:Prompt Validation(Prompt验证)
在GitHub Action中,用jq校验LLM输出JSON是否符合Schema:# 验证LLM输出是否含code、imports、explanation字段 jq -e '.code and .imports and .explanation' output.json > /dev/null -
Stage 2:Syntax & Type Check(语法与类型检查)
- Python:
mypy --show-error-codes --disallow-untyped-defs src/ - TypeScript:
tsc --noEmit --skipLibCheck(跳过node_modules,提速3倍) - Go:
go build -o /dev/null ./...(编译所有包,不生成二进制)
- Python:
-
Stage 3:LLM-Specific Lint(LLM专用Lint)
我们写了三个小工具:python-llm-lint:扫描# LLM-GENERATED标记的代码,检查是否有eval()、裸print()、未处理的except:ts-llm-lint:扫描// @ts-expect-error,要求注释必须含具体错误信息,不能只写// @ts-expect-errorgo-llm-lint:扫描go:generate指令,确保生成的文件在git status中已暂存(防LLM生成后忘记git add)
-
Stage 4:Human-in-the-Loop Gate(人工审核门禁)
所有LLM生成的PR,必须由至少1位资深工程师审核,且审核评论必须包含:✅ Logic: 是否符合业务逻辑(LLM可能正确实现技术,但违背需求)✅ Safety: 是否有安全漏洞(如LLM生成os.system(user_input))✅ Maintainability: 是否可维护(如LLM用map[string]interface{}代替定义struct)
注意:我们禁用“LLM自动合并”。曾有一次,LLM生成的Go代码在
go test中通过,但go run main.go时panic——因为测试用例没覆盖nil指针场景。自动化永远无法替代人类对“业务意图”的把握。
5. 常见问题与排查技巧实录:那些让团队加班到凌晨的“幽灵Bug”
5.1 Python高频问题:类型擦除后的“薛定谔错误”
问题现象 :LLM生成 def process(items: List[Dict[str, Any]]) -> List[str]: ... ,本地测试通过,CI却报 AttributeError: 'str' object has no attribute 'get' 。
根因分析 : Any 类型在运行时完全擦除,LLM生成的代码假设 items 里每个元素都是 dict ,但实际输入可能是 ["a", "b"] (字符串列表)。 mypy 无法捕获,因为 List[str] 也满足 List[Dict[str, Any]] 的鸭子类型。
排查技巧 :
- 在函数入口加运行时校验:
assert all(isinstance(i, dict) for i in items), f"Expected list of dicts, got {type(items[0])}" - 用
pydantic.TypeAdapter做深度校验:adapter = TypeAdapter(List[Dict[str, str]]),然后adapter.validate_python(items) - 终极方案 :禁用
Any,改用object或Union[Dict, List, str],让LLM明确知道“可能是什么”,而非“什么都行”
5.2 TypeScript高频问题:泛型推导的“蝴蝶效应”
问题现象 :LLM生成 const result = await fetchData<User>(url) ,但 User 接口里有个字段 profile: Profile | null ,LLM后续生成 result.profile.name ,TypeScript不报错,运行时却 Cannot read property 'name' of null 。
根因分析 :TypeScript的 strictNullChecks 只检查 null / undefined 是否被显式处理,但LLM生成的 result.profile.name 属于“可选链未启用”场景。它假设 profile 一定存在。
排查技巧 :
- 强制Prompt要求:“所有可能为
null或undefined的属性访问,必须用可选链?.或空值合并??” - 在
tsconfig.json中开启"strictPropertyInitialization": true,让LLM生成class User { profile!: Profile }时,立刻报错(!断言不被允许) - 实测有效方案 :用
zod定义Schema,LLM生成z.object({ profile: z.object({ name: z.string() }).nullable() }),然后schema.parse(data),运行时抛出明确错误
5.3 Go高频问题:错误处理的“沉默崩溃”
问题现象 :LLM生成 resp, err := http.Get(url) ,然后直接 json.NewDecoder(resp.Body).Decode(&data) ,但 err 未检查。当网络超时时, resp 为 nil , resp.Body panic。
根因分析 :Go的错误处理是显式的,但LLM常把 err 检查当成“装饰性代码”,认为只要写了 if err != nil 就行,忽略了 err 的 业务含义 。 http.Get 的 err 可能是网络错误,也可能是DNS失败,LLM生成的 log.Fatal(err) 直接终结进程,而非重试。
排查技巧 :
- 用
go:generate生成错误处理模板://go:generate go run gen-err-handler.go --func="fetchData" --retry=3,自动生成带指数退避的重试逻辑 - 在
go.mod中引入github.com/pkg/errors,强制Prompt要求:“所有错误必须用errors.Wrap(err, "fetchData failed")包装,禁止裸return err” - 团队规范 :所有HTTP客户端方法,必须返回
(*Response, error),且error类型为自定义ClientError,含Code(如ErrNetwork)、Retryable(bool)字段,LLM生成时必须填充
5.4 跨语言通用问题:Prompt漂移(Prompt Drift)
问题现象 :同一Prompt,在Python项目中生成 pandas.read_csv ,在TS项目中生成 fetch ,在Go项目中生成 ioutil.ReadFile ,但三者处理的其实是同一份CSV数据。LLM“忘记”了上下文一致性。
根因分析 :LLM是无状态的,每次请求都是全新上下文。它不记得10分钟前在Python项目里用过 pandas ,所以TS项目里就用 fetch ,Go项目里就用 ioutil ——这导致数据管道断裂。
排查技巧 :
- 建立项目级Prompt Context Cache :在Git仓库根目录建
.llm-context文件,记录:
每次调用LLM前,自动注入此文件内容data_source: csv_file preferred_library: python: pandas typescript: papaparse go: github.com/gocarina/gocsv - 用Git Hook做一致性校验 :
pre-commit钩子扫描所有LLM生成的文件,检查pandas是否只出现在Python文件,papaparse只出现在TS文件,违者拒绝提交 - 终极方案 :所有数据IO操作,封装为项目级SDK。LLM只生成
sdk.ReadCsv("users.csv"),具体实现由SDK决定,LLM无需知道底层
最后分享一个小技巧:我们给每个LLM生成的代码块,自动添加
// Generated by [model] on [date]. Do not edit manually.注释。当开发者手动修改后,Git diff会清晰显示“这里是LLM生成,这里是人工修改”,方便回溯协作痕迹。这比任何流程文档都真实。
我在实际使用中发现,效率提升最大的不是选对语言,而是 让LLM明白自己的边界 。Python的 mypy 报错、TypeScript的 tsconfig 警告、Go的 go vet 提示,都不是在刁难LLM,而是在给它画一张精确的地图——告诉它“这里可以飞,那里有悬崖”。当LLM不再猜测,而是按图索骥,人机协作的熵值自然归零。
更多推荐
所有评论(0)