Other Readings异读 返回作品
字号
主题
下载
下载全书

全书 · v0.1 · 2026-10-11

第三章:算法学科(Algorithmic Discipline)

尼古劳斯·珀赫哈克 · 2024 年原著 · Claude 辅助全译AI 辅助初译,未经人工终校第 4 / 11 单元

我们拒绝:国王、总统和投票。我们信奉:粗略共识与可运行的代码。——Dave Clark (1992)

在修读计算机科学课程时,人们会对“算法是什么”形成一种直觉性的理解。我们能够用伪代码(pseudo code)[1]把算法写下来,用 Java 或 C 等不同的编程语言实现它们,分析其复杂度,并将其性能与其他算法进行比较。我们学习诸如快速排序(Quick Sort)和旅行商问题(Traveler Salesman Problem)之类的术语。然而,当人们试图说明这些构造物的社会权力时,算法这一形象却引发了不少讨论,最终汇聚为这样一个问题:“算法究竟是什么?”(Ziewitz 2016, 4)[2]。若干学者已经为这个问题找到了答案,这些答案与计算机科学话语中的定义和理解时而联系紧密,时而关联甚少。算法是调控我们日常生活的强大实体(Beer 2009),是“现代理性的阐释之钥”(Totaro and Ninno 2014),是对“自我批判性判断”的取代(Daston 2010),是一种分类工具(Bechmann and Bowker 2019),或者是数学或计算机科学中原本“抽象的‘有效程序’(由精确的、‘机械的’指令构成的有限集合)”的物质性实现(D. MacKenzie 2019, 41)——这里仅列举数例。鉴于人们对算法这一现象持有如此多样的视角,很容易给人留下这样的印象:这些学者虽然各自都在谈论算法,所谈论的却是根本不同的东西(另见 Burke 2019)。他们未必共享同一个算法定义,但在他们看来,算法身上总有某种普遍可寻之物,无论那是理性、能动性还是分类。当然,这既无助于回答算法是什么,也无助于解释算法的社会权力从何而来。但它表明,算法及其效应已经成为一种关切之事(matter of concern)。

正如 Seaver(2017)所论,算法并不存在一个“恰当的”定义。Seaver 借助人类学的敏感性,并汲取后行动者网络理论(post-ANT)的构想,主张我们应当说明算法的不同实演(enactment)。如此一来,算法及其属性便不再是有待发现的本质,也不再是某种普遍原则。关于算法的一般性陈述已无从做出,因为这取决于人们是在哪个社会场域中提出“算法是什么”这一问题。因此,Seaver(2017)敦促我们不要去回答算法是什么、或者它有何特殊之处的问题;相反,我们将在所研究的田野中找到这个问题的答案。一旦考虑到算法的多重性(multiplicity),“算法是什么”这个问题就变得更加复杂了。将算法视为实演的视角,也深刻影响了研究这些行动者的方式。由于算法的各种实演在运作方式以及可被接近的方式上各不相同,探究的模式也必须随之改变。它们都指向算法,尽管方式不同、视角各异。算法可以是制造不平等的不透明行动者(Noble 2018),也可以是一套需要向伦理委员会作出解释的视频监控程序(Neyland 2016),可以是一种话语叙事(Beer 2017),也可以是一组被实现出来的具体指令(Dourish 2016)。因此,在谈论算法时,讨论这些行动元(actant)的人至少把三种不同版本的算法混在了一起。第一,算法的一般原则:在有限时间内解决某一给定问题的一组指令。这也是教科书对算法的定义,常见于计算机科学与工程领域。第二,多种形式的不稳定、未经协调的装配体(assemblage):在其中,一切都有待讨论,决策有待做出,代码有待编写,需求有待工程化,诸如此类。这既包括算法最初被实现为代码的过程,也包括算法系统为适应不断变化的需求而持续进行的开发与调整。我在此将其称为生成中的算法(algorithm in the making),它也体现在类似于科学技术研究(STS)中经典实验室研究的那类研究中——因而也体现在我在此呈现的自身工作中。第三,在现实世界中(in the wild)被实现和物质化的算法,它决定给谁一份工作、把警察派往何处、或向谁呈现何种信息。后者是算法的一种稳定化、制度化的形式,它位于组织内部的某处、隐藏在应用程序接口(API)背后,作为一个确实强大的行动者,把所有的混乱、多重性、图示、图表等统统藏进一个黑箱。无论如何,算法都是多方面的互动、联结(association)与转译(translation)的产物。那么问题就在于:从哪里开始,往哪里看,向哪里去。这些不同的视角虽然各自都有价值,却引发了一场关于“当我们说算法时我们究竟在研究什么”的讨论。各种立场的光谱,一端是对算法的情境性实演,即叙述(narration),追问“算法”一词如何被赋予意义;另一端则是媒介理论中的观察,即媒介人工物(例如一个具体的排序算法)具有非常明显的效应。前者主张研究者应作为社会科学家,不应盲目遵从学科的与技术的定义(Seaver 2017),也就是说,不要变成工程师,而要信赖社会科学与人文学科的方法论来刻画算法的属性。后者则对这一立场提出了反论。Manovich(2013a)[3]等人认为,人们应当能够亲自编程,才能完全把握技术的秩序化(ordering)效应。要理解算法是什么以及它如何对世界进行秩序化,我们就必须从这一行动者的技术属性出发,也就是说,从技术专长出发,并借助技术专长。介于两者之间的一种观点是,我们应当遵循所研究田野的主位术语(emic terms)(Dourish 2016),即采用计算机科学对算法的定义。Burke(2019)继而接过这一论点,指出尽管在寻找共同定义方面存在问题,“算法”一词对计算机科学而言仍然是一个重要的术语。因此,在本章中,我希望探讨这一论证上的张力,出发点是这样一种假设和观察:算法是(也)在软件开发项目中被“做”出来的东西;我将追踪应对这些如此难以把握的行动者所必需的物质性与话语性要素。我首先讨论媒介理论学者所探讨的算法与软件的本体论地位问题,然后通过追问以下问题使之复杂化:算法如何经由软件开发者的实践而被实演——他们实现不同的技术、使用软件库、搭建 iPython 笔记本之类的开发环境,这里仅举数例。因此,要理解算法的秩序化效应,我们也需要把计算机科学作为这诸多实演之一纳入分析。基于我作为该推荐算法开发项目一员的经验,我认为,归根结底,这两种视角并不相互对立,而是代表了同一现象的不同要素:显明而持久的算法,是一种集体的、情境性的实演的产物。下面,我将重构一种关于算法的媒介理论视角,并论证算法的制作依赖于两种不同形式的集体实演。在实现推荐算法的过程中,该项目依赖于:a)一个共同体所提供的、总是已经给定的工具所构成的运作秩序;b)调动各种技术所凭借的话语结构与知识分布结构。Manovich(2013a)或 Dourish(2016)所谈论的算法已经是实演——但只是特定的实演。而且,正如我们将在关于算法制度与算法政治的讨论中看到的,它们并不是仅有的实演。

