使用人机协同构建可审批的 AI 数据库助手(ToolApprovalRequestContent)

decade
5
2026-04-15

本教程演示如何基于 C#、Entity Framework Core、OpenAI/DeepSeek 模型,以及 AI Function Calling 机制,构建一个支持人工审批的人机协同数据库助手
核心思想是:低风险操作由 AI 自动执行,高风险操作必须经过人工确认。


一、什么是“人机协同”?

在人机协同系统中,AI 不再是完全自主执行所有任务,而是按照风险等级分工:

  • AI 负责理解自然语言

  • AI 负责生成 SQL 和调用工具

  • 人工负责审批高风险操作

  • 系统负责流程衔接和状态恢复

这是一种非常适合企业场景的模式,尤其适用于:

  • 数据库管理

  • 财务审批

  • 工单流转

  • 运维执行

  • 权限变更

  • 合同审核

简单来说:

让 AI 提高效率,让人类保留最终控制权。


二、本项目实现了什么?

这个示例实现了一个 DBA Agent(数据库管理员助手),它可以把用户的自然语言需求转成 SQL Server 操作。

支持四类数据库工具:

  1. QueryData

    • 执行 SELECT

    • 只读查询

    • 可直接执行,无需审批

  2. InsertData

    • 执行 INSERT

    • 新增数据

    • 默认可直接执行

  3. UpdateData

    • 执行 UPDATE

    • 修改数据

    • 属于高危操作,必须人工审批

  4. DeleteData

    • 执行 DELETE

    • 删除数据

    • 属于高危操作,必须人工审批

这就是一个典型的人机协同设计:

  • 读和新增:AI 自动处理

  • 修改和删除:人类把关审批


三、整体流程图

整个交互流程可以理解为下面这样:

TEXT
用户输入自然语言        ↓AI Agent 理解意图        ↓判断要调用哪个数据库工具        ↓如果是 Query/Insert → 直接执行如果是 Update/Delete → 触发审批拦截        ↓人工在控制台输入 y / n        ↓批准:继续执行拒绝:终止执行        ↓AI 汇总结果并返回给用户

四、项目中的关键设计思路

这份代码最重要的不是“怎么连数据库”,而是怎么实现可控的人机协同机制

核心有 4 个部分:


1. 用 DI 管理数据库上下文和工具

代码中先初始化依赖注入容器:

var builder = new ServiceCollection();builder.AddDbContext<MyAgentDbContext>(options =>     options.UseSqlServer("Server=DESKTOP-ABQMKQL;Database=testDB;Integrated Security=True;TrustServerCertificate=True;"));builder.AddTransient<ToolsToSql>();var services = builder.BuildServiceProvider();var sqlTools = services.GetRequiredService<ToolsToSql>();

这里做了两件事:

  • 注册 MyAgentDbContext

  • 注册数据库工具类 ToolsToSql

其中:

builder.AddTransient<ToolsToSql>();

表示每次获取工具类时都创建新实例,避免生命周期冲突。


2. 把数据库方法包装成 AI 可调用工具

接下来,把普通 C# 方法封装成 AI 工具:

var queryTool = AIFunctionFactory.Create(sqlTools.QueryData);var insertTool = AIFunctionFactory.Create(sqlTools.InsertData);var updateToolBase = AIFunctionFactory.Create(sqlTools.UpdateData);var deleteToolBase = AIFunctionFactory.Create(sqlTools.DeleteData);

这一步的意义是:

让大模型不仅能“聊天”,还能“调用函数”。

也就是说,大模型在理解用户说“帮我查一下用户表”之后,不只是生成文字回答,而是可以真正去调用 QueryData(sql)


3. 为高危操作增加审批拦截器

这是整个人机协同的关键:

var updateToolWithApproval = new ApprovalRequiredAIFunction(updateToolBase);var deleteToolWithApproval = new ApprovalRequiredAIFunction(deleteToolBase);var aiTools = new List<AITool> {     queryTool, insertTool, updateToolWithApproval, deleteToolWithApproval };

这里的设计非常重要:

  • QueryDataInsertData 直接暴露给 AI

  • UpdateDataDeleteData 先用 ApprovalRequiredAIFunction 包装

  • 包装后,AI 调用这些工具时不会立刻执行

  • 系统会先拦截,生成一个 审批请求

这就是“人机协同”的核心实现方式:

不是禁止 AI 做高风险操作,而是让 AI 发起申请,由人类决定是否放行。


4. 给 Agent 写明确的系统提示词

系统提示词里明确约束了 Agent 的行为:

