通过模块化提示转译构建可扩展的 AI Agent
英文标题:Building scalable AI agents with modular prompt transpilation
单体系统提示在生产中面临变更爆炸范围模糊、复制粘贴漂移和运行时错误延迟等扩缩瓶颈。解决方案是将提示模块化为可复用的技能文件,利用转译器实现构建时静态验证,以确保依赖完整、变量存在,并在 CI 流水线中强制执行漂移检查。进一步借助渐进式公开让代理在运行时动态加载所需技能,甚至代理可以提议改进自身指令层并通过标准审查流程合并。这一方法将提示工程转变为构建系统问题,为开发者构建可靠、可维护的生产级 AI 代理系统提供了工程化基础。
88.4 KB
35.3 KB
41.3 KB
67.6 KB
86.1 KB
66.7 KB
64.4 KB
19.9 KB
496.8 KB
64.7 KB
67.8 KB
中文

当你刚开始构建 AI 代理时,一个单一的整体系统提示通常是可以的。你有一些指令,也许有一两个工具定义,所有内容都存放在一个可读的文件中。
但是当你开始将它们用于生产目的时,这种格式就会崩溃。团队开始叠加安全策略、领域特定规则、格式要求以及升级行为。突然间,你的整个代理控制平面都包含在一个单一的指令文件中,而这正是问题开始的地方。
这是一个经典的软件工程扩展问题。当你把每个关注点都推到一个单一文件里时,你就失去了对系统进行推理的能力。协作变成一场噩梦,测试变得挑剔,一个旨在改进某个工作流的小改动可能会悄悄地破坏另一个工作流。
在生产规模上,提示的可维护性就变成了代理的可靠性。
为什么单体提示词会失效
我们通常会看到提示词超出一定规模后的三种主要故障模式:
- 模糊的冲击范围: 在标准软件工程中,审查者很容易通过模块边界、调用点和测试来推断变更的范围。但系统提示的差异更难处理。增加一句话可能会在整个代理中产生意想不到的副作用,这通常难以预测或测试。
- 复制粘贴漂移: 随着组织规模的扩大,许多团队最终会为各种应用程序复制共享逻辑,例如内部服务使用说明、PII 处理、安全策略或升级协议。这导致复制粘贴或同一功能出现多个版本,从而产生不一致。
- 延迟的运行时错误: 为了管理杂乱无章的情况,团队通常求助于即席字符串格式化或简单模板。虽然这有助于编写,但它将错误检测推到了运行时。你可能部署了一个提示,只有在触发特定的、很少使用的工作流时才会失败,因为缺少变量或无效的导入路径。
模板是一个好的开始,但它们还不够。生产系统需要确定性的构建、静态验证和 CI/CD 集成。
像对待软件制品一样对待提示
此处的解决方案是将提示视为构建制品,而不是静态文本。
与其维护一个单一的整体提示文件,你可以编写模块化的技能文件。这允许你缩小每个文件的范围并封装特定的行为,从而使团队能够分离关注点并独立迭代组件。
一个顶层的代理提示模板可能看起来像这样:
agents/sre_agent.prompt.md (prompt template file)
{% include "shared/safety.prompt.md" %} {% include "shared/tool_usage.prompt.md" %}
You are an SRE triage agent operating in the {{ environment }} environment.
{% if allow_remediation %} You may recommend remediation steps, but destructive actions require human approval. {% else %} You may inspect, summarize, and explain the issue, but do not recommend remediation actions. {% endif %}
{% macro bullet_section(title, items) %}
{{ title.rstrip() }}
{% for item in items %}
- {{ item.rstrip() }} {% endfor %} {% endmacro %}
{{ bullet_section("Required investigation steps", [ "Inspect recent deployment events", "Check service metrics for latency or error-rate changes", "Review logs for repeated failure patterns" ]) }}
纯文本
这可以让你两全其美。模板层允许你组合共享指令、注入特定环境的值并使用宏。但对于构建系统来说,每个 include 都是一个依赖项,每个变量都是一个要求。结果是得到一个确定性的、完全渲染的制品,你可以在它到达模型之前对其进行测试、审计和差异比较。然后我们可以使用转译器来解析模板导入,生成一个可以被代理直接使用的文件。
例如,如果 environment = production 且 allow_remediation = true,转译后的制品将如下所示:
You are an SRE triage agent operating in the production environment.
You may recommend remediation steps, but destructive actions require human approval.
Required investigation steps
- Inspect recent deployment events
- Check service metrics for latency or error-rate changes
- Review logs for repeated failure patterns
纯文本
一个高层次的转译管道看起来大致如下:
构建时验证是强制性的
一个生产级的转译器应该在运行时之前捕获错误。
我们应该在构建过程中运行验证检查,以发现缺失的导入、未定义的变量和循环依赖。依赖图在这里非常宝贵,这强化了对健壮模板引擎的需求。如果你将每个提示片段视为有向图中的一个节点,你可以轻松捕获递归导入,否则这些导入会在生产环境中导致无声的故障。
这还可以实现漂移检查。你可以设置 CI 管道,使其能够从源文件重新生成转译后的提示(称为黄金文件),并将其与当前提交的制品进行比较。如果输出不同,构建将失败。这确保了你仓库中的代码与生产环境中运行的代码完全一致,消除了源文件与部署制品之间的差距。
动态技能和代理作者更新
随着你的模块化提示片段技能库不断增长,你不一定希望每个代理每次都加载每个技能。这样做会消耗令牌并引入噪声,从而干扰代理的特定任务性能。
一个更好的架构模式是利用渐进式公开。这里我们将稳定的控制平面与特定于任务的上下文分离开来。编译后的基础提示应强制执行不可协商的行为,如身份和安全边界。然后,在运行时,代理可以使用工具仅动态检索当前任务所需的特定技能模块;这减少了上下文耗尽,并帮助代理专注于其任务。
一旦你拥有了这种模块化系统,你便开启了一个强大的工作流:代理可以帮助维护自己的指令层,帮助创建一个自我维持的代理系统。当代理解决了一种新型事件时,它理论上可以起草一个新的技能模块,更新相关的导入,并打开一个拉取请求。
代理并不是实时修改自己的指令;它是在提出一个代码变更。然后,转译器会对该提案进行与任何其他代码变更相同的验证和审查。人类审查者可以检查 PR,运行评估,并合并该变更。
结论
一个生产提示转译器将提示工程重新定义为构建系统问题。
当我们构建模块化的技能文件时,我们可以解析依赖关系、验证导入,并强制执行漂移检查,就像我们在标准软件基础设施中所做的那样。代理变得能够建议对其自身逻辑的改进,前提是这些变更通过了我们现有的验证和审查流程。
随着 AI 代理深入集成到关键工作流程中,其指令层需要达到我们对软件所要求的相同可靠性标准。提示不应仅仅被编辑,而应该被构建、验证、版本化和部署。
English / 原文

