AI对程序员的影响是好是坏呢,10年老程序员用AI做宠物医疗系统,中转网关选型、架构设计与踩坑记录
一、项目背景与痛点
上个月接了个私活,给本地一家连锁宠物医院做智能预诊 + 电子病历 + 宠物档案管理系统。核心流程很简单:
用户端输入宠物症状 → AI 生成预诊报告 → 医生后台审核确认 → 形成结构化病历 → 归档便于后续随访。
但做到 AI 接入层时,遇到了几个很现实的问题:
-
网络问题:直接调 OpenAI/Claude 官方接口需要代理,公司内网环境挂代理连开发机都费劲,频繁超时。
-
计费不透明:官方按美元扣费,汇率波动,且没有细粒度的额度管控,测试阶段心里完全没底。
-
多模型管理麻烦:预诊用 Claude 3.5,轻量任务用 DeepSeek,兜底用 GPT-4o-mini,每个模型都要单独管理 Key 和 Endpoint,代码里一堆
if-else。 -
成本不可控:开发测试阶段疯狂调接口,几天就能烧掉几十美元,私活预算扛不住。
二、API 接入方案选型
针对上述问题,我梳理了三种技术方案:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 官方 API 直连 | 官方保障,文档齐全 | 需代理、延迟高、美元计费、多模型管理复杂 | 有稳定海外网络环境的企业 |
| 自建反向代理 | 完全可控、无中间商 | 维护成本高、需解决线路稳定性、证书、限流等问题 | 有运维资源的中大型团队 |
| 第三方中转网关 | 国内直连、统一接口、人民币计费、额度管控 | 多一层依赖、文档/调试能力参差不齐 | 独立开发者、中小团队、快速验证 MVP |
最终选择了第三方中转网关方案。原因很实际:这是私活项目,工期紧、预算有限,没有精力自建代理。在对比了几家国内中转服务后,选用了 Aegisy(官网:),主要看中了国内直连延迟低、支持多模型统一接口、可按人民币充值并设置额度预警。https://www.aegisy.top/
用户注册可以得到试用额度,前期可以直接写代码测试,对新用户相对比较友好
这里不展开具体品牌对比,只分享选型逻辑:选中转网关时,建议重点考察三点——线路稳定性(国内直连延迟)、接口标准度(是否兼容 OpenAI 格式)、成本可控性(是否支持额度限制和预警)。
三、系统架构设计
技术栈是标准的 Java Web 组合:
-
后端:Spring Boot 3.x + MyBatis-Plus + PostgreSQL(pgvector 扩展做向量检索)
-
AI 接入层:统一 HTTP Client 对接中转网关,内部做模型路由
-
前端:Vue3 + Element Plus
-
部署:Docker Compose,单机 2C4G 云服务器
3.1 核心模块划分
-
智能预诊模块
-
接收用户输入的症状描述
-
调用 AI 生成预诊报告(包含疑似病症、建议检查项、用药参考)
-
医生后台审核确认后方可入库
-
-
病历管理模块
-
标准 CRUD,但病历内容采用结构化 JSON 存储(诊断、用药、医嘱、随访计划)
-
支持按宠物档案维度检索历史病历
-
-
知识库问答模块(RAG)
-
基于宠物医疗 FAQ 和药品说明书构建向量库
-
用户提问时先检索相关知识片段,再拼接进 Prompt 做约束生成
-
向量库直接用 PostgreSQL 的
pgvector扩展,避免额外引入 Milvus/Pinecone
-
3.2 AI 接入层架构
为了不把网关地址和 Key 写死在业务代码里,我封装了一个统一的 AI Service:
@Service
public class AiDiagnosisService {
@Value("${ai.gateway.base-url}")
private String baseUrl;
@Value("${ai.gateway.api-key}")
private String apiKey;
private final WebClient webClient;
public AiDiagnosisService(WebClient.Builder builder) {
this.webClient = builder
.baseUrl(baseUrl)
.defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + apiKey)
.build();
}
/**
* 流式预诊:使用 SSE 实时推送给前端
*/
public Flux<String> streamDiagnosis(DiagnosisRequest request) {
String prompt = buildMedicalPrompt(request);
Map<String, Object> body = Map.of(
"model", routeModel(request.getComplexity()), // 根据复杂度路由模型
"messages", List.of(Map.of("role", "user", "content", prompt)),
"stream", true,
"temperature", 0.3 // 医疗场景降低随机性
);
return webClient.post()
.uri("/v1/chat/completions")
.bodyValue(body)
.retrieve()
.bodyToFlux(String.class)
.onErrorResume(e -> {
log.error("AI 调用异常", e);
return Flux.just("{\"error\":\"预诊服务暂不可用,请稍后重试\"}");
});
}
/**
* 模型路由策略:
* - SIMPLE: DeepSeek-V3(关键词提取、症状分词)
* - COMPLEX: Claude 3.5 Sonnet(预诊报告生成)
* - FALLBACK: GPT-4o-mini(兜底)
*/
private String routeModel(Complexity level) {
return switch (level) {
case SIMPLE -> "deepseek-chat";
case COMPLEX -> "claude-3-5-sonnet-20241022";
default -> "gpt-4o-mini";
};
}
}
3.3 成本控制机制
中转网关控制台支持单 Key 额度限制和IP 白名单,我在系统里做了两层防护:
-
网关层:设置 Key 的日消费上限(50元),超出自动失效,防止测试阶段被刷。
-
应用层:对 AI 调用做滑动窗口限流(RateLimiter),单个用户每分钟最多 3 次预诊请求。
// 应用层限流示例(基于 Guava RateLimiter)
@PreAuthorize("hasRole('USER')")
@PostMapping("/diagnosis/stream")
public Flux<String> diagnosis(@RequestBody @Valid DiagnosisRequest req) {
if (!diagnosisRateLimiter.tryAcquire()) {
return Flux.just("{\"error\":\"请求过于频繁,请稍后再试\"}");
}
return aiDiagnosisService.streamDiagnosis(req);
}
四、踩坑记录与解决方案
4.1 文档边缘场景覆盖不足
官方文档对常规调用说明比较清楚,但错误码和异常场景描述不够细致。例如:
-
当模型触发
content_filter时,返回的 JSON 结构没有明确示例 -
流式输出中途断连时,客户端重连策略文档只提了一句,没有代码参考
-
多轮对话中
system角色的权重和长度限制说明缺失
解决方案:自己用 Wireshark + 日志拦截器抓包,整理了一份内部的《异常码速查表》。建议大家在生产环境接入任何第三方 AI 网关时,都先跑一轮完整的异常 case 测试。
4.2 调试链路不透明
医疗系统对可观测性要求高,我需要知道每次 AI 调用的完整耗时、Token 消耗、是否重试。但网关返回的响应头里只有基础耗时,缺少上游模型的详细 trace。
解决方案:在 WebClient 外包了一层 OkHttp 拦截器,自己打日志:
client.addInterceptor(chain -> {
Request request = chain.request();
long startNs = System.nanoTime();
Response response = chain.proceed(request);
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
log.info("[AI-Gateway] {} {} | {}ms | model={}",
request.method(),
request.url(),
tookMs,
request.header("X-Target-Model"));
return response;
});
4.3 额度监控延迟
控制台的费用统计有 5-10 分钟延迟。开发阶段高频调试时,额度掉了但界面没刷新,容易造成误判。
建议:不要完全依赖控制台做实时预算判断,应用层自己维护一个调用次数和 Token 数的本地计数器,做粗粒度预估。
4.4 长文本上下文截断
宠物病历包含既往病史、过敏史、长期用药记录,上下文很容易超过 8k Token。测试时发现偶尔会出现内容截断或总结性压缩,导致返回的病历不完整。
解决方案:放弃"一次性塞全文"的策略,改用分段 RAG 检索:
-
先将长病历按段落切分,做 Embedding 存入 pgvector
-
用户提问时,检索 Top-3 相关片段
-
只将相关片段 + 当前症状拼接进 Prompt,控制单次调用在 4k Token 以内
-- pgvector 相似度检索示例
SELECT content, embedding <=> query_embedding AS distance
FROM pet_medical_chunks
WHERE pet_id = ?
ORDER BY embedding <=> query_embedding
LIMIT 3;
五、运行数据与效果
系统上线前做了压测,数据如下:
| 指标 | 结果 |
|---|---|
| 平均响应时间 | 2.3s(含 AI 生成) |
| 流式首字延迟 | 800ms |
| 单日最大调用量 | 1200 次 |
| 开发+测试周期总费用 | ¥186 |
| 预诊报告可用率 | 75%(25% 需医生修正,符合预期) |
医生端反馈:对于皮肤病、肠胃炎、呼吸道感染这三类高频病例,AI 预诊能节省约 30% 的初诊时间,给出的用药建议框架基本可用。但涉及复杂慢性病和罕见病时,仍需医生主导判断。
六、总结与建议
6.1 中转网关适合什么场景?
经过这个项目的实践,我认为第三方 AI 中转网关比较适合:
-
国内独立开发者/小团队:不想折腾代理和海外支付,快速验证 AI 功能
-
多模型混合策略:一个项目里要根据任务类型切换不同模型,统一接口能减少很多胶水代码
-
预算敏感型项目:需要人民币计费和额度管控,防止测试阶段费用失控
不适合的场景:
-
对延迟要求极高的实时语音/视频交互(建议直接用官方或自建专线)
-
需要完整审计日志和合规追溯的金融/医疗核心系统(中转网关作为接入层没问题,但必须在上面再包一层自己的网关做日志留存)
6.2 给同类项目的建议
-
不要裸调第三方网关:务必在应用层包一层自己的限流、降级、日志拦截器。
-
医疗场景一定要降低 Temperature:我设的是 0.3,防止 AI 胡编乱造药品剂量。
-
长文本不要用大上下文硬塞:RAG 检索 + 片段拼接,比直接扔 8k Token 更稳。
-
先小规模验证再放量:任何第三方服务,都建议先用免费额度或小额充值跑通核心流程,确认延迟和稳定性符合预期后,再投入生产
推荐阅读标签: #AI编程 #GPT-5.5 #Claude4 #API中转 #Cursor #ClaudeCode #CodexCLI #大模型API #AI写代码 #开发者工具 #Token计费 #开源模型 #MCP协议 #A2A协议 #AIAgent #智能体 #流式输出 #函数调用 #长上下文 #降本增效 #算力成本 #提示词工程 #OpenAI兼容 #多模态大模型 #推理模型 #LLMAPI #API代理 #AI网关
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)