news 2026/8/23 4:03:06

构建AI API网关:从OpenAI接入到APP集成的全链路实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
构建AI API网关:从OpenAI接入到APP集成的全链路实践

1. 项目缘起:当“一键接入AI”成为刚需,我们到底在聊什么?

最近两年,AI大模型的风潮席卷了几乎所有应用领域。无论是开发者社区里的技术讨论,还是产品经理们的需求文档,“为我们的APP加个AI大脑”几乎成了标配。但当你真正着手去做,会发现事情远没有想象中简单。市面上充斥着各种“一键接入”、“快速集成”的宣传,背后却是复杂的API申请、高昂的成本、令人头疼的合规审查,以及最关键的——如何让这个“大脑”真正理解你的业务逻辑,而不是变成一个只会说车轱辘话的聊天机器人。

我手头这个项目,核心目标就是解决这个痛点:让任何APP都能以最低门槛、最高效率,接入以ChatGPT-4为代表的最新一代AI能力。这不仅仅是调用一个API那么简单。它涉及到如何将OpenAI这类平台的强大能力,封装成一个稳定、安全、易用且成本可控的服务通道,让开发者无需关心底层模型的训练、部署和运维,只需专注于自己的业务逻辑和用户体验。

从网络上的热词也能看出大家的关注点:api errorinsufficient balancemaximum context length,这些是开发者每天都会遇到的真实问题;无违禁词ai聊天ai编程,这些是用户对AI能力的直接期待;而app抓包失败transport failure则暴露了集成过程中的技术障碍。这个项目,就是要成为连接“强大但复杂”的AI底层能力与“简单而直接”的应用层需求之间的那座桥。

2. 核心架构拆解:从OpenAI API到你的APP,中间发生了什么?

很多人以为“接入AI”就是拿到一个API Key,然后往接口里发请求。这种想法过于天真,在实际生产环境中会踩无数的坑。一个健壮的AI接入通道,其架构必须考虑多个层面。

2.1 通道层的核心价值:不止是转发请求

所谓“通道”,首先是一个代理与路由层。你的APP不直接调用OpenAI的官方接口,而是调用我们构建的通道服务。这样做有几个无法替代的好处:

  1. 统一鉴权与风控:你可以在通道层统一管理所有下游APP的访问权限、调用频率(Rate Limit)和用量配额。比如,为免费用户设置更低的每分钟请求次数,为VIP用户开放更高的并发和更长的上下文长度。这能有效防止API Key被盗用导致的巨额账单。
  2. 请求预处理与格式化:不同的APP对AI的输入输出格式要求不同。通道层可以充当一个“翻译官”,将APP传来的五花八门的请求(可能是JSON,也可能是表单数据),统一转换成符合OpenAI API规范的格式。同时,它也可以对用户输入进行基础的清洗和过滤,比如去除敏感信息、截断过长的文本,避免触发上游平台的审核机制。
  3. 响应后处理与标准化:OpenAI返回的响应是原始的流式或非流式数据。通道层可以将其解析、格式化,甚至进行二次加工(比如提取关键信息、转换为固定结构的JSON),再返回给APP,极大简化了客户端的处理逻辑。
  4. 失败重试与负载均衡:当OpenAI服务暂时不可用或返回特定错误(如429 Too Many Requests)时,通道层可以自动进行指数退避重试。如果项目接入了多个AI服务商(如同时支持OpenAI、智谱、DeepSeek),通道层还能实现智能路由和负载均衡,在某个服务商出现问题时自动切换,保障服务的高可用性。
  5. 成本与用量监控:这是企业级应用最关心的一点。通道层可以精确记录每一次调用的模型、Token消耗和费用,并生成可视化的报表。你可以清晰地看到哪个APP、哪个功能消耗最大,从而进行成本优化。

2.2 应对常见的API错误:从报错信息到解决方案

