Codex 通过中转使用 GPT-5.6 时 Web Search 失败的解决办法

随着GPT-5.6 的发布,Codex 也为其进行了特殊的修改。

使用中转/反代在 Codex 中调用 GPT-5.6 时,如果 Web Search 调用失败,常见原因并不在 Codex 本身,而是中转服务尚未适配新版搜索接口。

GPT-5.6 在 Codex 中会使用新的逻辑,也就是 responses lite 分支。该分支本地不再提供 Web Search 工具,搜索能力依赖服务端实现的新接口。因此,即使模型能正常对话,如果中转站没有支持对应的 Search API,Web Search 仍然会失败。

目前,CPA、sub2api 等部分中转工具已经支持该接口,但仍有一些中转站尚未适配。另外,即使接口已存在,在部分中转实现中也需要将模型的 provider 设置为 openaiOpenAI,才能正确启用 Web Search。

Linux.do(下文简称 L 站)已经有相关讨论,见:
https://linux.do/t/topic/2565293

因此可以根据中转站的支持情况选择两种处理方式:

  1. 中转站已支持新版 Search API:将模型的 provider 设置为 openaiOpenAI,然后重新测试 Web Search。
  2. 中转站尚未支持新版 Search API:关闭 responses lite,让 Codex 回退到旧的请求逻辑。

需要注意的是,部分中转站可能会将新版 Search API 按调用次数单独计费。选择方式一前,建议先查看中转站的计费说明和请求日志,确认实际调用量与费用。

下面介绍第二种做法。

先复制一份 Codex 官方的 models.json 到本地:

https://github.com/openai/codex/blob/main/codex-rs/models-manager/models.json

然后找到对应模型的配置,例如:

1
2
3
"slug": "gpt-5.6-sol",
... ...
"use_responses_lite": true,

use_responses_lite 改为 false

1
"use_responses_lite": false,

接着在 config.toml 中配置本地模型配置文件的路径:

1
model_catalog_json = "path\models.json"

path\models.json 替换为实际文件路径,让 Codex 读取这份本地配置。这样 Codex 会走旧的逻辑分支,适合中转站尚未支持新版 Search API 的情况。

修改前建议先备份配置;后续升级 Codex 或更新模型配置后,也建议重新确认该设置是否仍然生效。

上述回退方法同样来自 L 站的讨论:
https://linux.do/t/topic/2563511/5

L 站确实卧虎藏龙。

Astro v6 Node Adapter后端的环境变量设置(v5 到 v6 的一个 breaking change)

这其实是Astro v6的一个改动,Changed: import.meta.env values are always inlined

In Astro 5.13, the experimental.staticImportMetaEnv flag was introduced to update the behavior when accessing import.meta.env directly to align with Vite’s handling of environment variables and ensures that import.meta.env values are always inlined.

In Astro 5.x, non-public environment variables were replaced by a reference to process.env. Additionally, Astro could also convert the value type of your environment variables used through import.meta.env, which could prevent access to some values such as the strings “true” (which was converted to a boolean value), and “1” (which was converted to a number).

Astro 6 removes this experimental flag and makes this the new default behavior in Astro: import.meta.env values are always inlined and never coerced.

所以下面这篇文章讨论的前提,都是Astro v6。

Astro官方文档里有关于环境变量的章节,Using environment variables,里面有个例子:

1
2
3
4
5
// When import.meta.env.SSR === true
const data = await db(import.meta.env.DB_PASSWORD);

// When import.meta.env.SSR === false
const data = fetch(`${import.meta.env.PUBLIC_POKEAPI}/pokemon/squirtle`);

它主要使用Vite的环境变量,Env Variables and Modes,但这里其实就有个坑点,那就是这种方式的值会在build的时候被替换成实际的值,而不是在运行时动态获取,这意味着:

  • 在build的时候就需要提供这个环境变量,不然无法替换;
  • 在运行时无法改变这个变量,因为他已经被写入了构造物里。

假设你在代码里写了:

1
const db = drizzle(import.meta.env.DATABASE_URL);

那么在build时提供了系统环境变量或者.env的时候,且值是 mysql://user:password@localhost:3306/db,它最终的dist会变成(也就是直接inline替换了):

