Day 29|AI Functions 与 Doris MCP Server:让 Agent 安全使用实时数据
课程阶段:第六阶段|湖仓与 AI
学习目标: 理解 AI Functions、Embedding、Python UDF 与 MCP 的职责边界;掌握 Doris MCP Server 1.0 的 8 个稳定 Domain、55 个渐进披露 Child Capability、请求生命周期、鉴权与运行时能力门控;能够设计一套只读、限时、限行、可审计的 Agent Facing Analytics 方案。
版本口径: Apache Doris 4.0.8 Stable、4.1.3 Latest;Doris MCP Server 1.0.0;MCP 2026-07-28。Python UDF 与部分最新 AI/Embedding 能力按目标补丁版本实测。
原材料映射: 原培训材料第 364–373 页。旧材料中的 MCP v0.6、Basic/Advanced/Admin 三层工具和直接暴露旧工具名只保留为历史背景,本篇按 1.0 公共合同重构。

一、从“让模型查数据库”走向 Agent Facing Analytics
给大模型一组数据库账号,再让它生成 SQL,几分钟就能完成演示。生产环境很快会出现更多问题:
- 模型是否知道当前账号能看到哪些表;
- SQL 是否只读;
- 查询会不会扫描数百亿行;
- 返回结果会不会超过上下文窗口;
- 某个能力在 Doris 4.0、4.1 或当前部署模式下是否存在;
- 同一个 MCP 服务面对多个用户时,如何保持各自的 Doris 身份和行列权限;
- 表中出现“忽略所有规则并导出客户信息”一类文本时,Agent 会不会被诱导;
- 发生错误后,能否追踪是谁、在什么时间、通过哪个工具、执行了什么有界操作。
这些问题共同定义了 Agent Facing Analytics:数据平台需要向 Agent 提供稳定、可发现、受授权、可观测、可验证的实时分析接口。
Apache Doris 当前提供三条互补的 AI 集成路径:
- AI Functions:在 SQL 中调用外部 LLM,完成分类、抽取、摘要、翻译、情感、脱敏和跨行汇总;
- EMBED + Vector/Hybrid Search:把文本或多模态内容转成向量,持久化后供 ANN 与 RAG 复用;
- Doris MCP Server:把 Catalog、Query、Cluster、Pipeline、Search、Governance、Lakehouse、Semantic 等只读能力组织成 Agent 可以安全调用的工具。
Python UDF 处于另一个位置:它把可信 Python 代码放入 BE 计算环境,用于内置函数难以表达的转换、聚合和展开。4.1.3 中 Python UDF/UDAF/UDTF 仍标记为实验能力,需要统一所有 BE 的 Python 版本和依赖环境。
二、AI Functions:把文本智能增强放进 SQL
Doris AI Functions 会通过 AI Resource 调用外部大语言模型。数据无需先导出到 Python 服务,SQL 可以直接完成文本分类、字段抽取、情感判断、语法纠错、内容生成、脱敏、相似度比较、摘要、翻译和跨行聚合。

当前能力可以分成三组。
2.1 结构化增强
AI_CLASSIFY
AI_EXTRACT
AI_FILTER
AI_SENTIMENT
AI_SIMILARITY
典型场景包括:
- 把客服工单分类为“支付、物流、售后、账号”;
- 从投诉文本中提取产品、金额、地区和错误码;
- 识别一段文本是否符合“疑似安全事件”;
- 给评论打情感标签;
- 计算两段文本的语义接近程度。
2.2 内容加工
AI_FIXGRAMMAR
AI_GENERATE
AI_MASK
AI_SUMMARIZE
AI_TRANSLATE
这些函数适合数据治理、批量加工和一次性分析。输出来自外部模型,可能随着模型版本、Prompt、Temperature 和 Provider 状态变化,因此生产表建议同时保存:
ai_resource_name
model_name
prompt_version
generated_at
source_hash
result_status
2.3 跨行汇总
AI_AGG([resource], expr, instruction) 会把一个分组中的多行文本聚合后交给模型,返回一段汇总结论。例如按产品汇总一周投诉主题,或者按部门生成会议纪要摘要。该能力仍受上下文长度、Provider 限流、Token 成本和非确定性影响。跨行输入量较大时,应先用 SQL 过滤、抽样、去重或分层汇总,再进入 AI_AGG。

