乐于分享
好东西不私藏

月下载1.3亿的库被AI重写并改了协议,开源维护者遭“网暴”后发声:我觉得大家反应有点过头,当时联系不到原作者,新版是重写!

月下载1.3亿的库被AI重写并改了协议,开源维护者遭“网暴”后发声:我觉得大家反应有点过头,当时联系不到原作者,新版是重写!

作者 | elvex        整理 | 屠敏
出品 | CSDN(ID:CSDNnews)

不久前,我们曾报道过,作为每月下载量超过 1.3 亿次、被无数软件直接嵌入的 Python 经典编码检测工具 chardet 深陷舆论漩涡之中

起因是这个项目的原作者 Mark Pilgrim 在开发五年后便选择退网,过起了“隐居的生活”,而项目后续维护、开发工作几乎全部落在开源维护者 Dan Blanchard 一人的身上,他凭一己之力苦苦支撑项目至今已有十余年时间

最近,Dan Blanchard 借助 Claude Code,仅用五天时间就将整个库从零重写,并宣布以新的开源许可证发布。

颇具戏剧性的是,已经沉寂 15 年的原作者 Mark Pilgrim 突然现身留言,对 Dan 这种“更换许可证”的做法提出了质疑,并要求对方停止更换。

这一操作瞬间引爆社区,争议迅速蔓延。

  • 一部分人认为:“作为开源维护者,你可以重写,也可以采用新的授权协议,但不能直接覆盖原有项目的开源授权;如果要另起炉灶,就应该重新换个名字再发布。”

  • 也有人站在维护者一边,认为“这么多年的投入以及当下的重写本就是为了让项目变得更好。”

与此同时,更深层的问题也被一并抛出:AI 辅助重写是否合理?所谓“洁净室”(clean room)方法是否成立?软件许可的未来又将走向何方?

对此,当年提出“开源定义”的美国著名程序员 Bruce Perens 甚至将这一事件类比为印刷术和科学方法的发明。他在接受外媒 The Register 采访时直言:“软件开发的整个经济模式已经彻底崩溃了。”

在争议之中,作为长期维护者的 Dan Blanchard 也出面,与美国企业级代理平台 Elvex CEO Sachin Kamdar、市场营销主管 Doyle llrvin 进行了一次深入访谈,回应外界的种种质疑。

在他看来,这次重写在结构上是完全独立的(通过第三方开源软件代码分析工具 JPlag 评测,相似度低于 1.3%,而此前人工维护版本的相似度高达 80%);同时,他也咨询了法律顾问,并将整个过程保持公开透明。更重要的是,这次改写确实带来了一个对用户更好的版本。

Dan 坦言,自己多年来维护 chardet 从未从中获利,未来也没有商业化的打算。而新版本采用的许可证更加开放、限制更少,性能也实现了高达 48 倍的提升——考虑到该软件运行在海量设备上,有人甚至调侃,这或许是“AI 首次实现碳负排放的应用”,因为整体 CPU 使用量反而下降了。

事实究竟是什么样的?

以下是 Dan 的完整对话内容:

月下载量高达 1.3 亿次,GitHub Star 数 2.5k 的 chardet 究竟是什么?

Sachin Kamdar今天我特别高兴能把 Dan Blanchard 请到节目里。

我和 Dan 很早之前就认识了,差不多 10 年前,我们一起在一家叫 Parsley 石油公司共事。Dan 是当时非常厉害的工程师之一,做过很多不同方向的项目。后来他又去了几家公司,现在在美国金融科技公司 Monarch Money 做工程师。

不过今天我们找他来,是因为过去大概 10 天里,他做的一件事在网上火了。Dan,要不你先简单介绍一下自己?聊聊你的背景、平时主要关注什么,顺便也讲讲 chardet 到底是什么?

Dan Blanchard:就像你刚才说的,我以前在 Parsley 和你一起工作过,在哪里大概工作了六年,所以我们合作的时间还是挺长的。

其实我在 Parsley 的时候,就已经在维护开源的 Python 字符编码检测库 chardet 了。

这个库我前前后后维护了大概 12 年。最早接触应该是 2012 或 2013 年,正式接手大概是 2014 年,具体时间我记不太清了,但差不多就是 12 年这个时间维度。

Sachin Kamdar那 chardet 到底是做什么的?“字符编码检测”听起来有点抽象,先解释一下这个概念,然后再说说你当初为什么会接手维护它?

Dan Blanchard:这个说起来还挺有意思的。我最早开始做这件事的时候,是在一家叫 ETS 教育考试服务中心工作,负责自动作文评分的软件,算是“AI 还没火之前”的早期 AI 应用。

