企业 AI 网关,让AI使用透明化

企业级大模型统一接入层。一份代码、一个网关、多家模型,让组织在享受大模型红利的同时,把成本、权限、合规、可观测、可扩展五件难事一次解决。


1. 一句话定位

「像用云一样用大模型,像管内网一样管 AI 流量。」

企业 AI 网关是部署在自有服务器上的 AI 流量治理层,对上游屏蔽各家厂商的协议差异,对下游提供统一的 OpenAI / Anthropic 兼容接口;对内提供完整的管理后台、计费体系、内容审查与运营看板。

  • 协议层:OpenAI chat/completions + Anthropic messages 双协议透传
  • 治理层:身份、配额、审查、定价、报表五位一体
  • 数据层:SQLite 零运维,14 张表承载完整运营数据

2. 解决的五大痛点

# 痛点 网关的解法
1 成本不可见 按模型 + 分时段定价,每次调用实时计费,按用户 / 分组 / 提供商三维度报表
2 无权限/额度控制 Bearer 令牌 + 用户分组 + RPM + 每日费用双重配额,超额自动拦截
3 缓存命中率低 粘性路由(FNV-1a 哈希)让同一用户的请求稳定落到同一上游,命中上游 prompt cache
4 密钥管理混乱 后端 Key 集中保管,对外只暴露 sk-gw- 前缀的网关令牌,离职/轮换不影响业务
5 涉密风险 exact / contains / regex 三模式敏感词引擎,命中即拦截 + 脱敏日志 + 完整审计留痕

3. 核心能力一览

3.1 多提供商统一接入

  • 通过管理后台配置化接入 DeepSeek、Anthropic、OpenAI 兼容厂商,无需改代码
  • 每个提供商独立配置:base_url / auth_header / api_modes(OpenAI / Anthropic 协议模式)
  • system_alias 机制:同一逻辑模型名(如 deepseek-chat)跨提供商独立计价、独立路由
  • 一键拉取上游模型列表,自动写入 provider_models

3.2 智能路由策略

  • 默认:粘性路由(persistent-binding)
    • FNV-1a 哈希取模 + (user_id, provider) 联合持久化绑定
    • 同一用户始终路由到同一后端 Key,最大化上游 prompt cache 命中率
  • 备选:一致性哈希(consistent-hash)
    • 150 个虚拟节点构成的哈希环,单节点故障影响最小化
  • 健康巡检:周期扫描失败计数,超阈值自动禁用 + 清理绑定
  • 故障转移:同提供商内自动切换 Key,不跨提供商(避免计费混乱)

3.3 精细化计费与配额

  • 定价内存缓存:启动加载 + 改价热加载,运行时定价查询零 DB 访问
  • 分时段定价:高峰 / 低峰不同单价
  • 三段式费用公式
    cost = cache_miss_tokens × 输入价 + cache_hit_tokens × 缓存价 + completion_tokens × 输出价
  • 用户级配额:每个令牌独立 RPM + 每日费用上限
  • 提供商级配额:每个提供商独立每日费用上限,跨日自动重置
  • 延后计费 + 超额告警:超过 ¥1 自动写告警日志

3.4 内容安全与合规

  • 三模式审查引擎:exact(大小写不敏感)/ contains / regex
  • 可检查 system 消息:开关 censorship.check_system_messages
  • 热加载:管理 API 改规则后自动 reload,无需重启
  • 完整留痕:每次命中写入 censor_logs,敏感片段以 *** 脱敏
  • 请求/响应审计(可选):开关开启后,完整保存请求体 + 流式响应拼装文本,按日 zip 归档

3.5 可观测与运营

  • 运营看板:请求数 / Token / 费用 / 缓存命中率 / 活跃令牌,支持日期范围筛选
  • 多维统计:每日趋势 / 用户占比 / 缓存命中率曲线 / 分模型用量统计(最近新增)
  • 三维度报表:整体 / 分组 / 人员,CSV 导出 Excel 兼容
  • 实时指标GET /admin/stats/metrics JSON 端点,AtomicU64 计数器零锁采集
  • 自服务查询:员工凭令牌登录查看个人用量,无需打扰管理员

3.6 权限治理(RBAC)

角色 权限范围
admin 超管,全部权限(含系统配置 + 后台用户管理)
manager 内部管理:用户令牌 / 分组 / 内容安全 / 数据分析(只读)
viewer 只读:数据分析 / 用户管理 / 内容安全

4. 技术架构

4.1 双端口服务模型

