aardio 文档

aardio 调用 AI 大模型

一. 基本用法

本节的完整范例源代码

  1. 创建 AI 客户端

    import web.rest.aiChat;
    var aiChat = web.rest.aiChat({
        key = '这里指定 API 密钥';
        url = "这里指定大模型接口地址";
        model = "这里指定模型名称"; //llama.cpp 本地模型可以省略
        temperature = 0.1; //可选指定温度 
        maxTokens = 16384; //可选指定最大回复长度
        protocol = null; //可选指定 API 接口协议类型
        extraParameters = {}; //可选增加的`自定义参数`
    } )
    
  2. 创建聊天消息对列,保存对话上下文。

    var msg = web.rest.aiChat.messages();
    
    //可调用 msg.system() 函数添加系统提示词。
    msg.system("你是桌面智能助手。");
    
    //添加用户提示词
    msg.prompt( "请输入问题:" );
    

    也可以用模拟 AI 的角色添加回复到消息对列

    //模拟 AI 角色
    msg.assistant("请输入问题:" );
    

    这样自问自答的历史消息可以起到小样本学习的作用,让 AI 后面的回复更符合要求,小样本学习的效果有时候会非常好。

  3. 向 AI 服务器发送请求,接收 AI 回复

    var resp,err,errCode = aiChat.messages(msg,
        function(deltaText,reasoning,reserved){
    
            /*
            reasoning 可能为 null 或字符串。
            推理模型会首先通过 reasoning 参数输出推理过程(同样是增量字符串),同时 deltaText 为空字符串 "" 。
            reserved 是保留参数,必须忽略。
            */
            if(reasoning) return;
    
            //回复完成则 deltaText 为 null , 参数为 null 时应保证幂等性(连续调用不重复执行/无副作用)
            console.writeText(deltaText)
    
            //如果需要输入增量输入到目标窗口
            //key.sendString(deltaText)
    
            //显示为屏幕汽泡提示,支持增量文本。
            //winex.tooltip.popupDelta(deltaText) 
        }
    );
    

    调用 ai.messages 就开始对话,如果参数 @2 指定了 SSE 流式回调函数,就自动切换到 SSE 流式调用( 打字效果, 逐步渐进式回复增量文本 ),服务器每次发送增量文本都会传入 deltaText 参数,当 AI 回复结束时 deltaText 为 null 。

    aiChat.messages 有两种不同的用法,返回值也有所不同:

    如果只需要非流式回复的正文,可以调用 ai.getText(msg)。此函数内部仍调用 messages(msg),但能够自动兼容所有支持的协议,并直接提取与返回可见正文:

    var text,err,errCode = ai.getText(msg);
    if(text !== null) print(text);
    

    如果请求失败则返回值 respnullfalse 等非真值,而返回值 err 包含可能的错误字符串。web.rest.aiChat 继承自 web.rest.client,所以也可以用 aiChat.lastResponseError() 获取错误对象(解析 JSON 格式错误信息得到的对象),用 aiChat.lastResponseString() 获取服务器的原始错误信息(字符串对象),或者用 aiChat.lastStatusCode 获取 HTTP 响应状态码。更多用法请参考 使用 web.rest 客户端

本节的完整范例源代码

推理强度 #

主流大模型可选的推理强度如下:

具备深度推理能力的现代大模型通常都可以指定推理强度,但并非所有模型都支持以上全部设置值。个别模型会将一些推理强度映射到其他强度,也有一些模型仅支持思考开关而但不能自定义推理强度。一些第三方平台会自动转换这个参数以兼容不同模型,web.rest.aiChat 也会进行兼容性转换(并不保证支持所有模型)。

在调用 AI 接口的 aardio 代码中指定推理强度

import web.rest.aiChat;
var aiChat = web.rest.aiChat({
    key = '这里指定 API 密钥';
    url = "这里指定大模型接口地址";
    model = "openai/gpt-5.6-sol"; 
    reasoning = {
        effort = "high"
    }
} )

web.rest.aiChat 会根据当前选择的接口协议自动转换参数。对于 OpenAI 接口, reasoning.effort 会被转换为转换为请求参数中的 reasoning_effort

个别模型可选指定 reasoning.maxTokens 以限制推理消耗的最大 tokens 。 但这种明确限制最大 token 数量的方式已逐渐被淘汰,现代模型已不建议使用。