网络热词中频繁出现的API错误,正是我们需要在通道层重点处理的。我们来逐一拆解:

  • api error: 400 the thinking_budget parameter must be a positive integer

    • 根因:这是调用某些支持“思考过程”(如OpenAI o1系列模型)的API时,参数格式错误。thinking_budget必须是一个正整数。
    • 通道层处理策略:在请求转发前,对参数进行强类型校验和范围校验。如果APP传来的参数是字符串或负数,通道层应直接返回友好的错误提示,而不是让这个错误请求到达OpenAI再返回晦涩的400错误。
  • api error: 400 this model's maximum context length is 1048576 tokens...

    • 根因:请求的上下文长度(输入+输出的Token总数)超过了模型支持的上限。
    • 通道层处理策略:实现一个智能上下文管理模块。在转发请求前,计算本次请求的预估Token数(可以基于字符数进行粗略估算,或集成tiktoken库进行精确计算)。如果超过阈值,则自动触发处理策略,例如:
      1. 总结压缩:调用一个快速、廉价的小模型(如gpt-3.5-turbo)对过长的历史对话进行总结,用总结文本替代原始长文本。
      2. 滑动窗口:只保留最近N轮对话,丢弃最早的对话历史。
      3. 关键信息提取:从长文本中提取出与当前问题最相关的片段。 通道层应提供配置选项,让APP开发者根据业务场景选择最合适的策略。
  • api error: 402 insufficient balanceapi error: 400 model not found

    • 根因:API Key余额不足,或请求的模型名称不存在/不可用。
    • 通道层处理策略:维护一个模型与账户健康状态池。定时检查所有配置的API Key余额和可用模型列表。当检测到某个账户余额低于阈值或模型不可用时,自动将其标记为“不可用”,并将流量切换到备用账户或模型上。同时,向管理员发送告警通知。
  • transport failureconnection lost mid-response

    • 根因:网络不稳定,导致HTTP连接中断,尤其是在流式响应(Streaming Response)时更容易发生。
    • 通道层处理策略
      1. 在通道服务器与OpenAI服务器之间使用持久化HTTP连接(HTTP Keep-Alive),减少连接建立的开销。
      2. 实现断线重连和响应续传机制(对于非流式请求)。对于流式请求,需要在客户端(APP)和通道层之间建立更稳定的双向通信(如WebSocket),由通道层来保证与OpenAI连接的稳定性,并对APP客户端进行心跳检测和重连。
      3. 在多个地域部署通道节点,让APP可以连接地理距离最近的节点,降低网络延迟和丢包率。

2.3 安全与合规:绕不开的“违禁词”问题

无违禁词无限制是用户的需求,但却是开发者和平台方的风险。完全不做过滤,可能导致服务被上游供应商封禁,甚至引发法律风险。如何在体验与安全间取得平衡?

  1. 分层过滤策略

    • 第一层(客户端/通道入口轻量级过滤):过滤明显违法违规、人身攻击、极端敏感词汇。这层过滤要快,规则要简单,目的是拦截最明显的恶意请求。
    • 第二层(通道层上下文理解过滤):这是关键。很多违规内容是通过组合、隐喻、谐音表达的。这里需要集成一个轻量级的文本分类模型(或调用内容安全API),结合整个对话的上下文进行判断。例如,单独问“苹果”没问题,但在讨论“制作”的上下文中连续出现“苹果”和“配方”,就需要警惕。
    • 第三层(后置审计与学习):记录所有被拦截的请求和模型生成的内容(需脱敏),定期进行人工复审,用于优化过滤规则和模型。这是一个持续迭代的过程。
  2. 用户体验优化:当过滤被触发时,不应简单回复“你的请求违规”。更好的做法是,让AI以符合规则的方式引导对话。例如,用户问如何制作危险物品,AI可以回答:“抱歉,我无法提供制作危险物品的指导。不过,我可以和你聊聊相关材料的科学性质,或者推荐一些安全的科普读物。” 这需要我们在系统提示词(System Prompt)中进行精心设计。

3. 实战:构建一个最小可行通道服务

理论说再多,不如动手搭一个。下面我们用一个最简单的Node.js + Express例子,演示通道服务核心部分的实现。请注意,这是一个高度简化的示例,生产环境需要考虑性能、安全、可扩展性。

3.1 项目初始化与依赖安装

首先,创建一个新目录并初始化项目。

mkdir ai-api-gateway && cd ai-api-gateway npm init -y npm install express axios dotenv cors npm install -D nodemon

创建必要的文件:

ai-api-gateway/ ├── .env ├── .gitignore ├── package.json ├── server.js └── config/ └── index.js