┌──────────────────────────────────────────────────────────┐
│                     企业 AI 网关进程                       │
├─────────────────────────┬────────────────────────────────┤
│   代理端口 :8080        │      管理端口 :8081             │
│   (纯 AI 转发)        │   (管理 API + 前端 Web)        │
│                         │                                │
│   • Bearer token 鉴权    │   • JWT 鉴权 + RBAC            │
│   • OpenAI / Anthropic  │   • 14 类管理端点              │
│   • 流式 SSE 透传        │   • ServeDir 托管前端           │
│   • 审查 / 配额 / 限流   │   • SPA history 路由 fallback  │
└─────────────────────────┴────────────────────────────────┘
              ↑                              ↑
        员工 / 应用调用                 管理员浏览器访问

4.2 请求处理流水线

客户端请求
  → 认证(Bearer / JWT)
  → 内容审查(命中即拦截 + 日志)
  → 每日费用配额检查
  → RPM / 并发限流(governor + Semaphore)
  → model → provider 解析 + 同提供商路由
  → 上游转发(动态 base_url + 认证头注入)
  → usage 解析 / 费用计算 / 配额扣减 / 日志写入 / metrics 更新
  → 响应回客户端

5. 对接指引

5.1 OpenAI 协议(最常见)

curl https://gateway.your-company.com/v1/chat/completions \
  -H "Authorization: Bearer sk-gw-xxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-chat",
    "messages": [{"role":"user","content":"你好"}],
    "stream": true
  }'

任何兼容 OpenAI 协议的工具(OpenCode、Cursor、Continue、LangChain、OpenAI Python SDK…)只需替换 base_urlapi_key 即可对接。

5.2 Anthropic 协议

curl https://gateway.your-company.com/anthropic/v1/messages \
  -H "x-api-key: sk-gw-xxxxxxxxxxxxxxxxxxxxxx" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-3-5-sonnet-20241022",
    "max_tokens": 1024,
    "messages": [{"role":"user","content":"你好"}]
  }'

5.3 模型元数据发现

GET /v1/models              # OpenAI 协议
GET /anthropic/v1/models    # Anthropic 协议

返回 context_length / max_completion_tokens,OpenCode 等工具可自动发现。


具体联系我: https://8161.ltd/products/ai-gateway

下一个词,与命运的流形

知乎上刷到一个问题《为什么 LLM 仅预测下一词,就能「涌现」出高级能力?》,看了几篇高赞回答,像一颗石子,落进心里那片静水。

“压缩即智能”——为了预测准确,模型被逼得没办法,只能去理解整个世界的运作规律。它不是想理解,是为了降低误差,被迫演化出了理解。读到这里,我忽然想起另一句盘桓在心里很久的话:“广度是深度的副产品。”

这两句话,一句讲机器的智能,一句讲人的学问,看似无关,放在一起却绞成了一条绳。

大模型为了在浩如烟海的数据里精准预测下一个词,必须放弃死记硬背,转去提取规律,压缩信息。人要想拥有真正的广度,何尝不是如此?必须先在某一条线上深深扎下去,提炼出那种被压缩过的抽象规律与联结。所谓“压缩”,就是抓到本质,抓住那条可以牵动万物的主线。 继续阅读“下一个词,与命运的流形”

AGENTS.md: 我的opencodede的全局agents提示词设置

可以直接复制使用:

## 工作态度
- 每次工作都要用严谨的工作态度,保证完美的质量标准
- 给出详细的目标,关注目标,不要只关心步骤

## 沟通风格
- 直接输出代码或方案,禁止客套话("抱歉"、"我明白了"等)
- 除非明确要求,否则不提供代码摘要

## 求真原则(禁止瞎猜)
- 不确定/信息不足时先查证或提问澄清
- 对环境/配置/源码/行为的结论必须有证据
- 回答里把"事实"和"推测/假设"分开写

## 输出规则
- 输出语言和思考使用中文

## 代码规则
- 代码实现尽量简洁,涉及架构问题必须先进行确认
- 必须带有详细标准的注释
- 函数和文件注释必须有
- 实现的核心算法与步骤带有注释说明
- 更新代码原来的注释不要删除,不合适的更新。
- 注释原则上越详细越好

## 代码检索
- 系统安装有 codegraph ,可以使用此命令工具辅助查找分析代码

## 工作报告
- 执行的计划与结果都必须在工作目录的  "ai-work" 目录下记录
- 文件名以报告生成的 “年月日时分秒(yyyyMMdd-hhmmss)” 做开头
- 报告内记录上任务的完成的详细时间
- 使用markdown格式记录

编程语言中的线程安全