个别模型使用 thinking 字段设置思考选项,aardio 接受此参数但不会做任何转换,并将其直接发送给服务器。

在 AI 设置界面指定推理强度

aardio 编写的程序(例如 aardio autos)通常使用标准库 web.rest.aiChat.settingForm 创建 AI 接口设置接面。这个设置界面的 推理强度 选项会被转换为上述的 reasoning.effort 的字段。

设置推理强度

在 AI 设置界面的 API 配置右键菜单项点复制分享链接可获得 ai+ 格式链接。在 aardio 代码编辑器右键菜单点击 粘贴与更正 可识别 ai+ 链接并自动生成调用 API 接口的示例代码。

medium 这个名词错误地暗示了它适合大多数任务,但这通常是一个误解。
对于 AA(aardio autos) 这类支持交错思考的智能体(Agent),推理强度至少要设为 high 或者更大的 xhighmax

也可以通过 AI 设置对话框的 自定义参数 用 JSON 指定推理强度,例如 DeepSeek Pro 4 可以将 自定义参数 指定为:{"reasoning_effort":"high","thinking":{"type":"enabled"}}。这相当于在代码中修改 web.rest.aiChat 的 extraParameters 参数,aardio 会将自定义参数直接发送给服务端(不会进行任何转换)。要使自定义 JSON 里的 reasoning_effort 生效,则必须将它上面的推理强度选项设为auto (也就是忽略这个选项)。

选择合适的推理强度

如何选择:

  1. 难度较高在相对聚焦的攻艰任务,建议设为最大推理强度 maxxhigh
  2. 难度一般但相对发散的常规任务,推理强度建议设为 high
  3. 简单并且需要快速响应的任务,可以选择更低的推理强度。中低强度通常并不适合智能体工具。

根据 AI 的表现调整推理强度:

  1. 如果 AI 思考时草率粗心或者偷工减料,可尝试调高推理强度。
  2. 如果 AI 原地磨洋工、拖拖拉拉,执行速度太慢;或者跑偏方向过度设计,抓不住重点(顾此失彼),在一些无意义的地方反复挖坑填坑;甚至因为思维链太长而不堪重负长时间卡住不动。这时候就很有可能是推理强度太高,可以调低试试。

一句话总结就是:强度越小越擅长做减法(更),强度越大越擅长做加法(更努力)。高强度推理消耗的 tokens 也会更多。

我们应当根据 AI 的表现与具体任务选择与调整合适的推理强度,具体情况具体对待。

使用最大推理强度时可以适度关注 AI 输出的思考内容,避免 AI 跑偏与过度设计。例如在 AA(aardio autos) 里可以停止思考过程,然后输入临时纠偏的用户提示词(仅注入交错思考),再点击继续,这种人机合作的模式通常会带来非常好的效果。

三. 兼容接口

1. OpenAI 兼容接口。

web.rest.aiChat 默认使用 OpenAI 兼容接口。 基本上大部分大模型都使用 OpenAI 兼容接口,例如 DeepSeek 。

调用 OpenAI 流式接口示例:

import console.int; 
console.showLoading(" Thinking "); 

//1. 创建 AI 客户端
//---------------------------------------------------------------------
import web.rest.aiChat;
var aiChat = web.rest.aiChat(
    key =   'YOUR_API_KEY';
    url = "https://api.deepseek.com/v1";
    model = "deepseek-v4-pro";
    temperature = 1;
    reasoning = {effort: "high"}; // "none" 关闭思考
    //maxTokens = 16384;
)

//2. 创建消息队列
//---------------------------------------------------------------------
var msg = web.rest.aiChat.messages();
msg.prompt( "请介绍你自己" );

//3. 第三步:发送请求。
var resp,err = aiChat.messages(msg,
    function(deltaText,reasoning){

        if(reasoning) {
            return console.writeColorText(reasoning,0xA);
        }

        //回复完成则 为 null 。
        console.writeText(deltaText) 
    }
);

console.error(err);

OpenAI GPT 5.6 服务端联网搜索工具 #

OpenAI GPT 5.6 提供了一些服务端工具,以调用搜索工具为例:

OpenAI 缓存透传 #

OpenAI 支持自动前缀缓存,通常不需要额外设置参数。