.env文件中配置你的OpenAI API Key和其他敏感信息:

# 主备API Key,用逗号分隔 OPENAI_API_KEYS=sk-your-key-1,sk-your-key-2 # 当前使用的Key索引 CURRENT_KEY_INDEX=0 # 服务端口 PORT=3000 # 允许的APP客户端域名(CORS) ALLOWED_ORIGIN=http://localhost:8080

3.2 实现核心的请求转发与负载均衡

server.js中,我们实现最核心的代理逻辑。

const express = require('express'); const axios = require('axios'); const cors = require('cors'); require('dotenv').config(); const config = require('./config'); const app = express(); app.use(express.json()); app.use(cors({ origin: config.allowedOrigin })); // 简单的API Key轮询负载均衡 class KeyManager { constructor(keys) { this.keys = keys; this.index = 0; } getCurrentKey() { return this.keys[this.index]; } rotateKey() { this.index = (this.index + 1) % this.keys.length; console.log(`切换到API Key索引: ${this.index}`); } // 可以扩展更多策略,如基于余额的权重选择 } const keyManager = new KeyManager(config.openaiApiKeys); // 统一的错误处理与重试 async function callOpenAIWithRetry(payload, maxRetries = 3) { let lastError; for (let i = 0; i < maxRetries; i++) { try { const apiKey = keyManager.getCurrentKey(); const response = await axios({ method: 'post', url: 'https://api.openai.com/v1/chat/completions', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, data: payload, timeout: 30000, // 30秒超时 }); return response.data; } catch (error) { lastError = error; console.error(`第 ${i + 1} 次调用失败:`, error.response?.status, error.response?.data?.error?.message || error.message); // 如果是额度不足或Key无效,切换Key if (error.response?.status === 401 || error.response?.status === 429 || error.response?.status === 402) { keyManager.rotateKey(); await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); // 指数退避 continue; } // 如果是服务器错误,重试 if (error.response?.status >= 500) { await new Promise(resolve => setTimeout(resolve, 2000 * (i + 1))); continue; } // 其他客户端错误(如400参数错误),直接抛出,重试无意义 break; } } throw lastError; } // 核心的代理端点 app.post('/v1/chat/completions', async (req, res) => { try { // 1. 请求验证(可扩展JWT等机制) const clientId = req.headers['x-client-id']; if (!clientId) { return res.status(401).json({ error: { message: '未授权的客户端' } }); } // 2. 请求预处理(示例:添加系统提示词) const userPayload = req.body; const enhancedPayload = { ...userPayload, messages: [ { role: 'system', content: '你是一个有帮助的助手。请用中文回答。' }, ...(userPayload.messages || []) ] }; // 3. 上下文长度检查(简化版) const totalContent = enhancedPayload.messages.map(m => m.content).join(''); if (totalContent.length > 10000) { // 简单字符数判断 return res.status(400).json({ error: { message: '请求上下文过长,请简化问题或开启上下文管理功能。' } }); } // 4. 调用OpenAI const openaiResponse = await callOpenAIWithRetry(enhancedPayload); // 5. 响应后处理(示例:记录日志) console.log(`客户端 ${clientId} 调用成功,模型: ${openaiResponse.model},消耗Token: ${openaiResponse.usage?.total_tokens}`); // 6. 返回结果 res.json(openaiResponse); } catch (error) { console.error('通道处理失败:', error); const status = error.response?.status || 500; const message = error.response?.data?.error?.message || error.message || '内部服务器错误'; res.status(status).json({ error: { message } }); } }); app.listen(config.port, () => { console.log(`AI API 通道服务运行在 http://localhost:${config.port}`); });

config/index.js中管理配置:

module.exports = { openaiApiKeys: process.env.OPENAI_API_KEYS.split(','), port: process.env.PORT || 3000, allowedOrigin: process.env.ALLOWED_ORIGIN || '*' };

3.3 运行与测试

package.json中添加启动脚本:

"scripts": { "dev": "nodemon server.js", "start": "node server.js" }

然后运行npm run dev。服务启动后,你就可以用任何HTTP客户端(如Postman或你的APP)来测试了。

测试请求示例