1
const db = drizzle("mysql://user:password@localhost:3306/db");

Read More

谷歌GenAI Java SDK tts示例 (gemini-3.1-flash-tts-preview)

谷歌官方文档是: https://ai.google.dev/gemini-api/docs/speech-generation

但是很尴尬,他没有java sdk的示例,而且java sdk的example里也没有对应的例子,https://github.com/googleapis/java-genai/tree/main/examples.
这两个和文档不一致examples/src/main/java/com/google/genai/examples/InteractionMultimodalResponseAudio.java, examples/src/main/java/com/google/genai/examples/InteractionMultimodalResponseAudioWithGenerateContent.java.

但其实只需要用他统一的generateContent方法就可以了.

调用方式其实和文档里的python一样,只要知道对应的类即可.

Read More

Vercel AI SDK 的工具审批(Approval)流程详解

概述

在 AI 应用中,当 AI 助手需要调用本地文件系统或其他敏感工具时,出于安全考虑,需要在执行前获得用户的明确批准。Vercel AI SDK(文中使用 v6 版本,这狗东西 API 一直变来变去的)提供了工具审批(Tool Approval)机制,允许开发者在 AI 执行工具前拦截并请求用户确认。

注意这个参数主要是为了配合stopWhen(也就是工具自动调用),也就是:

1
2
3
4
5
6
const result = streamText({
model: newapi.chat(config.model.model),
messages,
tools,
stopWhen: stepCountIs(5), // 这里 自动工具调用
});

同时也注意这东西的调用方式灵活的很,毕竟他不是应用级别的封装,不用这套自己也可以搓一个出来。

同时在 AI SDK UI 中的调用流程是完全不一样的,这里只针对 Core 的 API。(但是其实也八九不离十了)

Read More

Astro 项目集成 Better Auth 指南(使用drizzle+PG)

本文档说明如何在 Astro 项目中集成 Better Auth,使用 Drizzle 作为数据库适配器,PostgreSQL 作为数据库。

emmmm,文档是在实践完之后写的,不是边实践边写的,可能会有所遗漏,但是扫了几遍源码,应该八九不离十。

注意这个需要 server 支持,所以需要 server adapter,比如 node 的@astrojs/node

我使用的是默认 static,需要后端运行时渲染的地方用export const prerender = false;,如果你的 output 设置为了 server,那么就不需要 prerender=false。

📖 官方文档参考


步骤 1:安装依赖

首先,安装 Better Auth 及相关依赖:

1
2
3
4
5
# 安装核心依赖
pnpm add better-auth drizzle-orm pg dotenv

# 安装开发依赖
pnpm add -D drizzle-kit tsx @types/pg

