Directus AI 助手系统提示词设计剖析:prompt.md 的四维角色定位与安全约束链
本文以 api/src/ai/tools/system/prompt.md 为主体,逐节解读 Directus 内置 AI 助手(Directus Assistant)的默认系统提示词:角色定位、四大能力领域、沟通风格、关键操作规范与安全规则,并结合 工具定义源码、工具注册机制 与 聊天控制器 等实现,说明这份提示词如何被加载、如何被项目管理员的自定义配置覆盖,以及其中每条安全规则背后的代码级保障。读完本文,你不仅能完整理解这份提示词的每一条约束,还能掌握 Directus AI 工具链的挂载、可见性门控与审批执行机制。
1. 这份 prompt.md 在 Directus AI 架构中的定位
prompt.md 不是一个孤立的文案文件,它是名为 system-prompt 的 AI 工具的默认返回内容。在 api/src/ai/tools/system/index.ts 中,该工具被明确定义为:
export const system = defineTool<z.infer<typeof SystemPromptValidateSchema>>({
name: 'system-prompt',
description: "Returns the AI usage guidance configured by this project's administrator, if any.",
keywords: ['instructions', 'role', 'assistant prompt', 'system instructions'],
annotations: {
title: 'Directus - System Prompt',
},
inputSchema: SystemPromptInputSchema, // z.object({}) —— 不接受参数
validateSchema: SystemPromptValidateSchema, // { promptOverride?: string | null }
readOnly: true,
async handler({ args }) {
return {
type: 'text',
data: args.promptOverride || requireText(resolve(__dirname, './prompt.md')),
};
},
});
由此可以得到三个关键事实:
prompt.md是回退值(fallback)。handler 优先返回args.promptOverride,只有当管理员没有配置自定义提示词时,才会通过requireText同步读取并返回这份内置的prompt.md。- 它是只读工具(
readOnly: true),不参与任何数据变更,注册机制会据此为它打上readOnlyHint: true/destructiveHint: false的注解(见 registry.ts 的 getRootTools)。 - 它在工具总表中排第一位。api/src/ai/tools/index.ts 中
ALL_TOOLS数组以system开头,随后是items、files、folders、assets、flows、triggerFlow、operations、schema、collections、fields、relations等 12 个工具,system-prompt与它们共同构成 AI 可检索、可执行的 Directus 工具目录。
这份提示词的语义因此是:"当你(AI)通过工具接入 Directus 时,你应该遵循的使用准则"——它既定义了助手的专家画像,也划定了不可逾越的操作红线。
2. 角色定义与四大能力领域(Core Expertise)
文档开篇将助手定位为:
You are Directus Assistant, an expert in Directus CMS with direct access to a Directus instance through specialized tools.
即"通过专用工具直接访问 Directus 实例的 Directus CMS 专家"。紧接着给出四个能力领域,这四项与 Directus 的产品能力一一对应:
| 能力领域 | 职责范围 | 对应的 Directus 能力 |
|---|---|---|
| Content Specialist(内容专家) | 内容管理、编辑与优化 | Items 数据读写(对应 items 工具) |
| Schema Architect(模式架构师) | 数据库设计、关系与数据建模 | 集合/字段/关系管理(对应 collections、fields、relations 工具) |
| Automation Expert(自动化专家) | Flows、Webhooks 与工作流程配置 | 流程操作(对应 flows、operations、trigger-flow 工具) |
| API Integration(API 集成) | REST/GraphQL 模式与系统集成 | Directus 即时 API 能力 |
值得注意的是,聊天侧的基础系统提示词(SYSTEM_PROMPT 常量)使用了几乎相同的角色声明句式,说明 prompt.md 与聊天基础提示词共享同一套角色设定,前者是工具调用侧的使用指导,后者是对话流的行为基线。
3. 沟通风格:三条纪律(Communication Style)
文档的 Communication Style 一节规定了三条沟通纪律,每条都指向 LLM 应用中的典型失败模式:
- Be concise(简洁)——用户偏好短小直接的回复,确认操作只给一句话,例如
Created collection 'products'。这避免了 LLM 常见的冗长复述,也契合 Directus 管理后台聊天窗口的交互密度。 - Match the audience(匹配受众)——面对开发者用技术语言,面对内容编辑用通俗语言。这意味着助手需要根据当前用户角色(Directus 支持管理员、编辑器等多角色)动态调整表达。
- NEVER guess(绝不猜测)——如果对字段取值或用户意图的信心不足 99%,必须反问澄清。这是一条对抗 LLM"幻觉式补全"的硬约束:宁可多问一句,也不要把猜测的值写入数据库。
这三条在 聊天基础提示词 的 ## Communication Style 小节中逐字复现(含同一句 one-line confirmations 示例),进一步证实两份提示词是同一行为规范在不同注入点的分发。
4. 关键操作规范(Critical Operations)
这是整份 prompt.md 的核心,分三个子节。
4.1 Schema & Data Changes:模式与数据变更
文档要求三条:
- Confirm before modifying(变更需确认):修改 Collections、fields、relations 一律需要用户批准;
- Check namespace conflicts(检查命名空间冲突):明确指出一个容易踩坑的语义——集合文件夹(collection folders)与普通集合共享命名空间;集合文件夹不同于文件文件夹,它们只是没有对应数据库表、用于分组的集合条目;
- Respect workflows(尊重工作流):修改前检查 draft/published 状态,即 Directus 的版本发布(Versioning)机制下,草稿与已发布内容并存时不能直接覆盖。
这些约束并非只停留在"提示词层面"。注册器 MountedToolRegistry 的执行流程 中,任何非只读工具在执行前都必须通过 isToolCallApproved 回调审批(APPROVAL_REQUIRED 错误码),且 allowDeletes === false 时 action: 'delete' 会直接抛出 InvalidPayloadError。也就是说,"确认后再改"这条提示词规则,在代码层有对应的强制闸门。
4.2 Safety Rules:四条安全规则
| 规则 | 含义 |
|---|---|
| Deletions require confirmation | 删除任何内容前必须询问,ALWAYS ask |
| Warn on bulk operations | 影响大量条目时要主动预警(示例:"This updates 500 items") |
| Avoid duplicates | 当无法修改已有条目时,绝不创建重复条目 |
| Use semantic HTML | 内容字段中不使用 class、id 或内联样式,除非用户明确要求 |
前两条在聊天基础提示词中同样出现,且额外多了 Permission errors: Report immediately, don't retry(权限错误立即上报、不重试)——这对应注册器对权限类错误 recoverable: false 的处理策略(toRegistryError 中只有 InvalidPayloadError 被标记为可恢复)。"语义 HTML" 规则则面向富文本内容字段:Directus 的内容字段存储 HTML,若 AI 生成带内联样式的 HTML 会破坏后台编辑体验,因此默认禁止。
4.3 Error Recovery:错误恢复策略
文档给出了三级错误处理:
- Auto-fix clear errors——对明显错误(如
field X required)自动重试一次; - Stop after 2 attempts——两次尝试后仍失败或错误不明,停止并向用户求助;
- Optimize queries——使用
fields参数最小化过度取数,大数据集使用分页。
第一、二条与聊天基础提示词的 Error Handling 节一致("Auto-retry once for clear errors"、"Stop after 2 failures, consult user")。第三条指向 Directus REST API 的查询语义:fields 参数控制返回字段、分页控制数据量,这与 items 工具 等数据读取工具使用的 Directus query 参数体系一致。
5. Workflow:三步工作流与工具发现机制
prompt.md 的结尾给出助手的标准作业流程:
- 以
schema()调用开始,发现(discover)所有集合; - 用
schema(keys: ["collection_name"])获取与当前任务相关的字段级细节; - 基于用户需求与权限执行操作。
这个工作流与注册器的**根工具(root tools)**结构精确对应:getRootTools 返回 search、execute 两个元工具加上可见的 schema 工具。schema 是唯一与 search/execute 并列的根工具,助手无需先搜索即可直接调用它做模式发现——这正是文档第 1、2 步的底层支撑。
而第 3 步"执行操作"在完整工具目录中则遵循 search → execute 两段式:先 search({ query }) 或 search({ names }) 检索并加载工具详情,再 execute({ name, input }) 执行内层工具。这一扩展流程由 聊天基础提示词的 Tool Usage Patterns 一节(Discovery First 第 3–5 条)承担,与 prompt.md 的简化版 Workflow 互补:前者面向 Directus 后台内嵌聊天,后者面向通过 system-prompt 工具获取指导的外部 AI 接入方。
6. 注入链:从项目设置到 LLM 上下文
promptOverride 参数并非由模型自由填写,其值由系统注入。完整链路如下:
- 读取设置:聊天中间件 load-settings.ts 通过
SettingsService读取项目设置单例中的ai_system_prompt等字段,将settings['ai_system_prompt']存入res.locals['ai'].systemPrompt; - 传递上下文:chat.post.ts 控制器 把
systemPrompt: res.locals['ai'].systemPrompt传入chatRequestToolsToAiSdkTools与createUiStream; - 参数替换:注册器 MountedToolRegistry.#parseInput 对
system-prompt工具有专门分支——
const rawInput = tool.name === 'system-prompt'
? { promptOverride: this.#context.systemPrompt }
: input;
即模型传入的任何参数都会被替换为管理员配置值,保证提示词来源可控;
4. 可见性门控:#isToolVisible 中,当挂载上下文的 systemPromptEnabled === false 时,system-prompt 工具对模型不可见;
5. 回退默认值:若无覆盖值,handler 返回内置 prompt.md 全文。
单元测试 api/src/ai/tools/system/index.test.ts 完整验证了这条逻辑:promptOverride 为 undefined 或 null 时返回 requireText 读取的默认提示词;传入自定义字符串(如 'Lorem')时原样返回;工具名为 system-prompt、非 admin 工具、具备输入与校验 schema。
7. 实践要点与自定义建议
基于以上实现,可以得出几点可直接落地的结论:
- 覆盖方式:在项目设置(
directus_settings单例)中配置ai_system_prompt字段即可整体替换本 prompt.md 的内容,替换发生在注册器参数注入层,无需改动代码; - 约束的优先级:管理员自定义提示词是"软约束",而注册器的
allowDeletes拦截与isToolCallApproved审批是"硬约束"——即使提示词被改写,删除拦截与非只读审批仍由代码强制执行,这是提示词工程之外的第二道防线; - 保持 99% 规则的语义:若自定义提示词,建议保留"不确定就问"与"删除前确认"两条,因为它们与 Directus 的版本化、权限模型耦合最深,去掉后错误写入风险显著上升;
- 工作流不可省略 schema 先行:
schema()→schema(keys)的两步发现是根工具设计的既定路径,自定义提示词若改写工作流,需与 search/execute 元工具的发现语义保持一致,否则模型可能跳过工具详情加载直接execute,触发UNKNOWN_TOOL类错误(注册器对此返回recoverable: true并提示回到 search)。
8. 小结
prompt.md 虽只有数十行,却以"角色画像 + 沟通纪律 + 变更确认 + 安全规则 + 错误恢复 + 发现式工作流"的完整结构,定义了 Directus AI 助手的行为边界;而 system 工具定义、注册器、设置中间件 与 聊天控制器 共同构成了"管理员可覆盖、系统可门控、代码强制兜底"的三层提示词分发体系。理解这条链路,是阅读 Directus AI 模块(api/src/ai/ 下的 chat、tools、providers、mcp 子目录)的合理起点。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00