string instructionsSys = """你是一个专业、严谨且高效的智能数据库管理员 (DBA Agent)。...1. QueryData (SELECT):用于查询和读取数据,属于安全操作,可直接调用。2. InsertData (INSERT):用于新增记录,属于安全操作,可直接调用。3. UpdateData (UPDATE):用于修改现有数据。这是【高危操作】,系统配置了拦截器,你调用此工具后系统会暂停并等待用户人工审批。4. DeleteData (DELETE):用于删除现有数据。这是【高危操作】,系统配置了拦截器,你调用此工具后系统会暂停并等待用户人工审批。...1. 极度严谨 (防误操作):在编写 UPDATE 或 DELETE 语句时,绝对禁止遗漏 WHERE 条件。2. 主动沟通:如果用户需求模糊,请先提问澄清。3. 审批感知:执行 UPDATE 或 DELETE 前提醒用户进行审批。4. 专业反馈:结果要用 Markdown 输出。5. T-SQL 规范:必须使用 SQL Server 语法。""";

这段提示词的作用不是“装饰”,而是让模型具备明确边界感:

  • 知道有哪些工具

  • 知道哪些操作是高危的

  • 知道不能漏掉 WHERE

  • 知道需求模糊时要先问

  • 知道最后要格式化输出

在人机协同系统里,提示词就是 AI 的操作规程


五、如何创建 Agent

Agent 的创建代码如下:

var dbAgent = chatClient.AsAIAgent(    instructions: instructionsSys,     tools: [..aiTools],     services: services);var session = await dbAgent.CreateSessionAsync();

这里完成了三件事:

  • 把聊天模型变成 Agent

  • 把工具列表交给 Agent

  • 创建一个会话 session

这个 session 很重要,因为审批后要恢复上下文继续执行,必须依赖会话状态。


六、对话循环是如何运行的?

主循环中,用户输入自然语言:

var userInput = Console.ReadLine()?.Trim();if (string.IsNullOrEmpty(userInput)) continue;if (userInput.ToLower() is "exit" or "quit") break;

然后把输入交给 Agent:

var response = await dbAgent.RunAsync(userInput, session);

这一步之后,可能有两种情况:

情况 A:普通操作

比如:

  • “查询所有用户”

  • “新增一条员工记录”

那么 Agent 会直接执行工具并返回结果。

情况 B:高危操作

比如:

  • “把张三的状态改成离职”

  • “删除订单表里 ID=10 的数据”

那么 Agent 会触发审批请求,而不会立即执行。


七、如何识别审批请求?

代码会扫描返回消息中的审批内容:

var result = response.Messages    .SelectMany(x => x.Contents)                    .OfType<ToolApprovalRequestContent>()           .ToList();

如果 result.Any() 为真,说明:

AI 发起了一个需要人工确认的高危操作。

这时系统会在控制台显示警告:

Console.WriteLine("\n⚠️ [系统警告] 拦截到高危数据库操作,需要人工审批!");

八、人工审批是如何完成的?

系统会逐个审批请求询问用户:

Console.Write("\n❓ 是否允许执行该操作?(y/n): ");var answer = Console.ReadLine()?.Trim().ToLower();bool isApproved = (answer == "y" || answer == "yes");

如果用户输入 y

approvalResponses.Add(approvalReq.CreateResponse(true));

如果用户输入 n

approvalResponses.Add(approvalReq.CreateResponse(false));

这一段的本质就是:

  • AI 先申请

  • 人工做决定

  • 系统把决定反馈给 Agent

这正是标准的人机协同闭环。


九、审批后如何恢复 Agent 执行?

审批只是中间一步,批准或拒绝后,还要把结果传回给 Agent,让它继续后续流程:

var chatMesg = new List<ChatMessage>();foreach (var message in approvalResponses){    chatMesg.Add(new ChatMessage(ChatRole.User, [message]));}response = await dbAgent.RunAsync(chatMesg, session);

这里非常关键。

因为 Agent 的执行并没有结束,只是“暂停等待审批”。
当系统把审批结果作为新的消息传回去时,Agent 才能继续:

  • 如果批准了,就执行 SQL

  • 如果拒绝了,就告诉用户操作被取消

所以这一步可以理解为:

把人工决策重新送回 AI 工作流,恢复执行。


十、数据库工具类是怎么设计的?

项目中用 ToolsToSql 封装了数据库操作。


1. 查询工具 QueryData

[Description("执行 SQL Server SELECT 查询操作,该操作仅读取数据,无需审批可直接执行")]public string QueryData(string sql)

它的特点:

  • 只执行 SELECT

  • 读取结果集

  • 把结果转成 JSON 返回

  • 自动附带执行时间和状态

返回结果类似:

✅ 查询执行成功!操作类型: SELECT 查询SQL语句: SELECT * FROM Users返回数据: [...]审批状态: 自动放行 (无需审批)执行时间: 2026-04-15 12:00:00

2. 新增工具 InsertData

[Description("执行 SQL Server INSERT 插入操作,用于向数据库新增记录,通常无需审批可直接执行")]public string InsertData(string sql)

特点:

  • 执行 INSERT

  • 返回影响行数

  • 作为低风险操作自动放行


3. 修改工具 UpdateData

