AI驱动的架构发现:工作原理揭秘 - Archyl Blog

我构建了一个能够阅读代码库并生成架构图的AI系统。以下是我在技术、挑战以及为什么它并非魔法方面的心得体会。

AI驱动的架构发现:工作原理揭秘

去年,我接手了一个零文档的代码库。跨15个服务的200,000行代码,由一个已经离开的团队编写。我的任务是充分理解它,以便添加新的支付集成。公司估计仅梳理架构就需要2-3周时间。

正是这段经历促使我构建了Archyl的AI发现功能。在花了数月时间使用大型语言模型分析代码之后,我想分享哪些方法真正有效、哪些无效,以及为什么AI驱动的架构发现强大但并非神奇。

手动发现的问题

在深入AI之前,让我们先了解为什么我们首先需要它。

当我面对那个无文档的代码库时,我的发现过程是这样的:

第1周:在代码中用grep搜索关键词。找到主要入口点。在白板上画一些方框。意识到我误解了服务边界。擦掉重画。

第2周:采访那个资历足够老、还记得一些历史的工程师。他告诉我的内容有一半与我在代码中发现的相矛盾。原来事情已经改变了,但没有人更新他的认知模型。

第3周:终于感觉对系统有了足够的理解,可以进行修改。创建文档,发誓会保持更新。(剧透:我没有。)

这个过程缓慢、容易出错,而且无法扩展。每个新团队成员都要经历同样痛苦的发现过程。文档在几个月内就会过时。

AI发现的实际工作原理

当你将代码仓库连接到Archyl并运行发现时,底层是这样工作的:

第1步:仓库扫描

首先,我们构建代码库的映射。这还不是AI——而是简单的文件系统遍历:

  • 列出所有文件和目录
  • 识别配置文件(package.json、go.mod、docker-compose.yml)
  • 找到入口点(main函数、index文件、API路由)
  • 根据导入构建依赖图

这给了我们骨架。我们知道存在哪些文件以及它们如何相互引用。但我们还不了解它们_做什么_。

第2步:分块分析

这就是LLM发挥作用的地方,也是事情变得棘手的地方。

现代语言模型有上下文限制。GPT-4可以处理大约128K个token,Claude可以处理200K。这听起来很多,但一个中等规模的代码库很容易超过这个限制。所以我们不能简单地把整个代码库塞进提示词中问"这是什么?"

相反,我们将代码库分成可消化的块:

  1. 按目录或模块分组文件
  2. 将每个块连同其在项目中位置的上下文一起发送给LLM
  3. 要求模型识别:这段代码负责什么?使用了什么模式?它与哪些外部系统交互?

响应以结构化数据的形式返回——JSON描述系统、容器和组件及其关系。

第3步:聚合与协调

这是最困难的部分,也是我花费最多开发时间的地方。

每次分块分析给我们的是一个局部视图。用户服务块知道用户数据库的存在。支付块知道Stripe的存在。但两者都不知道全貌。

我们需要协调这些局部视图:

  • 合并重复实体("UserDB"和"users_database"是同一个东西吗?)
  • 推断块之间的关系(订单服务调用用户服务,但它们是分开分析的)
  • 解决冲突(一个块说我们用PostgreSQL,另一个说MySQL——哪个是对的?)

这种协调使用另一轮LLM分析,加上基于常见模式的启发式方法。它并不完美。有时AI会出错。这就是为什么发现产生的是供人类审查的_建议_,而不是最终文档。

第4步:C4模型生成

最后,我们将发现的实体映射到C4模型元素:

  • 外部系统(第三方API、我们不管理的数据库)
  • 容器(我们的可部署单元)
  • 组件(容器内的主要模块)
  • 关系(谁调用谁、数据流向哪里)

结果是一组反映AI对你架构理解的C4图表草稿。

AI做对了什么

在开发过程中对数十个代码库运行发现后,以下是给我留下深刻印象的方面:

技术栈检测

LLM在识别项目使用的技术方面表现出色。它们能识别框架模式、库的惯用写法和配置文件格式。当GPT看到@Controller注解时,它知道你在使用Spring。当它看到fiber.New()时,它知道你在使用Go Fiber。

服务边界检测

在微服务架构中,AI能可靠地识别服务边界。它理解/services/user/中的代码可能与/services/order/是不同的服务。它能识别Docker Compose文件作为服务拓扑的指示器。