做计算机科学(Doing Computer Science)

Latour(1999b)曾经说过,社会产生于社会学,文化产生于人类学。此类术语的生产,只有在与知识生产体制(regimes of knowledge production)的关联中才使它们变得有意义。因此,提出如下工作假设似乎是正当的:算法产生于计算机科学。因此,眼下这项探究的目标之一,便是把“算法”一词理解为“某一特定职业文化——计算机科学家、软件设计者和机器学习从业者的文化——之中的一个行业术语”(Dourish 2016, 2)[4]。否则,正如 Dourish(2016)所论,我们将无法找到恰当的干预或批判形式。这一立场同样见于更早提出的软件研究(software studies)之中:

要理解新媒体的逻辑,我们需要转向计算机科学。正是在那里,我们有望找到刻画那些已变得可编程的媒体的新术语、新范畴和新操作。我们从媒体研究走向某种可称为软件研究的东西,从媒介理论走向软件理论(Manovich 2001, 48)。

这一观点的基础在于更早的讨论,部分源自媒介理论领域——尤其是柏林媒介理论学派(Berlin School of Media Theory)。Kittler(1999)在那里主张,要把握技术的文化与社会影响,就必须深入理解技术,因为“媒介决定我们的处境”(Kittler 1999, XXXIX)。在此语境中,唯有与我们周遭的技术进行彻底的正面交锋,才能形成批判、分析与解放所必需的视角。这种视角所许诺的是:通过转向一种软件理论或算法理论,社会研究和文化研究将能够以新颖的、而且——对这一进路的倡导者而言更重要的是——恰切的术语来谈论这一现象。对于软件研究和批判代码研究(critical code studies)的学者而言,这意味着转向构成软件的实际代码,以理解社会与文化领域在新的数字化条件下如何被影响和决定。在其著名的表述中,Lessig(1999, 2006)将代码等同于法律,即把技术代码等同于法律规范(legal codes)。代码和软件不再是受规制的对象,而日益成为一种规制力量本身。

在现实空间中,我们认识到法律如何进行规制——通过宪法、成文法及其他法律规范。在赛博空间中,我们必须理解一种不同的“代码”如何进行规制——那些使赛博空间成为其所是的软件和硬件(即赛博空间的“代码”),也如何按其所是来规制赛博空间(Lessig 2006)。

代码——在此指赛博空间的构成——是一种强大的规制者,它决定谁能访问数字对象或服务,哪些交流形式是可能的,以及信息在何处被收集。针对同一现象,Galloway(2004)将互联网描述为一个从来都与自由无关、而与控制相关的地方。在这位作者看来,施加控制的一个重要机制是协议(protocol)的实现——这种控制形式使得在互联网这样的去中心化结构中行使权力成为可能。Galloway(2004)是完全就字面意义而言的,因为他把 TCP、DNS 或 HTTP 等通信协议(这里仅举数例)认定为政治技术。这些协议规制着我们在互联网中行动和生活的方式,就如同减速带通过一种“物理的组织系统”(Galloway 2004, 241)来规制我们的驾驶行为一样。

Montfort 等人通过分析仅仅一行计算机代码的文化、历史与社会意义,展示了这种态度,他们认为“为了充分理解红线歧视(redlining)[……] 的运作方式,或许有必要考察银行审批抵押贷款系统的具体代码”(Montfort et al. 2012, 10)。一行代码就能造成差别。因此,要理解社会的数字化[5],接触具体的代码行对于批判性探究就变得十分重要——对于机器学习这类看似不透明的应用也是如此。Adrian Mackenzie 指出:“无论机器学习涉及怎样的抽象层次,代码几乎从来不是密不透风、不可穿透的。作为陈述,一切都摆在表面上”(A. Mackenzie 2017, 26)。因此,研究算法和机器学习意味着从一种新的视角来研究代码。于是,这些学者所识别出的挑战是:我们要建造何种形式的赛博空间?我们愿意实现怎样的规制体制——Lessig 甚至将其比作宪政体制?要能够为这些问题提出答案——无论多么不完整——我们就必须阅读、编写并讨论我们数字社会中的代码与算法。因此,Manovich(2013a)主张,为了逃离软件的牢笼,我们需要学会编写自己的代码。于是,我们必须调动计算机科学和软件开发的实践与范式来提出我们的批判。从一种不同的视角,即批判的视角,去“做”软件、代码和算法,也由此变成了一种政治探究的形式。

算法媒介及其物质性(Algorithmic Media and its Materiality)

然而,计算机科学是一个广阔的领域。我们应当把算法定位在何处?其效应,即它所造成的差别,究竟是如何产生的?根据迄今为止给出的论证,这个层面应当是用编程语言编写的计算机代码。打开这些 .java 文件,看看那条有罪的语句在哪里,我们便离发现这项技术的社会影响不远了。然而,这一立场并非没有争议。Dourish(2017)指出,我们应当承认,一个算法的实现(也包括实际的代码)所需要的不只是抽象的程序。算法是我们世界中具体的、物质性的行动者。它们是“可识别的、具体的媒介人工物,而当被视为一台更大机器的一部分时,它们更容易被识别”(Burke 2019, 4)。根据 Hayles(1999)的观点,信息社会或数字社会生活在一种虚拟性(virtuality)的状况之中,在此状况下,文化感知在信息与代码的物质性和作为抽象实体的信息之间制造出区分。但这种虚拟性不过是一种成就:它通过我们的感知使信息的核心特征——即信息被存储于其上、并可能作为计算机程序被执行于其上的媒介——变得不可见。没有物质性的信息是不存在的,因为信息总是依赖于某一媒介上的物质显现。在 Hayles(1999, 13)看来,将代码或信息(至少在冯·诺依曼架构中,这一区分已变得毫无意义)从其物质基础中抽象出来,是一种想象。而为了充分理解软件和算法如何运作——以及它们如何产生秩序化效应——我们也应当考虑计算的物质世界,即中央处理器(CPU)、主板设计、所使用的数据存储技术等等。没有这些,对代码的视角就是不完整的。类似的洞见更早就促使 Kittler(1995)提出了“不存在软件”这一论断。这一论断也反映了 Kittler 对作为技术中介之核心要素的硬件的深度投入和兴趣。对他而言,这标志着一种“从软件到硬件、从较高观察层次到较低观察层次的下降”(Kittler 1995, 150)。在此语境中,软件和算法都不作为其自身而存在,而只作为一种把硬件要素之间的互动抽象掉的视角而存在。人们需要的不是关于软件的理论,而是“硬(件)理论”(hard(ware) theory)(Parikka 2012, 64)。与这一立场相反,Manovich(2013a)宣称只存在软件。Manovich 并未(至少未明确地)援引 Kittler,他认为“数字媒体”(Digital Media)这一术语具有误导性,因为数字内容(如图像文件)的转译会因所使用的软件不同而大相径庭。 Manovich(2013a, 138)写道:“取决于你用哪个软件来访问它,你对同一个数字文件所能做的事情可能会发生巨大变化。”对 Manovich 而言,软件是数字之物的决定性要素,因为它以不同的方式转换和呈现数字数据。如果我们想理解数字化世界的建构,软件层面才是相关的层面,因为正是它把逻辑引入了我们被中介的互动之中。因此,我们应当考虑的不是信息的物质性,而是计算机代码所引入的不同逻辑。计算机硬件是一台通用化的机器,而软件则对我们的世界进行秩序化。Rossiter(2016)在谈及数字基础设施和代码时,以类似的方式表述了这一论点。在其著作中,Rossiter(2016)将软件描述为我们现代世界的协调力量。