[Description("执行 SQL Server UPDATE 更新操作,该操作会修改数据,必须经过审批才能真正执行")]public string UpdateData(string sql)

特点:

  • 实际执行 UPDATE

  • 但它在进入执行前,已经被审批拦截器包裹

  • 只有批准后才会真正运行


4. 删除工具 DeleteData

[Description("执行 SQL Server DELETE 删除操作,该操作属于高危动作,必须经过严格审批才能真正执行")]public string DeleteData(string sql)

特点与 UpdateData 类似,但风险更高。


十一、为什么这套方案体现了“人机协同”?

很多人以为“人机协同”就是“AI 帮人做事”。
其实更准确的理解是:

AI 负责处理复杂度,人类负责兜底风险。

在这份代码中:

AI 负责的部分

  • 理解自然语言

  • 判断用户意图

  • 生成 SQL

  • 自动调用工具

  • 整理执行结果

人类负责的部分

  • 审批 UPDATE

  • 审批 DELETE

  • 拒绝危险操作

  • 最终掌控执行权

系统负责的部分

  • 工具注册

  • 审批拦截

  • 会话恢复

  • 结果回传

这三者共同组成:

  • AI 的智能

  • 人的判断

  • 系统的控制

这就是完整的人机协同。


十二、一个典型使用示例

示例 1:查询数据

用户输入:

查询 users 表中的所有数据

可能流程:

  1. AI 判断这是查询操作

  2. 调用 QueryData

  3. 直接返回结果

不需要人工审批。


示例 2:新增数据

用户输入:

往 users 表插入一条记录,姓名为张三,年龄 25

可能流程:

  1. AI 生成 INSERT

  2. 调用 InsertData

  3. 自动执行

  4. 返回影响行数

通常也不需要审批。


示例 3:修改数据

用户输入:

把 users 表中 id=3 的用户名改成李四

流程如下:

  1. AI 判断是 UPDATE

  2. 触发审批拦截

  3. 控制台提示是否批准

  4. 人工输入 y

  5. Agent 恢复执行

  6. 返回更新成功结果


示例 4:删除数据

用户输入:

删除 users 表中 id=8 的记录

流程如下:

  1. AI 判断是 DELETE

  2. 系统拦截

  3. 控制台审批

  4. 人工可输入 n

  5. 操作被拒绝

  6. Agent 向用户说明删除未执行


十三、这套设计的优势

1. 安全

高危操作不会被 AI 直接执行,避免误删、误改。

2. 可控

人类始终掌握最终决定权。

3. 高效

低风险操作自动化,高风险操作半自动化。

4. 易扩展

以后可以把审批范围扩展到:

  • 导出敏感数据

  • 调用外部接口

  • 批量变更权限

  • 执行运维脚本

5. 适合企业落地

这是比“纯自动 Agent”更容易被企业接受的一种方案。


十四、实践建议

如果你准备把这个方案真正用于生产环境,建议继续完善以下内容:

1. 不要把 API Key 写死在代码里

当前代码里有类似:

var chatClient = StaticGetIChatClient("deepseek-chat", "你的key", "https://api.deepseek.com/v1");

实际项目中应改为:

  • 环境变量

  • 配置文件

  • Secret Manager

  • Key Vault


2. 数据库连接字符串也不要硬编码

建议放在:

  • appsettings.json

  • 环境变量

  • 配置中心


3. 对 SQL 做更严格校验

目前主要依赖模型提示词约束,但生产环境最好增加程序级校验,例如:

  • UPDATE 必须包含 WHERE

  • DELETE 必须包含 WHERE

  • 禁止多语句执行

  • 禁止执行 DDL

  • 禁止危险关键字组合


4. 加审计日志

建议记录:

  • 谁发起的请求

  • AI 生成了什么 SQL

  • 谁审批通过/拒绝

  • 最终执行结果

  • 执行时间


5. 审批界面可以升级

现在是控制台输入 y/n,以后可以换成:

  • Web 审批页

  • 企业微信/钉钉审批

  • Slack / Teams 消息确认

  • 邮件审批链接


十五、总结

这份代码展示了一个非常实用的人机协同模式:

  • 自然语言 → AI 理解

  • AI → SQL 工具调用

  • 高危操作 → 人工审批

  • 审批结果 → 恢复执行

  • 最终结果 → Markdown 输出

它不是让 AI 完全替代人,而是让 AI 成为一个有边界、有规则、可控的执行助手。

你可以把这个模式理解为一句话:

让 AI 负责“会不会做”,让人类决定“该不该做”。

这就是人机协同最有价值的地方。


十六、可直接复用的教程结语

如果你正在做 AI Agent、企业自动化、数据库 Copilot 或智能审批系统,这种“AI 自动执行 + 人工审批兜底”的方案非常值得采用。

它比纯人工更高效,比全自动更安全,尤其适合:

  • 企业内部系统

  • 数据敏感场景

  • 有合规要求的业务流程

  • 希望逐步引入 AI 的团队