所谓“字符编码检测”,其实可以这么理解:你电脑上或者互联网上的所有文本文件,底层本质都是一串数字。大家常说的 0 和 1,你也可以理解成一系列数字。

而“字符编码”,就是一套映射规则,有点像凯撒密码那种:某个数字对应某个字母,另一个数字可能对应一个符号,或者你键盘上能打出来的任何字符。

最早、也是最经典的一种字符编码是 ASCII 编码,它只支持 127 个字符。很长一段时间里,尤其是在美国这种以英语为主的环境中,大家会觉得:127 个字符完全够用了,键盘上这些不就全了吗?

可是这种情况下,像中文、希伯来语等其他语言都“被忽略”了。

所以后来在 70、80 年代,逐渐发展出了各种不同的字符编码。再往后还有 DOS 时代的一些编码,现在虽然不主流,但偶尔还能见到。更早甚至还有大型机时代的编码体系,不过基本已经没人用了。

“字符编码检测”的核心问题是:给你一个文件,你要判断——这是英文?日文?中文?系统会通过统计方法和一些规则去推断它的编码方式,以及它使用的语言。因为语言一旦判断出来,编码范围也就能缩小很多,很多编码其实是和特定语言绑定的。

举个简单的例子,如果你看到一段文本里,经常出现对应“T”“H”“E”的数字组合,那大概率就是英文。这类规律就能帮助判断编码。

所以,chardet 本质上就是干这个的——帮你判断文本的编码

它最早的来源,其实可以追溯到 90 年代末 Netscape 浏览器里的一个组件,叫“通用字符编码检测器”。后来 Netscape 变成了 Mozilla,再后来就是 Firefox。也正是在这个基础上,最早的 Python 版本 chardet 被开发出来。

这个 Python 版本是在 2006 年由 Mark Pilgrim 写出来的,他把那套 C 语言实现直接翻译成了 Python。

Sachin Kamdar如果用更通俗一点的方式来解释,你可以把它理解成一个“乐高积木”:你搭建软件的时候,会把它作为一个基础模块嵌进去。它的作用,是帮软件判断一些内容——比如,这个文档是用什么语言写的、采用什么字符编码。

你刚才提到它每个月有 1.3 亿次下载,那基本可以说明,这个东西已经被嵌进了各种各样的软件里,到处都在用?

Dan Blanchard:对,没错。之所以用得这么多,很大一部分原因是因为一个 Python 库,叫 requests。基本上只要写过 Python 的人,应该都用过它。

requests 是用来做网络请求的,比如下载网页、访问 API,可以说是 Python 里最常用的网络库之一。而在底层,它就依赖字符编码检测。

早期版本里,它只用 chardet;后来新版也支持另一个库,叫 CharSet Normalizer,用户可以二选一。

因为 requests 几乎被所有涉及网络的 Python 程序使用,所以 chardet 也就跟着被广泛使用了。

原作者几乎从“互联网”消失了,Dan 顶上成为了一名核心维护者

Sachin Kamdar所以这个库用处极大、覆盖面极广,你是怎么成为它的维护者的呢?

Dan Blanchard:我当时在 ETS 工作,我们算是比较早一批开始采用 Python 3 的团队。

大概在 15 到 20 年前,Python 社区其实有过一场很大的争议——语言本身发生了比较大的变化,导致你原来在 Python 2 里能跑的代码,到了 Python 3 基本都得重写。

chardet 这个项目,因为 Mark Pilgrim是在 2006 年写的,后来他在 2009 或 2010 年左右就不再维护了(具体时间我记不太清)。他当时几乎是“从互联网消失”了,把自己相关的代码仓库也都删掉了,包括 chardet。后来是其他人把这些代码给找回来了,这个我们可以后面再细说。

当时的情况是:有一个基于 Python 2 的 chardet,同时还有一个 Python 3 的分支,叫 charade,是 Ian Cordasco 做的。他也是 chardet 的维护者之一,同时也是 Requests 这个库的维护者之一。Requests 当时正在尝试迁移到 Python 3,于是他们就说:“我们需要一个 Python 3 版本的这个库”,于是他就 fork 了一份。

我是在这个阶段加入进来的。当时我的目标很简单:把它重新变回一个统一的代码库。也就是说,不再是 Python 2 一份、Python 3 一份,而是合并成一套代码,同时兼容两边。那时候做这种“同时兼容 2 和 3”的事情,其实技术上还挺难的,但我之前正好有不少这方面的经验。