虽然 Manovich 并不否认 Kittler 提出的论点,但在他看来,相关的探究层面是另一个层面。他着眼于代码层面来进行干预。然而,这两个论断——只存在软件,与不存在软件——引出了一个问题:这些不同层面之间是什么关系?正如 Lessig(2006)所论,赛博空间是由软件和硬件构建的。如果我们遵循 Kittler 的论证,那么软件并未给局面增添任何东西,它本身不具有任何属性。一切都可以化约为硬件之间的互动。也许存在软件,但即便如此,它也无关紧要。那么,软件、硬件、或许还有运行时(runtime)的本体论地位,其相关性究竟何在?[6]

计算机语言(Computer Language)

正是这一探究上的难题困扰着软件研究的学者们。如果不存在软件,我们如何能够介入数字社会的建构?Galloway(2006)将这些视角结合起来,认为它们并非各有其合理性的不同探究层面,而是在逻辑上等价的。

人们绝不应把这台“较高的”符号机器理解为在经验上不同于通过逻辑门的电压所构成的“较低的”符号互动的任何东西。它们确实是复杂的聚合体,但若以为用八行汇编代码写一个“if/then”控制结构,要比用一行 C 语言来写更具或更不具机器性,那就愚蠢了,正如同一个二次方程可以膨胀出任意多个乘数而依然保持平衡。二者之间的关系是技术性的(Galloway 2006, 321)。

这里有一条有趣的转译链条在起作用。软件,比如 BIOS、操作系统,或者用于撰写本文的文字处理程序,都是计算机系统的抽象,但这些抽象是通过不同层次的转译协同运作的(Hayles 1999)。每一个抽象层次都是其下一层的能指(signifier),同时又被其上一层所指涉。机器码在编译器语言的层面上被指涉,而编译器语言必须被转译为机器码。但反过来,机器码又指涉处理单元(ALU)内部的逻辑运算。它们不仅协同运作,而且在逻辑上是等价的。无论我们从哪里进入,信息技术系统所产生的效应都是一样的。没有哪个转译层次会增添或减去什么,因为不同的转译层次只充当中介者(intermediary),并不改变陈述的性质,而是表征同一个逻辑结构。遵循这一论证就意味着,探究的层面变得无关紧要,因为我们可以在任何我们想要的地方进入这条转译链条。无论从何处进入,我们所发现的(仅仅)是一条指涉链条中的另一个要素。这就解释了用 C++ 等编程语言写下的陈述与可观察效应之间的直接映射。用这些编程语言写下的陈述是述行性的(performative)。正如 Kittler 所论,通过编写特定的代码行,工程师能够行使权力、界定情境,并以直接的方式创造现实。一个简单的 if … then 语句就能改变软件影响社会(和技术)情境的方式(Neyland and Möllers 2017)。简言之,代码通过书面表达的表述而具有述行性,这与语言相仿。Bernhard Rieder(2017, 102)认为,“代码[……]是以计算机能够理解的方式来表达[这些]技术的媒介”。算法是逻辑结构,代码是表达它们的语言。Parikka 援引 Kittler(1990)的早期著作写道:“技术媒介时代的语言不只是自然语言:它是由媒介所引入的新的技术与物理体制,比如打字机,以及后来的计算机软件语言,在方法论上应当以类似的方式来看待它们”(Parikka 2012, 70)。在这一视角中,硬件与软件之争通过如下方式得到化解:把编程语言理解为与计算机进行交流的一种形式,以便将陈述的意义机械地转译为(计算机的)行动。换言之,只存在硬件,但我们需要软件来进行交流。

将代码理解为一种具有自身效应的语言形式,这一观点在批判代码研究(CCS)中已存在一段时间了。Cox 和 McLean(2012)认为,代码能够而且应当按照 Austin(1975)所描述的言语行为(speech act)来理解。Austin 认为,在通过言语进行行动时,我们在说话时实际上能够产生现实,也就是说,能够进行带有后果的行动。Austin 主张,借助述行性言语行为,我们是在“以言行事”(doing things with words)。举一个例子来说明这种言语行为:设想一位牧师说出这样的话:我在此宣布你们结为夫妻。仅仅说出这些话,一个事实就不只是被援引,而且被创造了出来。这位牧师仅仅是用她的声音在行动。以类似的方式,代码在批判代码研究中被解读为这样一种言语行为。仅仅通过写下一些代码,人们就能建构现实,无论是通过软件架构中的决策,还是通过让计算机按照所表述的脚本(script)行动。因此,对代码进行分析揭示出一种语言行为,这种语言行为“在世界中活跃,并拥有一个活生生的身体”(Cox and McLean 2012, 110)。

遵循这一论证,我们可以把代码当作语言来看待,但它构成了一种特殊的语言形式,因为它是可执行的(Galloway 2004, 165)。这便在 Austin 心目中的语言形式与批判代码研究和软件研究把代码思考为语言的方式之间制造出了区分。在这一视角中,代码被视为比单纯的言语更为强大,因为它通过在运行时层面的执行而在世界中实施行动。这使得 Hayles(2005)区分了语言性述行(linguistic performance)与机器性述行(machinic performance)。这一论证乍看颇具说服力:语言性述行首先存在于人的心灵之中,然后必须被转译为行为,也就是说,在输入与输出之间存在一个(主观)解释的中介过程。相比之下,软件的述行性要直接得多,因为代码的执行是直接发生的,没有中介(Hayles 2005, 50),也没有变异(Galloway 2004, 165)。于是,有软件与无软件之间的问题便得到了化解,因为不同的能指让人能够轻易地从一个层面穿行到另一个层面,而无需解释效应的增添或减损。代码是述行性的,因为它可以被直接映射到一个预期的结果上。然而,彻底贯彻符号学的进路反而会使我们远离这样一种理解。技术不仅指涉不同的技术层面,也指涉维持这种关系稳定的不同集体(collective)。

言语行为及其集体(Speech Act and its Collectives)

在迄今为止所描述的论证中,有两个重要的要素被结合在一起,为聚焦于代码的分析提供了正当性。第一,代码或算法的探究层面并不重要,因为人们进入的是一条指涉与转译的链条。代码是执行诸层面的一种表征或抽象。第二,这些转译是决定论式的,也就是说,不同的抽象在逻辑上彼此等价。这最终使我们能够把代码理解为一种特殊的语言形式,它在这样一种模型中具有述行性:我们可以在原因与结果之间毫无问题地来回移动。编码化的言语行为与述行性效应之间的关系是机器性的。在 Kittler 或 Galloway 的视角中,代码、软件与硬件之间的转译在逻辑上是等价的,因而维持着相同的效应。然而,抽象的算法原则向代码和软件的转译是偶然的(contingent)。但一旦被实现为一段可被转译为运行程序的具体代码序列,算法就会保持稳定。这便是批判代码研究或软件研究的终极论据。如果我们想研究算法,就必须研究具体的代码,而不是某些伪代码表征或原则,也不是开发者的实际实践。