curl -X POST http://localhost:3000/v1/chat/completions \ -H "Content-Type: application/json" \ -H "x-client-id: my-test-app" \ -d '{ "model": "gpt-3.5-turbo", "messages": [ {"role": "user", "content": "你好,请用一句话介绍你自己。"} ], "stream": false }'

这个最简单的通道已经具备了多Key负载均衡、自动故障转移、基础错误处理和请求包装的能力。你的APP只需要将请求目标从api.openai.com改为你自己的通道地址,并带上一个简单的客户端标识即可。

4. 从通道到“一键接入”:客户端的封装策略

有了稳定的通道服务,下一步是降低APP端的集成门槛。目标是让开发者用最少的代码,甚至一行配置,就能用上AI功能。这里的关键在于提供平台原生的SDK。

4.1 设计跨平台客户端SDK

一个好的SDK应该像瑞士军刀,开箱即用,但功能强大。以微信小程序和Flutter为例,看看设计思路:

核心SDK设计原则

  1. 配置极简:只需初始化时传入通道服务器地址和一个APP ID。
  2. 异步友好:所有API调用返回Promise(JS/TS)或Future(Dart),方便异步编程。
  3. 错误统一:将底层各种网络错误、API错误,封装成有明确分类和提示的SDK自定义错误。
  4. 流式支持:对于需要实时响应的场景(如聊天),必须支持流式响应(Server-Sent Events或WebSocket)。
  5. 类型安全:提供完整的TypeScript类型定义或Dart强类型,提升开发体验。

示例:一个假设的微信小程序SDK的初始化与调用

// 在小程序app.js中初始化 import { AIClient } from '@my-org/ai-client-wechat'; App({ onLaunch() { this.ai = new AIClient({ baseURL: 'https://your-gateway.com', // 你的通道地址 appId: 'your-miniprogram-app-id', timeout: 30000, }); } }); // 在页面中使用 Page({ async onAskAI() { try { this.setData({ loading: true }); const response = await getApp().ai.chatCompletion({ model: 'gpt-3.5-turbo', messages: [{ role: 'user', content: this.data.question }], stream: false, // 小程序暂不支持stream,可用轮询模拟 }); this.setData({ answer: response.choices[0].message.content }); } catch (error) { wx.showToast({ title: `AI出错: ${error.message}`, icon: 'none' }); } finally { this.setData({ loading: false }); } } })

4.2 处理移动端网络特殊性

移动端网络环境复杂,SDK需要做更多适配:

  • 断网重连与请求队列:在网络断开时,将用户的AI请求暂存到本地队列。当网络恢复后,自动按顺序发送。这对于内容创作类APP(如AI写作助手)体验提升巨大。
  • 离线缓存策略:对于一些通用性较强的AI回复(例如,常见的知识问答、文案模板),可以在SDK层面实现简单的缓存。当用户提出相似问题时,优先返回缓存内容,并后台异步更新。这既能提升响应速度,也能节省Token。
  • 流量优化:默认使用压缩率更高的模型(如gpt-3.5-turbo而非gpt-4),并在SDK中提供图片、文件上传的压缩功能,减少数据传输量。

4.3 安全与认证深化

上述示例中只用了简单的x-client-id,生产环境需要更严格的机制。

  1. 动态令牌(JWT):APP启动时,用其唯一的App Key和Secret向通道服务申请一个短期有效的JWT Token。后续所有请求都携带此Token。通道服务验证Token的合法性和有效期。这比固定ID更安全。
  2. 请求签名:对于敏感操作,可以对请求参数、时间戳和密钥进行签名,防止请求在传输中被篡改。
  3. 设备指纹:结合设备ID、IP等信息生成设备指纹,用于识别异常请求和防止账号滥用。

5. 进阶:成本控制、监控与持续优化

通道搭建起来只是第一步,如何以合理的成本稳定运行,并持续提升效果,才是长期挑战。

5.1 精细化成本控制策略