所以我把这两个代码库重新合并在了一起。合并之后的版本大概是 chardet 2.3。从那之后,我们开始发布同时兼容 Python 2 和 Python 3 的版本,一直持续到很久之后才彻底放弃对 Python 2 的支持。

说实话,这个时间点其实比理想中要晚了不少,但当时就是这样。

“一接手时就想换协议了,但并不是为了想赚钱”

Sachin Kamdar大概过去了 10 到 15 年,你一直在维护它Mark Pilgrim  已经很久没上线,也没给项目贡献代码了。此时基本上是你和几个其他人维护这个库。

那么,你是什么时候开始考虑换一个新许可证的?什么时候开始思考那些最终引发争议的事情?

Dan Blanchard:我考虑更换许可证已经很久了实际上,从我一开始维护 chardet 那天起,我就不想让它继续用 LGPL 许可证了。

先简单解释一下:

  • LGPL 是“较宽松的 GNU 公共许可证”(Lesser GNU Public License)。GPL 是“普通的 GNU 公共许可证”(Greater GNU Public License,只是没有前面的 L)。LGPL 一般用于库,因为它比 GPL 要宽松一些。GPL 的限制更严,其中一些规定对商业用途不太友好,如果你想用它做商业项目,就必须开源你的代码。 

  •  MIT 许可证则更加开放——意思是,你想怎么用这段代码都行,我不对你做什么负责。如果你修改了代码,最好能贡献回去,但并没有强制要求。总体来说,这是一个非常灵活的许可证。

Sachin Kamdar所以这三种都是针对开源项目的许可证,它们对使用和限制的程度不同。开发者如果是项目的创建者,可以选择其中一种来应用在自己的项目上。你之所以对 LGPL 感到不满,是因为它有一些限制?

Dan Blanchard:对。我对 LGPL 的一些限制感到不满,并不是因为我想从中赚钱。实际上,这场争议让我最抓狂的一点就是,有人说“他只是想借这个赚大钱”。我完全没有赚钱的打算。有人愿意付钱让我支持它那当然很好,但我不会靠一个角色就能赚到数百万美元。

这是一个已经存在了 30 年的字符编码检测库。现在的新版本是完全重写的,所以从技术上来说,它是一个不同的东西。这也是为什么有人会指责我对它做了什么的原因。

Doyle Irvin:如果其他人想在商业软件中使用它,这个新许可证就会让事情简单得多。换句话说,即便这个库已经被广泛采用,许可证的改变可能会让它使用得更广泛。开源项目得到更多关注,也意味着能得到更多人的支持——尤其是你这种长期无偿维护的人,多一点帮助总是好的,对吧?

Dan Blanchard:没错,完全同意。比如你看 chardet 仓库里的第 36 个 issue,是 2014 年 10 月的。我在里面说了一段现在回头看挺有意思的话,大概是:“这对我来说有点奇怪,因为我自己就是维护者之一,但我还是想问一句,我们能不能改一下许可证?”

然后我和 Ian,还有当时参与较多的 Eric Rose 展开了一番讨论。最后我们得出的结论是:我们需要联系 Mark。但没人知道怎么联系 Mark,因为他已经消失了,所以我们完全不知道该怎么办。

大概在那之后六个月,我其实又挖到了一些线索。结果挺烦的是,我后来把自己的 Twitter 账号给删了,因为我当时在 2015 年还在 Twitter 上和 Python 之父 Guido van Rossum 聊过这件事。

当时的对话大致是这样的:Guido 问我,是否支持把 chardet 加入 Python 标准库。我回答说“当然,那太好了”。

之所以讨论这个,是因为当时有人提议把 requests 加入标准库。最后没成,但 requests 有两个依赖,其中一个是 chardet,还有另一个我记不太清了。我记得当时他们说,“chardet 是 LGPL 的许可”,所以这是个问题,因为标准库不能加 LGPL 的依赖。

Sachin Kamdar这是 Guido 说的意思——他觉得,如果许可证不允许,就不能加入标准库。

Dan Blanchard:对,他当时说,“但是许可证……”

于是我们就想,也许可以换个许可证。他当时的态度是,“如果能想办法换,那太好了。”

我记得在讨论里,有人看到这件事之后联系了 Mark,但我不认识这个人。他们问 Mark,Mark 回答说,“不行,许可证是 LGPL,因为我代码的基础就是 LGPL。”

这就是 GPL 系列许可证的一部分特点,它有所谓的“copyleft”条款——任何基于原作品的派生作品都必须使用相同的许可证。所以把代码从一种语言翻译到另一种语言,本质上就是派生作品,显然也需要同样的许可证。