然而,这种关于机器性述行性以及行动向不同的——在经验上等价的——层面进行转译的构想,遭遇了一些论证上的缺陷。Adrian Mackenzie(2005)以 Linux[7] 为例表明,代码可以被理解为一种言语行为,它在社会世界中以述行的方式产生效应,但并非只是在向直接行动的转译中产生效应,而是通过界定情境来产生效应。我们值得反思一下这里所面对的是何种言语行为。通常,人们援引 Austin 时所指的是那些以自身为目的的言语行为,比如“我向你承诺……”。在这里,一旦话语被说出,该行为的目标便已实现。用 Austin 的语言来说,这些言语行为是言外行为(illocutionary)。它们无需进一步的行动便具有述行性。而言后行为(perlocutionary)则在因果链条中产生效应。在这里,言语行为的目的在于让某人基于所说的话去做某事。就代码作为言语行为而言,我们(大多数时候)面对的是言后言语行为。简单的语句 print “This text is produced by an perlocutionary speech act”; 会在你的计算机屏幕上打印出所表述的字符串——因而是言后的。然而,如果我们把软件结构(A. Mackenzie 2005)视为一种言语行为,那么效应在编写代码时就已经实现了,因此它当然(ipso facto)是言外的。这个例子说明了 Galloway(2006)论证中的一个问题。如果我们把不同的层面理解为在经验上相等,我们就忽视了——正如 Manovich(2013a)同样指出的——硬件充当的是一种更为通用的媒介,而软件则通过改变后续软件包或互动的条件来重新界定情境。与此同时,一个软件包或操作系统的结构也为使用它们的开发者界定了参数。因此,为 Linux 编写软件与为 Windows 开发软件的运作方式并不相同。硬件也是如此:它允许某些操作,却禁止另一些操作。我们或许能够向下穿行,但“整体总是小于其部分”(Latour et al. 2012)。只有当我们考虑到被置入彼此关系之中的每一个要素时,我们才能理解相关代码的述行性[8]。

因此,将代码概念化为言语行为,便提出了一个问题:是怎样的发话(enunciation)的社会技术语境使代码得以具有述行性?这要求我们以稍有不同的方式来阅读 Austin 的著作。与其关注一句话语的生成性运作,比如“我宣布你们结为夫妻”,人们也可以追问:在什么情况下这样一个陈述会成为真的?在其他进路中,例如实用主义及其以实践为导向的真理定义中,这个问题得到了比 Austin 更为广泛的探讨。众所周知,托马斯定理(Thomas theorem)指出:“如果人们把情境定义为真实的,那么它们在其后果上就是真实的”(Thomas and Thomas 1928, 572)。这一表述触及了一个 Austin 也已看到的重要关联:要成为述行性的,或者用 Austin 的说法成为“有效的”(operative),使其产生后果的条件是重要的。换言之:只有当他人接受了这一定义,使之产生后果时,述行这样一个事实才能奏效。言语行为不是孤立的事件,而是共同体互动与共享实践的效应。因此,言语行为必须在一个主体间的意义建构过程中被变得具有述行性(Berger and Luckmann 1967)。Butler(1997)在讨论 Austin 的理论时认为,言语行为是一种行为举止(conduct)的结果。

例如,当我说“我谴责你”时,我很可能说出了一个言语行为,而且确实是 Austin 意义上的言外行为;但如果我并不处在一个能使我的话被视为具有约束力的位置上,那么我很可能说出了一个言语行为,但按照 Austin 的意义,这个行为是不适切的或不恰当的(unhappy or infelicitous):你毫发无损地逃脱了。因此,许多这样的言语行为在狭义上是“行为举止”,但并非所有言语行为都具有产生效应或引发一系列后果的力量(Butler 1997, 16)。

Latour(2009)甚至将这一论证又推进了一步,把它扩展到使言语行为成为可能的物质世界。说话、接受所说之言、将其实现等等的安排,是在一个由人类与非人类行动者构成的集体中展开的。Introna(2016)接过这一点,批评了对机器性述行性与语言性述行性的区分。他声称:“可以论证,所有形式的代码都必须是‘可执行的’——否则它就不会被转译为任何形式的能动性。法律规范为了转译立法机构的能动性,同样需要是可执行的。这些不同类型的‘可执行性’之间的区别,在于此种执行所必需的构成性条件的性质”(Introna 2016, 26,强调为原文所有)。因此,每一个陈述——包括言语行为和代码片段——的现实性与可执行性,都内在于一个行动者网络之中,而不是外在于它(Latour 1990)。

因此,接下来我将基于我的经验观察论证:算法的稳定性是至少两种不同形式的集体努力所取得的成就。第一,整个工具生态系统本身,就是一个更广泛的共同体的要素与成就,它使算法的实现与落实成为可能。软件和代码的述行性,是被调动起来的技术行动者(例如编译器或软件库)相互作用的结果,这些行动者促成并限制着算法的潜在行动——或者本身就承载着已经实现的算法技术。第二,算法本身并非凭空而来,而是从整个学科共同体中被调动起来的技术和话语要素,例如以教科书或最佳实践范例的形式。因此,算法技术是一种知识资源,它被接受、挪用、调整,并被反馈回共同体。这两种形式的共同体成就,使算法在实际开发项目中变得举足轻重。而如果我们要寻找算法的学科性实演,就必须把这两种援引共同体的形式都纳入考量。

稳定转译的不稳定性:总是已经被秩序化的世界(Instability of stable translations: the always already ordered world)

正如 Passoth(2019)所论,当我们谈论数字之物时,至少涉及三种不同的物质性——硬件、软件和运行时。而且它们在逻辑上并不等价。按照 Chun(2008)的观点,一直到晶体管层面都存在稳定转译这一假设,本身就是一种效应,不能被视为理所当然[9]。把代码从刚才描述的种种互动中剥离出来,会使代码被转译为具体行动的可能性条件变得不可见。她把这种态度称为“巫源逻辑”(the logic of sourcery)(Chun 2008, 9)。没有合适的 CPU,对存储在磁盘上的机器码的解释便无法进行;没有合适的编译器,将高级代码转译为机器码的过程也无法进行。但是,质疑这些行动者的既定性,打开那些将它们置于其位的联结,就意味着会发现一个由其他人类与非人类行动者构成的广阔网络,它们参与稳定化了像编译器这样平凡的东西——我们用编译器把任何程序的源代码转译为一个实际可运行的二进制文件。为此,我们依赖了相当多未被质疑、而被假定为既定之物的资源。仅编译器本身就是一个在其背后聚合了许多不同行动者的工具:开发者共同体、对处理器机器码的描述、许多描述如何解析、优化然后转译代码表达式的技术的书籍。

