基于 Drogon 框架的 AI API 网关服务,提供 OpenAI 兼容的 Chat Completions 和 Responses API 接口。
最后更新:2026-08-05 14:35:00 CEST(中欧夏令时间)
- ✅ OpenAI Chat Completions API 兼容(流式/非流式)
- ✅ OpenAI Responses API 兼容(流式/非流式,含 previous_response_id 续聊)
- ✅ 多 Provider 支持(可扩展工厂模式:chaynsapi / nexosapi / retoolapi / openai)
- ✅ Nexos Web Provider(对外 HTTP:
/nexosapi/v1/*) - ✅ Retool Workspace Provider(对外 HTTP:
/retoolapi/v1/*) - ✅ OpenAI 兼容上游 Provider(
OpenAiProvider,通过custom_config.providers.openai配置,非独立/openai/v1/*路由) - ✅ 工具调用(Tool Calls)完整支持
- ✅ 工具调用桥接(XML Bridge)— 为不原生支持工具调用的通道提供桥接
- ✅ 工具调用验证(ToolCallValidator)— 支持 None/Relaxed/Strict 三种校验模式
- ✅ 参数形状规范化(ToolCallNormalizer)— 自动修复常见参数格式问题
- ✅ 工具定义编码(ToolDefinitionEncoder)— compact/full 两种模式
- ✅ 强制工具调用兜底(ForcedToolCallGenerator)— tool_choice=required 场景
- ✅ 严格客户端规则(StrictClientRules)— Kilo-Code / RooCode / Codex 客户端适配
- ✅ Codex XML 工具桥接 — 在上游不支持原生函数调用时,通过 XML 格式转发工具请求
- ✅ 外部状态需求识别 — 自动识别文件、仓库、命令、构建和测试等请求并要求执行工具
- ✅ 会话追踪(Hash / ZeroWidth 两种模式)
- ✅ 会话连续性决策(ContinuityResolver + TextExtractor)
- ✅ 历史回放预算(HistoryReplayBudget)— 按完整 turn 截取近期历史,超限整段省略并写入提示,不截断单条内容
- ✅ 响应索引(ResponseIndex)— Responses API GET/DELETE 支持
- ✅ 并发门控(SessionExecutionGate + CancellationToken + RAII Guard)
- ✅ 输出清洗(ClientOutputSanitizer)
- ✅ 统一错误模型(Errors)+ 错误统计(ErrorStatsService + ErrorStatsConfig)
- ✅ 账号池管理(自动注册、Token 刷新、类型检测、轮转、备份)
- ✅ ManagedAccount 抽象层(传统账号 + Retool Workspace 统一管理入口)
- ✅ Retool Workspace 资产管理(workspace/session/workflow/agent 元数据持久化)
- ✅ Retool Workspace 创建入口(通过 aiapi_tool 内部编排执行)
- ✅ 渠道管理(多渠道、状态控制、并发限制)
- ✅ 服务状态监控(请求/错误时序、渠道与模型状态;JSON Metrics API)
- ✅ 内置日志查看 API(文件列表、尾部读取、过滤)
- ✅ 管理接口认证(AdminAuthFilter)
- ✅ 请求限流(RateLimitFilter)
- ✅ 配置校验(ConfigValidator)
- ✅ 后台任务队列(BackgroundTaskQueue)
- ✅ 健康检查端点(/health + /ready)
- ✅ 完善的单元测试(当前包含 18 个测试源文件 +
test_main.cc测试入口) - ✅ Chat/Responses JSON 与 SSE Sink 分离,统一处理流式和非流式输出
┌─────────────────────────────────────────────────────────────────┐
│ HTTP 层 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Controllers + Filters │ │
│ │ AiApiController — AI 核心 API 路由 │ │
│ │ AccountController — 账号管理 API │ │
│ │ RetoolWorkspaceController — Retool Workspace API │ │
│ │ ChannelController — 渠道管理 API │ │
│ │ MetricsController — 监控指标 API │ │
│ │ LogController — 日志查看 API │ │
│ │ HealthController — 健康检查 API │ │
│ │ AdminAuthFilter — 管理接口认证 │ │
│ │ RateLimitFilter — 请求限流 │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 适配层 │
│ ┌─────────────────┐ ┌──────────────────────────────────┐ │
│ │ RequestAdapters │ ──▶ │ GenerationRequest │ │
│ │ (Chat/Responses)│ │ (统一请求结构) │ │
│ └─────────────────┘ └──────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 生成编排层 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ GenerationService │ │
│ │ - runGuarded() (主入口,含并发门控) │ │
│ │ - materializeSession() (请求 → 会话) │ │
│ │ - executeProvider() (调用上游) │ │
│ │ - emitResultEvents() (结果处理 + 事件发送) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │ │ │ │ │
│ ▼ ▼ ▼ ▼ ▼ │
│ ┌────────┐ ┌────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ToolCall│ │Session │ │ToolCall │ │Output │ │Continuity│ │
│ │Bridge │ │Manager │ │Validator │ │Sanitizer │ │Resolver │ │
│ └────────┘ └────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │SessionExecution │ (并发门控 + CancellationToken) │
│ │Gate │ │
│ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Provider 层 │
│ ┌─────────────┐ ┌─────────────────────────────────────┐ │
│ │ ApiManager │ ──▶ │ APIinterface │ │
│ │ (路由选择) │ │ - generate() │ │
│ │ ApiFactory │ │ - ProviderResult │ │
│ └─────────────┘ └─────────────────────────────────────┘ │
│ │ │
│ ├── chaynsapi (Chayns AI Provider) │
│ ├── nexosapi (Nexos Web Provider) │
│ ├── retoolapi (Retool Workspace Provider) │
│ └── openai (OpenAI 兼容 Provider) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 输出层 │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────────┐ │
│ │ IResponseSink │ │GenerationEvent│ │ HTTP Response │ │
│ │ (接口) │◀─│ (事件模型) │──▶│ (JSON/SSE) │ │
│ └───────────────┘ └───────────────┘ └───────────────────┘ │
│ │ │
│ ├── ChatJsonSink (Chat 非流式 JSON) │
│ ├── ChatSseSink (Chat 流式 SSE) │
│ ├── ResponsesJsonSink (Responses 非流式 JSON) │
│ ├── ResponsesSseSink (Responses 流式 SSE) │
│ ├── CollectorSink (事件收集,内部用) │
│ └── NullSink (丢弃输出,测试用) │
└─────────────────────────────────────────────────────────────────┘
项目当前采用按职责拆分的模块化结构:
src/
├── controllers/ HTTP 控制器、过滤器及 Chat/Responses Sink
├── apiManager/ Provider 工厂与 API 管理
├── accountManager/ 传统账号池管理
├── managedAccount/ 统一 ManagedAccount 抽象及后端实现
├── channelManager/ 渠道状态、并发和路由管理
├── dbManager/ 账号、渠道、配置、指标和 Workspace 持久化
├── sessionManager/ 会话、生成编排、连续性和工具调用
│ ├── continuity/ 连续性、历史预算、响应索引和文本提取
│ ├── core/ GenerationService、请求适配和会话门控
│ └── tooling/ 工具桥接、验证、规范化、编码和 XML 编解码
├── retoolWorkspace/ Retool Workspace 管理与服务
├── metrics/ 错误事件、错误统计与状态指标
├── tools/ ZeroWidth 编码及账号登录客户端
├── utils/ 配置校验、后台任务、响应流等公共工具
└── test/ 功能测试与测试入口
aiapi/
├── CMakeLists.txt # CMake 构建配置(根目录)
├── Dockerfile # Docker 构建文件
├── config.example.json # 配置文件模板(JSON)
├── config.sqlite.example.json # SQLite 配置模板
├── docker-compose.env.yml # Docker Compose(环境变量方式)
├── docker-compose.volume.yml # Docker Compose(卷挂载方式)
├── requirements.txt # Python 依赖(登录/注册服务)
├── doc/ # 文档目录
│ ├── aiapi_callflow_and_api_examples.md # 详细调用关系与接口样例
│ ├── development-plan.md # 开发计划
│ ├── optimization-report.md # 优化报告
│ ├── error_stats_dev_plan.md # 错误统计开发计划
│ ├── service_status_monitoring_design.md # 服务状态监控设计
│ ├── aiapi 错误统计与监控方案(设计文档) # 错误统计与监控方案设计
│ └── session/ # 会话连续性模块文档
│ ├── README.md # 会话模块索引
│ ├── session_continuity_refactor_design.md # 重构设计
│ └── session_continuity_refactor_development_plan.md # 重构开发计划
│
└── src/
├── CMakeLists.txt # CMake 构建配置(源码)
├── main.cc # 程序入口
├── config.yaml # Drogon YAML 运行配置
│
├── controllers/ # HTTP 控制器 + 过滤器
│ ├── AiApiController.h/cc # AI 核心 API 路由控制器
│ ├── AccountController.h/cc # 账号管理 API 控制器
│ ├── RetoolWorkspaceController.h/cc # Retool Workspace API 控制器
│ ├── ChannelController.h/cc # 渠道管理 API 控制器
│ ├── MetricsController.h/cc # 监控指标 API 控制器
│ ├── LogController.h/cc # 日志查看 API 控制器
│ ├── HealthController.h/cc # 健康检查 API 控制器
│ ├── ControllerUtils.h # 控制器公共工具
│ ├── AdminAuthFilter.h # 管理接口 Bearer Token 认证过滤器
│ ├── RateLimitFilter.h # 请求限流过滤器(令牌桶)
│ └── sinks/ # 输出 Sink 实现
│ ├── ChatJsonSink.h/cpp # Chat 非流式 JSON 输出
│ ├── ChatSseSink.h/cpp # Chat 流式 SSE 输出
│ ├── ResponsesJsonSink.h/cpp # Responses 非流式 JSON 输出
│ └── ResponsesSseSink.h/cpp # Responses 流式 SSE 输出
│
├── sessionManager/ # 核心业务逻辑(分层组织)
│ ├── README.md # sessionManager 模块文档
│ │
│ ├── contracts/ # 接口契约与数据结构
│ │ ├── README.md # 契约层文档
│ │ ├── GenerationRequest.h # 统一请求结构
│ │ ├── GenerationEvent.h # 统一事件模型
│ │ └── IResponseSink.h # 输出通道接口
│ │
│ ├── core/ # 核心服务
│ │ ├── README.md # 核心层文档
│ │ ├── GenerationService.h/cpp # 生成编排服务(主入口)
│ │ ├── GenerationServiceEmitAndToolBridge.cpp # 事件发送 + 工具桥接逻辑
│ │ ├── RequestAdapters.h/cpp # HTTP 请求 → GenerationRequest 适配器
│ │ ├── Session.h/cpp # 会话管理 + ZeroWidth/Hash 追踪
│ │ ├── SessionExecutionGate.h # 并发门控(单例 + RAII Guard)
│ │ ├── ClientOutputSanitizer.h/cpp # 输出清洗
│ │ └── Errors.h # 统一错误模型
│ │
│ ├── continuity/ # 会话连续性
│ │ ├── README.md # 连续性模块文档
│ │ ├── ContinuityResolver.h/cpp # 会话连续性决策器
│ │ ├── HistoryReplayBudget.h/cpp # 历史回放预算控制
│ │ ├── ResponseIndex.h/cpp # 响应存储索引(Responses API GET/DELETE)
│ │ └── TextExtractor.h/cpp # 文本提取工具
│ │
│ └── tooling/ # 工具调用相关
│ ├── README.md # 工具调用模块文档
│ ├── ToolCallBridge.h/cpp # 工具调用桥接(Native / TextBridge)
│ ├── ToolDefinitionEncoder.h/cpp # 工具定义编码(compact/full)
│ ├── XmlTagToolCallCodec.h/cpp # XML 格式工具调用编解码
│ ├── ToolCallValidator.h/cpp # 工具调用 Schema 校验
│ ├── ToolCallNormalizer.h/cpp # 参数形状规范化
│ ├── ForcedToolCallGenerator.h/cpp # 强制工具调用兜底生成
│ ├── StrictClientRules.h/cpp # 严格客户端规则
│ └── BridgeHelpers.h/cpp # 桥接辅助函数
│
├── apipoint/ # Provider 抽象与实现
│ ├── APIinterface.h # Provider 接口(generate / getModels)
│ ├── ProviderResult.h # Provider 结果结构
│ ├── chaynsapi/ # Chayns Provider 实现
│ │ └── chaynsapi.h/cpp
│ ├── nexosapi/ # Nexos Web Provider 实现
│ │ └── nexosapi.h/cpp
│ ├── retoolapi/ # Retool Workspace Provider 实现
│ │ └── retoolapi.h/cpp
│ └── openai/ # OpenAI 兼容 Provider 实现
│ └── OpenAiProvider.h/cpp
│
├── apiManager/ # Provider 管理
│ ├── Apicomn.h # API 公共定义
│ ├── ApiFactory.h/cpp # Provider 工厂
│ └── ApiManager.h/cpp # Provider 路由选择
│
├── accountManager/ # 账号池管理
│ └── accountManager.h/cpp # 账号 CRUD + Token 刷新 + 自动注册
│
├── managedAccount/ # 更高层账号/工作区抽象
│ ├── contracts/
│ │ └── ManagedAccount.h # 统一资产记录 / 执行上下文
│ ├── backends/
│ │ ├── IManagedAccountBackend.h
│ │ ├── ClassicProviderAccountBackend.h/cpp
│ │ └── RetoolWorkspaceBackend.h/cpp
│ └── service/
│ └── ManagedAccountService.h/cpp
│
├── retoolWorkspace/ # Retool Workspace 子系统
│ ├── RetoolWorkspaceInfo.h
│ ├── RetoolWorkspaceManager.h/cpp
│ └── RetoolWorkspaceService.h/cpp
│
├── channelManager/ # 渠道管理
│ └── channelManager.h/cpp # 渠道 CRUD + 状态控制
│
├── dbManager/ # 数据库管理
│ ├── DbType.h # 数据库类型枚举(PostgreSQL/MySQL/SQLite3)
│ ├── account/
│ │ ├── accountDbManager.h/cpp # 账号持久化
│ │ └── accountBackupDbManager.h/cpp # 账号备份持久化
│ ├── channel/
│ │ └── channelDbManager.h/cpp # 渠道持久化
│ ├── config/
│ │ └── ConfigDbManager.h/cpp # 配置持久化(app_config 表)
│ ├── retoolWorkspace/
│ │ └── RetoolWorkspaceDbManager.h/cpp # Retool Workspace 持久化
│ └── metrics/
│ ├── ErrorStatsDbManager.h/cpp # 错误统计持久化
│ └── StatusDbManager.h/cpp # 服务状态持久化
│
├── metrics/ # 错误统计服务
│ ├── ErrorEvent.h # 错误事件定义
│ ├── ErrorStatsConfig.h/cpp # 错误统计配置
│ └── ErrorStatsService.h/cpp # 错误记录服务
│
├── models/ # 数据模型
│ └── model.json # 模型定义文件
│
├── tools/ # 工具类
│ ├── ZeroWidthEncoder.h/cpp # 零宽字符编码/解码
│ └── accountlogin/ # 账号登录自动化
│ ├── login_client.cpp # C++ 登录客户端
│ ├── loginlocal.py # 本地登录脚本
│ ├── loginremote.py # 远程登录脚本
│ ├── chayns-login.service # systemd 服务文件
│ └── test.py # 登录测试脚本
│
├── utils/ # 通用工具
│ ├── BackgroundTaskQueue.h # 后台任务队列
│ ├── ConfigValidator.h/cpp # 配置校验器
│ ├── IoLoopResponseStream.h # IO 循环响应流
│ ├── LoginResponseLogSummary.h # 登录响应日志摘要
│ ├── NexosRegistrationMailPolicy.h # Nexos 注册邮件策略
│ └── NexosUserAgent.h # Nexos User-Agent 工具
│
└── test/ # 单元测试
├── CMakeLists.txt # 测试构建配置
├── test_main.cc # 测试入口
├── test_chayns_model_catalog.cpp # chayns 模型目录测试
├── test_continuity_resolver.cpp # ContinuityResolver 测试
├── test_error_event.cpp # ErrorEvent 测试
├── test_error_stats_config.cpp # ErrorStatsConfig 测试
├── test_forced_tool_call.cpp # ForcedToolCallGenerator 测试
├── test_generation_service_emit.cpp # GenerationService emit 测试
├── test_history_replay_budget.cpp # HistoryReplayBudget 测试
├── test_io_loop_response_stream.cpp # IoLoopResponseStream 测试
├── test_login_response_log_summary.cpp # LoginResponseLogSummary 测试
├── test_nexos_registration_mail_policy.cpp # Nexos 注册邮件策略测试
├── test_nexos_user_agent.cpp # NexosUserAgent 测试
├── test_normalize_tool_args.cpp # ToolCallNormalizer 测试
├── test_request_adapters.cpp # RequestAdapters 测试
├── test_response_index.cpp # ResponseIndex 测试
├── test_sinks.cpp # Sink 输出测试
├── test_strict_client_rules.cpp # StrictClientRules 测试
├── test_tool_call_validator.cpp # ToolCallValidator 测试
└── test_xml_tool_call_codec.cpp # XmlTagToolCallCodec 测试
| 方法 | 路径 | 功能 |
|---|---|---|
| POST | /chaynsapi/v1/chat/completions |
Chat Completions(流式/非流式) |
| POST | /chaynsapi/v1/responses |
Responses API(流式/非流式) |
| GET | /chaynsapi/v1/responses/{id} |
获取已创建的响应 |
| DELETE | /chaynsapi/v1/responses/{id} |
删除已创建的响应 |
| GET | /chaynsapi/v1/models |
获取可用模型列表 |
| POST | /nexosapi/v1/chat/completions |
Nexos Web Chat → OpenAI Chat Completions |
| POST | /nexosapi/v1/responses |
Nexos Web Chat → OpenAI Responses |
| GET | /nexosapi/v1/responses/{id} |
获取已创建的 Nexos 响应 |
| DELETE | /nexosapi/v1/responses/{id} |
删除已创建的 Nexos 响应 |
| GET | /nexosapi/v1/models |
获取 Nexos 可用模型列表 |
| GET | /nexosapi/v1/account/quota |
获取 Nexos 账号订阅/额度信息 |
| POST | /retoolapi/v1/chat/completions |
Retool Workspace Chat Completions |
| POST | /retoolapi/v1/responses |
Retool Workspace Responses |
| GET | /retoolapi/v1/responses/{id} |
获取已创建的 Retool 响应 |
| DELETE | /retoolapi/v1/responses/{id} |
删除已创建的 Retool 响应 |
| GET | /retoolapi/v1/models |
获取 Retool 可用模型列表 |
-
nexosapi不再从配置文件读取cookies/default_model/default_handler_id/model_mapping/models -
账号 cookies 来自账号管理:请通过
/aichat/account/add添加apiName=nexosapi的账号,并把完整 cookies 放到authToken -
模型列表实时获取:每次调用
/nexosapi/v1/models或聊天请求时,都会从 Nexoschat.data实时解析当前账号可用模型 -
额度查询:
GET /nexosapi/v1/account/quota返回当前 Nexos 账号订阅/额度信息
retoolapi通过 Retool Workspace 池路由请求;标准 OpenAI 兼容接口本身不要求显式传workspaceId,未传时会从可用 workspace 池自动分配。- 成功响应会在
_meta中返回本次实际命中的workspaceId / routeType / provider / resourceName,便于排查路由结果。 claude-*的 workflow 路径已支持,包括claude-sonnet-4-6。agent-claude-sonnet-4-6当前明确不支持:Retool 原生 agent thread 链路会返回 Anthropic 上游错误
This model does not support assistant message prefill. The conversation must end with a user message.- 因此当前支持性应按实际链路理解,而不要仅以
/retoolapi/v1/models暴露的模型名判断可用性。
| 模型 | workflow | agent |
|---|---|---|
claude-sonnet-4-20250514 |
支持 | agent-claude-sonnet-4-20250514 支持 |
claude-sonnet-4-5-20250929 |
支持 | agent-claude-sonnet-4-5-20250929 支持 |
claude-sonnet-4-6 |
支持 | agent-claude-sonnet-4-6 不支持 |
说明:
claude-opus-*是否可用还会受到目标 workspace 的 Anthropic 资源限流配置影响;若 workspace 侧 RPM 为 0,则会直接返回 rate limit 错误。
| 方法 | 路径 | 功能 |
|---|---|---|
| POST | /aichat/account/add |
批量添加账号(支持对象/数组) |
| POST | /aichat/account/delete |
批量删除账号(含上游删除) |
| POST | /aichat/account/update |
批量更新账号信息 |
| POST | /aichat/account/refresh |
异步刷新所有账号 token + 类型 |
| POST | /aichat/account/autoregister |
自动注册新账号(最多 20 个/次) |
| GET | /aichat/account/info |
获取内存中的账号列表 |
| GET | /aichat/account/backupinfo |
获取账号备份信息 |
| GET | /aichat/account/dbinfo |
获取数据库中的账号列表 |
| GET | /aichat/account/settings |
获取账号自动化设置 |
| POST | /aichat/account/settings |
更新账号自动化设置 |
| 方法 | 路径 | 功能 |
|---|---|---|
| POST | /aichat/retool/workspace/create |
调 aiapi_tool 完整创建 Retool workspace 并入库 |
| POST | /aichat/retool/workspace/upsert |
手动写入/覆盖 workspace 资产 |
| GET | /aichat/retool/workspace/info |
获取单个 workspace 信息 |
| GET | /aichat/retool/workspace/list |
获取 workspace 列表 |
| GET | /aichat/retool/workspace/pool-status |
获取 workspace 池状态 |
| POST | /aichat/retool/workspace/disable |
禁用 workspace |
| POST | /aichat/retool/workspace/enable |
启用 workspace |
| POST | /aichat/retool/workspace/delete |
删除 workspace |
| POST | /aichat/retool/workspace/verify |
本地验证 workspace 资产字段完整性 |
create 当前会同步调用 aiapi_tool 内部接口:
POST /api/v1/workflows/retool-workspace/provision-sync
| 方法 | 路径 | 功能 |
|---|---|---|
| POST | /aichat/channel/add |
批量添加渠道 |
| POST | /aichat/channel/delete |
批量删除渠道 |
| POST | /aichat/channel/update |
更新渠道配置 |
| POST | /aichat/channel/update-status |
更新渠道启用/禁用状态 |
| GET | /aichat/channel/list |
获取渠道列表 |
| 方法 | 路径 | 功能 |
|---|---|---|
| GET | /aichat/metrics/requests/series |
请求量时序统计 |
| GET | /aichat/metrics/errors/series |
错误量时序统计(多维过滤) |
| GET | /aichat/metrics/errors/events |
错误事件列表(分页) |
| GET | /aichat/metrics/errors/events/{id} |
错误事件详情 |
| GET | /aichat/metrics/status/summary |
服务状态概览 |
| GET | /aichat/metrics/status/channels |
渠道状态列表 |
| GET | /aichat/metrics/status/models |
模型状态列表 |
| GET | /aichat/logs/list |
日志文件列表 |
| GET | /aichat/logs/tail |
日志尾部读取(支持级别/关键词过滤) |
| 方法 | 路径 | 功能 |
|---|---|---|
| GET | /health |
返回服务状态、版本、运行时长 |
| GET | /ready |
检查数据库、Provider、账号池可用性(依赖不足时返回 503) |
核心编排服务,管理整个生成流程。代码拆分为两个 .cpp 文件:
GenerationService.cpp— 主流程(runGuarded / materializeSession / executeProvider)GenerationServiceEmitAndToolBridge.cpp— 事件发送 + 工具桥接逻辑
runGuarded(req, sink, policy)
├─ materializeSession() → GenerationRequest → session_st
├─ ContinuityResolver::resolve() → 会话连续性决策
├─ sessionManager.getOrCreateSession()
└─ executeGuardedWithSession()
├─ ExecutionGuard(RAII) → 获取并发锁
├─ transformRequestForToolBridge() → 工具定义注入(Bridge 模式)
├─ executeProvider() → 调用上游 AI
├─ emitResultEvents() → 结果处理 + 事件发送
│ ├─ sanitizeOutput() → 文本清洗
│ ├─ parseXmlToolCalls() → XML 工具调用解析
│ ├─ ToolCallNormalizer → 参数规范化
│ ├─ ToolCallValidator → Schema 校验 + 过滤
│ ├─ StrictClientRules → 严格客户端规则
│ └─ 零宽字符会话ID嵌入
└─ coverSessionresponse() → 会话上下文更新 + 转移
| 事件类型 | 说明 | 关键数据 |
|---|---|---|
Started |
生成开始 | responseId, model |
OutputTextDelta |
文本增量(流式) | delta, index |
OutputTextDone |
文本完成 | text, index |
ToolCallDone |
工具调用完成 | id, name, arguments, index |
Usage |
Token 使用量 | inputTokens, outputTokens |
Completed |
生成完成 | finishReason (stop/tool_calls) |
Error |
错误 | code, message, detail |
为不支持原生 Tool Calls 的上游通道提供 XML 桥接,模块已拆分为独立组件:
| 组件 | 文件 | 职责 |
|---|---|---|
| ToolCallBridge | ToolCallBridge.h/cpp |
桥接主逻辑(请求注入 + 响应解析) |
| ToolDefinitionEncoder | ToolDefinitionEncoder.h/cpp |
工具定义编码(compact/full 模式) |
| XmlTagToolCallCodec | XmlTagToolCallCodec.h/cpp |
XML 格式工具调用编解码 |
| ToolCallValidator | ToolCallValidator.h/cpp |
Schema 校验(None/Relaxed/Strict) |
| ToolCallNormalizer | ToolCallNormalizer.h/cpp |
参数形状规范化(数组/别名/默认值) |
| ForcedToolCallGenerator | ForcedToolCallGenerator.h/cpp |
tool_choice=required 兜底生成 |
| StrictClientRules | StrictClientRules.h/cpp |
Kilo-Code/RooCode 严格模式适配 |
| BridgeHelpers | BridgeHelpers.h/cpp |
桥接辅助函数 |
请求侧:
- ToolDefinitionEncoder 将工具定义编码为文本格式
- 生成随机触发标记(如
<Function_Ab1c_Start/>) - 构建
<tool_instructions>提示注入到 request message
响应侧:
- 通过触发标记定位 XML 块(防止误解析历史消息)
- XmlTagToolCallCodec 解析
<function_calls>/<function_call>结构 - ToolCallNormalizer 参数规范化 + ToolCallValidator Schema 校验 + 降级策略
| 组件 | 职责 |
|---|---|
| ContinuityResolver | 决策当前请求是否属于已有会话的延续 |
| HistoryReplayBudget | 控制上游历史回放体积:按完整 conversation turn 保留最近消息;超单条/总预算时整段省略并插入提示,不截断原文 |
| ResponseIndex | 响应存储索引,支持 Responses API 的 GET/DELETE 操作 |
| TextExtractor | 从复杂消息结构中提取纯文本内容 |
HistoryReplayBudget 已接入 chaynsapi / nexosapi / retoolapi / openai 各 Provider 的历史组装路径。可通过 custom_config.history_replay 调整预算(单位:字节):
| 配置项 | 默认 | 说明 |
|---|---|---|
max_request_bytes |
262144(256KiB) |
整次历史回放总预算 |
max_message_bytes |
131072(128KiB) |
单条消息上限;超出则整条替换为提示 |
max_tool_message_bytes |
49152(48KiB) |
tool 角色消息上限(与单条上限取更小值) |
上限硬封顶为 8MiB。未配置时使用上表默认值。
| 客户端 | 标识 | 特殊处理 |
|---|---|---|
| Kilo-Code | Kilo-Code |
严格模式:StrictClientRules 注入 apply_diff SEARCH/REPLACE 精确匹配与失败恢复策略;配合 ToolCallValidator 做工具参数约束 |
| RooCode | RooCode |
同 Kilo-Code(仅 Roo/Kilo 启用严格客户端规则) |
| Claude Code | claudecode |
零宽会话 ID 在 tool_calls 前单独发送 |
| 其他 | — | 宽松模式,不强制 Roo/Kilo 专用规则 |
当客户端或上游通道不支持原生 Provider/Recipient/Namespace/JSON 函数调用时,网关可以使用 XML Bridge 传递工具请求。桥接策略包含:
- 使用
<function_calls>/<function_call>XML 结构描述工具调用; - 保留工具名称与 JSON 参数;
- 对
tool_choice=required或当前请求明确依赖外部状态的场景强制要求执行工具; - 识别文件、目录、仓库、Git、命令、构建、测试等关键词,避免在未检查外部状态时凭空回答;
- 收到带有
[tool_result ...]的结果后继续生成最终响应; - 支持并行工具调用配置。
该逻辑主要位于 src/sessionManager/core/GenerationServiceEmitAndToolBridge.cpp,请求适配位于 RequestAdapters.cpp。
| 模式 | 实现 | 说明 |
|---|---|---|
| Hash | 消息内容 SHA256 | 默认模式,基于 systemPrompt + messages 哈希 |
| ZeroWidth | 零宽字符嵌入 | 在助手回复中嵌入不可见的 sessionId |
- RejectConcurrent:同一会话有请求在执行时,新请求返回 409 Conflict
- CancelPrevious:取消之前的请求,执行新请求
- 使用 RAII
ExecutionGuard自动管理生命周期
错误按 4 个域分类:
| 域 | 说明 | 典型事件 |
|---|---|---|
SESSION_GATE |
会话并发门控 | 并发冲突、请求取消 |
UPSTREAM |
上游 Provider | HTTP 错误、超时 |
TOOL_BRIDGE |
工具桥接 | XML 未找到、校验过滤、降级、强制生成 |
INTERNAL |
内部异常 | 运行时异常、未知错误 |
配置通过 ErrorStatsConfig 管理,支持运行时调整保留策略。
| 过滤器 | 作用范围 | 说明 |
|---|---|---|
| AdminAuthFilter | /aichat/* |
Bearer Token 认证,admin_api_key 为空时跳过(向后兼容) |
| RateLimitFilter | AI API 端点 | 令牌桶限流,可配置 requests_per_second 和 burst |
# 非流式
curl -X POST "http://localhost:55555/chaynsapi/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "GPT-4o",
"messages": [{"role": "user", "content": "Hello"}]
}'
# 流式
curl -N -X POST "http://localhost:55555/chaynsapi/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "GPT-4o",
"stream": true,
"messages": [{"role": "user", "content": "Hello"}]
}'# 创建 Response
curl -X POST "http://localhost:55555/chaynsapi/v1/responses" \
-H "Content-Type: application/json" \
-d '{
"model": "GPT-4o",
"input": "Hello"
}'
# 续聊
curl -X POST "http://localhost:55555/chaynsapi/v1/responses" \
-H "Content-Type: application/json" \
-d '{
"model": "GPT-4o",
"previous_response_id": "resp_abc123",
"input": "Tell me more."
}'
# 获取 Response
curl "http://localhost:55555/chaynsapi/v1/responses/{response_id}"
# 删除 Response
curl -X DELETE "http://localhost:55555/chaynsapi/v1/responses/{response_id}"# 添加账号
curl -X POST "http://localhost:55555/aichat/account/add" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_KEY" \
-d '{
"apiname": "chaynsapi",
"username": "user@example.com",
"password": "xxx"
}'
# 自动注册 5 个账号
curl -X POST "http://localhost:55555/aichat/account/autoregister" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_KEY" \
-d '{"apiname": "chaynsapi", "count": 5}'
# 刷新所有账号状态
curl -X POST "http://localhost:55555/aichat/account/refresh" \
-H "Authorization: Bearer YOUR_ADMIN_KEY"# 添加渠道
curl -X POST "http://localhost:55555/aichat/channel/add" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_KEY" \
-d '[{
"channelname": "main",
"channeltype": "chaynsapi",
"channelurl": "https://api.example.com",
"channelkey": "sk-xxx",
"maxconcurrent": 10,
"supports_tool_calls": false
}]'
# 获取渠道列表
curl "http://localhost:55555/aichat/channel/list" \
-H "Authorization: Bearer YOUR_ADMIN_KEY"# 服务状态概览
curl "http://localhost:55555/aichat/metrics/status/summary" \
-H "Authorization: Bearer YOUR_ADMIN_KEY"
# 错误时序统计(最近 24 小时)
curl "http://localhost:55555/aichat/metrics/errors/series" \
-H "Authorization: Bearer YOUR_ADMIN_KEY"
# 日志尾部(过滤 ERROR 级别)
curl "http://localhost:55555/aichat/logs/tail?lines=100&level=ERROR" \
-H "Authorization: Bearer YOUR_ADMIN_KEY"
# 健康检查
curl "http://localhost:55555/health"
curl "http://localhost:55555/ready"
# 监控指标示例
curl "http://localhost:55555/metrics"- C++17 或更高版本
- Drogon 框架
- JsonCpp
- OpenSSL
- spdlog
- PostgreSQL / MySQL / SQLite3(可选,通过
dbtype配置切换)
cd aiapi/src
mkdir build && cd build
cmake ..
make -j$(nproc)cd aiapi/src/build
ctest --output-on-failure
# 或直接运行测试可执行文件
./test/aiapi_testcd aiapi/src/build
./aiapi服务默认监听 0.0.0.0:55555
# 方式一:环境变量注入配置
docker compose -f docker-compose.env.yml up --build aiapi
# 方式二:卷挂载配置文件
cp config.example.json config.json
# 编辑 config.json 填入实际配置
docker compose -f docker-compose.volume.yml up --build aiapi
# 方式三:SQLite + 卷挂载持久化
cp config.sqlite.example.json config.json
mkdir -p data logs cores
# config.json 中默认使用 ./data/aiapi.db,对应宿主机 ./data/aiapi.db
docker compose -f docker-compose.volume.yml up --build aiapidocker-compose.env.yml 与 docker-compose.volume.yml 中的服务名、镜像名、容器名均统一为 aiapi。
Docker 入口脚本支持:
CONFIG_JSON环境变量 → 直接覆盖配置文件CUSTOM_CONFIG环境变量 → 使用 jq 合并到现有配置
配置文件位于 config.example.json,主要配置项:
{
"listeners": [
{ "address": "0.0.0.0", "port": 55555 }
],
"db_clients": [
{ "name": "aichatpg", "rdbms": "postgresql", "host": "...", "...": "..." }
],
"app": {
"number_of_threads": 4,
"log": {
"use_spdlog": true,
"log_level": "DEBUG"
},
"cors": { "enabled": true, "allow_origins": ["*"] }
},
"plugins": [
{ "name": "drogon::plugin::PromExporter", "config": { "path": "/metrics" } },
{ "name": "drogon::plugin::AccessLogger" }
],
"custom_config": {
"dbtype": "sqlite3",
"admin_api_key": "",
"session_tracking": {
"mode": "zerowidth"
},
"tool_bridge": {
"definition_mode": "compact",
"include_descriptions": false,
"max_description_chars": 5000,
"trigger_random_length": 8,
"strict_sentinel": true
},
"login_service_urls": [
{ "name": "chaynsapi", "url": "http://login-service:8004/api/v1/logins" }
],
"regist_service_urls": [
{ "name": "chaynsapi", "url": "http://orchestrator-service:8000/api/v1/workflows/register-and-login" }
]
}
}账号自动化策略默认从 custom_config.account_automation 提供初始值;运行时优先从数据库配置表 app_config 读取,若表中缺失配置项则自动写入默认值。
auto_delete_enabled:是否自动删除过期的 free 账号delete_after_days:账号创建超过多少天后删除,默认6auto_register_enabled:当渠道账号数量不足时,是否自动补注册账号
| 配置路径 | 说明 | 可选值 |
|---|---|---|
custom_config.dbtype |
数据库类型 | postgresql / mysql / sqlite3 |
custom_config.admin_api_key |
管理接口 Bearer Key(为空则兼容放行并告警) | 任意非空字符串 |
custom_config.session_tracking.mode |
会话追踪模式 | hash / zerowidth |
custom_config.tool_bridge.definition_mode |
工具定义编码模式 | compact / full |
custom_config.tool_bridge.include_descriptions |
是否包含工具描述 | true / false |
custom_config.tool_bridge.max_description_chars |
描述截断长度 | 0-5000 |
custom_config.tool_bridge.trigger_random_length |
触发标记随机长度 | 6-12 |
custom_config.tool_bridge.strict_sentinel |
严格哨兵模式(全局默认) | true / false |
custom_config.tool_bridge.strict_sentinel_by_channel |
按渠道覆盖严格哨兵 | { "channel": bool } |
custom_config.tool_bridge.strict_sentinel_by_model |
按模型覆盖严格哨兵 | { "model": bool } |
custom_config.tool_bridge.rewrite_user_input_conflicts |
是否改写用户输入中的冲突指令 | true / false |
custom_config.rate_limit.enabled |
AI 接口限流开关 | true / false |
custom_config.rate_limit.requests_per_second |
每秒令牌补充速率 | 正整数 |
custom_config.rate_limit.burst |
瞬时突发上限 | 正整数 |
custom_config.session_persistence.memory_expire_hours |
内存会话 TTL(小时,可为小数) | 正数,默认 24 |
custom_config.session_persistence.memory_cleanup_interval_hours |
过期会话轮询清理间隔(小时,可为小数) | 正数且不大于 TTL,默认 1 |
custom_config.session_persistence.db_retention_hours |
数据库会话快照保留期(小时,可为小数) | 正数,建议 ≥ TTL,默认 24 |
custom_config.session_persistence.store_session_payload |
是否将会话 payload 写入 chat_session_state |
true / false |
custom_config.session_persistence.store_response_body |
是否将响应体随 response_index 落库 |
true / false |
custom_config.response_index.max_entries |
Responses 索引最大内存条目数 | 正整数 |
custom_config.response_index.max_age_hours |
Responses 索引过期时间(小时) | 正整数 |
custom_config.response_index.cleanup_interval_minutes |
索引清理周期(分钟) | 正整数 |
custom_config.providers.openai |
OpenAI 兼容 Provider 配置 | api_key / base_url / default_model |
custom_config.providers.nexos |
Nexos Provider 配置 | base_url |
custom_config.upstream_error_texts |
上游错误文本匹配列表 | 字符串数组 |
custom_config.cors.allowed_origins |
CORS 白名单 | 字符串数组 |
history_replay:历史回放预算(max_request_bytes/max_message_bytes/max_tool_message_bytes,默认 256KiB / 128KiB / 48KiB)
三个时间参数统一以小时为单位,支持小数(0.5 = 30 分钟、0.25 = 15 分钟)。程序启动时读取并换算为秒(四舍五入,最小 1 秒)后应用到会话清理线程,日志会打印实际生效值:
[会话持久化] 参数生效: 内存TTL=24h, 内存清理间隔=1h, DB保留=24h, payload落库=on, response_body落库=off
"session_persistence": {
"memory_expire_hours": 24,
"memory_cleanup_interval_hours": 1,
"db_retention_hours": 24,
"store_session_payload": true,
"store_response_body": false
}| 参数 | 作用 |
|---|---|
memory_expire_hours |
session_map 中会话的空闲存活时长;超时后被清理线程淘汰,并同步删除对应 DB 行(避免懒加载“复活”过期会话) |
memory_cleanup_interval_hours |
清理线程轮询周期,决定过期判定的时间精度。必须不大于 memory_expire_hours,否则启动校验失败 |
db_retention_hours |
chat_session_state 快照保留期,防止表无限增长。若小于 memory_expire_hours 会输出告警——活跃会话的快照将被提前清理,进程重启后无法懒加载恢复 |
store_session_payload |
关闭后不再写入会话快照,response_index 映射不受影响 |
store_response_body |
关闭后仅落库响应索引映射而不存响应正文,可显著降低存储占用 |
迁移提示:旧版的
memory_expire_seconds/memory_cleanup_interval_seconds/db_retention_seconds(单位:秒)已废弃且不再生效。为避免老配置直接启动失败,配置校验器对这些键仅输出告警而非报错,请尽快改用对应的*_hours键。
| 错误码 | HTTP Status | 说明 |
|---|---|---|
| BadRequest | 400 | 请求格式错误 |
| Unauthorized | 401 | 未授权 |
| Forbidden | 403 | 禁止访问 |
| NotFound | 404 | 资源不存在 |
| Conflict | 409 | 并发冲突(同一会话已有请求在执行) |
| RateLimited | 429 | 限流 |
| Timeout | 504 | 超时 |
| ProviderError | 502 | Provider 错误 |
| Internal | 500 | 内部错误 |
| Cancelled | 499 | 请求被取消 |
| 文档 | 说明 |
|---|---|
| 调用关系图与接口样例 | 详细的模块拆解、时序图、数据结构和 curl 示例 |
| 开发计划 | 项目整体开发计划与里程碑 |
| 优化报告 | 性能优化分析与改进记录 |
| 错误统计开发计划 | 错误统计系统开发计划 |
| 错误统计与监控方案 | 错误统计与监控系统设计文档 |
| 服务状态监控设计 | 服务状态监控系统设计 |
| 文档 | 说明 |
|---|---|
| 会话模块索引 | 会话连续性模块文档入口 |
| 重构设计 | 会话连续性重构设计方案 |
| 重构开发计划 | 会话连续性重构开发计划 |
| 文档 | 说明 |
|---|---|
| sessionManager 模块 | 会话管理核心模块说明 |
| contracts 层 | 接口契约说明 |
| core 层 | 核心服务说明 |
| continuity 模块 | 会话连续性模块说明 |
| tooling 模块 | 工具调用模块说明 |
项目包含 18 个功能测试文件(另有 test_main.cc 作为测试入口),覆盖核心模块:
| 测试文件 | 覆盖模块 |
|---|---|
test_request_adapters.cpp |
HTTP 请求适配器 |
test_xml_tool_call_codec.cpp |
XML 工具调用编解码 |
test_tool_call_validator.cpp |
工具调用 Schema 校验 |
test_normalize_tool_args.cpp |
参数形状规范化 |
test_forced_tool_call.cpp |
强制工具调用兜底 |
test_strict_client_rules.cpp |
严格客户端规则 |
test_sinks.cpp |
输出 Sink |
test_generation_service_emit.cpp |
GenerationService 事件发送 |
test_continuity_resolver.cpp |
会话连续性决策 |
test_response_index.cpp |
响应索引 |
test_error_event.cpp |
错误事件模型 |
test_error_stats_config.cpp |
错误统计配置 |
test_chayns_model_catalog.cpp |
chayns 模型目录 |
test_io_loop_response_stream.cpp |
IO 循环响应流 |
test_login_response_log_summary.cpp |
登录响应日志摘要 |
test_nexos_registration_mail_policy.cpp |
Nexos 注册邮件策略 |
test_nexos_user_agent.cpp |
Nexos User-Agent |
test_history_replay_budget.cpp |
HistoryReplayBudget 历史回放预算 |
- Chat Completions API 基础功能
- Responses API 基础功能(含 previous_response_id 续聊)
- 流式输出支持(CollectorSink → SSE 分块传输)
- 工具调用支持(原生 + Bridge)
- 工具调用桥接(XML Bridge + 随机 Sentinel)
- 工具调用验证(None/Relaxed/Strict + 降级策略)
- 参数形状规范化(ToolCallNormalizer:数组/别名/默认值)
- 工具定义编码(ToolDefinitionEncoder:compact/full)
- 强制工具调用兜底(ForcedToolCallGenerator)
- 严格客户端规则(StrictClientRules:Kilo-Code / RooCode)
- 会话追踪(Hash/ZeroWidth + ContinuityResolver + TextExtractor)
- 并发门控(SessionExecutionGate + CancellationToken + RAII Guard)
- 输出清洗(ClientOutputSanitizer)
- 统一错误模型(Errors)
- 错误统计系统(ErrorStatsService + ErrorStatsConfig + 4 域分类)
- 账号池管理(自动注册 + Token 刷新 + 类型检测 + 备份)
- 渠道管理(CRUD + 状态控制 + supports_tool_calls)
- 服务状态监控(Summary + Channels + Models)
- 日志查看 API(文件列表 + 尾部读取 + 过滤)
- 服务状态/错误统计 Metrics API(JSON;非 Prometheus exposition 格式)
- 增量流式响应(AsyncStreamResponse + SSE 实时推送)
- 多 Provider(chaynsapi + nexosapi + retoolapi + OpenAI 兼容)
- HTTP 过滤器(AdminAuthFilter + RateLimitFilter)
- 健康检查端点(/health + /ready)
- 配置校验(ConfigValidator)
- 后台任务队列(BackgroundTaskQueue)
- 控制器拆分(6 个独立控制器)
- sessionManager 分层重构(contracts / core / continuity / tooling)
- HistoryReplayBudget(多 Provider 历史回放预算与完整 turn 截取)
- 核心单元测试(18 个功能测试源文件 +
test_main.cc测试入口)
MIT
最后更新时间:2026年8月5日 08:35(美国东部时间,ET,UTC-4)