有趣的是,当 Mark 复制这些代码时,它确实是 LGPL,但后来这些代码的许可证改成了 Mozilla 公共许可证(MPL),比 LGPL 宽松一些。但当时我们想改自己的许可证成 MPL 是不可能的。

原因是:想改许可证,我们需要 Mark 的签字授权,也需要当时所有贡献者的签字——因为通常改许可证必须得到每位贡献者同意,这几乎不可能做到。确实可以实现,但非常罕见,从实际操作角度讲,根本不现实。

我记得以前我也参与过一个开源项目,忘了具体哪个。那个项目由一家公司运营,他们想换许可证,于是给所有曾经贡献过代码的人发了一封邮件——哪怕只是改了一行代码,也要签署一份同意改许可证的协议。如果你不同意,他们就把你的贡献删掉,他们的态度基本是,“没关系,我们可以不用那部分代码。”

所以我想说,换许可证一直是我很想做的事。现在我重写的新版本,用了一个不同的许可证。严格来说,这算是一种重新授权,因为我保留了原来的名字。我之所以保留名字,是想让用户可以直接替换上新版本,而不用切换到一个全新的库。

而且新版本的好处不仅仅是许可证不同。性能几乎提高了 50 倍,准确率也大幅提升。在我手上 2000 多个文件的测试集中,准确率提升了约 10 个百分点。更快、更准确、内存占用更低——几乎各方面都比老版本好。

所以,对用户来说,这是在很多方面都更好的选择。考虑到每个月有 1.3 亿次下载,这还不算每天的实际使用量。如果你做一个能显著提升性能的改动,甚至会对整体计算资源产生可测量的节能效果。有人开玩笑说,这可能是 AI 领域第一个“碳中和”甚至“负碳”的应用,我觉得也许是吧。

Doyle Irvin:我觉得这个说法挺合理的。

Sachin Kamdar所以基本上,你想过改许可证,但实际上操作上不现实,于是你干脆用 Claude 代码从零重写,用上一个本该有的许可证,对吗?

Dan Blanchard:是的,而且不仅仅是为了许可证。我一直想做一些更大幅度的结构性改动,让它运行得更好、更快。但如果继续在旧版本上改,我投入了大量精力,却还是被原有的限制束缚住,这让我很沮丧。

我的目标一直是,希望这个库能进入 Python 标准库。那样的话,不只是我一个人负责维护,会有更多人参与支持。而且它本身就是一个标准工具库,不应该缺席。

Sachin Kamdar好的,你做到了。没什么大不了的。现在有了新的 chardet,更快、更强、更好,还有了新的许可证。

“我觉得大家的反应有点过头了”

Sachin Kamdar那我们来说说这些事情的影响吧。现在很多讨论都集中在许可证的价值上。如果你可以直接用 AI 从零构建东西,也能重新做一遍,那本质上并没有变化,只是现在实现起来容易多了。某些东西的门槛甚至可能消失了。

Dan Blanchard: 对。

Sachin Kamdar那你怎么想?你是怎么理解这种变化的?

Dan Blanchard: 我觉得大语言模型(LLM)让你做以前大家都能做的事情,只是快了很多。

有点讽刺的是,过去自由软件的支持者会庆祝那些原本专有的软件被改写得更自由。比如 Richard Stallman,他创立自由软件运动,本质上就是因为电脑上的打印机驱动不能用,他想改好它,但无法获取源码,只好逆向工程。还有一些 Windows 模拟器,如果你有 Steam Deck,也能玩所有 Windows 游戏,虽然它跑的是 Linux,这都是因为有人逆向了大量 API。我们都为此欢呼,因为这让软件对大家更好、更免费。而现在有些人反而对我做的事情生气——我让原本有限制的免费软件限制更少了。

Sachin Kamdar你觉得他们为什么生气?现在和过去有什么不同?

Dan Blanchard: 我觉得原因之一是我保留了原来的名字。很多人认为,如果换了名字,这场争议就不会发生。我觉得这个说法有道理。名字本身除了安装包之外,其实没什么本质意义。我并不在意叫什么。如果有办法让新版本代替旧的 chardet 安装,我会改名字。我保留名字,是为了让用户替换顺利、无痛。

假设法律上必须改名字,我仍然会负责旧项目,把旧项目在 GitHub 上归档,并标注“项目已停止维护,请转到新项目”。我甚至会让旧版本安装时提示:“此版本不再支持,请下载新版本。”

