网站后台模板 php,滕州网站开发,上海人才网积分查询,ui网页设计公司背景
前几天#xff0c;公司的同事们一起吃了个饭#xff0c;餐桌上大家聊到大模型的落地场景。我个人在去年已经利用百度千帆平台写过案例#xff0c;并发过博客#xff08;传送门#x1f449;#xff1a;利用文心千帆打造一个属于自己的小师爷#xff09;#xff0c…背景
前几天公司的同事们一起吃了个饭餐桌上大家聊到大模型的落地场景。我个人在去年已经利用百度千帆平台写过案例并发过博客传送门利用文心千帆打造一个属于自己的小师爷只不过那时候没有再继续深入真正做好大模型在项目上的落地。
这次刚刚开发完的一个考试系统里面正好有一个落地场景利用AI的能力来生成题库的解析内容可以大幅提高效率。
准备工作
因为公司的云服务商是腾讯所以我这次使用的是腾讯混元大模型在开始集成工作前要先去腾讯云的控制台开通相关的服务。
事实上所有集成任何第三方云端大模型的步骤都差不多这一步我就不多说了参照文档操作即可传送门腾讯混元大模型。
需要注意的是新申请的服务可以领取一定的免费额度而且lite模型目前是一直免费的这点和各家也都差不多。在这里插入图片描述
集成
接入方式
大模型集成到项目的方式有很多有的可能就是一个模块有的可能是一个独立服务总之就是根据实际的项目情况接入的方式呈现的结果都是不一样的。
我这边把大模型在系统里的定位就是一个随叫随到的智能助手在整个后台管理工作的场景中都可以方便的和大模型交互。
业务代码之前
配置
AiConfigs: [{IsOpenaiApi: yes,Model: moonshotai,SecretKey: ,SecretId: ,AppId: ,ApiKey: sk-{xxxxxxxxxx}},{IsOpenaiApi: no,Model: hunyuan,SecretId: {xxx},SecretKey: {xxx},AppId: xxx,ApiKey: }这里我是把请求模型的密钥参数放到配置文件里了事实上生产环境中更推荐的做法是把密钥参数放到系统的环境变量里更加安全。
这里这样配置是为以后扩展做准备此次集成的是混元大模型的sdk申请的方式是按sdk的方式申请云服务商一般会给到一组密钥对包括secretidsecretkey等而类似openai api的方式是只有一个appkey所以我这里是这样定义的参数方便后续反序列化。
其实目前各家基本都支持openapi的方式了但因为我这里只有公司腾讯云的子账号申请openapi风格的key需要主账号而且要主账号提供mfa验证码我有点社恐没去找主账号持有人沟通就暂时没用~
但我还是申请了一个个人的月之暗面moonshot账户传送门Moonshot AI并获得了一个openapi风格的apikey确保两种接入方式都支持。
定义对照模型
public class AiConfig
{[JsonProperty(IsOpenaiApi)]public string IsOpenaiApi { get; set; }[JsonProperty(Model)]public string Model { get; set; }[JsonProperty(SecretKey)]public string SecretKey { get; set; }[JsonProperty(SecretId)]public string SecretId { get; set; }[JsonProperty(AppId)]public string AppId { get; set; }/// summary/// IsOpenaiApi为yes时ApiKey为必填项/// /summary[JsonProperty(ApiKey)]public string ApiKey { get; set; }//public string Token { get; set; }
}这里的就是参照配置文件的格式创建对照模型方便后续的序列化工作。
创建工厂类
public class AiConfigFactory
{private readonly ListAiConfig _aiConfigs;public AiConfigFactory(ListAiConfig aiConfigs){_aiConfigs aiConfigs;}public AiConfig GetConfigByModel(string Model){return _aiConfigs.FirstOrDefault(config config.Model.Equals(Model, StringComparison.OrdinalIgnoreCase));}
}注入服务
private static void ConfigureAi(this IServiceCollection services, IConfiguration configuration)
{var aiConfigs new ListAiConfig();configuration.GetSection(AiConfigs).Bind(aiConfigs);// 注册工厂为单例服务services.AddSingleton(new AiConfigFactory(aiConfigs));//...其他配置
}
...
//这里我是把每个中间件都分离成一个小模块配置完成后在入口处统一注册
//像这样
builder.Services.ConfigureAi(_configuration);其他工作
因为是要全场景的运行ai助手得充分发挥系统基础设施的能力所以这里还有根据情况注入Redis消息队列数据库等中间件这部分代码都是很常见的不再赘述。
接入混元SDK
准备工作就绪以后就可以引入混元sdk了这部分就是标准的调参工作非常简单大家可以跳过本节直接参照混元的接口文档传送门混元大模型然后按照自己喜欢的放方式完成对接.
我这里简单介绍下
安装必要sdk
安装混元sdk可以直接在vs的nuget包管理器搜索TencentCloudSDK.Hunyuan关键字安装或者直接通过下面方式
# 命令行
dotnet add package TencentCloudSDK.Hunyuan
# 或者vs里打开程序包管理器控制台
Install-Package TencentCloudSDK.Hunyuan创建控制器
这里我只给出几个关键的业务代码
//chat接口
[HttpPost,ValidateAntiForgeryToken]
public async TaskIActionResult SimpleChat(ChatModel chatModel)
{if (string.IsNullOrWhiteSpace(chatModel.prompt))return Json(_resp.error(无输入));try{if(string.IsNullOrEmpty(chatModel.admin))chatModel.admin adminId;await _capPublisher.PublishAsync(CapConsts.PREFIX GetHunyuanResponse, chatModel);return Json(_resp.success(0, ok));}catch (Exception e){Assistant.Logger.Error(e);return Json(_resp.error(获取响应失败 e.Message));}
}[HttpGet(airesp)]
public async Task AiResponseSse(string admin)
{Response.Headers[Content-Type] text/event-stream;Response.Headers[Cache-Control] no-cache;if (HttpContext.Request.Protocol.StartsWith(HTTP/1.1)){Response.Headers[Connection] keep-alive;}try{if (string.IsNullOrEmpty(admin))admin adminId;while (true){await Task.Delay(50);// 从通道中读取消息这里等待消息到来if (!await _redisCachingProvider.KeyExistsAsync(cacheId admin))return;var message await _redisCachingProvider.LPopAsyncstring(cacheId admin);if (string.IsNullOrEmpty(message))continue;// 按照SSE协议格式发送数据到客户端await Response.WriteAsync($data:{message}\n\n);await Response.Body.FlushAsync();}}catch (Exception ex){// 可以记录异常等处理Console.WriteLine(ex.Message);}
}[NonAction]
[CapSubscribe(CapConsts.PREFIX GetHunyuanResponse)]
public async Task GetHunyuanResponse(ChatModel chatModel)
{try{Assistant.Logger.Warning(开始请求混元接口);var commonParams new HunyuanCommonParams();// 实例化一个client选项可选的没有特殊需求可以跳过ClientProfile clientProfile new ClientProfile();// 实例化一个http选项可选的没有特殊需求可以跳过HttpProfile httpProfile new HttpProfile();httpProfile.Endpoint commonParams.Endpoint;clientProfile.HttpProfile httpProfile;// 实例化要请求产品的client对象,clientProfile是可选的HunyuanClient client new HunyuanClient(_cred, commonParams.Region, clientProfile);// 实例化一个请求对象,每个接口都会对应一个request对象ChatCompletionsRequest req new ChatCompletionsRequest();req.Model HunyuanModels.Lite;if (!string.IsNullOrWhiteSpace(chatModel.model))req.Model chatModel.finalModel;Message message1 new Message();message1.Role user;message1.Content chatModel.prompt;req.Messages [message1];req.Stream true;ChatCompletionsResponse resp await client.ChatCompletions(req);// 输出json格式的字符串回包if (resp.IsStream){// 流式响应foreach (var e in resp){Assistant.Logger.Debug(e.Data);await _redisCachingProvider.RPushAsync(cacheId chatModel.admin, new Liststring() { e.Data });}}else{// 非流式响应Assistant.Logger.Debug(JsonConvert.SerializeObject(resp));}}catch (Exception ex){Assistant.Logger.Error(ex);}finally{await _redisCachingProvider.KeyExpireAsync(cacheId chatModel.admin, 600);}
}简单解释下这段代码主要分3个逻辑来处理云端返回的消息
第一步是前端通过接口把结构化的消息提交到服务端也就是SimpleChat接口 第二步SimpleChat接收到消息后立刻返回并发布任务让服务端后台开始请求混元的服务端获取相应结果并暂存到Redis队列里 第三步是服务端通过SSE链接的方式把Redis队列里的消息推到本地客户端 事实上不暂存直接推也是可以的我这里因为有其他业务交叉所以这样处理了一下。 另外对接混元sdk的方法还有一种common sdk的方式更加轻量级也就是把大量实例化和序列化的工作交给混元的服务器我们自己的服务端只承担点传输的工作对性能的优化也是有好处的而且也能更方便的把sdk的代码写法改成openai api的方式建议后续直接使用common sdk的方式。
前端代码就不在展示了按照喜好实现即可
效果 演示视频 总结
目前来说只是初步接入到了系统样式上还些问题需要处理而且目前只支持文字模式不支持图片也没有完全和业务绑定后续会把一些常见的场景比如题目解析智能分析用户的考卷等场景和ai深度结合。
好了基本就这样了