常见模式识别

AI在其训练数据中见过数百万个代码库。它能识别仓库模式、MVC结构、事件驱动架构和API网关设置。当你的代码遵循常见模式时,AI能快速识别它们。

外部集成发现

每个API密钥常量、webhook URL或SDK导入都是关于外部集成的线索。AI能捕获其中大部分,构建出你的系统依赖哪些第三方服务的图景。

AI做错了什么

以下是我需要设定合理期望的地方:

自定义领域逻辑

AI不理解你的业务领域。它可以判断你有一个processOrder函数,但不知道"处理订单"在你的特定业务上下文中意味着什么。它可能会误判领域特定组件的用途。

非常规架构

如果你的架构不遵循常见模式,AI会遇到困难。自定义插件系统、非传统的文件夹结构或自研框架会让它困惑。AI期望Rails应用看起来像Rails应用。

隐式依赖

并非所有依赖都在代码中显式声明。也许你的服务需要一个只存在于生产环境中的特定版本的Redis。也许有一个AI永远看不到的sidecar容器。运行时依赖对静态分析来说往往是不可见的。

过时的代码路径

AI不知道哪些代码是活跃使用的,哪些是多年无人触碰的遗留代码。它可能会突出显示一个仍在代码库中但不再部署的已弃用服务。

如何让AI发现更准确

通过反复试验,我找到了提高发现准确性的方法:

提供上下文

在运行发现之前,告诉AI你的系统信息。"这是一个带有支付处理的电子商务平台"给模型提供了一个参考框架。没有上下文,它就是在盲目猜测。

从结构开始

如果你有任何现有文档——哪怕是一个带有粗略架构草图的README——也请提供。AI将其用作先验信息来指导分析。

增量审查

不要一次对整个代码库运行发现。从一个服务开始。审查并纠正结果。然后扩展到下一个服务。你所做的更正会为未来的分析提供参考。

信任但要验证

将AI建议视为起点,而非最终答案。AI可能有80%的准确率。你需要验证另外20%。点击源代码链接,确认关系是否合理,并纠正错误。

技术细节

对于对实现感到好奇的人:

分块策略

我们使用语义分块而非固定大小分块。一个块通常是一个模块、一个服务或一个目录树。这使相关代码保持在一起,从而提高AI的理解能力。

提示词工程

提示词经历了显著的演变。早期版本产生冗长的叙述性描述。当前的提示词要求具有特定字段的结构化输出。我们使用少样本示例来演示预期的格式。

并发处理

大型代码库有数千个文件。顺序处理将耗时极长。我们并行分析块,可配置并发限制以避免API速率限制。

模型选择

不同的模型有不同的优势。GPT-4产生更准确的分析但成本更高。Claude在遵循结构化输出要求方面更好。我们两者都支持,另外通过Ollama支持本地模型,为不能将代码发送到外部API的团队服务。

AI驱动发现的未来

我们今天拥有的是第一版。以下是我正在努力的方向:

持续发现

不再是一次性分析,而是持续监控你的代码库。当代码发生变化时,自动更新相关图表。在架构漂移成为问题之前检测到它。

更深层的理解

当前的分析主要是结构性的。未来版本可以理解行为:"这个端点验证输入,调用支付服务,然后发送确认邮件。"从代码生成的时序图。

跨仓库分析

大多数组织有多个代码仓库。发现应该理解它们如何连接——仓库A中的哪些服务调用仓库B中的服务。

置信度评分

并非所有发现都同样确定。我们正在添加置信度评分,以便你知道哪些建议需要更仔细地审查。

总结

AI驱动的架构发现不是魔法。它是一个工具,可以加速理解代码库中乏味的部分,同时仍然需要人类判断来处理细微的部分。

当我今天对那个20万行的代码库运行发现时,我在10分钟内就能得到一个架构图草稿,而不是3周。它并不完美——我仍然需要审查和纠正。但比起一块空白的白板,这是一个好得多的起点。

如果你被无文档的代码淹没,试试AI发现吧。带着合理的期望:它不会理解你的业务领域,可能会遗漏不寻常的模式,而且绝对需要人工审查。但它能在极短的时间内让你完成80%的工作。


想了解更多?查看我们的C4模型介绍,了解AI发现生成的内容,或阅读为什么架构文档很重要