换言之,算法、软件、硬件乃至电工信号之间被假定的转译稳定性,是一种效应,而非一个既定事实。我们不应把源代码或算法视为一种本质,而应把它们理解为一种“再—源”(re-source)(Chun 2008, 9)。就该推荐系统而言,算法的发话建立在 Spark Hadoop 环境和 iPython 笔记本之上,建立在服务器集群及其背后所有的软硬件之上。没有这些,代码就不会产生任何效应,而这些要素的具体形式决定了结果。这些要素的稳定性是整个共同体协商的结果。推荐系统的装配包含了这些系统,而它们本身也是被装配起来的,并作为“按原样”(as-is)提供的黑箱而存在[10]。

算法基础设施(Algorithmic Infrastructures)

作为项目的一部分,项目负责人 Bob 和 Alice 参加了一个国际工作组,该工作组尝试不同形式的推荐算法,并彼此分享各自的算法。

将会成立一个国际工作组,它希望为用户追踪和算法的实验性开发建立一个跨机构的框架。他们将利用 iPython 笔记本,在其 Hadoop 和 Spark 系统上运行它。这个系统允许人们上传自己的数据和算法来进行测试。如果效果相当不错,就可以为这一设置定义一个 API 端点。Bob 进一步向我们解释说,可以复制这些 iPython 笔记本并与他人分享,让他们看到你做了什么(田野笔记)。

在田野工作期间,我所学到的不仅是人们所使用的算法原则——例如基于显式和隐式评分的协同过滤,基于词干化描述文本、标签和类别的基于内容的过滤,等等。此外,我还了解到,这个算法是在一个更大的研究者与开发者群体之中被分享的,他们在 Spark 和 Hadoop 的设置上测试各种实现,而代码则被键入 iPython 笔记本之中。图 1 展示了这样一种工具,它允许在欧洲广播联盟(European Broadcasting Union,EBU)预先界定的框架内进行开发,同时也显示了部分 iPython 笔记本列于何处。我不仅要学习算法原则,还必须学习机器学习和数据密集型应用的既有框架与新兴框架及基础设施。

发生了什么?我被引入了一个由现成的工具和设置所构成的世界,而这些工具和设置似乎是开发一个算法、并使团队内外的协作成为可能所必需的。项目使用了 Spark——一种常用于数据密集型项目的编程语言——这在很大程度上是因为它的 MLib 库。这个库实现了许多机器学习算法和实用工具,可以直接使用并进行实验。此外,Hadoop 是一个用于数据密集型和分布式计算解决方案的软件框架。二者都由 Apache 软件基金会(Apache Software Foundation)开发和提供。而且二者都通过 iPython 笔记本来访问,从而形成了一个用于实现、测试和分享推荐算法各种可能变体的界面。推荐系统的开发并非依托于通用工具,而是利用专门化的开发环境作为项目的基础。这些环境由一个专门化的专家共同体以协作的方式开发,其中甚至包括一种名为协同过滤的推荐技术的标准实现[11]。因此,开发项目的开端,便是把所有这些不同的行动者调动(mobilizing)到实际项目中来,并搭建一个能够开发、测试、分享和讨论推荐系统的环境。作为我探究的一部分,我开始在一台虚拟机上搭建自己的 iPython 笔记本,以便理解他们在做什么,并能够亲自测试。在每一次安装过程中,我都要确保相关的库已经安装好,确保我拿到了正确版本的软件——或者确保它确实与我所运行的 Linux 发行版兼容。这一调动过程远非无足轻重,但它对于后续可能的代码开发而言是至关重要的。正如 Adrian Mackenzie 在谈及软件时所说:“放任不管,它往往会分崩离析”(A. Mackenzie 2006, 12)。没有这些营造环境的步骤,推荐系统便是不可想象的。Burke(2019)也分享了他的观察:计算机科学共同体日益依赖于对共享软件库或服务的(再)使用。Burke(2019)描述道,在机器学习领域,Tenser Flow 已经成为一个广为人知、经常被用来实现机器学习应用的框架。由于实际算法应用所具有的分布式性质,在原则、软件、协议、硬件、以电压水平表示比特的电工表征之间这条持续进行的转译链条中,要确定实际的算法究竟是什么,似乎是不可能的。也就是说,作为整体的算法并不是这些项目中的某一个,而是全部。拿走其中任何一个要素,作为行动者的算法便不复存在。在转译的每一步中,我们都会发现更多以工具、库或服务的形式存在的、具有生产性和秩序化作用的黑箱。软件和算法并不(仅仅)依赖于一种自上而下的秩序化,也依赖于一个使稳定转译成为可能的环境,这个环境把权力委派(delegates)给一个协议或一个算法,以达成秩序化效应。正如 Latour(2004)援引 Heidegger 所论:从事实之物(matters of fact)转向关切之事(matters of concern),不把任何事物视为自在的本质,而是视为多重联结的成就,会更具生产性。举一个例子:机器语言层面上的那一套不同指令之所以能够运作,只是因为许多不同的实体能够被装配起来以维系它,从标准化文件到程序员的需要、处理器的硬件特性、编码方法,一直到生产场所,等等。它们中的每一个本身都是一个稳定化、组织化的黑箱,有着自己的联结、复杂性和安排,征召(enrolling)了“大量沉默的他者,并从中汲取其力量与可信度”(Callon 1987, 96)。稳定转译假定所有这些要素都已就位、可用,并以预期的方式运作。只有在一套给定的(总是已经[12]给定的)秩序之中,算法的有意义的转译和实现才是可能的。抽象层次不再是一个等级结构,而是处于同一层面上的、各自独立的不同黑箱。因此,在转译的不同环节之间移动,也意味着要考虑:为了把所指(signified)稳定为一个黑箱,调动了什么——以及这对于转译过程意味着什么,而指涉链条正是在这一转译过程中随时间被制作、又被重新制作的。能指、调动与稳定化之间的这种关系,继而建构了算法。通过把不同的行动者征召进(技术性)程序的(行动)程序之中,最终行动者的特性得到更多一点的界定,被稳定下来,并被赋予能动性。现在,把算法理解为所有这些要素的效应,会引出另一个结论。算法的述行性回指并建立在一个集体所委派的诸黑箱之上。因此,对这些生产性行动者的调动,使广播机构内部的开发团队变得大得多。经由联结,参与这个算法工作的不仅是 Alice、Bob 和我,还有许多参与所用工具和框架之管理、调试、打补丁和后续开发的人。因此,推荐系统的实现方式也受到了这些行动者的塑造。系统的开发必须嵌入一个已然存在的(而且极具生产性的)社会技术秩序之中[13]。在本节中,我基于在开发情境中所发现的技术设置,将算法重构为一种集体实演。然而,要充分把握这一现象,我们还需要考察算法的话语性实演。因此,在下一节中,我将把算法作为被叙述的行动者来加以讨论。