OpenAI的API按Token收费,不同模型价格差异巨大。控制成本不是一味选用便宜模型,而是在效果和成本间找到最佳平衡点

  1. 模型路由策略

    • 业务分级:将APP内的AI功能分为不同等级。核心对话功能用gpt-4,内容总结用gpt-3.5-turbo,简单的关键词提取甚至可以用更便宜的text-embedding模型或开源模型。
    • 智能降级:在通道层监控请求的响应时间或错误率。当gpt-4响应缓慢时,自动将非核心请求降级到gpt-3.5-turbo
    • 用户分级:免费用户使用gpt-3.5-turbo,付费会员使用gpt-4
  2. 上下文与提示词优化

    • 压缩历史消息:如前所述,这是降低Token消耗最有效的方式。对于长对话,定期将历史总结成一段简短的背景描述。
    • 优化System Prompt:System Prompt也会消耗Token。确保其简洁、精准。避免在其中放入冗长且不必要的行为描述。
    • 缓存嵌入向量:对于需要知识库检索(RAG)的应用,将文档块转换为向量(Embedding)后存入向量数据库。每次查询时,只需计算用户问题的向量,然后进行相似度检索,这比将整个知识库作为上下文喂给模型要便宜得多。

5.2 构建可观测性体系

没有监控的系统就是在“裸奔”。你需要知道通道的运行状况。

  1. 核心监控指标

    • 业务指标:总请求量、成功率、平均响应时间、各模型调用分布、Token消耗速率、费用消耗速率。
    • 系统指标:通道服务器CPU/内存/磁盘使用率、网络带宽、上游API(OpenAI)的延迟和错误率。
    • 用户指标:活跃APP数、用户请求频率分布、高频查询问题。
  2. 实现方案

    • 在通道服务的每个关键节点(收到请求、转发前、收到响应、返回前)埋点。
    • 使用像Prometheus这样的工具收集指标,用Grafana制作可视化看板。
    • 设置告警规则,例如:当gpt-4的每分钟错误率超过5%,或Token消耗费用超过每小时X元时,立即发送告警(邮件、钉钉、Slack)。
  3. 日志与审计:结构化记录每一笔请求和响应(注意脱敏),便于事后排查问题和分析用户行为模式。这些日志也是优化提示词和过滤规则的重要数据来源。

5.3 效果评估与迭代

AI应用的效果很难用简单的“对错”衡量,更需要一套评估体系。

  1. 人工评估样本池:定期(如每周)从生产日志中随机抽取一批用户与AI的对话记录,由产品经理或运营人员进行打分,评估回复的相关性、有用性、安全性、风格符合度等维度。
  2. A/B测试:当你想优化某个功能的提示词,或尝试切换新模型时,不要全量上线。通过通道层将少量用户流量(如5%)导向新策略,对比新旧策略下用户的停留时长、交互轮次、负面反馈率等核心业务指标,用数据驱动决策。
  3. 反馈闭环:在APP的AI回复界面提供一个简单的“赞/踩”按钮。将用户的负面反馈(“踩”)自动关联到当时的对话日志,并优先进入人工评估队列,快速发现和修复问题。

6. 避坑指南:那些我踩过的“坑”和填过的“土”

在实际运营这样一个通道服务的过程中,我遇到了无数教科书上不会写的坑。这里分享几个最典型的,希望能帮你绕过去。

坑一:低估了流式响应的复杂性早期我们为了简单,所有请求都使用非流式(stream: false)。后来做聊天功能时,用户抱怨响应太慢。改为流式后,问题接踵而至:网络中断导致回复不完整、前端渲染复杂、连接数暴增给服务器带来压力。填坑:不要在通道层简单透传流式响应。更好的做法是,通道层与OpenAI建立流式连接,然后将其转换为更易管理的Server-Sent Events (SSE)WebSocket推送给APP客户端。同时,在通道层实现一个响应缓冲区,即使客户端暂时断开,也能缓存一段时间的响应内容,待客户端重连后从中断处继续推送。

坑二:Prompt的“隐形”变更导致效果滑坡我们曾为了统一风格,在所有System Prompt末尾加了一句“请确保回答积极向上”。结果发现,一些需要客观分析的技术问题,AI的回答开始变得模糊和“和稀泥”。填坑任何对Prompt的修改,都必须经过严格的A/B测试。建立一套关键用例集(Golden Set),包含各种类型的典型用户问题。每次修改Prompt后,用这个用例集跑一遍,对比新旧Prompt的输出,确保核心能力没有退化。