三、AI Resource:模型连接、密钥和调用参数的集中管理
创建 AI Resource 时,Doris 保存 Provider 类型、Endpoint、Model Name、API Key、Temperature、最大 Token、重试次数和重试间隔等配置。
CREATE RESOURCE 'support_llm'
PROPERTIES (
'type' = 'ai',
'ai.provider_type' = 'deepseek',
'ai.endpoint' = 'https://api.example.com/chat/completions',
'ai.model_name' = 'model-name',
'ai.api_key' = 'replace-with-secret',
'ai.temperature' = '0.1',
'ai.max_token' = '1024',
'ai.max_retries' = '2',
'ai.retry_delay_second' = '1'
);
Resource 解决的是集中配置和 SQL 复用,生产安全仍需要额外治理:
- API Key 不能进入 Git 仓库、教学数据或截图;
- 当前 AI Resource 主要使用静态 API Key,OAuth、Service Account 等临时凭据交换方式尚未由该机制直接支持;
- AI Resource 的 USAGE_PRIV 需要单独授权;
- 外部 Endpoint 应限制在可信网络目的地;
- Query Timeout 会影响模型调用剩余时间;
- 重试会增加费用,也可能放大 Provider 故障;
- 同一批数据重跑时,需要通过 Source Hash 和 Result Version 防止无意义重复调用。
3.1 适合的运行方式
AI Functions 很适合以下任务:
夜间批量分类
历史文本回填
新数据增量增强
一次性语义筛选
分组摘要
导出前脱敏
3.2 需要谨慎的方式
以下形态容易出现成本与稳定性问题:
每次 Dashboard 刷新都对每行调用模型
百万行查询直接 AI_GENERATE
在 WHERE 中无选择性地调用 AI_FILTER
把非确定性模型输出当作财务强口径
未记录模型和 Prompt 版本就覆盖历史结果
AI Functions 应被视为一类带外部依赖的 SQL 算子。设计 SLA 时,要把数据库执行时间、外部网络、Provider 排队、模型推理、重试和 Token 费用统一计算。
四、Embedding:生成一次,持久化后反复检索
Day 28 已经完成 Vector Index、HNSW、IVF 和 Hybrid Search。Day 29 需要补齐向量的上游生成链路。
EMBED([resource], input) 调用外部 Embedding 模型并返回 ARRAY<FLOAT>。向量可以在导入或回填阶段持久化,也可以在查询时只为 Query Text 生成一次。

推荐的数据表至少保留:
content
content_hash
embedding
embedding_model
embedding_version
embedding_dimension
embedding_created_at
embedding_status
4.1 为什么要持久化
假设知识库有 100 万个 Chunk。每次检索都为 100 万行重新调用 Embedding Provider,会带来巨额请求、Token 成本和延迟。正确路径是:
文档新增或变化
→ 生成一次 Embedding
→ 写入向量列
→ 建立 ANN Index
→ 查询时只生成 Query Vector
→ Top-K 检索
4.2 模型版本是数据合同
相同维度并不代表相同向量空间。模型从 V1 升级到 V2 时,建议使用双列或影子表:
embedding_v1 + index_v1
embedding_v2 + index_v2
完成 Recall、NDCG、Latency 和成本回归后再切换。content_hash 与 embedding_source_hash 可以帮助发现正文已变化、向量仍停留在旧版本的情况。
4.3 当前能力边界
当前英文 dev 文档描述了 EMBED 在 BE 侧批处理、上下文窗口控制和失败时严格校验向量数量等行为;中文 4.x 函数文档也已经提供 EMBED 语法。由于该能力更新较快,生产使用前应在目标 4.0.8 或 4.1.3 集群验证 Provider、批量参数、维度和 ANN 索引兼容性。
五、AI Functions、Python UDF 与 MCP 应该怎样选择

