# 面向智能体的数据库接口设计：来自真实客户端测试的经验

工程笔记 · Mdexa Engineering · 2026-11-13

数据版本：catalogue of 43 cards; interface tests of 2026-11-12/13

https://mdexa.com/zh/research/N1-agent-database-interface/

**Mdexa Engineering** · 工程笔记，未经同行评审 · 2026-11-13 · 数据版本：43 张卡片的目录；2026-11-12/13 的接口测试

## 摘要

一个数据集数据库的接口，先用官方客户端库做了协议一致性检查，再由真实的智能体（Agent）客户端回答了九道题。这些题暴露出两类代价：智能体分不清"库里确实没有"与"搜索失败"，换了七次关键词才作答；想报告风险的智能体只能逐个数据集取证据。加入明确的"没有匹配"响应后，前一种情形的调用从 8 次降到 1 次；在紧凑结果行里加入风险标记后，后一种情形从 15 次降到 12 次，代价是每行多 48 个字符（约 11%）。随后的 30 题基准的首次运行（单次运行，首发 43 张卡）显示同样的现象以较轻的形式仍然存在：95 次搜索中有 13 次（13.7%）没有结果，有一个工具在匿名调用时每次都被拒绝。证据来自单个低成本模型的单次运行。文中提出若干补救办法，尚未验证。

**关键词：**智能体工具；模型上下文协议（MCP）；接口设计；空结果；工具描述；评测

## 1. 问题

Mdexa 是一个生物医学数据集信息卡数据库，智能体通过 MCP 服务或 HTTP API 查询。第一版提供六个工具：搜索、取信息卡、取许可证据、列分面、取获取方式，以及一个当时尚未开放的内容检索。它通过了我们自己的测试（当时我们自己的测试集中有 40 项检查）。通过自己的测试并不能说明模型实际会怎么用它，所以我们用真实客户端做了一次测试。

## 2. 测了什么

**协议一致性。**官方 TypeScript SDK 客户端（1.32.2 版）通过 stdio 与 Streamable HTTP 两种传输连上服务端，协商出协议版本 2025-11-25，列出六个工具并逐个调用。每种传输的 13 次工具返回结构都合规，没有警告。较新的协议版本（2026-07-28）服务端已实现，但没有官方客户端能验证，只有我们自己的测试覆盖 [1]。

**真实的智能体。**我们用一个真实的命令行智能体客户端对接该服务端，模型是经第三方通道访问的一个低成本模型，给它九道题（计数、许可列表、商用判断、仓库许可与数据许可、来源风险、获取方式、一个不存在的数据集，以及一道开放题）。43 次工具调用中，没有出现把只做链接的数据集说成可下载、或把受限的说成可商用的情形。强模型的对比没有做成：对应通道返回了错误。

## 3. 哪里出了问题，我们改了什么

**不存在的数据集。**被问到一个库里没有的数据集，模型用七组不同关键词搜索（共 8 次调用）才下结论。响应里没有任何东西告诉它"没有匹配"就是完整的答案。我们的修改是返回结构化的无匹配响应：一句"数据库中没有匹配的数据集"，目录总数，每个筛选条件单独放宽后各会多出多少条，以及"不要换词重试"的说明。同一道题随后只需 1 次调用。

**逐个数据集取证据。**在开放题里，模型为了解释风险，用约十次调用、逐个候选取了许可证据，因为紧凑结果行有许可状态而没有风险标记。我们在每个紧凑行里加了 `risk_flags` 和 `repo_only`（有仓库许可证，但没有任何说明它适用于数据）。当时 43 张卡中 4 张的 `repo_only` 为真。这道题的调用从 15 次降到 12 次；模型仍然为每个推荐项取证据，因为题目要求给出依据。每个紧凑行平均增加 48 个字符（约 11%）。

**把红线写进工具描述。**服务端级别的说明并不总会被读到，所以搜索工具的描述现在写明状态字段的含义，以及受限、冲突、未声明、无法核实绝不等于"可商用"。获取方式工具的描述写明 Mdexa 不提供任何数据集文件，智能体不应凭记忆写下载命令（第一次测试里就有模型凭自身知识给出下载命令）。描述里还写明查询词须全部命中，统计数量应使用分面列表而不是翻页。

**告诉你合法取值的筛选。**加入标签筛选时，未知取值会返回列出该分面合法取值的错误，保留分面会返回说明原因的错误，而不是一个空列表让智能体误读为"没有这样的数据集"。紧凑行为携带四个标签键，平均又增加了 50 个字符（472 到 522）。

**第三方文字。**引用的摘录来自 Mdexa 不控制的页面。携带它们的字段被命名为不可信的第三方文字，响应里写明应当把它们当作数据而不是指令，智能体说明里也重复了这一点。

## 4. 基准补充了什么

后来的基准的首次运行（单次运行，首发 43 张卡，2026-11-13；修订版报告在计划中）详细记录了接入工具条件下 30 道题的调用。30 题里智能体共做了 191 次 Mdexa 工具调用（每题 6.4 次）：搜索 95 次、读取信息卡 34 次、读取证据 25 次、列分面 20 次、取获取方式 9 次、找相似数据集 4 次、批量核对 4 次。95 次搜索中有 13 次（13.7%）零结果：5 次是要求所有词同时命中的多词查询，其余大多是在查库里确实没有的东西（有的题目就是这样要求的）。批量核对工具的 4 次调用全部被拒，因为匿名设置下它需要 API 密钥，模型因此白费一两次调用，之后退回逐项搜索。调用最多的五道题（11 到 14 次）里，第一次搜索通常已经返回了正确名单，后面的调用只是检查有没有漏。当前源码已在搜索结果里加入了明确的"名单已穷尽"说明；我们还没有重跑基准来测量它的效果。（以上是首次运行的记录，不是结论。此前一份内部分析给出的调用分项加起来与每题均值对不上；这里的数字已从原始记录和服务端日志重算。）

## 5. 我们由此得到的原则

1. 把空结果作为一等的、终局性的回答，并附足够的上下文（目录总数、各筛选条件排除了多少）让智能体相信它。
2. 默认少返回；在每个紧凑行里放智能体决定是否追问所需的字段（这里是风险标记和"仅有仓库许可证"标记）。
3. 把要紧的规则写进工具描述，而不只写在服务端说明里。
4. 让错误起到教学作用：列出合法取值。
5. 标注不可信的文字，并说明怎样对待。
6. 不提供对调用者根本用不了的工具（匿名客户端看得见却需要密钥的工具）。

## 6. 尚未解决的

- 得到完整答案后，模型仍会重复搜索；"名单已穷尽"的说明可能减少但未必消除，其效果尚未测量。
- 要求所有词同时命中的多词查询仍会产生空结果；基准分析建议改为按命中词数排序。
- 匿名可见的批量核对工具，仍只是建议的修法，未经验证。
- 紧凑行还没有说明某个数据集为什么命中；模型为了弄清楚会取整张卡（每张约 3.5 千字符）。
- 所有发现都来自单个低成本模型的单次运行；强模型、其他客户端和较新的协议版本都没有测。

## 参考文献

1. Model Context Protocol specification. https://modelcontextprotocol.io/specification

*工程笔记，未经同行评审。Mdexa Engineering，2026-11-13。依据内部测试记录，未公开。*
