spec 1.0 · 规范性

引导配置

引导配置是上下文层中与智能体无关的入口。它是一份人类可读的文档,任何智能体宿主和任何人都可以从这里开始,并回答三个问题:“这个上下文层是什么?我该加载什么?我在这里该如何行事?”

要求#

  1. 上下文层必须恰好有一份引导配置,位于清单中 bootProfilePath 所声明的路径。推荐的默认值是 docs/boot-profile.md

  2. 引导配置必须是纯 markdown,任何人不借助工具也能读懂。它不得依赖任何厂商的配置语法。

  3. 引导配置必须涵盖:

    • 身份:这个仓库或产品是什么,一段话说清。
    • 加载:什么样的任务该读什么上下文。这里必须给出一个无条件集合(任何任务之前都要读的内容),然后是按任务类型划分的选择器,依路径、依类别或经由上下文索引来路由,并为匹配不到任何选择器的任务定义兜底方案。用任务语言表述的这一节,就是“任务路由”算法(machine-readable-surface.md)在引导配置层面的表达;照做无需了解那个算法。
    • 姿态:对智能体运作方式的预期(何时可以直接推进、何时必须发问、绝不能做什么)。这可以通过引用治理内容或某份核心智能体配置来承载。
  4. 引导配置应当链接到清单、索引(若存在)与各智能体配置(若存在),使得从任何宿主进入的智能体都能发现完整的机器可读接口。

  5. 引导配置必须讲任务语言:它写明字面路径与具体加载顺序,照做无需了解本规范。清单与 schema 是为工具而存在的,不是为智能体;一份需要读懂规范才能照做的引导配置,是一致性上的坏味道。

  6. 引导配置应当说明上下文层的维护职责:它的变更记录在哪里(所声明的变更日志),以及决策如何沉淀(所声明的决策记录位置)。若引导配置两者都未提及,校验器会告警。

  7. 厂商入口文件按 context-layer.md 中的厂商适配器规则重定向到引导配置。

  8. 引导配置的无条件加载集合(它声明在任何任务之前都要读的内容)应当限定在每项任务都真正需要的范围内。只有部分任务需要的上下文应当按任务、按类别或经由索引来路由,而不是预先加载;决策记录应当按其声明的 affectedPaths / affectedCategories 来路由,而不是整个目录一次性加载,因为它们会无止境地累积。无条件集合中的每一样东西,在每项任务上都要付出代价。

  9. 联邦同级层。 声明了 federation.mounts 的上下文层(见 distribution.md必须在引导配置中以机器可检查的形式呈现这些同级层:一个或多个信息串为 leji-mounts 的围栏块,可置于文档任意位置,其条目按文档顺序拼接,且每个已声明的挂载恰好对应一条条目。一条条目写明该同级层、它的负责人、它承载什么,以及何时该读它,后两项用作者自己的任务语言表达。成型的示例见要求之后。

    文法是固定的,以便每个实现读法完全一致。一个块以三个或更多反引号加上信息串的一行开启,并由下一行三个或更多反引号关闭;关闭围栏的反引号数量不必与开启围栏一致。信息串只能是 leji-mounts 本身;其后携带任何 token 的围栏都是错误,绝不是被忽略的围栏。围栏行可以带有空格或制表符的缩进与填充,而其间的记录不得如此:一条记录从第 1 列的 - mount: 开始,其字段恰好缩进两个 ASCII 空格。一条记录内部,ownercarriesread-when 各出现恰好一次,顺序不限;未知字段、重复字段与缺失字段都是错误。值是 key: 前缀之后该行剩余的非空部分,不带前导或尾随的空格与制表符,也不含任何控制字符或行分隔字符。这套文法中的空白只有 ASCII 空格(U+0020)与制表符(U+0009),别无其他,在围栏行的缩进与填充中如此,在内容行中亦然;实现不得在此处使用运行时的空白字符类,因为各运行时对 U+0085 与 U+00A0 这类字符的归类并不一致,进而会对“块是否存在”产生分歧。解析前会先剥除前导的 UTF-8 字节序标记。行按 LF 切分,容忍尾随的 CR,空行与以 # 开头的整行被忽略(与 content-categories.md 的类别索引块相同),文件为 UTF-8。扫描是按行进行的,不考察 markdown 结构:一行若在可选的空格或制表符缩进之后带有三个或更多反引号与该标签,无论它位于文档何处,都会开启一个真实的块,包括位于更长的围栏示例内部或列表项内部。因此,只用于举例而非声明的示例要用不同的标签围栏,绝不能在 leji-mounts 之后多加一个 token:扫描器匹配的正是标签,所以 leji-mounts example 会开启一个真实的块并报出解析错误,而标签为 text 的围栏什么也不会开启。mount 必须与某个已声明挂载的 name 一致,owner 必须与该挂载所声明的 owner.name 一致,按解码后的字符串比较;为未声明的挂载写条目、为同一个挂载写第二条条目、以及已声明却没有条目的挂载,都是错误。未声明任何挂载的层不得携带 leji-mounts 块。

    同级层的位置被刻意排除在字段之外:挂载会被物化到一个机器本地、按内容寻址的投影中,因此读取者用 leji mounts locate <name> 来解析它,而不是去推断路径(见 distribution.md)。块周围的散文应当自然地解释路由方式;块是可检查的内核,绝不是那段散文的替代品,也不是 leji.json 中声明的替代品。已挂载的同级层是彼此独立的具名来源,绝不并入宿主层的类别;只有当任务匹配某个同级层的路由,或配置本身要求时,引导配置才把智能体导入该同级层。哪些内容不作检查也是刻意的:carriesread-when 是自由文本,它们与挂载路由元数据的吻合程度由团队自行担保,而不由工具验证;工具检查的是枚举、身份与存在性。在这里呈现同级层,使挂载的发现留在智能体的任务语言入口中,因此照做要求 5 时依然无需阅读清单。

一份成型的 leji-mounts#

一条条目,对应一个声明了名为 acme-product-context 的单一挂载的宿主层。该块在引导配置中位于第 1 列,就是这里读到的样子;外层的四反引号围栏是本文档的包裹,并不属于它。

```leji-mounts
- mount: acme-product-context
  owner: Product team
  carries: product-side domain language and the decisions behind the customer-facing surface
  read-when: a task touches product behavior, product terminology, or billing
```

智能体配置#

上下文层可以machine.agentProfilesPath 所声明的目录下定义按角色划分的配置(例如一份 reviewer 配置、一份 release 配置、一份 QA 配置)。每份配置:

  1. 必须是带 YAML frontmatter 的 markdown,且 frontmatter 对 agent-profile.schema.json 有效。

  2. 在继承解析完成后,必须携带该角色首先读取什么(requiredRead),以及它必须停下来发问的情形(mustAskWhen)。声明了 inherits 的配置,可以在其基配置已提供某一项时省略该项;未声明 inherits 的配置必须自行声明两者。

  3. 可以声明 inherits,它在 1.0 版本系列中是生效的:它指向本层配置集合中恰好另一份配置,该配置的 role 必须core,本配置扩展它的姿态与正文。本层的配置集合,是所声明的 machine.agentProfilesPath 之下的每一份文档,加上清单 agents 映射中指名的每一份文档,无论后者位于何处。解析只有单层,因此 rolecore 的配置不得声明 inherits,被指向的目标必须存在、必须id 唯一,且它自身不得声明 inherits。解析的组合方式:

    • 姿态数组requiredReaddefaultContextmustAskWhenmustRefuseWhen):基配置的条目按其撰写顺序在前,然后是派生配置的条目按其撰写顺序,并去掉基配置已经携带的条目。撰写顺序即加载意图,因此不作任何排序。
    • 其余每个字段idnamerolepurposeversionhostinvocationescalationownersfreshness):取派生配置自身的值,绝不继承。inherits 是一条解析指令,本身不属于解析后的配置。
    • 正文:两份正文都是规范性的,基配置在前,派生配置在后。

    无法解析被继承配置的消费者不得单独应用派生文件;派生文件只是一份配置的一半,因此消费者转而报告它不受支持。当某个 ask 条件与某个 refuse 条件同时适用于同一情形时,以拒绝为准。

    解析保证的是组合,而不是语义上的收紧:派生的散文若与基配置矛盾或削弱基配置,即为不符合规范,而且没有任何工具能检测自然语言中的矛盾。