但是,通过中转服务商请求 OpenAI 接口可能出现缓存功能失效,这是因为中转服务商可能轮换了不同的 key 发送请求。这会导致费用大幅增加。

解决方法是在自定义参数中显式指定 prompt_cache_key 字段。

示例:

var aiChat = web.rest.aiChat(
    key =  'API_KEY';
    url = "https://openrouter.ai/api/v1";
    model = "openai/gpt-5.6-terra";
    temperature = 1;
    reasoning = {effort = "high"};
    extraParameters  = {
        prompt_cache_key = "your_unique_session_id_12345"; 
    };
)

注意如果多用户共享相同的 prompt_cache_key 会被路由到固定的 GPU 机器,如果同一缓存键并发请求过多(通常超 15次/分钟),系统会触发溢出路由,从而降低缓存效果。因此应当避免多用户使用相同的 prompt_cache_key。

对于中转服务商,可以考虑对 API key 加盐然后计算 sha256 哈希作为 prompt_cache_key,例如: prompt_cache_key = crypt.sha256( config.key ++ io._exepath )

GPT5.5 的提示缓存(Prompt Caching)是完全免费写入的,便 GPT 5.6 写缓存会收费。总的来说指定 prompt_cache_key 通常都会大幅降低成本。

注意 GPT5.6 已经废弃 prompt_cache_retention ,缓存时间建议保值默认即可。

OpenAI Responses API #

将构造参数 protocol 指定为 "responses" 即可使用 Responses API:

import web.rest.aiChat;
var ai = web.rest.aiChat(
    key = 'YOUR_API_KEY';
    url = "https://api.openai.com/v1";
    model = "gpt-5";
    protocol = "responses";
    reasoning = {effort = "high"};
)

var msg = web.rest.aiChat.messages();
msg.system("你是桌面智能助手。");
msg.prompt("请介绍你自己");

var result,err = ai.messages(msg);
if(result) print(result.output_text);

Responses 分支支持普通 HTTP 请求与 HTTP SSE,不实现 WebSocket / Realtime API。每个请求固定发送 store=false,不使用 previous_response_id,而是完整重放本地消息。

在单次连续工具调用链中,服务端返回的原生 reasoning、function_call 以及本地生成的 function_call_output 会临时保留在调用方传入的工作消息副本中,以支持无状态续接和中止后继续。工具链正常结束后,界面或持久历史只应保存标准 user/assistant 可见消息;不要把这份临时原生链写入普通会话存档。

当配置了本地工具时,客户端会请求 reasoning.encrypted_content 并原样回放服务端返回的原生 output Items。工具回传请求仍会重新收集当前 system/developer 消息作为顶层 instructions,因此动态增加的系统提示词可在下一次请求生效。

2. Vertex / Gemini 接口

支持 OpenAI 兼容接口:

也可以支持 Google 自家的协议接口:

Vertex 密钥设置: #

使用 Vertex 接口时 web.rest.aiChat 构造参数表中的 key 字段需要指定 GCP 密钥数据。

打开「 Vertex AI 控制台 » 主菜单 » IAM 和管理 » 服务账号」 创建并下载 JSON 格式密钥 。

