数据截至 (上游 commit db580e952e54)
DB-GPT — 架构与原理
30 秒导读: DB-GPT 是一个开源的"AI 数据助手"。你把数据库/CSV/知识库接进来,用自然语言提问,它派一个或一组 Agent 去自动写 SQL、跑 Python、画图、出报告。它最值得学的不是"接了多少模型",而是一个能自我纠错的 Agent 循环:模型给一版答案 → 系统真去执行(跑 SQL/跑代码)→ 验证结果对不对 → 不对就把错误塞回去让模型重试。下面由浅入深讲清楚这套机器怎么运转。
1. 这是什么(零基础也能懂)
-
一句话定义: DB-GPT 是一个面向数据的 Agent 框架 + 应用——把"对着数据库/表格用人话提问"这件事,变成"AI 自己写 SQL/写代码、执行、验证、纠错"的自动化任务。
-
解决什么问题 / 给谁用: 假设你是个分析师,手里有一个几十张表的业务库。你想知道"上个月华东区哪个品类卖得最好",但你不想自己写 join、group by。你只想用中文问一句。DB-GPT 让一个
DataScientistAgent 去读表结构、生成 SQL、真的连库执行、看结果对不对,错了自己改,最后把数据画成图给你。 -
它能做什么(功能):
- 接数据库、CSV/Excel、数据仓库、知识库(RAG)
- 自然语言 → SQL,并自动执行、自动纠错(Text-to-SQL)
- 写 Python 代码做分析,在沙箱里执行
- 生成图表、仪表盘、HTML 报告
- 多 Agent 协作:一个规划、一个写 SQL、一个调工具
- 用 AWEL(数据流引擎)把这些拼成可复用的工作流
-
用起来什么样: 最小的真实用法就是"绑几样东西,然后
initiate_chat"。下面是仓库自带例子的精简版(examples/agents/single_agent_dialogue_example.py:24-52):
# 示意,改写自仓库 examples,演示"绑装 + 发起对话"的最小骨架
context = AgentContext(conv_id="test123", gpts_app_name="代码助手")
agent_memory = AgentMemory() # 记忆
agent_memory.gpts_memory.init(conv_id="test123")
coder = (
await CodeAssistantAgent() # 选一个现成的 Agent
.bind(context) # 绑上下文(会话 id、轮数上限…)
.bind(LLMConfig(llm_client=llm_client)) # 绑大模型客户端
.bind(agent_memory) # 绑记忆
.build() # 构建:预热资源、初始化记忆
)
user_proxy = await UserProxyAgent().bind(context).bind(agent_memory).build()
# 用户代理"发起"一次对话,把问题交给 coder
await user_proxy.initiate_chat(recipient=coder, reviewer=user_proxy,
message="用 python 计算 321 * 123")
重点看两件事:① .bind(...).build() 的链式装配(把 LLM、记忆、上下文、Action 一件件挂上去);② initiate_chat 把球发出去,后面整个 think→act→verify 循环就自动转起来了。
- 一句话直觉/类比: 把每个 Agent 想成一个会自己复盘的实习生:接到任务先想(think)、先自审(review)、动手干(act,真去跑 SQL/代码)、对答案(verify),发现搞砸了不甩锅,把报错读一遍、自己改一版再交(自我纠错)。DB-GPT 的精华就在这个"动手 + 对答案 + 改"的闭环,而不只是"问大模型"。
本节不碰代码细节,目标:你现在能跟别人讲清"DB-GPT 是个会自己写 SQL/代码、还会自我纠错的数据 Agent"。
2. 顶层全景(它大概怎么转)
DB-GPT 是个 monorepo,真正的代码在 packages/ 下分了 7 个包(commit 177bfc8,共 ~1250 个 Python 文件)。先看包的分工:
| 包 | 干什么 | 你想读哪块进这里 |
|---|---|---|
dbgpt-core | 框架核心:Agent 框架、AWEL 数据流、RAG、记忆、模型抽象 | 本文档绝大部分 |
dbgpt-serve | 把核心能力包成可部署的服务(REST/服务层) | 上线部署 |
dbgpt-app | 默认应用(对话、知识库、数据分析的产品层) | 端到端产品 |
dbgpt-ext | 扩展:具体的向量库/数据源/模型适配实现 | 接某个具体组件 |
dbgpt-sandbox | 沙箱:把 AI 生成的代码丢容器里隔离执行 | 安全执行 |
dbgpt-client | 调 DB-GPT 服务的 SDK | 集成 |
dbgpt-accelerator | 推理加速(flash-attn 等) | 自托管模型 |
Agent 框架自己的全景图(这是本文档的主线,所有路径相对 packages/dbgpt-core/src/):
用户问题
│ initiate_chat
▼
┌─────────────────────────────────────────────────────────┐
│ ConversableAgent (dbgpt/agent/core/base_agent.py) │
│ ── 一个 Agent 的"身体",承载五步循环 ── │
│ │
│ ① think 问 LLM,要一版答案/计划 │
│ ② review 自审这版答案合不合规 │
│ ③ act 真去执行(跑 SQL / 跑代码 / 调工具) │
│ ④ verify 对答案:执行成功吗?结果空吗?对不对? │
│ ⑤ 纠错 不对 → 把报错塞回去,回到 ①,最多 N 次 │
└───┬───────────────┬──────────────┬───────────────┬───────┘
│ │ │ │
▼ ▼ ▼ ▼
┌───────┐ ┌─────────┐ ┌─────────┐ ┌──────────┐
│Profile│ │ Memory │ │ Action │ │ Resource │
│人设+ │ │ 四层记忆 │ │ 解析+ │ │ DB/工具/ │
│prompt │ │ +进度 │ │ 执行 │ │ 知识/沙箱 │
│模板 │ │ +压缩 │ │ │ │ │
│profile/│ │ memory/ │ │ action/ │ │resource/ │
└───────┘ └─────────┘ └─────────┘ └──────────┘
多个 Agent 怎么协作?
▼
┌─────────────────────────────────────────────────────────┐
│ AutoPlanChatManager (dbgpt/agent/core/plan/...) │
│ Planner 拆任务 → Manager 选发言人 → 各 Agent 按计划干 │
└─────────────────────────────────────────────────────────┘
这一切的执行底座(可选):
▼
┌─────────────────────────────────────────────────────────┐
│ AWEL (dbgpt/core/awel) 用 a >> b >> c 拼异步数据流 DAG │
└─────────────────────────── ──────────────────────────────┘
怎么读这张图: 从上往下是抽象层级。最上面 ConversableAgent 是一个 Agent 的"身体",里面跑五步循环;它身上挂着四样东西(人设 Profile、记忆 Memory、动作 Action、资源 Resource);多个这样的身体由 AutoPlanChatManager 编排协作;最底层 AWEL 是个通用数据流引擎,Agent 之上之下都能用它编排。
部件一句话职责:
| 部件 | 干什么 | 在哪个文件 |
|---|---|---|
Agent (接口) | 定义 send/receive/thinking/act/verify 等抽象方法 | dbgpt/agent/core/agent.py |
ConversableAgent | 五步循环的真正实现(1462 行,框架心脏) | dbgpt/agent/core/base_agent.py |
Role | Agent 的"身份":人设、记忆读写、任务进度 | dbgpt/agent/core/role.py |
Profile | 人设 → Jinja2 system prompt 模板 | dbgpt/agent/core/profile/base.py |
Action | 把 LLM 文本解析成结构化动作并执行 | dbgpt/agent/core/action/base.py |
Resource | Agent 的"工具箱":数据库、工具、知识、沙箱 | dbgpt/agent/resource/base.py |
AgentMemory | 短期/长期/混合记忆 + 多 Agent 共享记忆 | dbgpt/agent/core/memory/agent_memory.py |
AutoPlanChatManager | 多 Agent:拆计划、选发言人、推进 | dbgpt/agent/core/plan/team_auto_plan.py |
AWEL DAG/BaseOperator | 异步数据流 DAG | dbgpt/core/awel/ |
主线走一遍(高层,不进代码):
- 用户(或
UserProxyAgent)initiate_chat,把问题作为一条AgentMessage发给目标 Agent。 - 目标 Agent 在
generate_reply里进入循环:think(组装 prompt + 记忆,问 LLM)。 - review 自审 → act(
Action.parse_action解析 LLM 输出的 JSON,真去执行,比如连库跑 SQL)。 - verify 对答案(
correctness_check:SQL 跑通了吗?有数据吗?)。 - 不通过就把失败原因当成新的"观察"塞回去,回到 think 重试;通过就写记忆、返回结果。
- 多 Agent 场景下,这套循环被
AutoPlanChatManager反复调用——每个子任务派给合适的 Agent 跑一遍。
目标:你现在看懂了"大盘"。接下来每一章拆一个机制。
3. 阅读地图(按这个顺序读)
| 顺序 | 章节 | 讲什么 | 适合谁 |
|---|---|---|---|
| 1 | 01-agent-loop.md | 单个 Agent 的五步循环——本框架最核心的价值,自我纠错怎么实现 | 所有人,必读 |
| 2 | 02-multi-agent-and-plan.md | 多 Agent 协作:Planner 拆任务、Manager 选发言人、按计 划推进 | 想做多智能体编排 |
| 3 | 03-memory-and-context.md | 四层记忆 + 任务进度追踪 + 四级上下文压缩(防爆 token) | 关心长任务/上下文管理 |
| 4 | 04-resources-and-tools.md | Resource/Tool/数据库/沙箱——模型怎么真正动到数据 | 接工具/数据源/安全执行 |
| 5 | 05-awel-dataflow.md | AWEL:用 >> 拼出来的异步数据流引擎 | 想理解执行底座/做工作流 |
建议: 先读 01(理解"一个 Agent 怎么自我纠错"),它是整个项目的灵魂;再看 02 理解协作;03/04 按需深入;05 是更底层的执行引擎,独立成篇。
4. 巧妙之处(先剧透,细节在各章)
- 执行驱动的自我纠错:很多框架只"让模型自评";DB-GPT 是真去执行再验证——SQL 跑不出数据、代码报错,都会被当成"观察"喂回模型重试(
base_agent.py:716-757)。详见 01。 - 任务进度永不丢:
_task_progress是个不进 pydantic 序列化的普通实例属性,专门用来在记忆被驱逐、上下文被压缩后,仍能告诉模型"已经做过哪些步、别重复"(role.py:212-240)。详见 03。 - 操作快照落盘:每步成功操作都写一个
step_NNN_action.json快照到磁盘,压缩上下文时丢的是"摘要里的细节",需要时模型可以read_file把精确值捞回来(role.py:408-470)。详见 03。 - 四级渐进式上下文压缩:截观察 → 丢旧轮次 → LLM 摘要 → 紧急截断,按 token 预算分级触发,还带熔断器(
context/manager.py:139-170)。详见 03。 >>拼数据流:AWEL 用 Python 的__rshift__重载,让a >> b >> c直接定义 DAG 依赖(awel/dag/base.py:101-117)。详见 05。
5. 边界与局限(诚实)
- 强依赖结构化 JSON 输出:
Action靠find_json_objects从 LLM 文本里抠 JSON(action/base.py:204-209);模型不按格式吐,这一步就抛"Unable to obtain valid output",落到纠错重试。弱模型上稳定性靠重试兜。 - 自我纠错有上限:重试受
max_retry_count和max_timeout双重限制(base_agent.py:738-749),超了就带着失败返回,不会无限磨。 - 沙箱安全是"限额 + 隔离"而非"形式化沙箱":
dbgpt-sandbox给的是内存/CPU/网络开关和容器隔离(sandbox/config.py:29-35),不是 seccomp/能力裁剪级别的硬隔离(代码里未见这类配置)。详见 04。 - 默认短期记忆很小:
AgentMemory默认ShortTermMemory(buffer_size=5)(agent_memory.py:303-304),长任务必须靠任务进度追踪 + 上下文压缩兜 底,否则会"忘事"。
6. 横向对比(同 shelf 的兄弟)
DB-GPT 在 data-agents area 里的定位,和别的 Agent 框架最大的不同是"以数据/SQL 执行为一等公民"。和通用 Agent 框架的取舍对比:
| 维度 | DB-GPT | 通用 Agent 框架(典型) |
|---|---|---|
| 核心循环 | think→review→act→verify→纠错,验证是"真执行后对答案" | 多为 think→act→observe,验证较弱或交给模型自评 |
| 价值中心 | Text-to-SQL / 数据分析 / 出图出报告 | 通用工具调用 |
| 多 Agent | 内置 Planner+Manager 计划编排 | 各家不同 |
| 执行底座 | 自带 AWEL 数据流 DAG | 多无独立数据流引擎 |
| 安全 | 内置容器沙箱包 | 多依赖外部 |
精读各机制请进各章。
7. 代码地图(导航索引)
| 主题 | 文件路径(相对 packages/dbgpt-core/src/) | 关键符号 |
|---|---|---|
| Agent 接口 | dbgpt/agent/core/agent.py | Agent, AgentMessage, AgentContext |
| 五步循环实现 | dbgpt/agent/core/base_agent.py | ConversableAgent.generate_reply |
| 身份/记忆读写/进度 | dbgpt/agent/core/role.py | Role, write_memories, task_progress_summary |
| 人设→prompt | dbgpt/agent/core/profile/base.py | ProfileConfig, format_system_prompt |
| 动作解析执行 | dbgpt/agent/core/action/base.py | Action.parse_action, ActionOutput |
| 具体 Agent 示例 | dbgpt/agent/expand/data_scientist_agent.py | DataScientistAgent.correctness_check |
| 多 Agent 编排 | dbgpt/agent/core/plan/team_auto_plan.py | AutoPlanChatManager.act, select_speaker |
| 记忆 | dbgpt/agent/core/memory/agent_memory.py | AgentMemory, AgentMemoryFragment |
| 上下文压缩 | dbgpt/agent/core/context/manager.py | ContextManager.manage_context |
| 资源/工具 | dbgpt/agent/resource/base.py, .../tool/base.py | Resource, FunctionTool, tool |
| AWEL DAG | dbgpt/core/awel/dag/base.py | DAG, DAGNode, DependencyMixin |
| AWEL 算子/执行 | dbgpt/core/awel/operators/base.py, .../runner/local_runner.py | BaseOperator.call, DefaultWorkflowRunner |