用AI解决开发痛点:打造智能数据库文档问答系统
开发痛点
在日常开发工作中,我经常遇到以下几个痛点:
- 表名查询困难:当需要查询表数据时,由于不是自己设计的表,常常不知道表名是什么
- 字段含义不明:不清楚字段的具体含义和枚举值的定义
- 文档缺失:字段的comment没有及时维护,也没有技术文档可以追溯
- 查找过程繁琐:只能打开项目代码查找枚举定义,过程繁杂冗余
我开始思考:能否借助AI的能力,将表定义和枚举定义提供给大模型(LLM),让AI直接给出我们需要的答案?
解决方案分析
经过分析,我决定采取以下方案:
- 选择RAG而非训练:训练LLM成本太高,优先选择RAG方案(检索增强生成,即将大模型不知道的知识通过相似性检索获取,作为上下文传给LLM)
- 自动化知识库构建:手动整理知识库繁琐且耗费人力,可以用工具自动解析项目中的migration(SQL语句)、Go文件中定义的const、enum等
实现过程
设计小工具docgen
我设计了一个名为docgen的小工具来生成知识库文档,流程如下:
为提高生成的知识库质量,我做了以下处理:
- 定义注释标签:使用
//@ai xxxx(描述)标签,只处理带有此标签的内容,防止误拉取一些const定义 - 选择友好格式:生成的知识库采用md文件格式,对LLM较为友好
- 添加标签系统:对提取的枚举定义打标签,方便LLM识别
生成效果展示
# 枚举类型
## MailStatus 邮件发送状态枚举
**标签:** `completed` · `failed` · `mail` · `pending` · `sending` · `status` · `status 邮件发送状态枚举` · `发送中` · `发送失败` · `已完成` · `待发送` · `邮件发送状态枚举`
| 变量 | 原值 | 描述 |
|---|---|---|
| MailStatusPending | 1 | 待发送 |
| MailStatusSending | 2 | 发送中 |
| MailStatusCompleted | 3 | 已完成 |
| MailStatusFailed | 4 | 发送失败 |
# 数据库表
## order_details
| 字段 | 类型 | 描述 |
|---|---|---|
| id | bigint | 自增ID |
| trade_date | character | 交易日期(2006-01-02) |
| user_id | bigint | 用户id |
| order_id | bigint | 订单ID |
| currency | character | - |
| trade_amount | numeric | 成交金额 |
| trade_quantity | numeric | 成交数量 |
| order_status | character | 订单状态:init-初始化,pending-待处理,processing-处理中,completed-已完成,cancelled-已取消 |
| fee | numeric | - |
对接LLM实现智能问答
生成文档后,下一步是对接LLM实现智能问答:
简易方案:使用现有平台
如果你使用过dify或coze这类LLM工作流平台,那么实现起来非常简单:
- 直接将生成的文件上传到知识库
- 构建自己的机器人
- 通过coze提供的API调用你构建的机器人
自建RAG系统
如果想自己实现RAG系统,主要技术点包括:
- 文本向量化:使用OpenAI的
text-embedding-3-small模型 - 向量存储:可选用开源产品如Chroma、Qdrant等,本项目选择Qdrant
- LLM调用框架:使用Go语言的langchain实现:langchaingo
- LLM选择:可选DeepSeek-R1、GPT等,需要有openai_key(国内有多种代理平台可申请)
防止LLM幻觉的简单处理
func (c *LLMClient) CreateQAChain() chains.Chain {
// 创建一个简单的提示模板
template := `使用以下上下文来回答问题。如果你不知道答案,只需说不知道,不要试图编造答案。
上下文: {{.context}}
问题: {{.question}}
回答:`
// 创建提示模板
prompt := prompts.NewPromptTemplate(
template,
[]string{"context", "question"},
)
// 创建LLM链
return chains.NewLLMChain(c.llm, prompt)
}
问答效果展示
使用DeepSeek-R1推理模型的问答效果:
用户: 订单状态的枚举有哪些
AI回答:
<think>
好的,我需要回答用户的问题:"订单状态的枚举有哪些"。首先,我要仔细查看提供的上下文,看看是否有关于订单状态枚举的信息。
用户提供的四个文档看起来都是重复的,每个文档都包含两个主要部分:枚举类型MailStatus和数据库表order_details。在枚举类型部分,MailStatus有四个状态:待发送、发送中、已完成、发送失败,对应的变量名和原值。但用户的问题是关于订单状态的枚举,而不是邮件状态。
接下来看数据库表order_details的结构。每个文档中的order_status字段描述是:"订单状态:init-初始化,pending-待处理,processing-处理中,completed-已完成,cancelled-已取消"。这里明确列出了订单状态的枚举值,每个值对应一个状态名称。虽然这些值是以字符类型存储的,并不是编程中的枚举类型,但根据问题中的"枚举"可能指的是这些可能的状态值。
需要确认的是,用户是否将数据库字段中的这些选项视为枚举。通常,数据库中的字符字段可能使用枚举约束,但根据提供的文档,这里并没有明确说明order_status是一个数据库枚举类型,而是用字符类型存储,并列出可能的取值。因此,这里的"枚举"可能指的是该字段允许的值列表。
因此,正确的订单状态枚举值应该是init、pending、processing、completed、cancelled,对应的中文描述分别是初始化、待处理、处理中、已完成、已取消。而邮件状态的枚举是另一个枚举类型MailStatus,与订单状态无关,所以不需要考虑。
总结,用户的问题答案应基于order_details表中order_status字段的描述,列出所有可能的值。
</think>
订单状态的枚举值包括:init(初始化)、pending(待处理)、processing(处理中)、completed(已完成)、cancelled(已取消)。这些状态定义在数据库表 `order_details` 的 `order_status` 字段中。
项目开源
上述两个工具:docgen和RAG问答系统已开源在GitHub上: github.com/botjay/Konw…
我会继续整理和分享一些AI小工具来解决开发和生活中的问题,以及AI基础概念的介绍,欢迎一键三连!