news 2026/9/10 14:05:59

Directus AI 的 files 工具:文件元数据 CRUD 与远程文件导入实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Directus AI 的 files 工具:文件元数据 CRUD 与远程文件导入实战指南

Directus AI 的 files 工具:文件元数据 CRUD 与远程文件导入实战指南

【免费下载链接】directusThe flexible backend for all your projects 🐰 Turn your DB into a headless CMS, admin panels, or apps with a custom UI, instant APIs, auth & more.项目地址: https://gitcode.com/GitHub_Trending/di/directus

导读

在 Directus 的 AI Agent / MCP 能力体系中,files是面向「文件资产」的核心工具:它允许 AI 在不接触二进制内容的前提下,查询文件元数据、批量更新标题与描述、维护标签与焦点坐标,以及从外部 URL 直接导入远程文件。本指南以 files 工具提示词 为主干,结合其 工具实现、Schema 定义 与 FilesService 服务层 源码,系统讲解files工具的四个动作(read/update/delete/import)、全部元数据字段、真实业务用法与底层调用原理,帮助你掌握在 Directus 中构建「内容素材管理」「资产清洗归档」「远程图片入库」等 AI 工作流的具体方法。

工具定位:什么是 Directus AI 的 files 工具

files是 Directus 面向 AI 暴露的一组工具之一,与collectionsfieldsitemsfoldersschemarelations等并列,统一在 AI 工具入口 中注册导出。它在代码中的完整定义为:

export const files = defineTool({ name: 'files', description: 'Reads and changes Directus file metadata or imports remote files. Use for uploads, media metadata, folders, titles, and file records.', instructions: requireText(resolve(__dirname, './prompt.md')), keywords: ['media', 'upload', 'import', 'asset metadata', 'attachments', 'documents'], annotations: { title: 'Directus - Files', destructiveHint: true, }, inputSchema: FilesInputSchema, validateSchema: FilesValidateSchema, output: FilesOutputSchema, readOnly: (input) => input.action === 'read', // ... });

从源码可以看出几个关键设计点(见 工具实现):

  • 工具名固定为files,供 Agent 在注册表中通过execute({ name: "files", input })精确调用(工具分发逻辑见 registry.ts)。
  • 提示词即指令:上面这份prompt.md通过requireText原样加载为工具的instructions,它是引导大模型正确构造请求参数的「行为说明书」。
  • readOnly是一个函数:当action === 'read'时该调用被判定为只读,从而可能跳过耗时的审批流程;其余写操作(update/delete/import)被标记为需要额外确认。工具的 MCP annotations 中destructiveHint: true也提示消费方「该工具可能造成破坏」。

要理解files的运行边界,还需知道整个工具注册表的执行模型:

  • Agent 先用根工具search发现并加载工具详情,再用根工具execute真正执行(工具详情中会包含此处加载的instructions,见 registry.ts);
  • 如果调用上下文设置了allowDeletes === false,任何action: 'delete'都会直接被拒绝并抛出InvalidPayloadError({ reason: 'Delete actions are disabled' })(见 registry.ts);
  • 执行前请求参数会先经过 ZodvalidateSchema校验、再由isToolCallApproved决定是否需要用户批准(见 registry.ts);
  • 每个工具内部使用new FilesService({ schema, accountability })操作directus_files集合,因此完整遵循 Directus 的权限系统(accountability 即当前登录用户上下文)。

支持的动作:read / update / delete / import

根据 files 工具提示词 及 Schema 定义 中的 discriminated union,工具按顶层action字段区分四种操作:

action用途必填参数
read按 query 列出/查询元数据,或按 keys 获取指定文件keys(可选)或query(可选),二选一
update修改已有文件的元数据data(对象或数组)+keysquery之一
delete按 keys 删除文件(含元数据与底层存储文件)keys(必填,数组)
import从 URL 导入远程文件并创建/更新其元数据data(数组,每项含urlfile

对应地,工具实现 的handler将四种动作分别映射到 FilesService 的方法调用链上:

  • read:有keys时调用service.readMany(keys, sanitizedQuery);否则调用service.readByQuery(sanitizedQuery),最终返回{ type: 'text', data }
  • update:按data形态分流——data为数组走service.updateBatch(data)(批处理,每个元素必须含id);data为对象且提供keysservice.updateMany(keys, data);两者皆无则按query定位走service.updateByQuery(sanitizedQuery, data)。更新成功后统一回读readMany(updatedKeys)作为返回值;
  • delete:调用service.deleteMany(args.keys)并返回被删除的主键列表;
  • import:对data数组中的每一项循环调用service.importOne(file.url, file.file),收集保存后的主键返回。

所有涉及查询的动作都会先经buildSanitizedQueryFromArgs把 AI 构造的查询对象清洗、校验为 Directus 标准 Query,与 REST/GraphQL 走的查询管线保持一致(见 utils.ts)。

操作示例详解

下面完整继承提示词中的四类典型调用。

1. 读取文件元数据(批量查询)

{ "action": "read", "query": { "fields": ["id", "title", "type", "filesize", "width", "height"], "filter": { "type": { "_starts_with": "image/" } }, "limit": 10 } }

含义:只返回图片类文件(MIME 以image/开头)的 6 个字段,最多 10 条。query支持完整 Directus 查询能力,包括fieldsfilterlimitoffsetpagesortsearchdeepaliasaggregategroupBy等,全部字段可参考 QueryInputSchema。

2. 读取单个文件元数据(按主键)

{ "action": "read", "keys": ["file-uuid-here"] }

keys必须是数组(["item"]而非"item"),元素为主键(string 或 number,见 PrimaryKeyInputSchema)。同时省略querykeys时,等价于不带任何条件地读取整个文件集合。

3. 通过 URL 导入文件

{ "action": "import", "data": [ { "url": "file-url", "file": { "title": "New Title", "description": "Updated description", "tags": ["tag1", "tag2", "category"], "folder": "folder-uuid" } } ] }

url为要抓取的远程文件地址,file为导入后要写入的元数据(支持FileItemInputSchema任意子集)。可一次传入多条记录批量导入。在底层,每次导入都会调用 FilesService 的importOne(见 files.ts),其核心逻辑为:

  1. 先做访问校验(validateAccess,要求当前 accountability 对directus_files具备create权限);
  2. 通过 axios 以stream方式请求该 URL,失败则抛ServiceUnavailableError(错误码服务名external-file);
  3. 从响应的最终重定向地址解析出文件名、从content-type解析 MIME;
  4. 依次校验全局 MIME 白名单(环境变量FILES_MIME_TYPE_ALLOW_LIST)与字段级 MIME 限制,不合规则抛InvalidPayloadError

提示:这里的“文件元数据导入”不等同于本地文件上传。如果你需要让 AI 读取已上传文件的图像内容,应配合提示词中提到的assets工具获取 base64 内容后再做视觉分析。

4. 更新文件元数据

单个文件(按 keys + 对象 data):

{ "action": "update", "keys": ["file-uuid"], "data": { "title": "New Title", "description": "Updated description", "tags": ["tag1", "tag2", "category"], "folder": "folder-uuid" } }

批量更新(data 为带 id 的数组):

{ "action": "update", "data": [ { "id": "file-uuid-1", "title": "New Title 1" }, { "id": "file-uuid-2", "title": "New Title 2" } ] }

data是数组时,其每个元素必须携带id,走updateBatch路径;这与仅按keys定位的“同一条更新作用于多个 key”是两种不同的语义,实际对应测试用例可参见 files 工具测试,其中分别验证了 keys 单对象、批量数组两种更新方式分别命中updateManyupdateBatch

5. 常用组合过滤器

{ "query": { "filter": { "_and": [ { "type": { "_icontains": "/png" } }, // PNG 文件 { "folder": { "_eq": "folder-uuid" } }, // 指定文件夹 { "filesize": { "_lt": 5000000 } }, // 小于 5MB { "uploaded_on": { "_gte": "$NOW(-7 days)" } } // 最近一周上传 ] } } }

要点:

  • Directus 过滤器运算符均可用(_eq_starts_with_icontains_lt_gte_null等);
  • _and/_or用于组合多个条件;
  • 时间字段支持$NOW(...)这类相对时间动态值,如上例的“最近 7 天”;
  • 注意_icontains的子串不包含前导点,匹配/png而不是image/png"image/"段,可同时命中image/png等具体子类型。

文件元数据字段清单

提示词完整列出了directus_files的可写/可查元数据字段(这些字段与 FileItemInputSchema 基本一一对应,schema 还额外覆盖了charsetembedtus_idtus_data等内部字段):

字段含义
id唯一标识符
storage使用的存储适配器(local / s3 / gcs…)
filename_disk磁盘上的实际文件名
filename_download建议下载文件名
title展示标题
typeMIME 类型(如image/jpegapplication/pdf
folder父文件夹 ID
uploaded_by上传用户
uploaded_on上传时间戳
modified_by最后修改者
modified_on最后修改时间
filesize字节数
width/height图片像素尺寸
duration音视频时长
description文件描述
location地理位置数据
tags标签字符串数组(如["product", "red", "handbag"]
metadata附加元数据对象
focal_point_x水平焦点(距左边缘的像素值)
focal_point_y垂直焦点(距顶部边缘的像素值)

特别说明:keystags都必须以数组形式传递(["item"]而非"item"),这也是提示词「Key Points」中的硬性要求;否则会在参数校验阶段被 Zod schema 拒绝。

真实业务场景:从素材检索到资产治理

提示词为files工具规划了两大类实际用途,下面完整展开并补充实现层面的解读。

场景一:为内容选择合适素材(Asset Selection for Content)

典型诉求:“在我们的素材库里,为新的帮助中心文章找出与客户支持相关的图片。”

{ "action": "read", "query": { "fields": ["id", "title", "description", "tags", "type"], "search": "help center" } }

search会对多个文本字段做模糊匹配,是最轻量的全文检索手段。对于海量素材,可配合filter先缩小范围(如typefolder),再结合fields控制返回体积,避免把大文件二进制拉入上下文。

场景二:素材组织与清洗(Asset Organization & Cleanup)

把一堆无元数据的文件变成可检索、可分类的资产,三步走:

① 找出缺失描述的文件:

{ "action": "read", "query": { "fields": ["id", "filename_disk", "title", "description"], "filter": { "description": { "_null": true } } } }

② 用视觉分析内容:如需理解图片语义,可调用assets工具获取图片的 base64 数据,交给视觉模型生成标题、描述与标签。

③ 回写结构化元数据:

{ "action": "update", "keys": ["image-uuid"], "data": { "title": "Red leather handbag product photo", "description": "Professional e-commerce photo with white background", "tags": ["handbag", "leather", "red", "product-photo", "accessories"], "focal_point_x": 512, "focal_point_y": 300 } }

提示词特别注解了焦点坐标的意义:当图片被裁剪成不同宽高比(缩略图、横幅图等)时,focal_point_x/focal_point_y能确保重要主体始终处于可视区域,坐标以原图左上角为原点、单位为像素。为图片写入准确焦点是电商、新闻类项目保证“自动裁剪不裁掉主体”的关键元数据资产。

上述「查缺失 → 分析 → 回写」是一个可由 Agent 自主循环的经典流程:read是只读操作(readOnly: action === 'read'),而update触达写路径并经由工具注册表进入审批/权限流程,形成「批量只读侦察 + 单点人工确认写回」的安全模式。

Key Points:调用 files 工具必须遵守的约定

以下五条约束来自 提示词 的 Key Points,是让 AI 调用稳定成功的关键:

  1. 始终以原生对象传参dataqueryfilter必须是对象/数组结构,不要传字符串化(stringified)的 JSON。实现侧,注册表在执行前会用coerceJsonFields做一次宽松的类型纠正,再用 Zod 严格校验(见 registry.ts),传字符串化 JSON 极易在strictObject校验处失败。
  2. 只管理元数据,不处理内容files工具负责文件记录与元数据,二进制上传不在其职责范围;真正的上传走 Directus Files API/界面。
  3. 遵守权限:所有操作在 FilesService 内部执行,会基于当前accountability做访问校验(如importOne中的validateAccess要求create权限),Agent 权限不会越过用户权限。
  4. 数组参数keystags必须为数组形式。
  5. 性能:大文件会被自动流式处理,但导入/读取超大文件仍可能影响整体性能,应限制导入并发与单次查询量。

从源码看整体调用链:一次 files 调用发生了什么

把上面的信息串起来,一次完整调用在 Directus 中经过的链路为(可对照 工具实现、registry.ts、FilesService 阅读):

  1. Agent(MCP/聊天等场景)通过根工具execute{ name: "files", input: { action, query/keys/data } }发起调用;
  2. MountedToolRegistry.execute按名找到工具,先执行validateSchema.safeParse做 Zod 校验(同时受allowDeletesisToolCallApproved门控,见 registry.ts);
  3. 进入files.handler,实例化携带当前用户上下文的FilesService
  4. 依据action分流到readMany/readByQuery/updateBatch/updateMany/updateByQuery/deleteMany/importOne
  5. 返回{ type: 'text', data },若数据为单条且配置了PUBLIC_URL,注册表还会通过工具的endpoint为其拼接管理后台详情页 URL(#addUrlbuildURL,见 registry.ts 与 工具实现),方便用户直接跳转到后台核对记录。

测试覆盖与验证

想要验证你对files行为的理解,可直接运行仓库中已有的单元测试:files 工具测试 使用 vitest + 对FilesService的 mock,覆盖了四类关键断言:

  • read by keys:验证read+keys会以(keys, {})调用readMany
  • update 两种形态:keys + 对象 data →updateMany;数组 data →updateBatch
  • deletedelete+ keys →deleteMany(keys)并返回 keys;
  • Schema 可接受性:对FilesValidateSchema.safeParse分别验证对象 data、数组 data 两种更新负载均通过校验;
  • 非法动作action: 'invalid'会抛出Invalid action.异常;
  • 工具配置:工具名称为files、非 admin 工具、description 与 input/validate schema 均已定义。

在本地开发调试时,可以vitest run api/src/ai/tools/files/index.test.ts单独执行该测试文件,作为理解工具行为与回归验证的入口。

总结

files工具的价值在于把 Directus 强大的文件资产管理能力封装成一个语义清晰、参数校验严格的 AI 函数式接口:对 Agent 而言它是一份自带 Zod 契约的「元数据操作说明书」,对人类开发者而言它是通往 FilesService 数据管线的桥梁。掌握read/update/delete/import四种动作的语义边界、记住「数组参数、原生对象、元数据优先」三条铁律,再结合 Directus 的权限与 MIME 白名单机制,你就可以在聊天、MCP 或自定义 Agent 中安全地搭建素材检索、资产清洗、远程取图入库等自动化工作流。

【免费下载链接】directusThe flexible backend for all your projects 🐰 Turn your DB into a headless CMS, admin panels, or apps with a custom UI, instant APIs, auth & more.项目地址: https://gitcode.com/GitHub_Trending/di/directus

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 14:03:08

COMSOL相场法模拟锂枝晶生长与电池优化

1. 项目概述:树枝晶生长模拟的工程价值树枝晶生长现象在金属凝固、电池失效等工业场景中普遍存在。以锂电池为例,充放电过程中锂枝晶的不可控生长会刺穿隔膜导致短路,这是制约高能量密度电池发展的关键瓶颈。传统实验观测手段存在成本高、周期…

作者头像 李华