When you’re first building an AI agent, a single, monolithic system prompt is usually fine. You have a few instructions, maybe a tool definition or two, and everything lives in one readable file.
But as you start using them for production purposes, that format simply just breaks down. Teams start layering on safety policies, domain-specific rules, formatting requirements, and escalation behaviors. Suddenly, you have your entire agent’s control plane within a single instruction file which is exactly where the trouble starts.
This is a classic software engineering scaling problem. When you push every concern into a single file, you lose the ability to reason about the system. Collaboration becomes a nightmare, testing gets finicky, and a small change meant to improve one workflow can quietly break another.
At production scale, prompt maintainability becomes agent reliability.
Why monolithic prompts break down
We typically see three main failure modes when prompts grow beyond a certain size:
- Obscured blast radius: In standard software engineering, it’s easy for reviewers to reason about the scope of a change through module boundaries, call sites, and tests. System prompt diffs are harder though. Adding a sentence could have unintended side effects across the entire agent, which is often hard to predict or test.
- Copy-paste drift: As organizations scale, many teams end up duplicating shared logic for various applications such as internal service usage instructions, PII handling, safety policies, or escalation protocols. This leads to copy-pasting or multiple versions of the same functionality leading to inconsistencies.
- Deferred runtime errors: To manage the sprawl, teams often resort to ad-hoc string formatting or simple templates. While this helps with authoring, it pushes error detection to runtime. You might deploy a prompt that only fails when a specific, rarely-used workflow is triggered because of a missing variable or an invalid import path.
Templates are a good start, but they aren't enough. Production systems require deterministic builds, static validation, and CI/CD integration.
Treat prompts like software artifacts
The solution here is to treat prompts like build artifacts as opposed to just static text.
Instead of maintaining one monolithic prompt file, you can author modular skill files. This allows you to reduce the scope of each file and encapsulate a specific behavior, which allows teams to separate concerns and iterate on components individually.
A top-level agent prompt template might look something like this:
# agents/sre_agent.prompt.md (prompt template file)
{% include "shared/safety.prompt.md" %}
{% include "shared/tool_usage.prompt.md" %}
You are an SRE triage agent operating in the {{ environment }} environment.
{% if allow_remediation %}
You may recommend remediation steps, but destructive actions require human approval.
{% else %}
You may inspect, summarize, and explain the issue, but do not recommend remediation actions.
{% endif %}
{% macro bullet_section(title, items) %}
## {{ title.rstrip() }}
{% for item in items %}
- {{ item.rstrip() }}
{% endfor %}
{% endmacro %}
{{ bullet_section("Required investigation steps", [
"Inspect recent deployment events",
"Check service metrics for latency or error-rate changes",
"Review logs for repeated failure patterns"
]) }}
Plain text
This gives you the best of both worlds. The templating layer lets you compose shared instructions, inject environment-specific values, and make use of macros. But for the build system, every include is a dependency, and every variable is a requirement. The result is a deterministic, fully rendered artifact that you can test, audit, and diff before it ever reaches the model. We can then use a transpiler to resolve the template imports to generate a file that is ready to be ingested by an agent.
For example, if environment = production and allow_remediation = true, the transpiled artifact would look like this:
You are an SRE triage agent operating in the production environment.
You may recommend remediation steps, but destructive actions require human approval.
## Required investigation steps
- Inspect recent deployment events
- Check service metrics for latency or error-rate changes
- Review logs for repeated failure patterns
Plain text
A high-level transpilation pipeline would look something like this:
Build-time validation is mandatory
A production-grade transpiler should catch errors before runtime.
We should be running validation checks for missing imports, undefined variables, and circular dependencies during the build process. Dependency graphs are invaluable here, reinforcing the need for a solid template engine. If you treat each prompt fragment as a node in a directed graph, you can easily catch recursive imports that would otherwise cause a silent failure in production.
This also enables drift checking. You can set your CI pipelines to be able to regenerate the transpiled prompt from source (referred to as the golden file) and compare it against the currently committed artifact. If the outputs differ, the build fails. This ensures that the code in your repo is exactly what’s running in production, eliminating the gap between source files and deployed artifacts.
Dynamic skills and agent-authored updates
As your skill library of modular prompt fragments grows, you don't necessarily want every agent to load every skill every time. Doing so consumes tokens and introduces noise that can interfere with the agent's task-specific performance.
A better architectural pattern would be to leverage progressive disclosure. This is where we separate the stable control plane from task-specific context. The compiled base prompt should enforce non-negotiable behaviors like identity and safety boundaries. Then, at runtime, the agent can use a tool to dynamically retrieve only the specific skill modules required for the task at hand; this reduces context exhaustion and helps to keep the agent focused on its task.
Once you have this modular system, you unlock a powerful workflow: agents can help maintain their own instruction layer, helping to create a self-sustaining agentic system. When an agent resolves a new type of incident, it could theoretically draft a new skill module, update the relevant imports, and open a pull request.
The agent isn't mutating its own instructions in real-time; it's proposing a code change. The transpiler then subjects that proposal to the same validation and review rigors as any other code change. A human reviewer can inspect the PR, run the evals, and merge the change.
Conclusion
A production prompt transpiler reframes prompt engineering as a build-system problem.
When we build modular skill files, we can resolve dependencies, validate imports, and enforce drift checks just as we do with our standard software infrastructure. Agents become capable of suggesting improvements to their own logic, provided those changes pass through our existing validation and review processes.
As AI agents become deeply integrated into critical workflows, their instruction layers need the same reliability standards we demand of our software. Prompts shouldn't just be edited, they should be built, validated, versioned, and deployed.