
airi 中的 xsAI 标准配方文本生成、工具流式循环、结构化输出与 Embedding 的规范示例【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi本文以 airi 仓库内xsai技能参考文档 recipes.md 为主体完整继承其中全部五个规范示例最小文本生成、带工具的流式文本、带校验的结构化输出、流式结构化输出、Embedding与四条通用编码规则并结合仓库内 telegram-bot、satori-bot、minecraft 等集成模块的真实依赖与导入方式说明这些配方在 airi 各 AI 集成中的落地形态读完即可复制可用的 OpenAI 兼容调用代码并理解其事件模型与选型约束。文档定位何时使用这些配方该文档是.agents/skills/xsai/技能下的参考文件之一其开头明确了触发场景Use this reference when the user wants code, when you are editing xsAI code, or when a prompt needs a canonical minimal example.即当需要产出 xsAI 代码、编辑已有 xsAI 代码、或提示词需要一个标准最小示例时应从本文件的配方出发。配套的 SKILL.md 进一步规定When writing or editing code, readreferences/recipes.mdfirst and start from the closest canonical example——写代码前先读 recipes从最接近的规范示例起步。同目录下的其他参考文档按主题分工例如 text-stream-tools.md 讲generateText/streamText与工具循环structured-output.md 讲generateObject/streamObject与 schema 选型package-selection.md 讲包的选择。通用规则五条必须遵守的约定文档 General rules 一节给出了编写示例代码时的硬性约束这些规则是后文所有代码示例的前置契约优先使用细粒度xsai/*包导入。新示例应写import { generateText } from xsai/generate-text这类形式而不是从伞包xsai导入仅在两种情况下切换到伞包xsai仓库本身已在使用它或用户明确要求单一依赖保持baseURL与model显式写出。xsAI 的调用约定中这两个参数是事实上的必填项SKILL.md 的 Key constraints 一节也重申 baseURLandmodelare usually required in practice for xsAI calls托管提供商要包含apiKeyNode.js 示例优先process.env浏览器示例优先localStorage本地或代理端点仅在目标确实需要时才包含密钥。任何时候都不得硬编码秘密信息保留仓库现有的 schema 库。不要无理由地在 Zod、Valibot、ArkType、Effect 之间来回切换。最小文本生成generateText基准示例文档给出的第一个配方是最小文本生成定位为简单脚本、测试、一次性助手的默认起点Use this as the default starting point for simple scripts, tests, and one-shot helpers。完整代码原样如下import { env } from node:process import { generateText } from xsai/generate-text const { text } await generateText({ apiKey: env.OPENAI_API_KEY!, baseURL: https://api.openai.com/v1/, messages: [ { content: You are a helpful assistant., role: system, }, { content: Write one sentence about the moon., role: user, }, ], model: gpt-4o, })逐行拆解要点import { env } from node:process示例目标是 Node.js因此从node:process取环境变量。文档特别强调These examples usenode:processbecause they target Node.js. For browser examples, prefer reading the API key fromlocalStorageinstead of hardcoding it.——浏览器示例应从localStorage读取密钥而非硬编码请求体四要素apiKey来自env.OPENAI_API_KEY!、baseURLOpenAI 兼容端点https://api.openai.com/v1/、messagessystem user 双消息、modelgpt-4o返回结果按文档说明是单值形式解构出text即可。text-stream-tools.md 补充了generateText的完整结果形状text、finishReason、usage、messages、steps、toolCalls、toolResults、reasoningText。流式文本与工具循环streamTexttool()stopWhen第二个配方演示带工具的流式文本是理解 xsAI 事件模型的关键。文档给出的完整示例import { env } from node:process import { streamText } from xsai/stream-text import { stepCountAtLeast } from xsai/stream-text/shared-chat import { tool } from xsai/tool import * as v from valibot const add await tool({ description: Adds two numbers, execute: ({ a, b }) (Number.parseInt(a) Number.parseInt(b)).toString(), name: add, parameters: v.object({ a: v.pipe(v.string(), v.description(First number)), b: v.pipe(v.string(), v.description(Second number)), }), }) const { fullStream } streamText({ apiKey: env.OPENAI_API_KEY!, baseURL: https://api.openai.com/v1/, messages: [ { content: You are a helpful assistant., role: system, }, { content: What is 12 plus 30? Use the add tool., role: user, }, ], model: gpt-4o, stopWhen: stepCountAtLeast(2), toolChoice: required, tools: [add], }) const text: string[] [] for await (const event of fullStream) { if (event.type text-delta) { text.push(event.text) } if (event.type tool-call || event.type tool-result) { console.log(event) } } console.log(text.join())示例中值得注意的参数与模式工具定义tool()接收name、description、execute纯函数返回字符串结果和parametersValibot schema。execute内将字符串参数parseInt后求和再转回字符串体现了工具入参/出参在传输层是字符串的约定stopWhen: stepCountAtLeast(2)显式的循环停止条件允许最多 2 个工具使用步骤。这是 xsAI 实现轻量 agent 循环的核心机制text-stream-tools.md 说明每个 step 会追加 assistant 输出与工具结果然后视需要再次发起 API 调用并支持and()/or()/not()组合更精细的停止逻辑toolChoice: required强制模型必须调用工具示例中Use the add tool的指令配合该选项保证工具一定会被触发消费fullStream通过for await迭代事件text-delta事件累积正文文本tool-call/tool-result事件用于日志观察。fullStream可能出现的完整事件类型包括text-delta、reasoning-delta、tool-call-streaming-start、tool-call-delta、tool-call、tool-result、finish、error来自 text-stream-tools.md两个流的取舍文档明确给出选择规则——UsetextStreamfor plain live text. UsefullStreamwhen the caller needs tool events, reasoning deltas, or finish metadata. 即纯实时文本用textStream需要工具事件/推理增量/结束元数据时用fullStream。此外streamText()是同步返回的调用方异步消费textStream、fullStream及messages/steps/usage等 promise见 SKILL.md 的 Key constraints。带校验的结构化输出generateObject第三个配方解决不要让模型自由发挥 JSON的问题。文档前置说明Valibot 示例要求项目中安装valibot/to-json-schema如果仓库已使用其他受支持的 schema 库则保持原选择对应通用规则第 5 条。完整示例import { env } from node:process import { generateObject } from xsai/generate-object import * as v from valibot const { object } await generateObject({ apiKey: env.OPENAI_API_KEY!, baseURL: https://api.openai.com/v1/, messages: [ { content: Extract the event information., role: system, }, { content: Alice and Bob are going to a science fair on Friday., role: user, }, ], model: gpt-4o, schema: v.object({ date: v.string(), name: v.string(), participants: v.array(v.string()), }), })要点schema 通过v.object({ date, name, participants })声明为三个必填字段date: string、name: string、participants: string[]返回结果是校验后的object文档给出的结论性建议Prefer this over asking the model for free-form JSON——优先generateObject而不是让模型输出自由 JSON底层原理上generateObject()、streamObject()、tool()都依赖xsschema做 schema 转换不同厂商可能需要额外的 JSON Schema 转换包Zod v3 需要zod-to-json-schemaValibot 需要valibot/to-json-schema见 structured-output.md 与 SKILL.mdgenerateObject还暴露schemaName、schemaDescription、strict以及可选的output: array选项。流式结构化输出streamObject与partialObjectStream第四个配方演示增量解析结构化数据完整示例import { env } from node:process import { streamObject } from xsai/stream-object import * as v from valibot const { partialObjectStream } await streamObject({ apiKey: env.OPENAI_API_KEY!, baseURL: https://api.openai.com/v1/, messages: [ { content: Extract the event information., role: system, }, { content: Alice and Bob are going to a science fair on Friday., role: user, }, ], model: gpt-4o, schema: v.object({ date: v.string(), name: v.string(), participants: v.array(v.string()), }), }) for await (const partialObject of partialObjectStream) { console.log(partialObject) }需要注意的实现细节结合文档与配套参考streamObject是 async 的与streamText同步返回不同streamObject的调用要await原因是schema conversion happens before the text stream starts——schema 转换发生在文本流开始之前structured-output.md 与 SKILL.md 均确认此约束object 模式使用partialObjectStream每次迭代拿到一个部分对象适合 UI 上渐进渲染已解析字段array 模式使用elementStream文档原文为 Use object mode for partial updates andoutput: arraywithelementStreamwhen the caller needs item-by-item results——当调用方需要逐条拿到数组元素时传output: array并消费elementStream。Embeddingsembed与embedMany第五个配方针对向量嵌入以本地 Ollama 兼容端点为例注意该示例不包含apiKey正好演示通用规则中本地端点仅在目标需要时才包含密钥import { embed } from xsai/embed const { embedding, usage } await embed({ baseURL: http://localhost:11434/v1/, input: sunny day at the beach, model: all-minilm, })要点输入为input单条文本modelall-minilmOllama 常见小模型baseURLhttp://localhost:11434/v1/Ollama 的 OpenAI 兼容端口返回解构出embedding向量与usage用量统计批处理使用embedMany文档原文为 UseembedManyfor batch inputs with the same provider and model——同一提供商与模型的多条输入用embedMany完整的 embedding 选项还包括可选的dimensions、apiKey见 media-and-embeddings.md。配方在 airi 仓库中的实际印证以上配方不是孤立示例airi 各 AI 集成模块的 package.json 与源码导入可验证其真实使用形态——均遵循通用规则第 1 条优先细粒度xsai/*包依赖声明apps/stage-tamagotchi/package.json 声明了xsai/generate-text、xsai/stream-text、xsai/tool、xsai/shared-chat、xsai/shared、xsai/model、xsai/generate-speech、xsai/stream-transcription等细粒度包均为catalog:版本同时还有xsai-apple-speech、xsai-transformers、xsai-ext/providers等生态扩展包integrations/telegram-bot/package.json 声明xsai/embed、xsai/generate-text、xsai/tool、xsai/shared-chat、xsai/utils-chatintegrations/satori-bot/package.json 声明xsai/generate-text、xsai/shared-chat、xsai/utils-chat实际导入integrations/telegram-bot/src/llm/actions.ts 中import { generateText } from xsai/generate-text、import type { GenerateTextOptions } from xsai/generate-text、import type { Message as LLMMessage } from xsai/shared-chat与import { message } from xsai/utils-chat与配方一的 API 形状一致GenerateTextOptions即generateText的入参类型integrations/satori-bot/src/core/planner/llm-client.ts 采用完全相同的导入组合integrations/minecraft/src/cognitive/conscious/llm-agent.ts 则导入Message来自xsai/shared-chat与generateText用于 Minecraft 认知模块的 LLM 调用从源码结构看xsai/shared-chat承担messages/Message等跨包共享类型xsai/utils-chat提供message()等构造消息的辅助函数xsai/tool提供配方二中的tool()工具定义能力——这与 recipes 示例的导入面完全对应。配方速查与包选择将五个配方与最小包选型汇总如下包名与用途对照来自 package-selection.md选最小可用包即通用规则第 1 条的操作化表述需求API最小包关键返回/事件一次性文本generateTextxsai/generate-texttext、finishReason、usage、toolCalls等流式文本/工具循环streamTextxsai/stream-texttextStream、fullStreamtext-delta/tool-call/tool-result/finish等事件校验过的对象generateObjectxsai/generate-object校验后的object增量对象解析streamObjectxsai/stream-objectpartialObjectStreamobject 模式/elementStreamoutput: array嵌入向量embed/embedManyxsai/embedembedding、usage补充选择规则需要多特性或单一依赖时用伞包xsai已有 JSON Schema 而不想耦合 schema 库时用rawTool()见 structured-output.md。最后重申边界这些配方全部面向OpenAI 兼容端点OpenAI、Ollama 等xsAI 的定位是额外小的 OpenAI 兼容运行时不承诺非兼容提供商 API 的支持。【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考