依赖说明

  • better-auth: 认证核心库
  • drizzle-orm: ORM 库,用于数据库操作
  • pg: PostgreSQL 驱动
  • drizzle-kit: Drizzle 开发工具(用于数据库迁移)
  • dotenv: 环境变量加载(drizzle.config.ts 需要

Read More

字符编码详解:UTF-8、Unicode、GBK 等

编辑说明:本文初稿完成后,通过 Claude Code 进行了技术审阅和优化润色,修正了 UTF-16 编码方式的描述,补充了 Unicode 平面结构、代理对机制、MySQL utf8mb4 等深度内容,使文章在保持通俗易懂的同时更加准确严谨。


字符编码详解:UTF-8、Unicode、GBK 等

一、核心概念:Unicode vs UTF-8

用快递系统来理解

Unicode(统一字符集)

  • 相当于:全国统一的地址编号系统
  • 作用:给世界上每个文字、符号分配唯一编号
  • 例子:
    • ‘A’ → U+0041(编号 65)
    • ‘中’ → U+4E2D(编号 20013)
    • ‘😊’ → U+1F60A(编号 128522)
  • 特点:只定义编号,不管怎么存储

UTF-8(编码方式)

UTF-8 根据 Unicode 码点的大小,使用不同长度的字节:

Unicode 范围 字节数 UTF-8 格式
U+0000 ~ U+007F 1 字节 0xxxxxxx
U+0080 ~ U+07FF 2 字节 110xxxxx 10xxxxxx
U+0800 ~ U+FFFF 3 字节 1110xxxx 10xxxxxx 10xxxxxx
U+10000 ~ U+10FFFF 4 字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  • 相当于:快递打包和运输方式
  • 作用:把 Unicode 编号转换成实际的字节数据
  • 例子:
    • ‘A’ (U+0041) → 01000001(1 字节)
    • ‘中’ (U+4E2D) → 11100100 10111000 10101101(3 字节)
    • ‘😊’ (U+1F60A) → 11110000 10011111 10011000 10001010(4 字节)
  • 特点:变长编码,节省空间

Read More

深入理解 SSR/CSR 与 SPA/MPA:现代前端渲染模式详解

前言

在学习现代前端框架时,你可能会发现它们的 SSR(服务端渲染)与传统后端框架的 SSR 似乎不太一样。这篇文章将详细解释它们的本质区别,以及 SSR/CSR 和 SPA/MPA 这两个维度的概念关系。

传统后端 SSR vs 现代前端 SSR

传统后端 SSR(PHP、JSP、Rails)

工作流程:

1
2
3
浏览器 → 请求页面 → 服务器生成完整HTML → 返回HTML → 浏览器显示

每次交互都重复这个过程

特点:

  • 纯服务器渲染,返回的是完整的静态 HTML
  • 每次交互都需要刷新整个页面
  • JavaScript 只是点缀(表单验证、简单动效)
  • 模板引擎在服务器端运行(如 PHP、EJS、Jinja2)

现代前端框架 SSR(Next.js、Nuxt、Remix)

工作流程:

1
2
3
4
5
首次访问:
浏览器 → 服务器SSR → 返回HTML + JS Bundle → Hydration → 变成SPA

后续导航:
客户端路由 → 仅获取数据 → 客户端渲染 → 无刷新更新

Read More

6GB显存跑Z-Image-Turbo完全指南

前言

我的拖拉机又开动了(指显卡风扇的噪音)。

这次是阿里开源的 Z-Image-Turbo,6GB 显存也能跑,而且效果还挺好。这篇博客就是纯纯的配置教程,不整那些虚的,直接告诉你怎么让小显存的卡也能愉快生图。

准备工作

首先,你需要:

  • ComfyUI(应该已经装好了吧,注意需要更新到最新版本,显卡驱动也要最新)
  • 6-12GB 显存(我用的 2060 6GB)
  • 16 以上内存(我用的是 16GB 内存,其实已经 swap 了)
  • 足够的硬盘空间下模型(量化版本所有东西最好保证 15GB 左右的空余空间)

第一步:拿官方工作流

官方已经给你做好工作流了,直接拖进 ComfyUI 的 web 界面就能用:

👉 官方工作流https://comfyanonymous.github.io/ComfyUI_examples/z_image/

拖进去之后你会发现缺模型,别慌,继续往下看。

Read More

自行部署 Next.js Docker 的挑战:臃肿、平台绑定与隐藏的“坑”

Next.js 作为目前最受欢迎的 React 全栈框架之一,凭借其强大的功能和“开箱即用”的体验赢得了大量开发者。然而,这种便利性很大程度上依赖于其创造者 Vercel 提供的原生托管平台。但是一旦开发者选择通过 Docker 自行部署,便会发现这条路并非坦途,充满了各种不易察觉的“坑”,并且会逐渐感受到框架本身的臃肿与对特定平台的深度绑定。

这里就总结了一下我这一年实践遇到的问题,建议没有 SEO 需求还是不要碰他了。

路由与请求类型的“黑盒”

在自行部署的环境中,Next.js 的一些内部机制会变得异常棘手。以 React Server Components (RSC) 的请求为例,它与页面的请求路径一致,但会附加一个 ?_rsc=... 参数以区分(也会增加一些 header)。问题在于,这个参数(以及额外的 header)在到达我们自己的应用逻辑之前,往往已被 Next.js 框架内部“消化”。这意味着,proxy.ts(16 之前的middleware.ts),无法捕获到 _rsc 这个参数。因此,从代码层面来看,开发者无法轻易判断一个传入的请求究竟是完整的页面加载请求,还是一个用于更新部分 UI 的 RSC 请求。

这在一些重定向场景中会造成一些问题。

Read More