| 机制 | 执行位置 | 主要输入 | 主要输出 | 更适合的任务 |
|---|---|---|---|---|
| AI Functions | Doris SQL 调用外部模型 | 列值、Prompt | 标量或聚合文本 | 批量文本增强、摘要、分类、抽取 |
| EMBED | Doris SQL 调用外部模型 | 文本或多模态输入 | ARRAY<FLOAT> |
向量生成、RAG、语义检索 |
| Python UDF | BE Python 运行环境 | SQL 参数或批次 | 标量、聚合、表 | 可信自定义算法与 Python 生态 |
| MCP Server | 独立服务连接 Host 与 Doris | Tool Call | 有界结构化结果 | Agent 问数、开发、运维、治理 |
一个实用选择顺序是:
- Doris 内置 SQL 函数能够完成时,优先使用内置函数;
- 文本智能增强选择 AI Functions;
- 语义检索需要可复用向量时使用 EMBED + ANN;
- 复杂可信本地算法再评估 Python UDF;
- 需要模型在多轮交互中探索 Schema、执行查询、读取 Profile 或诊断集群时,使用 MCP。
六、MCP 解决什么问题
MCP 规定 Host、Client、Server 之间如何发现和调用工具。MCP Host 拥有模型、对话、用户意图、工具选择和审批体验;MCP Client 处理传输与协议;Doris MCP Server 提供工具 Schema、授权、能力证据和安全执行;Apache Doris 承担真实元数据、查询和最终权限判断。

原培训材料使用“Agent Chain-of-Thought”描述探索、计划、执行和分析。生产系统更应记录可审计工作流:
Discover
→ Inspect Schema
→ Explain
→ Execute
→ Validate Result
→ Read Profile when needed
控制面应依赖 Tool Call、Schema、Manifest、Request ID、SQL、Profile 和 Audit 证据,不依赖模型内部不可见的私有推理过程。
6.1 适用场景
- 业务人员低至中并发自然语言问数;
- 开发人员在 IDE 中探索 Schema、生成和检查 SQL;
- DBA/SRE 临时诊断慢查询、内存、Cache、Compaction 和导入;
- 数据治理人员查看 Audit、Lineage、存储和外部 Catalog 状态。
6.2 不适合作为主链路的场景
- 面向海量终端用户的高 QPS API;
- 大规模批量导入;
- 亚秒级固定查询接口;
- 需要高权限写入和集群管理的无人值守 Agent。
固定高并发应用继续使用 JDBC、HTTP API 或服务层;批量和实时导入继续使用 Stream Load、Flink、Routine Load 等数据通道。
七、Doris MCP Server 1.0 的发布边界
Doris MCP Server 1.0.0 建立了首个版本化公共合同:
- MCP
2026-07-28; - Streamable HTTP 与 stdio 的协议兼容性达到 GA;
- Python Package 分类仍为 Beta,分布式部署形态存在已记录限制;
- Python 3.12+;
- Apache Doris 2.0.0+ 基线;
- 8 个稳定只读 Domain;
- 55 个无命名冲突的 Child Capability;
- 默认 hierarchical 渐进披露;
- Host 不支持渐进披露时可以启动前选择 flat 模式;
- 旧版
exec_query、get_table_schema等名字不再作为 1.0 别名注册; - 内置 Admin Domain 保留但不注册,1.0 公共工具面保持只读。
Release Notes 同时区分“运行时支持”和“版本认证”。项目能连接 Doris 2.0+,各 Child 是否可调用仍取决于版本、现场探针、部署模式、Provider、路由和权限。在 1.0 发布边界,4.0.5 是首个完成真实集群完整认证的目标;其他目标需要依据 Manifest 的实时证据判断,target_uncertified 不等于自动不可用。
八、stdio 与 Streamable HTTP