[图 1] 用于测试不同推荐算法的开发工具截图。(图像见原书第 72 页)

算法话语:叙述算法技术(Algorithmic Discourses: Narrating Algorithmic Techniques)

Latour 认为,Austin 对陈述性言语行为与述行性言语行为的区分仅仅基于语法和短期互动,而没有“追随整个发话体制”(Latour 2009, 225)来使二者之间的差异变得可见。如前所述,述行性的产生取决于某种得到维持的秩序,发话正是在这一秩序之中发生的。事实并不是仅仅通过说出某事就被创造出来的。相反,言说行为必须被其他行动者接受,他们才会相信、质疑或依照刚刚提供的这一事实之提议而行动。言语行为在本质上是主体间的。就代码而言,这一点可以在由行动者构成的广泛秩序与装配体中观察到,其中包括软硬件组件、其他开发者共同体等等。然而,发话还必须嵌入第二个维度之中。如果述行性只在一个总是已经被秩序化的世界中才有效,并且需要解释,那么述行性陈述的接收者如何理解这些陈述?一个人最初又是如何产生说出这些话的念头的?Austin 也承认,这关联着一个更广泛的社会规范、信念与知识系统(Austin 1975, 14),并把这些知识形式称为在特定社会中众所周知的“惯例”(conventions)与“仪式”(rituals)。因此,要知道在某种秩序化之中可能产生述行性效应,一个人首先必须已经习得:这样的话语与说话者的位置以及可能表述的范围相关。正如 Austin(1975)所设想的,言语行为的述行性指向一种使所说之言的效应成为可能的共享知识[14]。

这对于把代码理解为言语行为意味着什么?虽然代码的述行性仍然必须被纳入考量,但代码的能动性总是指向一个社会与物质的语境,因为“计算机代码从来不会脱离一套使其得以做事的先在实践而实际存在或运作”(A. Mackenzie 2005, 76)。在使言语行为有效、甚至使其有可能发生的那个装配体之中,有一部分便是观念、代码片段等在社会共同体中的嵌入性;在这些共同体中,以言行事的这些稳定行为通过重复而得到稳定化。正如 Butler 所论:

如果一个述行暂时取得了成功(而我将提出,“成功”总是而且仅仅是暂时的),那么这并不是因为某种意图成功地支配了言说行为,而只是因为这一行为回响着先前的行为,并通过对一套先在的、具有权威的实践的重复或引用而积累起权威的力量。这不仅仅是说言语行为发生在一种实践之中,而是说这一行为本身就是一种仪式化的实践(Butler 1997, 51)。

因此,持续的重复与流通把作为言语行为的代码稳定下来,并使之成为(学科性的)话语。与这一观察相一致,Wendy Chun 认为,软件总是嵌入在知识—权力结构之中(Chun 2008, 4)。这同样适用于作为抽象程序的算法。虽然算法会产生持久的效应,但仅仅聚焦于代码和运行时的物质性或算法本身,便会遮蔽这样一个事实:算法同样是多种其他行动者、认识论立场与话语相互作用的效应。正如 Mackenzie 所说:

从物质上看,代码只是机器学习之图示(diagram)中的一个要素。它以或多或少的可见程度,展示了多种力量(基础设施、科学知识、数学表述等)之间的关系。它由多重的制度性、基础设施性、认识论和经济性立场所排列,同时也暴露出这些立场(A. Mackenzie 2017, 22)。

正如我在本章开头所论,在修读一门关于算法的计算机科学课程时,我们会对算法是什么、我们如何使用它们以及以何种术语来思考它们形成一种直觉性的理解。因此,代码和代码片段几乎从来不是没有重复或流通的简单言语行为。一整个学科——连同其学位项目、会议、期刊、标准化委员会等等——都与我们通常所谈论的算法联系在一起。图 2 展示了一个插入排序(insertion sort)的简单例子,取自 Cormen et al.(2013, 18)。

当我们观看算法的这一表征时,许多东西都被默认了。例如,表达式 A.length 是指涉待排序集合之大小的能指,它假定我们确实知道给定集合的大小。待排序的集合 A 并未被定义,但它被假定为给定的。其他表述则指涉编程实践中已知的要素,例如 while 语句。如果你有任何编程经验,你就会知道它指的是一个执行循环的表述。与你可能在数学课上学到的不同,这里的等号并不表示两个项相等,而是一个运算符,把右侧项的结果复制到左侧所命名的变量中。换言之,一个算法的表述指涉着学科性知识,这种知识使人们能够理解用来描述某一具体算法的表达式。从未修过计算机科学课程、也未接受过编程范式入门的人,几乎无法破解眼前的这个表述。

与此同时,这一表征也是一种话语要素,因为它向计算机科学课程的学生展示了一个原型式的插入排序是什么样子[15]。选择这个例子并非随意,而是因为它出自一本关于算法与数据结构的著名教科书。如果你不确定某个特定算法如何运作(或应当如何运作),你总是可以求助于这些教科书。它们会向你展示排序算法是如何组装起来的。把这些表征形式作为学科性知识加以分发,赋予了这些技术以持久性,也赋予了其实现以正当性。当有人质疑你对某个算法的实现时,你总是可以调动这些教科书、最佳实践、大学学习时的讲义等等作为盟友,来为你的程序提供支持。虽然这个例子本质上很简单,但其原理对计算机科学而言却很重要。远比插入排序复杂的编程模式(programming patterns),作为解决方案和代码的结构化要素,在程序员共同体中被思考和分发[16]。因此,在转向计算机代码时,理解开发者如何“以言行事”(Austin 1975)固然重要,但同样重要的是代码片段背后的语境,它解释了为什么被调动的是这些代码行而非别的代码行,为什么是这种机器学习技术而非另一种,以及它造成了什么差别。一个算法并不仅仅由孤独的程序员所决定。相反,算法的原则与逻辑是通过不同的手段——例如教科书、软件库和科学共同体——得到分发和稳定化的。算法的实现“汲取了计算机科学与软件工程等学科所提供的丰富知识储备”(B. Rieder 2017, 101)。算法应用总是从一种具有共同进路、方法与范式的编码文化中涌现出来。在这个项目中,每当我面对关于推荐系统和机器学习的标准教科书时,我都多次体会到这一点。每当我询问算法时,我所面对的都是又一本教科书、又一篇论文,解释着这种算法进路。人们向我讲述 ACM RecSys 会议上的论文。在这个意义上,算法是由在开发过程中被调动起来的许多不同的话语装置(discursive devices)所构成的。

[图 2] 插入排序,取自 Cormen et al.(2013, 18)。(图像见原书第 76 页)

寻找算法(Looking for the Algorithm)

2016 年初,当我开始对这个民主推荐算法展开探究时,我也同样——在不知不觉中——对自己要寻找的究竟是何种算法举棋不定。我自己有实现和分析算法的经验,所以想去看代码,摆弄开发环境和 API。但我注定要找到别的东西。我就在那里,坐在一个满是软件开发者和计算机科学家的房间里。我有了自己的办公桌、自己的门禁卡,并被介绍为项目自己的社会学家。现在我该去哪里?我在哪里才能找到那个算法?我想理解这一程序的内部运作,并且——就像过去我在 IT 行业工作的日子里那样——阅读代码,喝大量的 Club Mate,重构成百上千行代码的意义。我甚至获得了访问项目文档库的权限。我开始翻看它。我所发现的并不是预期中的算法,而是描述、图示和对文献的引用。

