数据库里并不缺数据,真正稀缺的是一条安全、稳定、可审计的数据访问路径。业务提出一个查询需求后,团队往往还要编写接口、补充鉴权、设置限流、维护文档并接入监控。ApiGo 所强调的“对话即开发”,试图把这条以周计算的交付链路压缩成一次自然语言交互:开发者描述需要什么数据,平台将数据库能力转换成受治理、可供应用或 AI 调用的数据服务。
一句话背后,不只是生成 SQL
假设用户提出下面的需求:
创建一个查询最近 30 天高价值订单的接口,按客户汇总订单数和总金额,仅允许财务系统调用,每分钟最多 60 次。
如果系统只生成一段 SQL,它解决的仍然只是查询问题。一个真正可交付的数据服务至少还需要处理以下内容:
- 数据契约:明确参数、字段类型、分页方式、错误码和返回结构。
- 访问控制:识别调用方,并限制其能够访问的数据集和操作类型。
- 资源保护:设置超时、并发数、限流和最大返回行数,避免查询拖垮数据库。
- 可观测性:记录调用方、耗时、结果规模和失败原因,为审计与故障定位提供依据。
- 生命周期管理:让接口能够测试、发布、回滚、下线,而不是生成后直接暴露给生产流量。
因此,对话式开发的价值并不只是“少写代码”,而是把接口实现和治理策略放进同一条生成流程。自然语言是入口,数据服务才是交付物。
AI 调用让治理边界更加重要
传统前端通常按照固定页面调用固定接口,参数空间相对可控。AI Agent 的行为则更动态:它可能根据用户问题连续调用多个工具,也可能生成范围过大的查询条件。如果平台允许模型直接拼接 SQL,提示词注入、越权读取和高成本查询都会变成现实风险。
更稳妥的方式,是让 AI 只看到经过审批的数据服务目录。每个工具都应拥有明确的名称、用途、参数结构和权限范围。例如,模型可以调用 query_customer_order_summary,但不能获得通用的 execute_sql 能力。
一个适合暴露给 Agent 的工具描述可以这样设计:
{
"name": "query_customer_order_summary",
"description": "查询指定时间范围内的客户订单汇总,不返回客户联系方式",
"input_schema": {
"type": "object",
"properties": {
"start_date": { "type": "string", "format": "date" },
"end_date": { "type": "string", "format": "date" },
"min_amount": { "type": "number", "minimum": 0 }
},
"required": ["start_date", "end_date"]
}
}
这里有三个关键约束:接口按业务语义命名;输入参数是结构化的;敏感字段不会进入输出契约。即使上层模型受到不可信提示词影响,它能够触达的范围仍由数据服务决定。
用一个最小服务验证治理思路
下面的示例是可以本地运行的架构验证代码,不代表 ApiGo 的实际接口格式。它使用 FastAPI 和 SQLite 演示三个基础边界:只提供预定义查询、使用 API Key 鉴权、限制查询时间范围和返回规模。
安装依赖:
python -m venv .venv
. .venv/bin/activate
pip install fastapi uvicorn
创建 app.py:
from datetime import date, timedelta
import os
import sqlite3
from fastapi import FastAPI, Header, HTTPException, Query
app = FastAPI(title="Governed Order Data Service")
API_KEY = os.getenv("DATA_API_KEY", "change-me")
DB_PATH = os.getenv("DB_PATH", "orders.db")
def connect() -> sqlite3.Connection:
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
return conn
@app.on_event("startup")
def initialize_database() -> None:
with connect() as conn:
conn.execute(
"""
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY,
customer_id TEXT NOT NULL,
amount REAL NOT NULL,
ordered_on TEXT NOT NULL
)
"""
)
count = conn.execute("SELECT COUNT(*) FROM orders").fetchone()[0]
if count == 0:
conn.executemany(
"INSERT INTO orders(customer_id, amount, ordered_on) VALUES (?, ?, ?)",
[
("C001", 1200.0, "2025-01-10"),
("C001", 800.0, "2025-01-12"),
("C002", 2600.0, "2025-01-15")
]
)
@app.get("/v1/customer-order-summary")
def customer_order_summary(
start_date: date,
end_date: date,
min_amount: float = Query(default=0, ge=0),
x_api_key: str = Header(default="")
):
if x_api_key != API_KEY:
raise HTTPException(status_code=401, detail="invalid API key")
if end_date < start_date:
raise HTTPException(status_code=400, detail="invalid date range")
if end_date - start_date > timedelta(days=31):
raise HTTPException(status_code=400, detail="date range exceeds 31 days")
sql = """
SELECT customer_id,
COUNT(*) AS order_count,
ROUND(SUM(amount), 2) AS total_amount
FROM orders
WHERE ordered_on BETWEEN ? AND ?
AND amount >= ?
GROUP BY customer_id
ORDER BY total_amount DESC
LIMIT 100
"""
with connect() as conn:
rows = conn.execute(
sql, (start_date.isoformat(), end_date.isoformat(), min_amount)
).fetchall()
return {"items": [dict(row) for row in rows]}
启动服务并发起请求:
export DATA_API_KEY='local-secret'
uvicorn app:app --reload
curl --fail --silent --show-error \
-H 'X-API-Key: local-secret' \
'http://127.0.0.1:8000/v1/customer-order-summary?start_date=2025-01-01&end_date=2025-01-31&min_amount=1000'
这个示例刻意不接受 SQL 字符串。调用方只能填写经过验证的业务参数,数据库查询则由服务端固定管理。生产环境还应将静态 API Key 替换为短期令牌或工作负载身份,并补充网关限流、查询超时、审计日志、字段脱敏和行级权限。
评估平台时,要看生成之后发生什么
验证这类平台时,不宜只演示“输入一句话,立即获得接口”。更有价值的验收过程应覆盖完整生命周期:
- 生成是否可检查:开发者能否查看查询逻辑、参数定义和依赖的数据表。
- 发布是否有门禁:测试、审批和生产环境是否隔离,变更能否比较与回滚。
- 权限是否足够细:能否按接口、调用方、字段或数据范围授权。
- 成本是否可控制:是否支持限流、超时、缓存、分页和查询复杂度限制。
- 调用是否可追踪:能否回答谁在什么时间访问了哪些数据,以及请求是否由 AI 发起。
- 契约是否稳定:数据库表结构调整时,平台能否识别受影响的 API 和 Agent 工具。
还要特别检查自然语言的歧义。例如“高价值客户”可能指累计消费、单笔金额或客户等级。平台可以生成候选定义,但业务口径仍需要负责人确认。生成速度不能代替语义审核。
采用建议:先从只读、低敏、边界清晰的服务开始
对话式数据服务适合从报表查询、运营指标和内部知识助手等只读场景切入。选择一组已有明确 SQL 和数据负责人的需求,对比传统开发方式与平台方式在交付时间、权限配置、故障率和维护成本上的差异。
不要在第一阶段开放任意 SQL,也不要立即让 Agent 执行写操作。只有当身份认证、最小权限、审计、资源配额、变更审批和紧急停用机制都通过验证后,再逐步扩大数据范围。
“一句话生成接口”提供了新的开发入口,但决定平台能否进入生产环境的,仍然是那句话之后的工程能力:生成结果是否透明,访问边界是否可靠,运行状态是否可观察,变更是否可控制。把这些条件同时满足,数据库才真正变成了可被应用和 AI 安全消费的数据服务。