一个挑战
目前是正在写作file_read/write工具。AI往往是按行更改,很多操作也是依赖“按行”。所以我们不得不实现一个尽量高性能的文件读写层。然后这就带来了无穷无尽的问题……
1.1 并发问题
文件读写肯定要Async这点是毋庸置疑的。但是Async本身就带来了并发问题。翻开书本,我们可以知道:当进行文件读写的时候,我们应该使用的是读写锁:
读写锁(Read-Write Lock)致力于一种更加特定的场合的同步。对于一段数据,多个线程同时读取总是没有问题的,但假设操作都不是原子型,只要有任何一个线程试图对这个数据进行修改,就必须使用同步手段来避免出错。如果我们使用上述信号量、互斥量或临界区中的任何一种来进行同步,尽管可以保证程序正确,但对于读取频繁,而仅仅偶尔写入的情况,会显得非常低效。读写锁可以避免这个问题。对于同一个锁,读写锁有两种获取方式,共享的(Shared)或独占的(Exclusive)。当锁处于自由的状态时,试图以任何一种方式获取锁都能成功,并将锁置于对应的状态。如果锁处于共享状态,其他线程以共享的方式获取锁仍然会成功,此时这个锁分配给了多个线程。然而,如果其他线程试图以独占的方式获取已经处于共享状态的锁,那么它将必须等待锁被所有的线程释放。相应地,处于独占状态的锁将阻止任何其他线程获取该锁,不论它们试图以哪种方式获取。读写锁的行为可以如 表 1 所示。
读写锁状态 以共享方式获取 以独占方式获取 自由 成功 等待 共享 成功 等待 独占 等待 等待 表 1 读写锁的行为
1.2 行写入——极限的优化
AI 写文件按行。我们的工具按行读写文件。实现这一切是一件非常令人愤怒的事情。为了实现高效我不得不手动用FileStream.ReadBytes()来搞索引
然后,一个写入工具就要分替换、增加、删除三种方式。这也是为了AI能使用更少的 token 进行工具调用。
所以就先有了最底层的FileAccessor类。这个类就是提供了最底层的。
然后用 Codex 生成了剩下的,AI就是这一点好,有了模板有样学样