周一早上老板在群里发了一句:能不能让 AI 照着咱们自己的制度文件回答问题?别老让人翻共享盘。
我说能。
这活的核心其实不复杂:模型不知道你们公司的规定,你得在它回答之前,先把相关的那几段找出来,一起塞进问题里。找哪几段、怎么存、怎么按问题去捞,这些碎活就是 LlamaIndex 管的(同类还有别的库,路数差不多)。名字里带个 Index,干的就是建索引这事儿。
我当时的想法很朴素:把文件全给它,剩下的它自己办。
documents = SimpleDirectoryReader("Z:/制度汇编").load_data()
index = VectorStoreIndex.from_documents(documents)
两行,跑起来了,没报错。我还挺高兴,截图发群里说"通了"。
然后是下午
第一个来问的是财务的同事:"差旅住宿标准是多少?" 模型答了一个数,还挺笃定。她回了一句"这是哪一年的",我去翻,发现它引的是 2021 版,而 2024 版就在同一个文件夹里。
问题出在切块上。文件会被切成一段一段存起来,切的时候按字数切,不管标题。于是"2024 年修订"这个标题和下面的表格被切到了两块里,捞出来的时候只捞到表格,年份信息留在隔壁那块没被带上。模型看见一串数字,只能猜。
再往下查,更热闹:
- 三十来份是扫描件,一整页就是张图,读出来是空的。这类得先过 OCR,是另外一步。
- 报销标准那张表,被读成了一整行没断句的数字,"800 600 400" 连在一起,谁也不知道哪个对应哪一级。
- 有两份文件名是乱码,Windows 上能打开,脚本读的时候直接跳过了,日志里一句话都没留。
- 还有几份是老 Word 转的 PDF,页眉每页都重复一遍"内部资料 请勿外传",切完之后这类废话占了一堆块。
我原本以为"喂文件"是个导入动作,干了一天才明白它更像整理档案:先分出哪些能读、哪些是图、哪些过期了,再决定按什么切。库只负责后面那一截。
第二天我改了流程,先人工挑出还在用的十几份,扫描件单独走 OCR,表格单独转成文字描述,切的时候尽量贴着标题切。再问那个住宿标准,答对了,还带上了文件名。
至于那句"内部资料 请勿外传",我到现在没想好怎么干净地去掉。直接全局替换吧,怕有的正文里正好也提到;不管吧,检索的时候它老冒出来占位置。这事先搁着了。
被奇怪文件磨出来的不止我们,VidDown 上做格式转换那几个工具也一样。
老板后来又问了一句"那能不能连合同也一起",我说这个我们再聊聊。