【企业级AI Agent x 数据系统】【02】Function Calling 替代 Text-to-SQL:受控数据接口的工程范式
Function Calling 替代 Text-to-SQL:受控数据接口的工程范式
From Text-to-SQL to Function Calling: An Engineering Paradigm for Controlled Data Interfaces
—— 数据基础设施技术札记 · 2026
摘要OpenAI 在 2023 年公开 Function Calling 后,工业界对「LLM 与外部系统的接口范式」逐步达成新共识:从无类型自由文本(如 SQL 字符串)转向强类型结构化对象(如 JSON Schema)。本文系统阐述这一范式转变在数据消费场景下的工程意义。我们形式化对比 Text-to-SQL 与 Function Calling 的接口契约、给出 OpenAI / Anthropic / 开源 Function Calling 协议的细节差异、详解 JSON Schema 设计的关键原则(enum/range/required)、分析大规模工具集下 Tool Selection 的三类策略(全量加载 / Embedding 检索 / LLM 路由器),并提出 5 层安全模型(RBAC / Schema Validation / Cost Guard / Rate Limit / Output Sanitization)。实验在四维指标(语义匹配准确率 / 权限合规率 / 幻觉率 / 可解释性)上对比两种范式,结果显示 Function Calling 在权限合规、幻觉率、可解释性三个维度上具有结构性优势。本文不预设任何具体产品实现。
关键词:Function Calling · Tool Use · JSON Schema · 大语言模型 · Text-to-SQL · MCP · RBAC
1. 引言:接口范式的迁移
LLM 在企业数据系统中的应用,本质上是一个「接口范式」选择问题:LLM 与数据系统之间用什么形式交换信息?这个问题决定了一切后续工程——可观察性、可解释性、可控性、安全性、性能。
2022 年到 2023 年的主流答案是 Text-to-SQL:LLM 把自然语言翻译成 SQL 字符串,交给数据仓库执行。这一范式的工程致命缺陷我们已在前文系统论述(详见前文 LLM Compiler 工程化论述),不再重复。本文聚焦另一个问题:替代方案是什么?
OpenAI 在 2023 年 6 月公开发布 Function Calling [1] 给出了一个明确答案:LLM 不输出自由文本,而是输出符合预定义 JSON Schema 的结构化对象(包含 function name 与 arguments)。这一范式被 Anthropic Claude(Tool Use)、Google Gemini(Function Calling)、各大开源模型迅速跟进,至 2024 年已成为 LLM 与外部系统集成的事实标准。
本文不讨论 Function Calling 在通用 Agent 场景(如订机票、查天气)下的应用,而专注于其在数据消费场景下的工程意义——为什么它能解决 Text-to-SQL 解决不了的问题,以及在工程实现中的关键设计取舍。
2. 接口契约的形式化对比
Figure 1. Text-to-SQL 与 Function Calling 接口对比
2.1 类型系统的差异
如 Figure 1 所示,两种接口的类型签名截然不同。Text-to-SQL 的接口对是 (Question, SQL_String)——两端都是 string 类型,中间没有任何结构化约束。Function Calling 的接口对是 (Question, ToolCall),其中 ToolCall 是一个强类型对象 {name: str, args: JSON},且 args 必须符合预声明的 JSON Schema。
这一差异看似细微,工程含义深远。SQL 字符串作为接口意味着「LLM 的输出空间是无限的」——它可以生成任何字符序列,包括不存在的表名、错误的字段名、违法的语法、危险的 DDL。Function Calling 的 JSON Schema 把输出空间收敛到一个「有限的、声明式的、可验证的子集」——LLM 只能调用预声明的函数、传入预声明的参数、参数值必须在 enum / range 约束内。
2.2 失败模式的差异
Text-to-SQL 的失败模式是「语义错误」——LLM 输出了一个语法合法但语义错误的 SQL(猜了一个不存在的字段、用了错误的 JOIN 逻辑、漏了 WHERE 谓词),数据仓库正常执行后返回错误结果。这类错误不会触发任何 exception,只能通过下游数据校验发现,常常造成「假数据驱动错误决策」。
Function Calling 的失败模式是「Schema 验证失败」——LLM 输出的 JSON 对象不符合 schema(缺必填字段、传了 enum 外的值、超过 range 限制),在 JSON Schema 验证器一层就被拦截,整个调用根本到不了数据系统。这是「快速失败」(fail-fast)的工程哲学——错误在最早可能的环节被发现,而不是污染下游。
▎工程见解工程上一个常被低估的细节:Text-to-SQL 的失败是「静默的」(silent failure),Function Calling 的失败是「响亮的」(loud failure)。前者让 bug 潜伏数月才被发现,后者在 5 ms 内立即报错。两种失败模式的运维成本相差一个数量级——这是范式转变的最大隐性收益。
3. Function Calling 协议
Figure 2. Function Calling 协议的请求/响应流程
3.1 OpenAI 标准的 6 步流程
如 Figure 2 所示,Function Calling 协议的完整 6 步流程:(1)User 发送 NL Question + Tool Schemas;(2)LLM 决定调用某个 tool,返回 tool_call (name, args);(3)Backend 编译 tool_call 为具体 SQL(含权限注入),下发 Data Warehouse;(4)DW 返回 result set;(5)Backend 把 result 包装为 tool_result JSON 返回 LLM;(6)LLM 把 tool_result 转化为自然语言回答给用户。
3.2 OpenAI vs Anthropic vs 开源模型的协议差异
OpenAI 协议使用 function_call 字段(已逐步演化为 tool_calls 数组以支持并行调用)。Anthropic Claude 使用 tool_use 类型的 content block。Google Gemini 使用 functionCall 字段。开源模型如 Qwen-2.5 / GLM-4 / DeepSeek 跟随 OpenAI 协议,但对 JSON Schema 复杂度的支持度参差不齐——简单 schema(单层属性)所有模型都能稳定输出,深嵌套(5+ 层)+ 联合类型(anyOf / oneOf)则只有顶级模型能稳定遵守。
Anthropic 在 2024 年发布的 MCP(Model Context Protocol)[2] 进一步把 Function Calling 标准化为一个跨模型的协议层——任何符合 MCP 的工具服务器可以被任何符合 MCP 的 LLM 客户端调用。这是行业向「LLM 调用工具」接口标准化的关键一步。
4. JSON Schema 设计
Figure 3. 结构化工具定义的 JSON Schema
Figure 3 给出了一个典型工具定义——query_metric。这个 schema 的关键设计要素:
- enum 限定取值集合:metric 只能是 4 个预定义值之一,dimensions 项也只能是 4 个预定义维度。这把 LLM 的输出空间从无限收敛到有限。
- minimum / maximum 限定数值范围:time_range.n 限定在 1-365 之间,避免 LLM 传入负数或超大值导致数据仓库扫描失控。
- required 强制必填:metric 是必填项,缺失则 schema 验证失败。这避免 LLM 模糊指令(如「最近的销售额」无 metric)漏到后端。
- maxItems 限定数组长度:dimensions 最多 3 个,避免 LLM 一次性 group by 10 个维度产生爆炸性结果集。
- 嵌套对象 + required:filters 是对象数组,每个对象自身有 required 约束,确保 op 与 value 同时给出。
Schema 设计的本质是「把企业的所有领域约束前置到 LLM 调用层」——什么字段可查、什么维度可分组、什么过滤器合法、什么时间范围允许,全部用 JSON Schema 声明。LLM 在生成 tool_call 时必须遵守这些约束(现代 LLM 通过 grammar-constrained decoding 强制输出符合 schema 的 JSON)。
▎工程见解JSON Schema 的设计是「治理逻辑的形式化」。一个好的 schema 让 LLM 在 token 级别就不可能越界——这比「LLM 输出后再做检查」效率高一个数量级。把治理约束前置到 schema 层,是 Function Calling 范式相比 Text-to-SQL 的根本性工程优势。
5. 大规模工具集下的 Tool Selection
Figure 4. 大规模工具集下的 Tool Selection 策略
当企业的 Tool 集合规模从 5 增长到 5000 时,「把所有 Tool 的 schema 塞进 prompt」的简单做法立刻失效——context window 不够、prompt 成本爆炸、LLM 在巨大工具集中迷失。Tool Selection 成为新的工程问题。
5.1 三类策略
Figure 4 给出三类常见策略:
- Strategy 1 · 全量加载:把所有 N 个工具的 schema 塞进 prompt。适用 N < 30,超过则 prompt 爆炸。简单但不可扩展。
- Strategy 2 · Embedding 检索:用 Question 与 Tool description 做 embedding 相似度匹配,取 Top-K 工具。适用 N < 10000,精度依赖 embedding 模型质量与 tool description 写得好坏。
- Strategy 3 · LLM 路由器:用一个轻量级 LLM 先做工具分类,再把选中的少数工具发给主 LLM。适用 N > 10000,两段调用增加延时但精度可达 95%+。
5.2 工程选型决策
Embedding 检索的关键工程细节:(i)embedding 模型选择——通用 text-embedding 模型(OpenAI text-embedding-3-large、bge-large-zh)在 tool description 检索上表现已经足够,无需 fine-tune;(ii)Top-K 取值——K 太小漏 tool,K 太大 prompt 仍然爆炸;工程上常用「K=Top-5 + 用户问题置信度调节」;(iii)reranker——在 embedding 召回后用 cross-encoder 做二次排序,召回率提升 5-10%。
LLM 路由器的工程细节:(i)路由器 LLM 用小模型(如 GPT-4o-mini / Claude Haiku)即可,无需大模型;(ii)路由器的输出 schema 同样用 enum 严格约束在已注册工具名集合内,避免幻觉工具名;(iii)路由器与主 LLM 之间的延时可通过 prompt caching 与流式调用进一步压缩。
6. 安全模型
Figure 5. Function Calling 的 5 层安全模型
Function Calling 的安全模型分 5 层(Figure 5),从下而上依次执行:
- L1 · Tool Whitelist (RBAC):用户角色 → 可见工具集合。一个无权限调用 query_employee_salary 的用户,从一开始就看不到这个工具,LLM 也无法生成调用它的 tool_call。
- L2 · Schema Validation:JSON Schema 强类型校验。任何不符合 schema 的 tool_call 在这一层被拒绝。
- L3 · Cost Guard:在执行 tool 前估算 SQL 成本,超阈值拒绝(避免 LLM 触发巨大查询)。
- L4 · Rate Limit + Quota:每用户的 QPS 与每天 token 配额。防止 LLM 在循环或异常情况下消耗资源。
- L5 · Output Sanitization:tool 返回结果中 PII 字段脱敏、行数截断、敏感字段隐藏。
五层从下而上独立执行,任一层拒绝则立即返回 error。这种「纵深防御」(defense in depth)模式与传统 Web 应用的安全分层一致。Function Calling 相对 Text-to-SQL 的优势是:每一层的边界都是明确的——RBAC 在 schema 加载时执行、Validation 在 LLM 输出时执行、Cost Guard 在 tool 调用时执行——每层的失败都可以独立定位与审计。
7. 实验评估
Figure 6. 实验:准确率四维对比 + 大规模工具集延时
7.1 四维准确率对比
Figure 6(a) 给出 Text-to-SQL(GPT-4o)vs Function Calling 在四维度上的对比:(i)语义匹配准确率:FC + RAG 比 Text-to-SQL 高 16 个百分点;(ii)权限合规率:Text-to-SQL 在「越权查询」测试集上完全无法处理(0%),FC 通过 RBAC 100% 合规;(iii)幻觉率:FC 在 schema 约束下幻觉率为 0%,Text-to-SQL 仍有 38% 幻觉表名/字段;(iv)可解释性:FC 的 tool_call 是结构化对象,可以直接审计;Text-to-SQL 的 SQL 字符串审计成本极高。
7.2 大规模工具集延时
Figure 6(b) 给出三种 Tool Selection 策略在 N = 5 到 N = 1000 工具规模下的端到端延时。Full Loading 在 N > 50 时延时迅速恶化(context 爆炸 + LLM 失焦),在 N = 1000 时已无法使用。Embedding Selection 在所有规模下延时稳定在 400 ms 以内。LLM Router 因为多了一段调用,基础延时比 Embedding 高 100 ms,但在 N > 1000 时仍能保持稳定。
8. 讨论与局限
8.1 不适合 Function Calling 的场景
Function Calling 的核心假设是「企业数据访问模式有限且可枚举」——这一假设在结构化数据消费(如指标查询、明细查询)下成立,但在「探索性数据分析」(如数据科学家用 Jupyter 自由写 SQL)下不成立。后者本质需要的是「完整 SQL 表达力」,无法被几十个预定义 tool 覆盖。两种场景应分开设计——结构化消费走 Function Calling,探索性分析走受控的 Notebook + Sandbox。
8.2 工具粒度的取舍
Function Calling 的工具粒度(granularity)是一个工程取舍:粗粒度(如 query_anything(sql))退化为 Text-to-SQL;细粒度(如每个指标一个 tool: query_gmv, query_orders, query_users 各一个)则工具数量爆炸 + 维护噩梦。工程上常用「中粒度 + 参数化」:query_metric(metric_name, ...) 是一个 tool,但 metric_name 是 enum 约束在已注册指标集。这把工具数从 N 个降为 1 个 + N 个 enum 值,可维护性显著提升。
8.3 与 LangChain / LlamaIndex 等框架的关系
LangChain 与 LlamaIndex 等 Agent 框架本质上是 Function Calling 的应用层封装——它们提供 Tool 注册、Selection、Execution、Memory 管理等通用能力。在工程实践中,是否使用这些框架是一个 build vs buy 的取舍:框架降低初期开发成本,但增加运行时复杂度与维护负担。对成熟数据团队,「直接基于 OpenAI/Anthropic SDK 实现自定义 Agent」往往是更可控的选择。
9. 结论
Function Calling 替代 Text-to-SQL 不是「让 LLM 多了一个选择」,而是「企业数据消费接口范式」的根本转变。本文核心论点:
- 类型系统从无类型 SQL 字符串收敛到强类型 JSON Schema,是失败模式从「静默错误」到「响亮失败」的根本性升级;
- JSON Schema 是治理逻辑的形式化载体,把 enum / range / required 等约束前置到 LLM 调用层;
- 大规模工具集(N > 30)需要 Tool Selection,Embedding 检索是性价比最高的选择;
- 5 层安全模型(RBAC / Schema / Cost Guard / Rate Limit / Sanitization)是纵深防御的工程标配;
- 在结构化数据消费场景下,Function Calling 的权限合规率、幻觉率、可解释性均显著优于 Text-to-SQL。
▎工程见解更深的工程哲学:Function Calling 的兴起反映了一个工程规律——「LLM 越强,越应该用受控接口」。强大的 LLM 在自由文本下幻觉更隐蔽(因为语法都合法)、决策更难审计;只有把它约束在结构化输出空间,才能把它的「概率性能力」转化为「确定性的工程组件」。这与软件工程史上「编译型语言 vs 解释型语言」「静态类型 vs 动态类型」的演化规律一致——越是大规模生产系统,越向「类型化、可验证、可推理」靠拢。
10. 关于我们
贵州数幄科技有限公司是一家专注于人工智能与数据智能领域的科技公司。
公司致力于通过前沿的大模型技术、数据治理能力和智能决策解决方案,帮助企业实现从数据治理、分析预测到智能决策与自动化执行的全链路数字化转型,助力企业降本增效,构建数据资源资产化的坚实底座。
我们的主要产品: DataForge · MetaPulse · SemWave · CodeVox 四大产品矩阵, 自下而上完成「数据可见 → 可信 → 可懂 → 可用」全链路闭环.
参考文献
[1]OpenAI. Function Calling and Other API Updates. https://openai.com/blog/function-calling-and-other-api-updates, 2023.
[2]Anthropic. Model Context Protocol (MCP). https://modelcontextprotocol.io/, 2024.
[3]Schick T, Dwivedi-Yu J, Dessì R, et al. Toolformer: Language Models Can Teach Themselves to Use Tools. NeurIPS 2023.
[4]Yao S, Zhao J, Yu D, et al. ReAct: Synergizing Reasoning and Acting in Language Models. ICLR 2023.
[5]Qin Y, Liang S, Ye Y, et al. ToolLLM: Facilitating Large Language Models to Master 16000+ Real-world APIs. ICLR 2024.
[6]Patil S G, Zhang T, Wang X, et al. Gorilla: Large Language Model Connected with Massive APIs. arXiv 2023.
[7]Geng S, Josifoski M, Peyrard M, et al. Grammar-Constrained Decoding for Structured NLP Tasks without Finetuning. EMNLP 2023.
[8]Lattner C. The Tool Use Future of LLMs. Modular Blog, 2024.
[9]Hong S, Lin Y, Liu B, et al. Data Interpreter: An LLM Agent For Data Science. arXiv 2024.
[10]LangChain. https://www.langchain.com/
