@chronoai/toolkit/output-format
统一调度和拼装 AI 的输出格式提示词。
💡 为什么需要这个 Feature?
在开发 AI 应用时,我们经常需要让大语言模型(LLM)按照特定的格式(如 JSON)返回数据,以便代码解析。当你的 Agent 由多个独立的 Feature(比如“天气组件”、“记忆组件”、“推理组件”)拼接而成时,如果每个组件都在 prompt 里自己写一段“请返回包含 xxx 的 JSON”,最终的 Prompt 会极其混乱,AI 也很容易输出错误或破损的格式。
OutputFormatFeature 就像是一个“格式收发室”。你把它挂载在 Agent 上,其他所有的 Feature 就不需要自己写繁琐又重复的格式指令了,只需要向它“上报”自己的字段需求即可。它会自动把这些需求整合成一份干净、标准的格式规范,并注入到 system prompt 中。
为了让 AI 遵循格式的成功率最高,它将收集区域拆分成了两部分:
- 输出指导(tag:
output-guide):给 AI 的规则说明书。在这里定义每个字段的类型、含义和约束规则(例如:- answer (必填,字符串):给用户的最终回答)。 - 输出示例(tag:
output-example):给 AI 的参照模板。LLM 是超级“模仿大师”,直接给它看一个拼装好的格式示例(例如:"answer": "你好"),能大幅提升输出的准确性和稳定性。
本 Feature 会自动收集所有挂载的 Feature 上报的指导和示例,直接拼接组装后送给 LLM。
⚠️ 注意:本 Feature 仅负责**“提示词拼装”(教 AI 怎么输出)。如要在拿到大模型结果后解析并提取**数据,请配合使用纯工具函数
@chronoai/toolkit/output-parser。
安装
已包含在 @chronoai/toolkit 中,无需单独安装。
import { OutputFormatFeature } from '@chronoai/toolkit/output-format';
快速开始
1. 注册 Feature
agent.use(OutputFormatFeature, {
priority: 10, // 在 system prompt 中的优先级(可选)
extraRules: ['字段值使用中文'], // 额外约束(可选)
});
2. 其他 Feature 注册输出指导
通过 usePromptFragment 注册字段说明,tag 为 output-guide:
import { usePromptFragment } from 'chronoai';
// 某个「长记忆」Feature 注册它的输出字段要求
usePromptFragment('output-guide.memory', {
tags: ['output-guide'],
priority: 60,
content: '- `<saved_memories>`(可选):需要永久保存的关键信息。标签内输出 JSON 对象数组,每个对象含 `topic`(偏好主题)和 `content`(偏好细节)。',
});
// 另一个「工具调用」Feature 注册它的输出字段要求
usePromptFragment('output-guide.tools', {
tags: ['output-guide'],
priority: 50,
content: '- `<tool_calls>`(可选):需要执行的工具调用列表。标签内输出 JSON 对象数组,每个对象含 `name`(工具名称)和 `arguments`(参数对象)。',
});
3. 其他 Feature 注册输出示例
通过 tag output-example 注册示例片段。
// 「长记忆」Feature 提供的示例字段
usePromptFragment('output-example.memory', {
tags: ['output-example'],
priority: 60,
content: ` <saved_memories>
[
{ "topic": "饮食偏好", "content": "用户对花生过敏" }
]
</saved_memories>`,
});
// 「工具调用」Feature 提供的示例字段
usePromptFragment('output-example.tools', {
tags: ['output-example'],
priority: 50,
content: ` <tool_calls>
[
{
"name": "search_weather",
"arguments": { "city": "北京" }
}
]
</tool_calls>`,
});
跨 Feature 协作模式
OutputFormatFeature 不需要知道哪些 Feature 会注册字段。它只负责:
- 输出指导:将所有
output-guide片段按priority降序聚合后注入system标签 - 输出示例:将所有
output-example片段按priority降序聚合后注入system标签
💡 组装顺序如何决定?(priority 机制) 组装这些文本片段时,会严格按照每个片段设置的
priority数值从大到小(降序)排序:
- 高优先级(如
100):适合放置最核心、需要 LLM 最先看到的全局规范(如“请按以下 XML 标签输出...”)。- 中优先级(如
40~60):存放各个具体业务 Feature 提供的输出字段和样例,按业务本身的重要性决定顺序。- 低优先级(如
0或更低):存放兜底或补充性的严格底线约束,出现在区块最末尾。
不添加任何格式包裹,不感知 JSON / XML 等格式。包裹完全由各 Feature 自行约定。
最终注入 system prompt 的样子
基于上面的注册示例,最终注入到 system prompt 的内容如下(两个区域分别追加):
输出指导区域(output-format/guide):
## 输出格式要求
- `<saved_memories>`(可选):需要永久保存的关键信息。标签内输出 JSON 对象数组,每个对象含 `topic`(偏好主题)和 `content`(偏好细节)。
- `<tool_calls>`(可选):需要执行的工具调用列表。标签内输出 JSON 对象数组,每个对象含 `name`(工具名称)和 `arguments`(参数对象)。
字段值使用中文
输出示例区域(output-format/example):
## 输出示例
<saved_memories>
[
{ "topic": "饮食偏好", "content": "用户对花生过敏" }
]
</saved_memories>
<tool_calls>
[
{
"name": "search_weather",
"arguments": { "city": "北京" }
}
]
</tool_calls>
在提示词模板中手动使用
默认情况下(injectGuide 和 injectExample 均为 true),OutputFormatFeature 会自动将两个区域注入到 system 标签,如果你的提示词模板中已经包含了 system prompt 的聚合,则什么都不需要做。
如果你关闭了自动注入(injectGuide: false / injectExample: false),或者希望在自定义的提示词模板中精确控制这两段文本出现的位置,可以通过时间轴名称直接在模板中引用:
import { defineFeature, usePromptFragment } from 'chronoai';
const MyPromptFeature = defineFeature('my-prompt', () => {
// 将两段内容嵌入自定义的 system 模板的指定位置
usePromptFragment('my-prompt.system', {
tags: ['system'],
priority: 100,
content: `你是一个智能助手。\n\n{{ output-format/guide }}\n\n{{ output-format/example }}`,
});
});
类型导出
| 类型 | 说明 |
|---|---|
OutputFormatConfig | Feature 配置 |
时间轴
外部时间轴
| 名称 | 值类型 | 说明 |
|---|---|---|
output-format/guide | string | 聚合所有 output-guide 片段后的完整格式指导文本 |
output-format/example | string | 聚合所有 output-example 片段后的完整输出示例文本 |
内部时间轴
无。
配置参数
agent.use(OutputFormatFeature, config) 的 config 支持以下参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
priority | number | 否 | 10 | 格式提示词在 system prompt 中的优先级,数值越低越靠后 |
extraRules | string[] | 否 | — | 额外的全局格式约束,追加到指导区域尾部 |
guidePrefix | string | 否 | '## 输出格式要求' | 输出指导区域的前缀标题,注入到 LLM 前 |
examplePrefix | string | 否 | '## 输出示例' | 输出示例区域的前缀标题,注入到 LLM 前 |
injectGuide | boolean | 否 | true | 是否将输出指导自动注入到 system prompt;设为 false 时仅暴露时间轴,不注入 |
injectExample | boolean | 否 | true | 是否将输出示例自动注入到 system prompt;设为 false 时仅暴露时间轴,不注入 |