GCP 密钥数据应当是一个表对象或者 JSON 格式字符串( 密钥的第一个字符必须是 { )。

GCP 密钥数据主要字段说明:

如果 key 指定 GCP 密钥数据则 web.rest.aiChat 会自动获取 GCP 访问令牌,并且默认会跨线程缓存访问令牌以避免重复获取令牌。也可以自行调用标准库 web.rest.gcp.jwtBearerToken 提前获取访问令牌。

自定义思考配置:

示例:

import web.rest.aiChat;
var aiChat = web.rest.aiChat(
    key =   "密钥";
    url = "https://generativelanguage.googleapis.com/v1beta/";
    model = "gemini-3-flash-preview";
    reasoning = {effort = "high"};
)

如果 reasoning.exclude 不为 true 则输出思考过程。

Gemini 2.5 可使用 reasoning.maxTokens 设置推理时允许消耗的 tokens 上限,设 为 0 则关闭思考,设为 -1 则按需动态设置。 Gemini 3.x 则应使用 reasoning.effort 替代 reasoning.maxTokens 。

示例:

例如用 aardio 向 AI Studio 接口 https//:generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=YOUR_API_KEY 发送请求的代码如下:

import web.rest.aiChat;

// 1. 创建 AI 客户端。
var aiChat = web.rest.aiChat(
    key = "YOUR_API_KEY"; 
    url = "https://generativelanguage.googleapis.com/v1beta"; 
    model = "gemini-3.5-flash"; 
    //proxy = "socks=127.0.0.1:1081"; //代理服务器 
    //protocol = "google"; //generativelanguage.googleapis.com/v1beta 默认使用 Google 协议
);

// 2. 创建消息队列
var msg = web.rest.aiChat.messages();
msg.prompt("你好,请用中文介绍一下你自己。");

// 3. 发送请求,如果没有提供第二个回调函数参数,则会禁用流式回复并等待服务器返回完整结果
var resp, err = aiChat.messages(msg); 
print(resp.candidates[1].content.parts[1].text); //Google 协议返回的数据结构与 OpenAI 不同

Gemini 3.x 系列模型的 temperature 只能设为 1,不建议改动

3. Anthropic 接口

import web.rest.aiChat;
var aiChat = web.rest.aiChat(    
    key = '密钥';
    url = "https://api.anthropic.com/v1";
    model = "claude-opus-4-8";
    protocol = "anthropic";//指定使用 Anthropic 接口协议,也就是 Claude 大模型官网接口
    reasoning = { // 不指定 reasoning 则使用默认值
        effort = "max"; //设为 "none" 关闭思考
        // exclude = true; //不显示思考过程
    }
)

如果接口网址包含 anthropic 也会自动切换为 Anthropic 协议(可以省略 protocol 字段)。

reasoning.exclude 默认值为 false , 即使 Claude Opus 4.7+ 也一样。

Anthropic 官方接口可在 自定义参数 中添加 {"cache_control":{ "type":"ephemeral"}} 以开启全局自动缓存。需要注意 Anthropic 官方接口写入缓存是收费的,缓存机制也有点坑。尤其是第三方中转站通常无法正常支持缓存,添加 {"cache_control":{ "type":"ephemeral"}} 不但不能节省费用,反而会被反薅致费用爆增。相比起来,OpenAI 或者 DeepSeek 这些就要厚道得多,写入缓存完全免费,缓存折扣也也可显著减少费用。而且 OpenAI 还支持使用 prompt_cache_key 实现第三方中转站的缓存透传,可以大幅降低成本(这里指的是 OpenAI 官方的 GPT 系列,仅仅是实现了 OpenAI 协议的第三方模型可能会使用不同的缓存规则,有些可能并不支持缓存 )。

4. Ollama 接口

Ollama 本地模型在 aardio 或 ImTip 中的接口地址写以下任何一个都可以:

http://localhost:11434
http://localhost:11434/v1/
http://localhost:11434/api/

Ollama 只要填网址和模型名称,key不需要指定。

请参考: 自动部署本地 Ollama 模型

5. OpenRouter 接口

OpenRouter 使用的是 OpenAI 接口,所以不需要指定 protocol。

OpenRouter 的思考模型可通过 reasoning 字段指定推理参数,示例:

var aiChat = web.rest.aiChat({
    key = "api-key";
    url = "https://openrouter.ai/api/v1";
    model ="deepseek/deepseek-v4-pro";
    temperature = 1;
    reasoning = { 
        effort: "high"
        //exclude = true;
    }
})

如果指定了 exclude = true 则不会回显思考过程,一些模型通过 reasoning.effort 指定推理强度(例如 grok-code-fast-1 ), 一些模型则可以通过 reasoning.maxTokens 控制推理强度。

6. 七牛云 AI 大模型推理接口

示例:

var aiChat = web.rest.aiChat(
    key = '密钥';
    url = "https://api.qnaigc.com/v1"; 
    model = "z-ai/glm-5";
    temperature = 0.5;
    thinking = { type = "disabled" } 
    //protocol = "anthropic" //可选切换为 anthropic 协议
)

七牛云的接口有多个:

bypass 接口通常更稳定,避免了不必要且可能带来兼容性问题的协议转换过程。默认 aardio 会自动识别接口网址中的 anthropicvertex 关键词并转换为合适的协议(也可以使用参数中的 protocol 字段显式指定接口协议)。

七牛云接口部分模型支持用 reasoning.effort 或 thinking.type , thinking.budget_tokens 自定义思考模型或强度。或者直接用 extraParameters.thinkingextraParameters.reasoning_effort 指定附加参数也可以。

7. 智谱接口

示例:

var aiChat = web.rest.aiChat( {
    key = "密钥";
    url = "https://open.bigmodel.cn/api/paas/v4";
    model = "glm-5.1";
    temperature = 0.5;
    thinking = { type = "disabled" } 
})  

参数指定 thinking = { type = "disabled" } 关闭思考。
如果不指定 thinking 字段则默认开启思考(或指定为 thinking = { type = "enabled" } 显式启用思考)。

智谱 GLM 在思考模式下并未锁定或限制 temperature 参数, 但在测试中发现 GLM 5.1 的 temperature 参数不能设置得太小,例如设为 0.1 能力会显著退化

8. 魔搭接口

魔搭使用 OpenAI 接口,示例:

aiChat = web.rest.aiChat(    
    key =  "密钥";
    url = "https://api-inference.modelscope.cn/v1";
    model = "deepseek-ai/DeepSeek-V4-Pro";
    temperature = 1;
    extraParameters = {
        enable_thinking = true;
    };
)   

使用 extraParameters.enable_thinking 开始思考模式。

9. 火山平台大模型与智能体接口

火山方舟平台大模型(豆包、DeeepSeek 等)的接口以及智能体接口都兼容 OpenAI 接口。火山智能体的的接口地址为 https://ark.cn-beijing.volces.com/api/v3/bots,大模型接口地址为 https://ark.cn-beijing.volces.com/api/v3, 模型 ID 参数可以填模型 ID 也可以填智能体应用的 ID。 示例:

import web.rest.aiChat;
var aiChat = web.rest.aiChat(    
    key = '密钥';
    url = "https://ark.cn-beijing.volces.com/api/v3/bots"; //如不是智能体就去掉 "bots"
    model = "bot-20250115093718-r9gcj"; //模型或智能体 ID
    temperature = 0.1; //温度 
)

10. 阿里云 AI 模型与智能体接口

使用 web.rest.aiChat 可以兼容阿里通义千问的大模型接口以及智能体接口。

调用阿里大模型与智能体,API 接口网址只要写 https://dashscope.aliyuncs.com 就可以,然后 model 参数写模型 ID 或者智能体应用 ID。当然你也可以直接写阿里提供的接口网址。

import web.rest.aiChat;
var aiChat = web.rest.aiChat(   
    key = '密钥';
    url = "https://dashscope.aliyuncs.com";
    model = "qwen-coder-plus"; //这里写模型 ID 或者智能体应用 ID,aardio 会自动兼容
    temperature = 0.1;
    maxTokens = 4096,
)

四. AI 调用本地函数( Function calling ) #

1. 交错思考(Interleaved Thinking) #

所谓交错思考指的是大模型在开启思考模式以后,一边思考(推理)一边调用工具,在一次用户对话中思考与调用工具可以交错执行多次。 实际上在一次用户对话过程中可能会向服务器自动回传多次请求。

需要明确几个概念:

  1. 一轮用户对话:指用户向 AI 服务端发送用户提示词并发起对话请求,直到 AI 结束本轮对话。
  2. 交错思考+工具调用:这是指在一轮对话内 AI 连续地、交错地执行思考并发起工具调用,Agent 容器执行工具并返回结果(由智能体容器自动向服务端发起请求并回传工具调用结果)。
  3. 多轮对话:指在请求中包含之前的对话记录,在相同的上下文内进行连续的多轮对话。在 AI 设置中的最大 上下文轮数 指的就是上下文可以容纳的最大对话次数(这通常是一个近似值,因为执行环境可能会为一些自动插入的上下文预留位置)

在交错思考的过程中自动发起多次请求时需要回传思考内容(推理过程),而在一轮用户对话(包含交错思考与工具调用自动发起的多次请求)结束后,通常应当丢弃这些思考内容(推理过程)。在多轮对话的上下文中仅保留 AI 回复的正文(不应包含推理过程),即使用户继续对话,上一次的思考过程也应当被丢弃(否则上下文会迅速膨胀,多轮对话难以正常继续下去)。

交错思考的实现并没有统一的标准,各家的实现都不一样,web.rest.aiChat 则尽可能地兼容了不同的实现。

一些模型旧版本的交错思考功能并不完善,尽量使用它们的最新版本以避坑

最佳实践是:对于使用 web.form.chat 等 AI 对话前端界面,建议由界面线程的 web.form.chat 保存对话记录。 而在工作线程中单独创建新的 web.rest.aiChat 发送对话请求。对于支持交错思考的接口,web.rest.aiChat 会自行维护对话记录,并在对话记录中保存推理过程(思考过程)。因为 aardio 的线程隔离特性,这些推理过程并不会被自动添加到界面线程(例好 web.form.chat 对象的 chatMessages 属性),在工作线程中我们可以手动调用 web.form.chat 的 assistant 方法存储一些必要的工具调用结果到界面线程。在一轮用户对话结束后退出工作线程,这些思考过程将被自然丢弃。

完整的实现请参考 Autos 源码 。Autos 的工具实际是由标准库 autos.tools.handlers(工具实现),autos.tools.schemas(工具定义) 提供。而 autos.tools.handlers 中几个关键的代码编辑工具则基于标准库 string.patch, string.editor 。

2. AI 用工具(本地函数)的步骤

注意不是所有大模型接口都支持 function calling 。如果服务端报错缺少 content 字段,这通常是因为接口不支持 function calling,只能处理包含 content 的普通消息。

首先在创建 AI 客户端时,在参数中使用 tools 字段指定允许被 AI 调用(function calling)的本地函数。
tools 应当指定一个数组,数组的每个成员指定一个函数定义,细节可参考调用的大模型相关文档。

示例:

var aiChat = web.rest.aiChat(
    key = "密钥";
    url = "https://api.*****.net/v1";//接口地址
    model = "模型名称"; 
    temperature = 1; 
    tools = { //关键在于增加 tools 字段声明可以调用的本地函数,细节请参考 API 文档。
        {
            "type": "function",
            "function": {
                "name": "getWeather",
                "description": "获取给定地点的天气",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "地点的位置信息,比如北京"
                        },
                        "unit": {
                            "type": "string",
                            "enum": {
                                "摄氏度",
                                "华氏度"
                            }
                        }
                    },
                    "required": {
                        "location"
                    }
                }
            }
        }
    }
)