配置调校的是一个角色加载什么、如何行事;它们不复制上下文层的内容。

配置中可选的 hostinvocation 是单一担任者的简写:它们说明如何启用担任该角色的那一个参与者。其 command 是一个模板,遵循与 actor 命令模板相同的规则,包括 <prompt> 占位符及其位置(见 context-layer.md 的“要求”)。当某个角色有多于一个合格参与者,或同一个参与者因担任角色不同而需要不同调用方式时,改由清单中可选的 actors 注册表承载(同一节)。一个角色只用其中一种机制,绝不同时用两种。

注记(非规范性)#

引导配置有意保持简洁:它提供地图与姿态,而不是充当知识库。如果引导配置长达数屏,说明本该归入某个类别的内容被放进了入口。

这套设计旨在避免多余的间接层:智能体最先获得的上下文与真正约束之间每多一跳,就会额外消耗注意力。设计得当的上下文层根本不需要厂商入口文件(调用可以直接指向引导配置),而引导配置直接通向内容。深度应当存在于上下文层的文档中,而不是通往文档的路径上。

引导配置中声明“任何任务之前都要读”的每一份文档,在每项任务上都要付出代价,因此无条件集合是上下文层里最昂贵的空间。把它控制在真正普适的范围内,其余的通过按任务类型的加载、类别、索引,以及每份决策记录自己声明的作用域来路由。索引存在的意义,是让智能体加载任务需要的那一片,而不是整棵树;决策会无止境地累积,因此它们被路由,绝不作为一个目录预先加载。