坑三:滥用重试机制导致雪崩有一次OpenAI服务出现短暂波动,我们的通道层设置了激进的重试策略(立即重试5次)。导致在几十秒内,堆积的请求和重试请求像海啸一样涌向OpenAI,不仅耗尽了额度,还触发了更严厉的速率限制,服务完全不可用。填坑:重试策略必须包含指数退避熔断机制。例如,第一次重试等待1秒,第二次2秒,第三次4秒……同时,监控失败率,当短时间内失败率超过阈值(如50%),立即启动熔断,停止向该上游服务发送请求,等待一段时间后再尝试恢复。可以使用类似axios-retry的库来方便地实现。

坑四:忽视“长尾”模型的冷启动延迟除了常用的gpt-3.5-turbogpt-4,我们有时会应客户要求调用一些不常用的模型(如gpt-4-32k)。发现这些请求的首次响应时间特别长,有时超过10秒。根因:云服务商为了节省资源,会将不常用的模型实例“冷存储”,接到请求时才启动(冷启动)。这在高并发或实时交互场景是致命的。应对:对于需要保证低延迟的功能,避免使用这些“长尾”模型。如果必须使用,可以在系统低峰期(如凌晨)主动发送一些“预热”请求,让模型实例保持活跃状态。或者在通道层给这类请求设置更长的超时时间,并给用户明确的等待预期。

构建一个稳定、高效、易用的AI能力通道,绝非一蹴而就。它是一项涉及架构设计、算法优化、运维监控和产品思维的综合性工程。从最简单的请求转发做起,逐步迭代,围绕稳定性、成本、效果和安全这四个核心支柱不断加固,你的“一键接入AI”才能真正从口号变为赋能无数APP的坚实底座。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/23 4:00:15

无人机编队纯方位无源定位:数学建模与非线性最小二乘求解

1. 项目概述与核心价值最近几年&#xff0c;无人机编队飞行从技术演示逐渐走向了实际应用&#xff0c;无论是表演灯光秀还是执行协同作业任务&#xff0c;都离不开一个核心问题&#xff1a;如何让一群无人机在没有GPS或者GPS信号不佳的环境下&#xff0c;还能精确地知道彼此的位…

作者头像 李华
网站建设 2026/8/23 3:52:12

OSS上传报错“无法解析响应”的排查与解决指南

1. 问题初探&#xff1a;当OSS上传遭遇“无法解析的响应”如果你正在使用阿里云OSS、腾讯云COS或者其他兼容S3协议的对象存储服务&#xff0c;在程序里调用SDK上传文件时&#xff0c;突然在控制台或日志里看到Unable to execute HTTP request: 返回结果无效&#xff0c;无法解析…

作者头像 李华
网站建设 2026/8/23 3:50:54

AI辅助编程治理:如何驾驭“便宜代码”背后的昂贵判断成本

1. 项目概述&#xff1a;当“便宜”的代码遇上昂贵的判断“Cheap Code, Costly Judgment”这个标题&#xff0c;精准地戳中了当前AI辅助编程浪潮中的一个核心悖论。作为一名在软件工程一线摸爬滚打了十多年的老兵&#xff0c;我亲眼见证了从手动编码到IDE智能提示&#xff0c;再…

作者头像 李华
网站建设 2026/8/23 3:48:23

EvoHarness-RL:为LLM智能体设计运行时进化框架,解决长视野任务挑战

1. 项目缘起&#xff1a;当LLM智能体需要“跑马拉松”时最近在折腾长周期任务的LLM智能体时&#xff0c;我遇到了一个挺头疼的问题。想象一下&#xff0c;你训练了一个智能体&#xff0c;让它去完成一个需要多步骤、长时间运行的任务&#xff0c;比如管理一个持续数天的数据分析…

作者头像 李华
网站建设 2026/8/23 3:46:41

Transcript数据层设计:用TypeScript与Zustand构建健壮的会话记录系统

1. 项目概述&#xff1a;Transcript 数据层的核心价值在构建任何涉及复杂交互的应用时&#xff0c;数据层的设计往往是决定项目成败的关键。今天我想和大家深入聊聊我在kimi-code项目中&#xff0c;针对会话记录&#xff08;Transcript&#xff09;这一核心功能&#xff0c;如何…

作者头像 李华