ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Botpress Zai:基于 TypeScript 与 Zod 的生产级 LLM 工具库实战指南

Botpress Zai:基于 TypeScript 与 Zod 的生产级 LLM 工具库实战指南 AI 应用后端【免费下载链接】botpressThe open-source hub to build deploy GPT/LLM Agents ⚡️项目地址https://gitcode.com/gh_mirrors/bo/botpress点击查看免费下载Zaibotpress/zai是 Botpress 生态中的 LLM 工具库在 bpinternal/zuiZod 风格 schema 库与 Botpress API 之上为提取、校验、改写、排序、评分、总结等高频 AI 操作提供类型安全的一行式 API。本文以 packages/zai/README.md 为骨架结合 packages/zai/src 源码与 packages/zai/e2e 端到端测试完整讲解安装、十大核心操作、主动学习、模型配置、进度追踪与用量监控并剖析分块chunking、重试与容错等底层原理。读完本文你可以在自己的 Agent 或 Botpress Bot 中直接用 Zai 完成结构化信息抽取、内容审核、数据清洗与文档总结等生产级任务。一、Zai 是什么能力概览与设计定位Zai 的定位是一个AI 操作简化层把底层 LLM 调用的 prompt 构造、输出解析、失败重试、token 预算、并行分块等琐碎细节封装起来对外暴露extract、check、label、rewrite、filter、group、rate、sort、text、summarize十类语义化操作。从 packages/zai/src/zai.ts 的类定义可以看到每个操作最终都经由ZaiContext.generateContent见 packages/zai/src/context.ts调用Cognitive.generateText因此 Zai 天然继承了下层认知服务的模型解析、用量元数据与缓存能力。核心特性对应 README 的 Key Features简单 API常见 AI 任务一行完成类型安全基于 Zui/Zod schema 的全链路 TypeScript 支持与运行时校验主动学习Active Learning把成功执行的结果存表作为后续操作的 few-shot 示例随使用不断提升准确率性能内置重试默认最多 3 次见 packages/zai/src/context.ts#L201、自动分块与错误处理无限文档任意长度输入自动分块、并行处理并合并用量追踪实时监控 token、成本与延迟。从 packages/zai/package.json 可确认其运行环境要求Node.js18.0.0包管理器为 pnpm10.29.3核心依赖包括botpress/cognitive1.2.2、json5、jsonrepair、lodash-es与p-limitbpinternal/zui与bpinternal/thicktoken为 peerDependencies。README 声明采用 MIT 协议包元数据中 license 字段记录为 ISC以实际发布为准。二、安装与快速开始安装三个包即可开始npm install botpress/zai botpress/client bpinternal/zui最小可用示例README Quick Startimport { Client } from botpress/client import { Zai } from botpress/zai import { z } from bpinternal/zui // 初始化 const client new Client({ botId: YOUR_BOT_ID, token: YOUR_TOKEN }) const zai new Zai({ client }) // 从文本中抽取结构化数据 const person await zai.extract( John Doe is 30 years old and lives in New York, z.object({ name: z.string(), age: z.number(), location: z.string(), }) ) // 结果: { name: John Doe, age: 30, location: New York } // 内容判定 const isPositive await zai.check(This product is amazing!, expresses positive sentiment) // 结果: true // 文本生成 const story await zai.text(Write a short story about AI, { length: 200 }) // 文档总结 const summary await zai.summarize(longDocument, { length: 500 })注意new Zai({ client })支持传入botpress/client的Client或botpress/cognitive的Cognitive实例——packages/zai/src/zai.ts#L274-L276 中会通过Cognitive.isCognitiveClient自动包装。若只传tokenClient 即可通过 Botpress 云 API 完成认证无需显式提供 botId。三、十大核心操作详解所有操作返回统一的Response对象详见第五节直接await得到简化结果.result()得到完整结果。以下是 README 核心章节的完整展开。1. Extract从文本中抽取结构化数据extract依据 Zui schema 从非结构化文本中抽取对象或对象数组// 抽取单个对象 const product await zai.extract( text, z.object({ name: z.string(), price: z.number(), inStock: z.boolean(), }) ) // 抽取数组 const products await zai.extract(text, z.array(productSchema))源码层面的关键实现packages/zai/src/operations/extract.tsschema 校验z.is.zuiType(_schema)不通过会直接抛错zai.extract only accepts schemas created with bpinternal/zui保证 API 只接受 Zui schema分块策略chunkLength默认16_000token取值范围 100100,000超长输入会被 tokenizer 切块以p-limit限制并发 10 个提取请求随后把各块结果拼接成part-N数据递归合并为最终结果去重、冲突时取最合理且高频的值严格模式strict默认true设为false时所有字段视为可选、忽略缺失字段子分块强制关闭严格模式以免误伤健壮解析模型输出用■json_start■/■json_end■定界符包裹解析时依次经过jsonrepair修复、JSON5.parse宽松解析、safeParse校验见 packages/zai/src/operations/extract.ts#L375-L404解析失败抛出JsonParsingError还支持instructions自定义抽取指引如只抽取已确认的信息。2. Check自然语言布尔判定check判断输入是否满足某个自然语言条件返回布尔值并附带解释const result await zai.check(email, is spam) const { value, explanation } await result.full()注意 README 中result.full()与源码实际方法存在差异完整结果应通过await result.result()获取{ output: { value, explanation }, usage, elapsed }直接await则得到简化布尔值——check的 Response 在构造时通过(result) result.value完成简化packages/zai/src/operations/check.ts#L337-L367。实现要点packages/zai/src/operations/check.ts输入与条件会按比例截断输入占 prompt 预算的 50%、条件占 20%避免超长内容打爆上下文模型被要求先给出Analysis:论证再以■TRUE■/■FALSE■结尾若两者同时出现取最后一次出现的标记为准支持options.examples传入人工示例{ input, check, reason }用于约束判定一致性——非常适合垃圾邮件过滤、情绪分析、业务规则校验等场景。3. Label多标签判定一次调用打多个布尔标签const labels await zai.label(review, { positive: expresses positive sentiment, technical: mentions technical details, verified: from verified purchaser, }) // 结果: { positive: true, technical: false, verified: true }4. Rewrite文本改写支持翻译、语气调整等任意改写指令// 翻译 const french await zai.rewrite(text, translate to French) // 改语气 const formal await zai.rewrite(Hey! Whats up?, make it professional)注意引号转义字符串内嵌撇号时请使用双引号或转义避免语法错误。5. Filter自然语言过滤数组用自然语言条件筛选数组元素const techCompanies await zai.filter(companies, are technology companies) const recentPosts await zai.filter(posts, were published this week)6. Group自动分组group支持三种用法// 自动分组LLM 自行决定分组名 const grouped await zai.group(tasks, { instructions: Group by priority level, }) // 结果: { High Priority: [...], Medium Priority: [...], Low Priority: [...] } // 指定初始分组 const categorized await zai.group(emails, { instructions: Group by topic, initialGroups: [ { id: work, label: Work }, { id: personal, label: Personal }, ], }) // 大数据集按 chunk 处理以提升性能 const organized await zai.group(largeArray, { instructions: Group by date, chunkLength: 8000, })7. Rate1-5 分制评分rate支持单标准与多标准评分底层把分值映射为very_bad(1)/bad(2)/average(3)/good(4)/very_good(5)见 packages/zai/src/operations/rate.ts#L11-L18// 字符串指令自动生成 3-5 个评分标准await 得到各元素总分数组 const scores await zai.rate(products, is it a good value product?) // 结果: [12, 8, 15] // 获取明细含每个标准的细分得分 const { output } await zai.rate(products, is it a good value product?).result() // 结果: [ // { affordability: 4, quality: 5, features: 3, total: 12 }, // { affordability: 3, quality: 2, features: 3, total: 8 }, // ... // ] // 使用固定评分标准对象形式标准名 - 评分说明 const ratings await zai.rate(passwords, { length: password length (12 chars very_good, 8-11 good, 6-7 average, 4-5 bad, 4 very_bad), complexity: character variety (all types very_good, 3 types good, 2 types average, 1 type bad), strength: overall password strength, }) // 结果: [ // { length: 5, complexity: 5, strength: 5, total: 15 }, // { length: 1, complexity: 1, strength: 1, total: 3 }, // ]实现分四阶段packages/zai/src/operations/rate.ts先由 LLM 生成或从对象指令解析评估标准再按tokensPerItem默认 250范围 1100,000与maxItemsPerChunk默认 50范围 1100把数组分块随后以p-limit(10)并行评分各块输出■0:criterionlabel;...■格式并回填缺失项为 average3最后扁平化结果并累加 cost/token 元数据。README 示例注释中给出约 500 条数据、自动分块并行处理约 120ms的量级参考实际耗时取决于模型与网络。8. Sort自然语言排序// 按自然标准排序LLM 自行决定排序标准 const sorted await zai.sort(emails, sort by urgency) // 获取含评分明细的排序结果 const { output } await zai.sort(tasks, sort by priority).result() // 多标准复合排序 const prioritized await zai.sort(tickets, sort by customer importance and issue severity) // 大数据集并行分块排序 const orderedItems await zai.sort(Array(500).fill(item), sort by relevance)9. Text文本生成const blogPost await zai.text(Write about the future of AI, { length: 1000, temperature: 0.7, })10. Summarize任意长度文档总结summarize号称能处理从几段话到整本书的文档根据篇幅自动选择滑动窗口或归并排序策略见 packages/zai/src/operations/summarize.ts// 简单总结 const summary await zai.summarize(article) // 自定义聚焦点与格式 const technicalSummary await zai.summarize(paper, { length: 500, prompt: Focus on technical implementation details, })可选参数及默认值均来自源码的 Zui 校验参数默认值取值范围说明promptNew information, concepts and ideas that are deemed important字符串总结的关注点format多段落、Markdown 分节的纯文本字符串输出格式要求length25010100,000token目标总结长度intermediateFactor4110中间层总结可为目标长度的倍数maxIterations100≥1最大迭代次数sliding.window50_00010100,000滑动窗口大小sliding.overlap2500100,000窗口重叠 token 数四、主动学习让结果越用越准Active Learning 会把每次成功执行的结果存入 Botpress Table之后遇到相似输入时先查表命中即直接复用近似缓存未命中则把历史示例作为 few-shot 上下文交给模型从而提升准确率与一致性。启用方式README 示例const zai new Zai({ client, activeLearning: { enable: true, tableName: ai_learning_data, taskId: sentiment-analysis, }, }) // 指定 taskId 进行学习式判定 const result await zai.learn(sentiment-analysis).check(text, is positive)源码中的约束与机制packages/zai/src/zai.ts#L60-L78tableName必须匹配/^[A-Za-z0-9_/-]{1,100}Table$/默认ActiveLearningTable即必须以Table结尾taskId匹配/^[A-Za-z0-9_/-]{1,100}$/默认default不同 taskId 拥有独立的学习示例集启用后Zai 内部使用TableAdapterpackages/zai/src/adapters/botpress-table.ts表中每条记录包含taskType/taskId/key/instructions/input/output/explanation/metadata及审核字段statuspending|rejected|approved与feedback评分very-bad|bad|good|very-good 评论input列标记为可搜索列便于按输入相似度检索每个操作的实现里都有一致模式用fastHash(JSON.stringify({ taskType, taskId, input, ... }))生成 key → 查getExamples→精确命中直接返回缓存结果token/cost 记 0→ 否则走 LLM → 成功后在未中止时saveExample落库附带 cost/latency/model/tokens 元数据。check、extract、rate的源码均有此链路。此外learn(taskId)返回的是启用了学习的新 Zai 实例可与其他配置链式组合例如zai.with({ modelId: fast }).learn(quick-checks)。五、配置详解模型、命名空间与实例派生模型选择modelId支持三种形态packages/zai/src/zai.ts#L139-L156 校验best | fast | auto或包含:的完整模型 ID// 默认最优模型 const zai new Zai({ client, model: best }) // 快速模型低延迟场景 const fastZai new Zai({ client, model: fast }) // 指定具体模型 const customZai new Zai({ client, model: gpt-4-turbo })同时支持有序回退模型数组modelId: [openai:gpt-4, anthropic:claude-3-5-sonnet-20241022]——认知服务端会按序回退代码注释明确说明cognitive-v2 路径支持服务端回退旧集成路径仅使用第一项。其他配置项ZaiConfigpackages/zai/src/zai.ts#L103-L134还包含userId可选的用户标识会透传到认知请求的meta.metadata.userId用于用量归因namespace任务命名空间默认zai与taskId拼接为${namespace}/${taskId}作为学习任务完整 IDmetadata任意 KV 元数据value 最长 128 字符附加到每次认知调用并在服务端记入用量事件可用于按会话维度拆解成本zai.with({ metadata: { conversationId } })memoizeMemoizer 或其工厂函数用于缓存认知调用结果配合 Botpress ADK 的 workflowstep函数可在流程中断后续跑跳过已完成的认知调用。实例派生with()zai.with(options)返回合并配置的新实例不改动原实例适合按操作切换模型/命名空间/学习任务const fastZai zai.with({ modelId: fast }) const customerZai zai.with({ namespace: customer-support }) const gpt4 zai.with({ modelId: openai:gpt-4 })六、进度追踪与用量监控响应对象的三类能力每个操作返回ResponseT, Spackages/zai/src/response.ts它是 PromiseLike 的事件源直接 await得到简化值如check的布尔值、字符串指令rate的分数数组.result()得到{ output, usage, elapsed }完整结果事件订阅on(progress | complete | error)、once、off支持链式调用。进度追踪const response zai.summarize(veryLongDocument) // 订阅进度事件大文档分块时多次触发 response.on(progress, (progress) { console.log(${progress.percent}% complete) }) const summary await response进度事件由ZaiContext在每次底层请求/响应/错误时触发payload 即Usage对象packages/zai/src/context.ts#L58-L90requests总数、错误数、响应数、缓存命中数、进度百分比 0.01.0、cost输入/输出/总计 USD、tokens输入/输出/总计。用量监控const result await zai.extract(text, schema) const usage await result.usage() console.log({ tokens: usage.totalTokens, cost: usage.totalCost, latency: usage.totalLatency, })与上文同理README 中的result.usage()字段命名在源码中对应usage.tokens.total / usage.cost.total且更完整的做法是const { output, usage, elapsed } await zai.extract(text, schema).result() console.log(usage.tokens.total, usage.cost.total, elapsed) // elapsed 单位 mselapsed从 Response 创建时起算_startedAt Date.now()缓存命中时 cost/token 记为 0。取消操作// 方式一直接中止 const response zai.summarize(document) setTimeout(() response.abort(Timeout), 5000) // 方式二绑定外部 AbortSignal const controller new AbortController() const resp zai.summarize(document, { signal: controller.signal }) // README 写法 // 更标准的源码用法是 bindSignal const resp2 zai.extract(data, schema).bindSignal(controller.signal)源码推荐通过response.bindSignal(signal)绑定外部信号packages/zai/src/response.ts#L246-L261完成后自动解绑abort(reason)会触发ZaiContext.controller的AbortController.abort各操作入口均有ctx.controller.signal.throwIfAborted()检查如 packages/zai/src/operations/extract.ts#L128中止后不会落库学习示例。七、高级用法链式组合const processedData await zai .with({ temperature: 0.3 }) // 注意源码配置项为 modelId 等temperature 通过操作级 options 控制 .learn(data-extraction) .extract(document, complexSchema)with()合并的是ZaiConfig类配置temperature等采样参数属于各操作的options范畴可查看对应操作 Options 定义确认支持项。超长文档处理// 自动分块、并行处理、递归合并100k tokens 亦可 const extractedData await zai.extract( hugeDocument, z.array(recordSchema), { chunkSize: 4000 } // 源码中对应参数名为 chunkLength )参数名注意extract的分块参数在源码中为chunkLength默认 16,000 token使用时以chunkLength为准分块后先并行提取再递归合并合并时取唯一值、冲突取最合理且高频值、保留已定义字段。自定义中止信号const controller new AbortController() const response zai.summarize(document, { signal: controller.signal }) // 需要时取消 setTimeout(() controller.abort(), 5000)八、API 参考速查Zai 类方法说明new Zai(options)创建实例{ client, userId?, modelId?, activeLearning?, namespace?, memoize?, metadata? }.with(config)以合并配置创建新实例不改原实例.learn(taskId)返回启用指定学习任务的新实例taskId 需匹配[A-Za-z0-9_/-]{1,100}操作方法签名简化结果.extract(content, schema, options?)options: { instructions?, chunkLength?(默认16000), strict?(默认true) }符合 schema 的对象/数组.check(content, condition, options?)options: { examples? }boolean.label(content, criteria, options?)多条件标签对象.rewrite(content, instruction, options?)改写指令文本.filter(items, condition, options?)自然语言条件过滤后数组.group(items, options?){ instructions?, initialGroups?, chunkLength? }分组对象.rate(items, instructions, options?)options: { tokensPerItem?(默认250), maxItemsPerChunk?(默认50) }指令为字符串时总分数组.sort(items, instructions, options?)自然语言排序排序后数组.text(prompt, options?){ length?, temperature? }文本.summarize(content, options?){ prompt?, format?, length?(默认250), intermediateFactor?, maxIterations?, sliding? }总结文本Response 方法用法说明await response简化结果await response.result(){ output, usage, elapsed }完整结果response.on(progress\|complete\|error, handler)事件订阅可链式response.once(...)/response.off(...)一次性订阅 / 退订response.bindSignal(signal)绑定外部 AbortSignalresponse.abort(reason?)中止操作九、底层实现要点分块、重试与容错Token 预算PROMPT_INPUT_BUFFER 1048、PROMPT_OUTPUT_BUFFER 512packages/zai/src/operations/constants.ts各操作据此为输入/输出留出缓冲tokenizer 由bpinternal/thicktoken提供并惰性初始化分块与并发extract/rate/summarize 等操作均基于 lodashchunk切块、p-limit(10)限流并行如 packages/zai/src/operations/rate.ts#L538rate 的并行分块在 README 注释中给出约 500 条/120ms 的参考量级重试与自愈generateContent默认最多重试 3 次maxRetries ?? 3解析失败时会把错误信息作为 user 消息回灌给模型要求重新输出packages/zai/src/context.ts#L201-L257输出定界与修复各操作使用■...■特殊标记做输出定界如 extract 的■json_start■/■json_end■、check 的■TRUE■/■FALSE■、rate 的■idx:criterionlabel■配合jsonrepairJSON5.parse ZuisafeParse三道解析防线缓存即学习精确命中的历史示例直接返回、零 token 消耗未命中时历史示例作为 few-shot 注入 prompt每个操作都有Expert Example #N格式实现用得越多、结果越稳。以上实现细节均有端到端测试覆盖仓库 packages/zai/e2e 下包含extract.test.ts、check.test.ts、rate.test.ts、sort.test.ts、summarize.test.ts、group.test.ts、filter.test.ts、label.test.ts、rewrite.test.ts、text.test.ts、zai-learn.test.ts、errors.test.ts等 15 个测试文件可运行pnpm test:e2e见 packages/zai/package.json 的 scripts在本地验证各操作行为。十、总结Zai 把调用 LLM这件高频杂事抽象成类型安全、可观测、可学习的十类操作extract/check/label负责结构化理解rewrite/filter/group/rate/sort负责内容加工text/summarize负责生成与压缩。其工程化亮点在于基于 Zui 的运行时 schema 校验保证输出形状可控自动分块 递归合并打破上下文长度上限重试 JSON 修复提升鲁棒性Response事件流与Usage统计让成本与延迟透明化主动学习则让系统随使用持续进化。若你的 Bot 或 Agent 需要稳定的信息抽取、审核、排序或总结能力Zai 是一个开箱即用的生产级选择。进一步探索完整的 API 文档见 packages/zai/README.md核心类与配置校验见 packages/zai/src/zai.ts各操作实现见 packages/zai/src/operations学习表适配器见 packages/zai/src/adapters/botpress-table.ts行为验证见 packages/zai/e2e。赞分享AI 应用后端【免费下载链接】botpressThe open-source hub to build deploy GPT/LLM Agents ⚡️项目地址https://gitcode.com/gh_mirrors/bo/botpress点击查看免费下载相关推荐react-boilerplate 异步组件加载指南基于 React.lazy 与 Suspense 的代码分割实践react boilerplate 异步组件加载指南基于 React.lazy 与 Suspense 的代码分割实践 本指南以 react boilerplaAI 应用后端Ontology Playground的CORS代理设计github-oauth-proxy的白名单机制Ontology Playground的CORS代理设计github oauth proxy的白名单机制 Ontology Playground 是一款免费在AI 应用后端LLM-as-a-Judge Skills 贡献指南基于 AI SDK 与 Zod 构建生产级 LLM 评估工具的完整开发流程LLM as a Judge Skills 贡献指南基于 AI SDK 与 Zod 构建生产级 LLM 评估工具的完整开发流程 本指南面向希望向 exampl人工智能AI 技能提示工程AI 评测上一篇提示词工程实战指南从随口一说到精准指令的完整方法论基于 easy-vibe 项目教程下一篇Rook StorageClassDeviceSets 详解在 Kubernetes 中用 PVC 定义可移植的 Ceph OSD 存储创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表