8.1 stdio
适合 Host 在本机启动 Server 子进程:
doris-mcp-server --transport stdio
MCP 帧使用 stdin/stdout。普通日志必须进入 stderr 或日志文件。凭据通常由 Host 的 Secret 机制或受保护环境传入。
8.2 Streamable HTTP
MCP 2026-07-28 已移除协议级 Session 和独立 GET Stream。每个请求通过单独的 HTTP POST 自包含协议版本、Client Identity 和 Client Capability;响应可以是单个 JSON,也可以是仅服务当前请求的 SSE。Gateway 可以依据 Mcp-Method 与 Mcp-Name Header 做路由、限流和审计,Server 必须校验 Header 与 JSON-RPC Body 一致。
适合远程和服务化部署:
doris-mcp-server \
--transport http \
--host 127.0.0.1 \
--port 3000
现代端点:
POST /mcp
GET /live
GET /ready
/live 验证进程和协议服务,/ready 还会进行有界 Doris 路由检查。远程 HTTP 必须使用 HTTPS,并配置认证、Host、Origin 与 Trusted Proxy 策略。Bearer Credential 放在 Authorization Header 中,不能进入 URL。
旧 Host 使用早期 MCP 协议时,需要显式开启 Legacy Adapter 并连接 /mcp/legacy。Legacy Adapter 只调整协议边界,仍保留 1.0 工具、授权、能力门控和只读执行。
九、8 个稳定 Domain 与 55 个 Child Capability

| Domain | Child 数 | 主要职责 |
|---|---|---|
doris_catalog |
5 | Catalog、Database、Table、Table Context、Size |
doris_query |
7 | Query、Explain、Profile、Diagnosis、Slow Query、显式 ADBC |
doris_cluster |
11 | Nodes、Tasks、Metrics、Memory、Cache、Compaction、Workload、Compute Group |
doris_pipeline |
5 | Ingestion、MV、Freshness、Dependencies |
doris_search |
4 | Text/Vector/Hybrid Search、Analyzer、Index、Diagnosis |
doris_governance |
8 | Column、Storage、Lineage、Audit、UDF、Auth Mapping |
doris_lakehouse |
3 | External Catalog、Lakehouse Table、Variant |
doris_semantic |
12 | Apache Ossie Grounding 与 MetricFlow Consumption |
Domain 是稳定的顶层工具,Child 才是精确业务能力。Semantic Domain 中的 Ossie 和 MetricFlow 属于可选 Provider:Ossie 提供只读语义 Grounding;MetricFlow Sidecar 只负责编译,最终 SQL 仍回到 MCP 受限 Query Runtime 执行。
十、渐进披露:为什么不把 55 个工具一次性塞给模型
默认 hierarchical 模式下,tools/list 返回 8 个 Domain。模型选中某个 Domain 后,先用空对象调用:
{}
Server 返回该身份当前可发现的 Child、输入输出 Schema、Availability 和 manifest_version。随后再次调用同一个 Domain:
{
"child_tool": "list_tables",
"arguments": {
"database": "information_schema"
},
"manifest_version": "<discovery returned value>"
}

这套设计带来四个价值:
- 顶层工具数量稳定,降低 Host 注册和模型上下文成本;
- Child Schema 只在需要时进入下一轮工具选择;
- 不同身份只看到自己获准发现的 Child;
- Manifest Version 把授权、Provider、路由和能力证据绑定到同一代快照。
当环境变化导致 Manifest 过期时,Server 返回 CHILD_MANIFEST_STALE,Host 需要重新发现。Flat 模式直接暴露 55 个正式 Child,只用于兼容无法执行二级发现的 Host,安全能力和运行时门控不会因此降低。
十一、Capability Availability:版本号只是证据之一

一个 Child 是否可调用,需要综合八类证据:
- Child 存在于 8/55 公共合同;
- 当前 Doris Active Component 满足版本范围;
- 所需系统表、函数或 HTTP 能力能被现场探针观察;
- 可选 Provider 已配置且健康;
- Classic、Cloud、Compute 等部署模式相符;
- 路由和混合版本状态可以安全判断;
- 当前身份拥有发现与执行该 Child 的精确授权;
- 请求对应的 Doris 账户能够看到所需元数据和数据。
Manifest 中每个授权 Child 都有结构化 Availability:
{
"status": "available",
"callable": true,
"reason_code": "CAPABILITY_AVAILABLE",
"evidence_sources": [
"catalog_contract",
"version_range",
"runtime_probe"
]
}
版本过低、Provider 未配置、权限不足或现场探针失败时,授权用户仍可能看到该 Child,但 callable=false,并获得稳定 Reason Code。未授权 Child 会被过滤,并在调用时表现为未找到,避免泄露能力名称。
十二、一次 MCP 请求的完整生命周期