那些指向我所寻找之算法的东西,仅仅是我心中所想之物的表征。图 3 展示了该系统架构的一个早期概念构想。可以看到,推荐系统被设想为相当核心的部分。至少,我现在知道了它在概念上是如何嵌入整个系统的。但我依然想要推荐系统的“硬核”维度(crunch dimension)——我怎样才能到达那里?幸运的是,我在项目中的位置主要与推荐系统的开发者 Alice 相对应。Alice 负责开发算法,并将其整合进视频点播平台的整体产品结构之中。我问她算法如何运作,以及我在哪里能找到它。结果,我收到了一些幻灯片、书籍章节和文章的链接。进入项目几周后,我收到了 Alice 的如下留言,附上了一篇关于基于隐式反馈的协同过滤的论文:

嗨!读完这篇文章后,你就会明白什么是基于显式反馈的协同过滤。但是:我们实际处理的是隐式反馈(用户并不直接给视频打分),所以我们得用不同的方法 :simple_smile: 这篇文章解释了如何做基于隐式反馈的协同过滤,以及它为什么不同。如果你觉得现在有用,可以读一读。不过你现在在做的聚类大概更重要——我自己还没来得及试。周五见!

PDF CollaborativeFilteringWithImplicitFeedback.pdf 288 kB PDF — 点击查看

在这个问题上工作的不只是 Alice 和我。相反,我们身处一个满是计算机科学家、数学家和工程师的房间,他们经由一整个学者与从业者共同体的不变的移动物(immutable mobiles)被传送到我们这里。我所寻找的算法由代码行构成,等待着被我解构。然而,我在作为一门学科的那段时间里所处理的,是向量空间可视化、优化公式和网络图示的堆积。

[图 3] 对该项目早期概念描述的重构。(图像见原书第 78 页)

图 4 展示了 Alice 提供给我的一篇论文中的一小段,它帮助我理解一种推荐技术:它如何运作,问题在哪里,以及如果我们决定实现这一技术,我们需要什么。这篇论文的背景是 Netflix 大奖赛(Netflix Prize)。开发者把它作为算法的参考资料交给我,这一事实表明了它对项目的重要性。在我作为一门学科的那段时间里,我还得到了更多的文献,以及对学术报告和教学报告幻灯片的引用。这些参考资料包括《海量数据集挖掘》(Mining of Massive Datasets)中关于推荐系统的一章[17],这是斯坦福大学计算机科学项目的一本教科书[18]。我还拿到了一些会议幻灯片,它们讨论和解释了这些技术及其问题[19]。

[图 4] 提供给我的一篇论文的片段(Koren, Bell, & Volinsky, 2009)。(图像见原书第 79 页)

发生了什么?我得到的并不是推荐系统的实际代码库,而是与有待开发的算法没有直接关系的材料。然而,这却是我理解这个项目、理解我们所面对的实际挑战之路上的重要一步。没有它,我就无法把握推荐系统——用开发者的话来说——是什么或者关乎什么。我所发现的不是装满源代码的文件,而是自己被计算机科学的文献和幻灯片所包围,其中栖居着数学表述、矩阵和伪代码。但在 Alice 看来,这一切对于理解推荐算法做什么、是什么都至关重要。我觉得自己仿佛被带回了大学时代:在那里,你首先学会编写一个 Hello World 程序——一段没有实际用途、纯粹为教学而存在的代码。然而,从这次互动以及我个人的转变中,还可以学到别的东西。我并没有被放任去直接对付代码,而是 Alice 从组织或她的办公室之外调动了许多其他资源。《推荐系统手册》(Recommender System Handbook)中的概念、观念和技术,以及 Netflix 开发者的文章,都被接受过来,被变得与眼下的项目相关,甚至与我作为社会科学家的探究相关。Alice 和其他开发者从大学、会议(例如 ACM RecSys 会议)和教科书中调动了许多不同的资源,以赋予算法一个初始的、暂时的形态。通过这样做,推荐系统变得具体了——所采用的技术变得持久了。被引入我们办公室的这个装配体,或者说行动者网络,界定了有待实现的算法的特征。这是界定算法系统最终将是什么样子、并使之对相关人员变得可触知的重要第一步。然而,在赋予推荐技术以持久性和具体性的同时,它也获得了某种抵抗力(resist-ability),这使得一整类进一步的转译和转换变得不太可能。通过界定推荐算法的某些特征,一个由工具、基础设施和互动构成的环境也随之被预设了(详细描述将在下一章给出)。算法从虚构走向了偶然。站在巨人的肩膀上,算法依然多于一,但无疑少于多。

学科话语在算法的实演中扮演着重要角色。通过接受由一个共同体所创造和委派的技术与知识,算法获得了形式,并在一定程度上获得了持久性。因此,话语——不同于 Foucault(1991)的结构主义观念,即话语无所不在、自我维持——在这里是被有选择地接受的,被当作资源来对待,并以物质化的形式出现:经由教科书、文章、会议论文[20]。因此,正是调动话语的实践把诸种说明(accounts),例如文本,与一种情境性秩序联系起来(Lynch 2000, 34),并界定了相关的行动者,因为它们被“分配了一个发言或被代言的‘角色’”(Passoth and Rowland 2010, 892)。通过这样做,算法——作为被实演的行动者——在开发项目中与开发者们所求助的整个共同体一道被叙述出来。归根结底,不是我们必须转向计算机科学,而是田野中的行动者自己这样做了。我们只是追随行动者。

算法不仅是一种地方性的实演,而且是由不同的行动者构成的,这些行动者既被(Alice)调动,也被(房间里所有其他看不见的人)委派。而且,尽管我们并没有先验地套用一个取自计算机科学或软件工程、把算法视为抽象原则的定义,我们却不知怎地恰恰回到了这个地方。Mackenzie 邀请我们超越地方性的设置,把焦点转向在具体情境之外被调动的东西,即追随代码“在一片地带上的移动,而与代码相联系的不同力量、构型、动态、知识、身体习惯[……]和事物就处于这片地带之上”(A. Mackenzie 2006, 10)。算法是什么、做什么,取决于情境性的实演以及在实际情境之外被调动的委派,由此也决定了所讨论之算法被选定的具体性程度及其持久性。通过算法的实演,它随之获得了具体性——它变成了一个物(thing)。

将算法置于语境之中(Putting Algorithms into Context)