但这样做的效果正好和我想表达的相反——想象一下,如果每个用户安装时都弹出这个提示,对于数百万次安装来说,这个能量消耗很大。

我觉得大家的反应有点过头了。有人甚至说我应该像性犯罪者一样被列入软件工程师黑名单,永远不被雇佣,简直疯了。

Sachin Kamdar我也想知道,如果回到过去,你没有用 Claude 的代码,而是自己一行行地写、改、重写这个东西,你觉得会不会引起争议?还是说正是因为用了 AI 才让人觉得可怕?

Dan Blanchard: 嗯,我觉得这个问题可以从两个方面来看。

我选择用 AI 的原因之一是速度快。我曾看到一篇文章,同事分享给我,说有家公司在几周内就重写了 Next.js。我记不清是哪家公司了,但我当时就觉得,“哇,这也太疯狂了。” 我心想,如果他们能做到,我用 AI 重写 chardet 当然也能做到。

但我之前没有自己动手的原因之一,是因为传统上有人用一种叫“洁净室(clean room)论”的方式来为重写或更改许可证辩护。我的理解是,如果你想让别人重写 Windows 的代码,需要有一组人看过原始代码,他们了解代码做了什么,然后写报告,比如“如果能实现 A、B、C 功能就好了”,但不能告诉开发者具体怎么写。然后另一组人根据这些规范去实现。这种做法在法律上几十年来都可辩护。

而我自己是唯一在做这个的人,所以如果我自己重写,别人可能会说,“Dan 对代码太熟悉了,不能算净室操作。”但是我用 Claude 的做法相当于模拟了净室:我没有告诉它该怎么写,只说,“绝对不要用之前的代码。”

还有件事我还没公开,但打算很快分享——你现在算是提前知道了。我让 Claude 做了一个小型单页应用,把我重写 chardet 五天内的全部对话历史整合起来。

因为当时文件散在多个目录,我还改了本地文件名,整个过程乱七八糟。这个应用把所有内容整合成一个完整历史,然后总结每次会话的内容。点击某次会话,就能看到每轮对话的具体内容。任何涉及外部操作的,比如网页搜索、抓取文件,都有标记,方便查看它在工作时参考了什么。

有人指出,我在一些计划文档(不是提示,而是 superpowers 生成的 plan docs)里,让 AI 去查看 chardet 仓库里的一个文件,这个文件主要是编码的元数据,比如“这个编码通常用于日语,这个用于英语”,标记哪些是现代编码、哪些是旧编码。这本身是公开信息,而且那份文件是我自己写的。

其实一直以来,如果能让原作者同意,更改许可证是允许的。我写的文件完全是我自己完成的,是几年前做的一个研究项目,整理了每种语言对应的编码。接下来我发布时还会揭示几个可能引起争议的点,但基本上都可以归结为两类:

  • 要么是我自己写的内容,比如用于训练模型的脚本;

  • 要么是 AI 在完成所有内容后做的最后检查,保证 API 兼容性——它参考了这些文件,但内容是它自己写的。

我觉得说“写完之后不能回过头去比较内容”,这不太合理,但我不是律师,所以发布后再看法律如何解读。

可能有人会觉得这更火上浇油,但我一直尽量透明。如果把所有事实公开,它们就是事实。如果以后因此产生诉讼,这些信息也会被披露,那干脆现在就放出来。

Sachin Kamdar对,现在争议已经闹大了,很多人开始站队了。你当初开始做的时候显然没料到会这样。现在你怎么看?会不会觉得,“也许我应该换种方式做”?

Dan Blanchard: 不,不是那样……

Sachin Kamdar就像现在回头看,胜率是 20/20。

Dan Blanchard: 我觉得我有时候可能太固执了。我觉得就算别人对我生气、对我恶意相向,我也不会改变我的看法。

如果有人能拿出事实、理性地讨论,而不是像十二岁小屁孩那样胡乱争辩,在网上捣乱,我很乐意和对方交流,甚至可能会被说服。我愿意认为自己是一个相对理性的人,人生中也在很多重要问题上改变过看法,如果有人能让我意识到自己错了,我可以接受。

我记得这件事发生之后,有个叫 Brian Fontana 的人留言,他是最新版本 LGPL 的作者之一。严格说,chardet 用的不是最新版本,而是 LGPL v2,他写的是 v3。不过他在 chardet 的 issue 里开了个讨论,说,“这段代码到底有多少是人类写的?”

我当时的回答是:基本上没有,我几乎没有直接写过这些代码。他说,根据当前的法院案例,如果一段代码完全由 AI 写成,那么很可能属于公有领域。我也咨询了另外两位律师,这似乎确实是共识。