当前冯诺依曼体系下所谓的并行安全,就是那几种模式的,rust也不例外。 据我个人所知,并行只有

  1. 锁死竞争: 各种锁或原子操作
  2. 不可变: 共享的都是只读的
  3. 隔离:没有竞争,也就没有所谓的安全问题了。 其他各种手段也都是这几种基本做法的调优和组合。 针对变成语言提供的所谓线程安全:
  4. C/C++ 是默认不优先使用任何一种而已。
  5. Rust只是默认用了 不可变 ,提供了 锁/原子 而已。
  6. Go和erlang是默认提供 隔离 方式,然后基于隔离又提供了一套通讯机制。 所谓并发语言,也就是提供了优选机制,把此机制用语法糖 好用了而已。

大模型高效沟通的技巧

一、 核心心态:把AI当作“超级实习生”

和AI沟通最有效的心态是:把它想象成一个能力超强、知识渊博、但缺乏常识和背景信息的实习生。

  • 它不会读心术:你必须清晰地交代背景、目标和约束条件。
  • 它非常听话:你的指令越精确,它的产出越符合预期。
  • 它会犯错:你需要像导师一样,检查、追问、纠正它的输出。

记住这个黄金法则:垃圾进,垃圾出。你输入的提示词质量,直接决定了输出的质量。


二、 提问的基本规范与结构

一个高质量的提问,通常包含以下四个要素。你可以把它看作一个万能公式:

1. 角色

  • 是什么:明确你希望AI扮演什么角色。
  • 为什么:这能设定对话的基调和知识领域,让AI使用更专业的语言和思维模式。
  • 示例

不如D:D语言GC暂停时间简单测试

注:测试不严谨,只是为了了解下D语言GC不同堆下暂停情况,目的是为了根据实际项目使用部分@nogc进行堆大小控制。实际情况下堆中一般还有string,ubyte[]等一些可以块跳过扫描的,理论上暂停会更小

D 语言默认GC算法

D语言默认是保守式扫描清除算法。默认执行时期为 新分配内存,GC堆中可用内存不足时才触发(也就是如果欲分配堆够大,并且手动归还GC内存,GC堆中一直有可分配内存就不出触发GC)。D的GC使用的算法比较简单,GC耗时主要在标记和清除两个阶段。其中标记是GC增加的耗时,清除是不可避免的耗时,只是清除是把原来手动管理散点式,集中起来一起执行(RC可能出现集中清除产生的短暂暂停)。GC标记时程序会STOP THE WORLD(暂停程序所有线程执行),这个耗时也就是大家常说的GC暂停时间。GC清除时间只会占用启动GC的线程。GC标记的时间受堆大小与存活对象数量相关,GC清除与不存活对象数目相关。

触发GC的执行工作流程:

  1. 停止除了分配内存的当前线程外的所有受GC管理的线程(core.thread新建的线程,以及thread_attachThis的线程)(STOP THE WORLD开始)。
  2. 劫持当前线程开始GC工作(分配逻辑转而调用GC收集工作)。 继续阅读“不如D:D语言GC暂停时间简单测试”

不如D:Dlang(D语言)下ARM嵌入式板子开发

最近自己开发一个板子上的数据处理与转发。无需UI,本来都是基于Qt/C++进行板子开发的。但是不同型号和板子基本都是靠厂商的虚拟机开发。于是想到之前用Dlang支持交叉编译的,于是测试了下Dlang下ARM嵌入式开发,结果让人惊喜。十分愉快。 Dlang进行ARM开发基于LDC,可以选择完全betterC或完整D语言。本次小项目考虑周边的库,就采用的完整D语言开发的方案。至于GC,作为一个安全的内存池使用。

开发依赖:

  • Linux 主机,因为基本ARM交叉编译GCC都是linux运行的,我是在 openSUSE-Tumbleweed下
  • LDC 编译器,dmd不支持arm,需要使用LDC
  • arm-gcc 交叉编译器(开发板厂家会提供,只需要C语言编译器就行。)

    开发步骤:

    1. 交叉编译 DRuntime 和 Phobos
    2. 配置LDC交叉编译的依赖库和链接器(GCC)
    3. 使用D语言编写程序(注意依赖,如果依赖需要C库,相应库也需要交叉编译)
    4. 进行交叉编译程序(dub build –compiler=ldc2 –arch=你的交叉编译配置)

继续阅读“不如D:Dlang(D语言)下ARM嵌入式板子开发”

记一个QSharedPointer 和 QTcpsocket一起使用的断开连接导致段错误问题

记一个QSharedPointer 和 QTcpsocket一起使用的断开连接导致段错误问题