然后我们需要在 aiChat.external 表里定义允许 AI 调用的同名函数,与前面的 tools 里声明的函数名称与原型说明要匹配。

示例:

//导出允许 AI 调用的函数
aiChat.external = {
    getWeather = function(args){ 

        //如果重复调用相同的函数,是因为模型实际并不支持 function calling
        console.log("正在调用函数,参数:",args.location,args.unit)

        //尽量用自然语言描述清楚
        return  args.location + "天气晴,24~30 度,以自然语言回复不要输出 JSON"
    } 
}

然后创建对话消息队列,示例如下:

//单独 创建 AI 会话消息队列以保存聊天上下文。
var chatMsg = web.rest.aiChat.messages();

//添加用户提示词
chatMsg.prompt("杭州天气如何?" );

最后发送请求启动对话:

console.showLoading(" Thinking "); 

//调用聊天接口。
var ok,err = ai.messages(chatMsg,console.writeText);

完整版范例源码

五. AI 续写与补全应用

如果需要更好的效果,则建议在 AI 提示词中添加更多的信息,例如让 AI 知道目标进程的文件名,并要求 AI 根据不同的程序给出更合适的解答,完整示例请参考: 范例 - 超级热键调用 AI 大模型自动续写补全

aardio 基于上面的范例已经内置了 F1 键 AI 助手,运行效果:

F1 键助手

利用 F1 键还可以在 aardio 中调用 AI 写其他编程语言的代码,例如写 Python 代码:

F1 键助手写 Python 代码

在调用 AI 续写补全时,清晰的提示很重要。例如上面我们简明扼要地通过变量命名与注释让 AI 明确 pyCode 里放的是 Python 代码。在编码补全时,在清晰的注释提示后面补全有更好的效果。 注意用法,那么在 aardio 环境中调用 AI 写前端代码、Python 代码、 Go 语言的代码的效果会很好,利用 AI 可以更好地利用 aardio 在混合语言编程上的优势。

六. AI 搜索 #

如果是用于 aardio 编程的 AI 助手推荐使用 aardio 提供的 VIP 专属接口,aardio 提供了专业版知识库,匹配速度更快,也更加智能与准确。

调用大模型服务端内置的搜索工具

请参考 GPT 5.6 服务端联网搜索工具

调用 Tavily 搜索接口 #

Tavily 搜索质量不错,而且只要注册账号就可以获取每月搜索 1000 次的免费额度,一般够用(响应比 Exa 慢)。

示例:


//导入 Tavily 搜索接口
import web.rest.jsonClient;
var http = web.rest.jsonClient();
http.setAuthToken("接口密钥");
var tavily = http.api("https://api.tavily.com");