所以实际上,如果最终结论是 chardet 必须进入公有领域,我也不会感到不快,因为那意味着它更加自由。但复杂的问题在于,公有领域的概念在美国以外并不存在,在其他国家并没有法律基础,这就很麻烦。

不过在讨论中,也有真正的律师也参与进来了。有人提到一个叫 Zero BSD 的许可证,我还没深入研究,但它类似公有领域,而且可能在国际上也适用,我可能会考虑把许可证改成这个。

另一个有趣的讨论是:如果代码进入公有领域,一旦开源后有人开始贡献,他们的贡献怎么办?因为技术上,他们可以选择贡献的许可证。

按我理解,目前并没有完善的法律机制能够让你明确地说:“这个仓库是公有领域,你对它的任何贡献都自动进入公有领域。”这在法律上几乎没有可行的方法。我认为这是开源发展的下一阶段需要解决的问题。

我看到 Sentry 也发布过类似的概念,他们称之为“Fair Source”,大致意思是当东西属于公有领域时,它不受版权保护,所以他们的方案不是传统版权许可证。他们在想,如果这些代码不可版权化,我们怎么才能不互相为难?fair source 的想法就是,你签一个协议,但具体执行机制不太明确,比如保证你不会拿它去做直接竞争。他们的思路是,“代码完全公有领域,但别搞恶意竞争”。我觉得这个概念挺有意思的。

原作者的突然发声

Doyle Irvin: 我最大的疑问是,这“他们”到底指谁?谁会去采取行动?像 Mark Pilgrim 会不会从他神秘消失的深处重新出现,然后说:“我要采取行动”?到底谁会真正去执行?

Dan Blanchard: 这场争议之所以激烈,是因为 Mark Pilgrim 再次出现,在 issue 上提了一个问题。据说已经有人证实是他本人。

我选择相信说这话的就是他本人。因此这是一个几乎没做过什么事情的 GitHub 账户,但它是在 15 年前创建的。所以感觉像是他以前有的一个“GitHub 小号”,一直没用过。顺便说明,我除了这一次外,从未见过他,也没跟他说过话。有人说我对他有敌意,其实没有。

 他当初做了一个东西,很有用,但后来他放弃了,其他人接手了。对我来说,说某个已经删除的人“拥有”它,有点奇怪。

另一点让我不太认同的是,人们说“他做了这一切”。我承认,但他当时用的算法,其实原始代码基本上就是逐行翻译的 Python 种子代码,看起来完全不像 Python,变量名都很奇怪,都是 Netscape 内部命名规范的遗留。原始 chardet 版本里的这些东西,现在都没了。

Doyle Irvin:所以他自己也是从别的地方拿来的,他不能说“这是我的”。他把它翻译成了别的东西,然后弃掉了。你从“垃圾堆”里接手维护了十年,现在你试图让它更自由,而且你也没想从中赚钱。

Dan Blanchard: 嗯。在新版本里面,我用了一个抄袭分析工具。

我当时心想,也许有个事实需要确认——我明确告诉 AI,不要用任何 GPL 或 LGPL 的代码,也不要看原来的 chardet 代码。可以看测试数据,因为测试数据本身不是代码,是它从网上下载的文件,还有我自己下载的文件,用来测试。测试文件一直标注了各自版权,从没附 LGPL,因为它们根本不是代码。

具体而言,我用一个叫 J-PLAG 的工具做了抄袭测试。

我运行了它,然后在回应 Mark Pilgrim 关于我没有权利修改代码的留言时,我展示了相关数据:如果你看一下 chardet 包里、从他第一版下载的代码——他只参与了第一版的开发,第二版及之后的版本都是其他人做的——那么新版本与旧版本中任何文件的最高相似度只有 1.3%,平均相似度大约 0.6%。

如果你看第六版(第七版是那个有争议的版本),第六版其实是我在底层做了重大改动的版本,包括模型训练方式、存储方式等等。即便是那个版本,最大相似度也才大约 80%,因为有些文件是沿用下来的,平均相似度大概在 10% 左右,介于 10% 到 20% 之间,我手边没有具体数字。

所以我觉得,这清楚地显示了代码几乎完全不同。

我还做了一张表,显示随着时间推移,各版本的相似度是如何下降的,但总是会有一些文件的最大相似度保持得比较高,因为部分文件被保留了。这也说明,没有任何文件完全沿用旧版,都是全新的。