回到我们开头的问题,即追问“算法究竟是什么?”(Ziewitz 2016, 4,强调为原文所有),我们——看起来——并未得出一个令人满意的结论。以恰当的方式谈论算法似乎是不可能的。我们是否应当彻底远离计算机科学和软件开发?与其放弃算法这一术语,或许更合理的是重新表述这个问题:“当我们把‘算法’作为分析关注的核心对象时,我们所注视的究竟是什么?”(Dourish 2016, 2)。算法是什么,无法以本质主义的视角来决定,因为它总是从我们的指缝间溜走。正如 Gillespie(2014)所论,我们应当抵制把算法放在驾驶座上的做法。相反,把算法理解为一种成就、一种社会物质性的实体——一种实演——或许更具生产性。于是,问题便不再是算法是什么,或者我们——作为社会科学家——在何处定位它,而是:在哪些情境中,田野中的行动者打开了哪些黑箱,去修补(tinker with)那些原本已被稳定化和秩序化的转译链条,以达成某种效应。在互动中,什么被变得相关?在处理算法时,什么成为了关切之事?

这或许是一个好时机——或者说与其他任何时机一样好——来反思实演这一概念在这里为我们做了什么。在本章中,我着重表明,算法是一整个集体的对象,技术、脚本和其他资源都是从这个集体中被调动出来的。把算法视为叙事,并扩展符号学和语言学的观念,隐含地把我们带到了述行性这一概念附近。没错:算法和算法技术可以被理解为一个社会技术系统的述行性效应。然而,实演这一概念反复出现——这不仅仅是、但也是因为追随了 Seaver,他敦促我们“把算法理解为由与之打交道的实践所实演的”(Seaver 2017, 5)。在这一点上,他追随了 Mol(2002)关于本体论——即现实本身——之实演的论述。Mol 由此超越了建构(construction)的概念,因为在她看来,建构这一观念意味着:所讨论的对象一旦被建构出来,便具有稳定性。与之相反,实演的观点认为,一个对象的同一性总是偶然的,取决于地方性的实践如何与之打交道。对象并不只是产生出关于同一对象的不同视角,而是对象本身发生了多重化。这也反映了激进版本的社会建构主义与实在论之间一场漫长且仍在进行的讨论,这场讨论涉及这样一个认识论问题:为了构建一个连贯而恰当的世界图景,我们对世界的感觉能否被视为理所当然。Mol 以如下表述解决了这一问题:对象“多于一——但少于多”(Mol 2002, 55)。偶然性被包含在实演之中——但这并不是对意义的任意赋予。物质性——或者更哲学地说:本体论——限制着实演的可能性。本体论不只是单向实践的结果,而是主体与客体之间互动的结果。它们全都是真实的,全都是被实演的。这也正是 Mol 弃用述行性这一术语的原因,因为在她看来,这个术语意味着存在一个后台,我们可以在那里找到真实之物。

然而,如前所述,限定实演方式的不仅仅是与对象——此处即一种算法技术——的互动,还有围绕它的整个社会技术结构。正如 Latour(1994)所论,我们几乎不会遇到这样的情境:其中没有被委派的行动者来影响、塑造、限制或丰富我们的行动可能性。对于算法的开发而言也是如此。我们不断面对各种各样的工具,例如编译器、开发环境、数据库等等。而它们中的每一个都是一个社会技术的黑箱,本身由许多人类与非人类行动者构成。这些黑箱是生产性的,它们使项目的开发和实现成为可能,但与此同时,它们也限制着可能性。对于软件库而言尤其如此,它们提供现成实现的例程和算法,供人们纳入自己的软件项目。正如 Latour 曾经写道:“整体总是小于其部分”(Latour et al. 2012, 591)。因此,算法必须被嵌入一个给定的工具与基础设施之秩序化之中,正是这一秩序化首先使代码的述行性成为可能。因此,开发项目不仅是一种情境性的实演,而且调动了许多不同的行动者——作为黑箱。算法只在这些行动者的特定组合之上才能运作。例如,Shor 算法(Shor 1994)是专门为量子计算机设计的,它在那里预设了其他行动者的一种给定配置。它预设了一种特定的秩序。

此外,算法是一种话语装置,指向一整个开发者共同体。算法的地方性实演与一整个学科的秩序化实践相联系,并且是其一部分。经由教科书、科学论文、会议论文集和幻灯片,乃至 Netflix 开发者所提供的技术,算法也是一种以互动和资源调动为特征的职业文化的要素。这些学科话语赋予算法以形态,并为开发者实现这样一个算法提供了出发点。这些算法技术由此作为抽象问题的抽象解决方案而出现。而要应用它们,要创造出一个确实产生效应的生产性解决方案,就需要预设特定的学科知识来阅读、理解和实现这些技术。

因此,考察实际的开发实践,是把算法的一种实演理解为秩序化效应的重要起点。算法并非凭空而来,但它们也不是纯粹技术的对象。有一整个学科和集体在做出非常实际的努力,生产出使算法成为可能的环境和学科话语。由此,我们回到了起点。为了理解算法作为(技术—)社会行动者的涌现,我们必须调动计算机科学和软件开发——但以一种不同的方式。我们最终处在这样一种境地:我们不再把算法当作一种本质去寻找,而是从“做算法”如何运作开始我们的探究。正如 Dourish 所论,我们于是开始把算法理解为“计算机科学家、软件工程师和系统开发者的职业实践对象”(Dourish 2016, 9)。追随开发团队的实践,继而引导我们把目光投向当前情境、当前组织之外。开发项目深深嵌入在 IT 开发者共同体和计算机科学学科之中。与其说是他们独自开发产品,不如说是一整个由在场的和(看似)缺席的行动者构成的集体在与我们并肩工作。

开发一个算法,就是调动不同的行动者,使它们彼此关联,使它们相互进入秩序。在修补这一组被委派的行动者——包括工具、知识和技术——的过程中,开发者重新排列、重新秩序化这些行动者,以产生某种效应。那么,我们在哪里定位算法呢?无处不在。算法既不只是技术,也不是实际的代码,也不能在工具中被找到。只有当它们全部汇聚在一起时,算法才会作为一个具有能动性的行动者涌现出来。因此,算法是什么的问题,便转变为这些不同的要素如何被(重新)装配的问题。因为开发者为了实演一个算法及其效应,会在对他们而言重要的不同层面上进行修补。要找到算法,我们不去某个预先界定的地方寻找,我们不只是打开源代码文件,也不只是阅读算法技术。相反,我们信赖在场开发者的知识。那么,什么对一个算法变得相关,就意味着追随行动者,也就是那些通过实践、话语和秩序化而被赋予行动者地位的东西。一个算法或许是一个可定位的物质人工物(Dourish 2016),但它也远不止于此。它是一整个学科的实演。我们不是去做计算机科学,而是追随算法的联结,进入计算机科学和软件开发的共同体之中。于是,算法的物质性便被界定为作为算法、并对算法而言具有重要性的东西(what matters as and for the algorithm)。然而,我迄今所讨论的只是算法的一种可能实演。而且,正如我们将在接下来几章中看到的,它无法孤立地界定一个稳定化算法的特征。相反,它是一种需要与其他实演、与“做算法”的其他形式相协调的实演。因此,在下文中,我将描述另外两种实演,以及它们彼此之间如何关联。

注释