//搜索,不建议指定 include_raw_content 参数( 返回的 raw_content 可能有乱码 ).
var resp = tavily.search(
    query = "aardio 如何读写 JSON",
    max_results = 3, //限制返回结果数,默认值为 5。
    //topic = "news", //限定返回最新数据
    //time_range = "month", //搜索最近一个月发布或更新的内容
    include_domains = ["www.aardio.com"] //可选用这个字段限定搜索的域名数组
)

//创建对话消息队列
import web.rest.aiChat; 
var msg = web.rest.aiChat.messages();

//将搜索结果添加到系统提示词
msg.url(resp[["results"]])

//添加用户提示词
msg.prompt( "DeepSeek 有哪些成就" );

请参考tavily 文档

调用 Exa 搜索接口 #

一般需要根据用户的最后一个提示词进行搜索,并将搜索结果添加到最后一个用户提示词之前。

//导入 Exa 搜索接口
import web.rest.jsonClient; 
var exaClient = web.rest.jsonClient(); 
exaClient.setHeaders({ "x-api-key":"接口密钥"} )
var exa = exaClient.api("https://api.exa.ai/");

//搜索
var searchData,err = exa.search({
    query:"DeepSeek 有哪些成就", 
    contents={text= true}
    numResults:2,
    includeDomains:{"www.aardio.com"},//可以在指定网站内搜索
    type:"keyword" //一般 keyword 搜索就够了(价格低一些)
})

//创建对话消息队列
import web.rest.aiChat; 
var msg = web.rest.aiChat.messages();

//将搜索结果添加到系统提示词
msg.url(searchData[["results"]])

//添加用户提示词
msg.prompt( "DeepSeek 有哪些成就" );

exa.ai 的搜索质量不错。

调用博查搜索接口 #

import web.rest.aiChat;
var msg = web.rest.aiChat.messages();

var bochaClient = web.rest.jsonClient(); 
bochaClient.setAuthToken("接口密钥");

//导入博查搜索接口
var bocha = bochaClient.api("https://api.bochaai.com/v1/{method}-search");

//搜索
var searchData,err = bocha.web({ 
    "query": "DeepSeek 最近有哪些新闻事件",
    "freshness": "noLimit",
    "answer": false,
    "stream": false,
    "count": 2; 
})

//添加到系统提示词
msg.url(searchData[["data"]][["webPages"]][["value"]])

msg.prompt( "DeepSeek 最近有哪些新闻事件" );

七. 在 HTTP 服务端开发 AI 中转接口

HTTP 服务端关键代码如下:

var apiKey = request.headers["authorization"]
if(apiKey) apiKey = string.match(authorization,"\S+\s+(\S+)");

if(!apiKey){
    response.errorStatus(401);
    return;
}

// ...... 其他代码省略

import web.rest.aiChat;

// 获取客户端请求的参数
var requestData = request.postJson()

var aiChat = web.rest.aiChat(    
    key =  'API_KEY'; //上游接口的 APK key
    url = "https://generativelanguage.googleapis.com/v1beta";
    model =  "gemini-3.5-flash";
    temperature = requestData.temperature;
    maxTokens = requestData.max_tokens; 
    tools = requestData.tools;
    reasoning = {
        effort = "high";
        maxTokens = -1;
    }
    protocol = "google";
)

var resp,err = aiChat.messages(requestData.messages,
function(deltaText,reasoning){ 

    if(!(deltaText || #reasoning) ){ 
        response.eventStream({data = {"DONE"}});
        return; 
    }   

    response.eventStream({
        data = {
            choices = {{
                delta = {
                    content = deltaText;
                    reasoning_content = reasoning;
                }
            }}
        }
    });  
});

if(err){
    response.error(err)
}

Markdown 格式