我一直在考虑用不同的方法来做这类分析。我计划写一些博客文章,逐步展示这些方法。顺便说一句,让 Clawd(大型语言模型)帮忙分析它自己,听起来挺好笑的,但我觉得 LLM 在这方面做得还挺好。所以我让它去看第六版和第七版的结构,并描述它们各自解决问题的方法,从架构上说明它们是如何工作的,然后指出相似点。

它的分析是:唯一相似的地方就是,它们都在解决同一个问题,并且都使用统计和模式匹配——这本来就是解决这个问题的方式。

另外还有一个叫 BOM(字节顺序标记)的东西——有些编码在文件开头有一个特殊的小数字,用来标明这是 UTF-8 还是 UTF-16。显然,检查文件里有没有这个标记,是确定编码的一种几乎百分百可靠的方法。但除此之外,除了这两个显而易见的技术之外,两个版本几乎没有共通之处。它们解决同一个问题,用的只是一些基本思路,这些思路本身就是解决问题的唯一方法。

当 AI 生成的内容遇上开源许可

Sachin Kamdar开源自由软件的很多发展都离不开社区,这才是它真正的价值。而社区对你做的这件事反应也非常强烈。你怎么看这件事?

你觉得,这是不是像 Bruce Perens 所说的那样,开源软件许可需要迎来某种“清算”,还是大家反应有点过度了?

Dan Blanchard:我觉得 Bruce Perens 说得对。软件许可的现状,以及法院里迄今的案例,都表明 AI 生成的代码很可能无法受版权保护。这对整个行业的影响比 chardet 还要深远。

现在几乎每家公司都用 LLM 生成大量代码,任何我认识的工程师都在用 LLM 写代码,因为效率太高了。如果这些代码都不受版权保护,那我们卖软件的方式会有什么变化呢?这真的很难说。

这也是 Bruce Perens 反应那么强烈的原因。他说,他不知道靠卖软件怎么赚钱。

他举的例子是,有家公司工具很贵,他不想花钱,于是让 LLM 看文档,让它生成一个克隆版本,几天就搞定了,他花在 token 上的钱远低于原本的购买成本。软件即服务(SaaS)模式以前可以生存,因为你和用户关系紧密,但现在有人 10 分钟就能克隆你的东西,原来基于一个简单想法建立的初创公司 MVP 也能被瞬间复制。

作为一个专业的软件工程师,我个人不喜欢这样的世界,但没办法,这就是现实。

Sachin Kamdar你认为需要做出哪些改变?

Dan Blanchard:我觉得得从社会层面去改变,就像那些支持全民基本收入的人可能是对的。

随着我在专职工作甚至开源项目中越来越多地使用 AI,我会越来越有这种感觉:某个时候可能会出现一种情况,我的工作——即便我希望公司继续付钱给我,也可能变得不那么必要了。

感觉就是,很多人类在做的检查工作,其实回报在递减。我可以想象有一种情景:有公司会说,人类也会出错,所以我们不必追求完美,因为人类本身就不完美。这种想法,挺可怕的。

Sachin Kamdar我觉得关键区别在于,智能体没有责任感,但人类有。在某种程度上,人类的角色已经从执行变成了“保险政策”。

Dan Blanchard:我完全同意。我想说,我在工作中有一条原则:每个 pull request 都有你的名字,因为你要为它负责,需要亲自确认没问题。

这也是我做 chardet 时的做法。我的名字在所有 commit 上。我有意让它显示“co-authored with Claude”(与 Claude 共同撰写),只有我单独做的 commit 才只有我名字。除此之外,都显示双作者。

我还做了大量测试,覆盖了很多之前没有测试的代码,如果不用 AI,我不会去做这么彻底。想想以前 chardet 代码库里那些完全没测试的部分,现在 100% 单元测试覆盖,真的挺震撼的。

Sachin Kamdar乐观来看,AI 虽然带来了项目开源许可方面的挑战,但也提升了效率,让数亿开发者受益。

Dan Blanchard: 没错。我觉得对 Python 社区来说,这绝对是一件好事。

Sachin Kamdar尽管每个人都想恪守职业操守,做“正确且符合道德”的选择,但在如今这种技术爆炸的节奏下,谁也无法真正慢下脚步。毕竟,AI 工具带来的价值增长实在太显著了,面对如此巨大的红利,任何人都很难简单干脆地说出一句:“不,我们绝不使用。”

Dan Blanchard: 对。自从上次我发布了有争议的 7.0 版本之后,最近这段时间我又推出了 7.01,只是修复了一个很小的 bug。之后我又发布了 7.1 和 7.2。

Sachin Kamdar不得不说,这个项目在短短三周内取得的进展,恐怕比过去任何一段时期都要显著。

