哈哈小说
第 8 卷 · 把电搬下来 · 第 159 章 · 58 段 · 1650 字

项目

第一百五十九章 项目

第二天早上,他七点半起来,在早餐店吃了碗豆浆油条,然后回到桌前,打开了电脑。

豆包昨晚发来了一条消息,是六个搜索方向:

「document cross-reference extraction」

「temporal consistency checking」

「knowledge graph from documents」

「document relation mining」

「citation graph」

「contract clause cross-reference」

然后是一行备注:「中文也可以搜:跨文档引用追踪、文件关系图谱、合同条款交叉索引。」


他在GitHub的搜索框里先打了「document cross-reference extraction」。

结果出来,三页,他逐个点开看。大多数是学术论文代码库,有配套的PDF但没有实际运行的代码,或者代码跑不起来,或者依赖的环境已经不维护了。有几个工具类的,做的是PDF解析,提取文字和格式,但「引用关系」只是把超链接给整理了一下,不是他想要的东西。

他换了「temporal consistency checking」。

插图

这个方向的结果更散,大多数是做数据库一致性验证的,和文档语义没有关系。有两个和他的想法接近一些——一个是做新闻文本时间线提取的,一个是做法律文件里的事件时序验证的。法律这个,他点进去仔细看了一下:做的是刑事案件的证据时间线,提取证词里的时间陈述,标记矛盾点。方向是对的,但这个项目只有readme,代码文件里只有一个空的`main.py`,上一次提交记录是十个月前,停了。


他把这个项目的链接存了下来,加在一个新建的文档里,备注了几个字:「时序验证,法律方向,已停,但思路可参考。」

然后他继续找。

「knowledge graph from documents」,结果更多,也更乱——这个方向现在是热门,有很多公司在做,从知识库构建到企业内部文档管理,各种包装方式都有。但他看下来,大部分都是「给文档加标签,然后搜索标签」——那还是搜索的逻辑,不是他要的发现。

他喝了口水,换了「contract clause cross-reference」。

这个结果更窄,但更接近。有三个项目:一个是美国某法律科技公司开源的合同审查工具,做的是把合同条款映射到标准条款库;一个是学术性质的,做跨合同条款引用的图结构建模;还有一个,他看了看,名字叫`ref-trail`,没有组织背书,是个人开发者做的。

他点进去。


`ref-trail`的README写了大概八百个字,没有图,没有截图,就是黑白的文字。

开头是一段说明:

「这个工具的目的是:给一组文件,找出文件里相互引用的地方,把这些引用串成一条链,看看这条链里有没有断点或者矛盾。最初的动机是我自己做投资尽调的时候,发现有一批文件里的引用关系手工追很费时,而且容易漏。」

陆衍停了一下,把这段话读了第二遍。

「最初的动机是我自己做投资尽调的时候……」

插图

他往下读。

工具目前能做的事:识别文件里出现的「见第X条款」「详见附件Y」「参考Z号文件」这类显式引用,然后从引用源文件追踪到被引用文件,如果被引用的文件不存在,或者被引用的内容和引用方描述的不一致,就标记出来。

「目前的限制,」README里写,「只处理显式引用,不处理隐式的语义关系。日期一致性和版本追踪是计划中的功能,还没做。」


陆衍往下翻,看提交记录。

这个项目三个月前开始,最近一次提交是十四天前,持续在更新。代码里有测试文件,有示例文档,有一个简单的命令行接口,能跑起来。

他把示例文档下载下来试了试,跑了一遍,输出了一个json,里面是每一条引用的状态:`valid`,`broken`,`inconsistent`。

`inconsistent`的那条,他点开看:示例文档里有一处说「参见附件B的第3.2条」,但附件B的实际文件里第3.2条写的内容和文档里描述的不一样——工具发现了这个,标了出来。

他盯着这个输出看了很久。


发给豆包:「找到一个叫ref-trail的项目,个人开发者,最初动机是投资尽调。现在做了显式引用追踪,日期和版本追踪还没做。」

豆包:「他的起点和你的描述重合度很高——自己遇到了问题,觉得现有工具不够用,就自己开始做。」

「但他做的是显式引用,」陆衍说,「我想做的是隐式的——文件A里的一个日期,文件B里的一个状态,两者之间没有直接的引用链接,但逻辑上是相关的,而且可能矛盾。」

插图

「显式引用是他的第一步,」豆包说,「做完了会往哪里走——这件事,他自己大概比你更清楚。」

「你的意思是,」陆衍说,「他可能也在想下一步。」

「有可能,」豆包说,「如果他的动机真的是尽调,他一定意识到显式引用只是一部分——日期矛盾、版本不一致、主体变更这些,都不是靠追引用链能找到的。」


陆衍看了看项目里有没有issues。

有四条open的issue,三条是用户提的bug,一条是开发者自己写的,标题是「TODO: implicit temporal inconsistency」——时序不一致检测,他自己列出来的下一步。

这条issue发出的时间是二十一天前。

陆衍看了看这个开发者的GitHub主页:没有公司信息,没有个人网站,只有几个项目,都是工具性质的,没有学术背景的痕迹。


他发给豆包:「这个人看起来不是研究员,是做过实际尽调工作的人,然后在业余时间做工具。」

豆包:「这类人的特点是:他理解问题,他能做工具,但他可能不确定这个方向值不值得all-in。」

「他还在做,」陆衍说,「十四天前有提交。」

「你想联系他?」

陆衍把这个问题在脑子里转了一圈,「联系什么理由?」

插图

「最直接的,」豆包说,「你用了他的工具,在一个真实的尽调场景里,发现它解决了一部分问题,但你遇到了这个工具还没覆盖的部分。你想聊聊。」

「这是真的,」陆衍说,「我刚用他的示例文档跑了一遍。」

「那就不是借口,」豆包说,「是事实。」


陆衍在项目的README里找了一会儿,没有联系方式,只有GitHub账号。他在他的profile页面翻了翻,有一个issues页面上留过邮件——是在另一个项目里,他回答一个用户问题的时候,末尾加了一句「可以发邮件」。

他把那个邮箱地址存下来。

然后他没有立刻写邮件。

他打开那个`ref-trail`的代码,开始认真读。他不是工程师,但代码里的注释写得很清楚,逻辑他能跟上:文件进来,先找所有的引用标记,然后去对应的文件里查,返回状态。

读了大概四十分钟,他在本子上写:

「这个人知道问题在哪里。他的TODO里有时序检测,说明他知道显式引用解决不了全部问题。他在等一个触发点。」

他看着这行字,加了一句:「或者不需要等,他需要一个对话。」

窗外,楼下早餐店的老板娘在拖地,扁担声细细地传上来,上海的年后第一个工作日就这么开始了。