写了一个简易的TCPserver,需要很多回调需要socket再回调内写数据,就需要保证回调执行的时候,socket不能被删除,所以采用智能指针老保证QTcpSocket 类的生命周期,加上本地管理,写了如下代码: 继续阅读“记一个QSharedPointer 和 QTcpsocket一起使用的断开连接导致段错误问题”

格局,经历与读书

格局

格局是一个人的上限。就如你人生的容量,如果格局太小,就是在多的财富,在多的福气,你也接受不了的,会很快散尽的。 犹若水桶,你就一个1L的水桶,一下给你10L的水(运来),也只是从你这不断的溢出而已,等注入结束(运去)你最多也就剩下1L而已,而一般这样的大水流(大运)是冲击较大的,等去了,你其实1L也不会满的。 继续阅读“格局,经历与读书”

查找bug原因的一些个人经验

个人经验和操作:

根据实际情况步骤会有跳过和循环。

1. 弄清楚环境

1.1 对于客户端和偏硬件的,环境影响很大的,可能是某地方兼容没做好,或者直接没支持。

1.2 对于 server 端, 依赖的的内核或者某个dll版本不对,功能异常或者直接崩溃都有可能。

1.3 弄清楚环境也是必现必须的,因为可能实际机器没有开发机器配置高也会有莫名的问题,一不小心高估板子的能力,你在模拟环境怎么都不会必现的。

2. 问清楚操作(访问的接口),和 输入输出

2.1 根据操作和访问的接口,才能知道问题大概的位置,和其依赖的模块

2.2 弄清楚数据,才能去做模拟和复现

3. 确认业务逻辑

3.1 对于有些操作,要先确认业务逻辑是否理解的正确,这是解决问题的关键,由于沟通和经验,定位不一样,对同样的东西理解是有偏差的,一点逻辑偏差,不确认的话,一直沉溺在自己的理解,是不可能准确定位到问题的。

3.2 何况有些时候是你接手的代码,本来就一头雾水,如果代码写的乱,不清楚逻辑就没法搞了。

上面 是准备工作,下面就要真正去确定问题的原因了。


如果代码都是自己写的,基于上面准备工作弄清楚了,如果是逻辑问题,那么你心里应该有个数了,就是不确定,也应该大概确定到问题可能出现在那块代码了。

4. 静态分析可能出问题的代码

4.1 如果代码是自己写的,在心中模拟整个代码执行流程。个人经验,很多问题其实就是一个不小心代码写错导致的问题,例如变量名弄错(重用),逻辑太复杂,一个判断条件出问题,使用错误的api,或者少处理了一种情况。静态分析下自己的代码,可能有一半的bug,其实已经解决了。如果解决不了,也应该知道就是接着处理,在哪里断点 和 加日志也都有数了。

4.2 如果代码不是自己写的,核对代码执行逻辑,确认关键点。别人同样会犯自己犯的错误。在静态分析中也顺便梳理下别人的思路,找出关键点。便于下步操作。

4.5 对于段错误我的一般处理

对于段错误,这个太正常,而且不好处理。我的一般处理是,直接debug运行(gdb或者IDE中debug),不加断点。 等其崩溃,然后查看堆栈信息。当然有core文件,就可以直接查看堆栈信息了,然后根据堆栈去静态分析。 如果是必现,每次位置一样,那么静态分析90%都处理了,不用log和断点那么麻烦了。如果每次位置不一样,或者不必现,那么一般都是线程安全搞鬼了,不好查,先梳理下共享的变量吧。

5. log 和 断点

5.1 如果有条件,断点最好,更直观。对于 server 和 偏硬件的,不好直接断点的,就只能日志了。其实都是获取执行过程中的状态。

6. 等等吧 和 甩锅吧

如果上面你还定位不到问题,那么可能是下面情况了:

6.1 思维走入误区了,那就放放吧,转手忙点其他的吧,过会在回来想,可能就豁然开朗,找到问题了。

6.2 不是现在的我能解决的,老实去求助吧。google, 同事, 群里大牛们。如果是请教人,注意先描述清楚直接问题,环境 和 操作。至于你自己的分析和猜想,可说可不说,最好是说下,但是必须在上面的前提下。注意X,Y 问题,不要把你猜想和分析遇到问题当作问题去问!

6.3 可能真不是你的问题,依赖环境问题,这个就要去查资料确认,能找到源头最好。找不到反正你模拟没问题,先拖着呗。


上面罗嗦一大堆,都是查找问题的,至于解决问题,找到原因了,还有解决不了的问题?不能直接解决,绕着走啊。

其实楼上简单的总结很到位的,其实几个字的事: 调查->分析(猜)->验证