Dan Blanchard: 是的。以前版本更新之间会有三年的间隔,因为那时候只能在我有空的时候才去开发。但现在,如果有人提交了一个 issue,我可能 10 分钟就能解决,然后顺便就发布个新版本了。

只要有 AI 的参与,人类投入多少精力,才算是项目的作者?

Sachin Kamdar非常感谢 Dan 和我们分享整个事件的来龙去脉。我觉得不仅仅是你做了什么、怎么做的有意思,更重要的是这对未来的发展也很有启发性。也许我们可以一个月后再请你回来聊聊。

Dan Blanchard: 好啊,我也很乐意。我希望未来会有一些积极的进展,或者至少争议会小一些,当然也可能出现更多有趣、值得讨论的争议性事情。

大概可以用一句话概括我的态度:我并不在意法院案件的最终结果。我觉得大家不太理解这一点。对每个人来说,做出一个明确的判决反而是有利的。现在最糟糕的,就是这种不确定性。

Sachin Kamdar我们现在就像在“西部荒野”,谁对谁错都不清楚。

Dan Blanchard: 对,就像有人跟我说:“你必须把许可证改回 LGPL”,那确实挺糟糕的,对吧?我自己也不太喜欢,但好吧,这算是一个决定,也没比以前更糟糕。

如果有人跟我说:“这个必须放到公有领域,不受版权保护”,那我也没问题,因为这可能意味着它有机会被纳入标准库。

如果有人说:“你现在可以保持 MIT 许可证不变”,那也很好,因为这正是我当前想做的。

我觉得唯一可能对我有法律风险的情况,就是如果我在法院败诉,然后需要赔偿。但我真的不明白,一件免费的东西被另一件免费的东西起诉,除了支付律师费之外,还能有什么损失呢?你知道,我也不打算点名,但有人曾主动表示愿意帮我筹集法律基金,以防万一。

所以我希望事情不会发展到那一步,但老实说,我也不知道还有什么其他办法。

Sachin Kamdar如果真的打官司,这条路会涉及很多不同的当事人,可能会是一条漫长的道路。

Dan Blanchard: 没错,确实是这样。说到这个,科罗拉多州最近有一个相关的诉讼案挺有意思。有个人用 AI 创作了一些艺术品,现在法院正在围绕一个核心问题展开讨论:一个人到底得在这部作品里投入多少心力,才能名正言顺地算作其“作者”?

虽然我不确定法律对“代码”的界定会不会和“艺术品”一样。总之,这确实是个值得关注的趋势。

来源:https://www.elvex.com/podcast/he-rewrote-chardet-with-claude-the-internet-blew-up-heres-his-take

推荐阅读:

从不1V1开会、不搞接班那一套,黄仁勋最新访谈:10万个智能体造不出下一个英伟达、AGI已实现、OpenClaw就是Token时代的iPhone

日薪5500+元的「AI喷子」火了?这家公司找人“专职骂AI”:目标是把它骂崩溃、反复“翻车”

月下载9700万的Python库被“投毒”!Karpathy紧急警告:一行pip install,敏感数据全泄

🔥  110 万美金悬赏!

AMD 2026 线上黑客松大赛来袭

从 MXFP4 MoE 算子爆改,到真实千倍并发下的吞吐量极限拉扯

不看资历,只看绝对速度

挑战DeepSeek−R1/KimiK2.5极致并发

入围即能拿 1 万美金

立即扫码报名

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-03-27 20:04:03 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/488808.html
  2. 运行时间 : 0.218484s [ 吞吐率:4.58req/s ] 内存消耗:4,827.80kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=e53ddb0b3ee8ac8c36b13386e458db79
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.68 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.80 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000876s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000708s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000321s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000269s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000471s ]
  6. SELECT * FROM `set` [ RunTime:0.000188s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000556s ]
  8. SELECT * FROM `article` WHERE `id` = 488808 LIMIT 1 [ RunTime:0.000577s ]
  9. UPDATE `article` SET `lasttime` = 1774613043 WHERE `id` = 488808 [ RunTime:0.007665s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000264s ]
  11. SELECT * FROM `article` WHERE `id` < 488808 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000476s ]
  12. SELECT * FROM `article` WHERE `id` > 488808 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.002582s ]
  13. SELECT * FROM `article` WHERE `id` < 488808 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000965s ]
  14. SELECT * FROM `article` WHERE `id` < 488808 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000754s ]
  15. SELECT * FROM `article` WHERE `id` < 488808 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000950s ]
0.222313s