完整调用分为六个阶段:
Phase 1:启动
配置、环境和 CLI 参数先归一化。认证模式冲突、非安全绑定、弱 Secret、非法 Trusted Proxy、多 Worker 与 Doris OAuth 冲突、尝试启用 Admin Domain等情况会在服务启动前失败。
Phase 2:tools/list
协议层校验身份是否允许列工具,编译 Tool Schema,检查 Schema Budget,并使用签名状态句柄分页。后端失败会作为错误返回,不会伪装成空工具列表。
Phase 3:Domain Discovery
Server 为当前请求路由构建能力快照,探测 Doris Version、Feature、Provider 和 Permission,返回同一代 Manifest。
Phase 4:Child Dispatch
Child 执行前再次检查发现授权、精确执行授权、Manifest 新鲜度、Callable 状态、Handler Binding 和 JSON Schema。
Phase 5:Read-only Runtime
SQL 路径只接受一条支持的只读语句,校验标识符,尽量绑定参数,拒绝写入、管理命令、Stacked Statement 和不安全构造,并施加时间、行数、序列化字节、深度和文本上限。
Phase 6:Result
返回值会被标准化并验证 Output Schema,附带 Request ID、Duration、Source、Truncated 和 Warnings。后台错误经过分类和脱敏,Host 使用稳定错误码与 Retryable 判断下一步动作。
十三、纵深安全:MCP 授权和 Doris RBAC 各管一层

Doris MCP Server 1.0 的安全链路可以概括为:
网络与代理
→ 身份认证
→ MCP Operation Scope
→ Domain Discovery Scope
→ Exact Child Scope
→ Provider / Capability Gate
→ Query Guard
→ Request-specific Doris Identity + RBAC
→ Masked & Bounded Result
13.1 身份认证模式
当前支持:
- 本地 stdio 的进程和环境边界;
- Static Bearer Token;
- JWT;
- External OAuth 2.0 / OIDC;
- Doris-backed OAuth。
Doris-backed OAuth 在 1.0 中使用进程内授权码、Token、Client 和用户连接池状态,要求 HTTP、单 Worker,并与 External OAuth 互斥。多 Worker 或多节点部署需要选择符合现有约束的认证形态。
MCP Authorization 规范要求 HTTP 客户端在每次请求中携带 Bearer Token,Server 只接受面向自身 Resource 和 Audience 的 Token。把其他服务签发的 Token 原样透传到 MCP 或下游 API,会破坏 Audience、审计和最小权限边界。
13.2 精确授权被检查多次
- 是否允许
list_tools、call_tool等 MCP Operation; - 是否允许发现某个 Domain 下的 Child;
- 是否拥有
child:call:doris_query:execute_query一类精确执行 Scope; - 是否允许使用 ADBC、Semantic、MetricFlow 或 Custom Provider;
- 请求路由对应的 Doris 账户是否拥有最终数据库权限。
发现权限不等于执行权限。Server 也不会在低权限路由失败后回退到更高权限 Global Service Account。
十四、只读 Query Guard:限制 SQL 形状和结果边界

内置 1.0 Tool Catalog 只读,doris_admin 保留但没有注册。Query Guard 会:
- 解析并只接受一条支持的只读语句;
- 拒绝 DDL、DML、Admin Command、Stacked Statement 与违反策略的构造;
- 校验 Catalog、Database、Table、Column、Function 和 Metric 标识符;
- 对调用值尽量使用参数绑定;
- 同时检查直接 Query、Explain 和 Diagnosis 目标 SQL;
- 应用
QUERY_TIMEOUT、MAX_RESULT_ROWS、MAX_RESULT_BYTES、复杂度和并发上限; - 在返回前执行 Masking、Truncation 和 Output Schema 校验;
- 清理原始 Backend Exception、Credential 和敏感 Trace Baggage。
这些控制与 Doris RBAC 协同。Query Guard 防止模型执行不合规 SQL,Doris RBAC 决定当前账户能看到哪些 Catalog、表、列和行。
生产环境应创建专用只读用户,例如只授权目标业务库、information_schema 中必要对象、指定 Workload Group 和必要的 Audit/System View。不要给 MCP Service Account 授予 LOAD_PRIV、ALTER_PRIV、DROP_PRIV、ADMIN_PRIV 或 NODE_PRIV。
