crispix搞定上线!!新加入crispix Tool和接入nanobanana2!!!
首页展示





碎碎念
这里是阿轩,已经两个月没发帖子了,还有近期的备考压力和各种东西也压得我喘不过气来。项目部分,主要是在填之前留下的坑和完善各种机制,比如智能体的优化 登录功能 会员机制 邀请码 验证码 异步化等....
之前帖子留的坑

这几个月的开发 后端

前端

Crispix Tool 工具箱
之前说挖的坑其实就是crispix tool工具部分,提供各种模板或者工具让用户可以简单的上传图片或者输入几个提示词就可以生成模板的效果,还提供了图片信息解析 历史记录 下载功能。
这个功能其实在之前的图库里面也有,我看身边人的评价说使用的效果挺好就把他加了进来,并完善了一下加了些工具,比如比较常用的电商工具 白底图 创意海报、,还有一些小创意 生成表情包 生成手办等。模型方面也加入昨天新出的模型nanoBanana 2还有之前的nanoBanana Pro,都是有加上去并配一些模板的(昨天为了适配这个模型爆肝了一天)
图库的工具部分(前身)

crispix的工具部分(现在)





工具历史记录
功能部分展示完,接下来说以下技术点,之前的图库图片工具的方式其实很简单,其实都是复用鱼皮那个扩图的逻辑,即同步调用api,前端收到返回。这样子做很方便,但是有弊端:
- 同步返回会存在超时问题,即api接口超过了前端设定的时间就没办法返回结果,比如这个工具api平台那边生了3分钟,但是你前端设置接口超时2分钟,那你这个东西最终生成了也拿不到,因为超时了
- 由于是同步接口,前端只要一关页面,这个任务就没了,需要重新生成
- 工具记录没有存数据库,不支持历史记录
- 链接没有存对象存储,而api平台那边返回的图片链接是有效期的(一般是3天),超过这个时间就这个链接就失效,所以需要存对象存储
- 没办法实时获取工具进度
解决方法
针对这些问题,其实有个很通用的解决方法,就是异步化+持久化存储,即先创建任务返回任务id,再通过前端轮询 查询工具接口 查询工具状态。这也是各大云平台提供异步api接口的通用方案。这里简单说明一下具体实现,首先技术选型 java异步线程池+redis+mysql,因为是小项目没有那么多调用和并发所以使用内存线程池(项目大了可以考虑使用mq),其次redis用来实时保存任务状态,以便于前端快速获取任务状态接口,任务状态更新就更新redis的数据。最后mysql持久化保存工具数据 任务状态(几秒一次的轮询调用给mysql太慢 也压力太大了,这种即时 需要频繁查询的数据选择redis是最好的)
工具历史表
可以看到里面包含了status状态和任务id,这两个就是实现线程池的关键,除此之外还要包含工具输入信息和输出信息以便于前端获取更新页面。
具体调用逻辑
创建任务阶段(包含异步调用任务)
前端发起点击发送调用工具接口=>后端创建任务保存数据库,更新任务状态为0,异步调用api接口(这里并不需要等api接口返回才返回,我们通过ThreadUtil.execute交给线程池异步执行,所以之后的逻辑是直接返回id,接口已经返回完但是任务还是在执行) =>返回任务id
轮询阶段
前端调用完创建任务接口,获取完任务id就保存=>进行几秒一次的轮询 根据任务id获取任务状态,直到超时或者是任务状态更新为成功或者失败
异步调用任务的逻辑
异步调用api接口,交给线程获取接口返回,如果返回成功执行下一步逻辑保存对象存储,更新数据库任务状态为1,执行过程中如果有失败,就抛异常更新数据库任务状态为2表示这个任务失败
▼java复制代码try { // 线程池异步执行,不会影响接口返回 ThreadUtil.execute(() -> { try { executeRecraftCrispUpscaleAsync(taskId, request, usageRecord.getId(), userId); } catch (Exception e) { log.error("工具执行失败,taskId: {}", taskId, e); updateToolStatus(taskId, usageRecord.getId(), ToolTaskStatus.FAILED, null, getErrorMessage(e), 0); } }); } catch (RejectedExecutionException e) { // 捕获异常,如果任务出现问题抛异常,改任务状态为2(失败) log.error("线程池队列已满,无法执行工具任务,taskId: {}", taskId, e); updateToolStatus(taskId, usageRecord.getId(), ToolTaskStatus.FAILED, null, "系统繁忙,请稍后重试", 0); return ToolExecuteResponse.builder() .taskId(taskId) .toolId(toolEnum.getToolId()) .status(ToolTaskStatus.FAILED.getValue()) .message("系统繁忙,请稍后重试") .build(); } // 接口正常返回任务id return ToolExecuteResponse.builder() .taskId(taskId) .toolId(toolEnum.getToolId()) .status(ToolTaskStatus.PROCESSING.getValue()) .message("工具调用已提交,正在处理中") .build(); }
大致逻辑就是这样子,这里就简单说明一下,实际还是要考虑很多的东西,比如历史记录的创建,前端轮询逻辑,后端各个部分的异常,超时问题,国外地域图片读取慢,大文件,对象存储获取不到等等等。。这些问题都是我近期慢慢摸索出来的,感兴趣的朋友我可以根据这些出个帖子,对了留个坑,下期来说一下国外地域获取慢的问题,需要中转站?代理?nonono,其实正式上线只需要配置一些东西就可以了,留个坑下期说。
智能体部分
智能体部分其实现在并没有什么大的改动,想要了解的话看这篇文章。 https://www.codefather.cn/post/2002428860112683009#heading-0 主要就是测模型,换工具这样子,因为当一个框架完善了之后,其实效果怎么样还是取决于模型,越好的模型运用效果越好。新年发布了好几款模型qwen3.5 plus doubao系列2.0。不得不说这次的模型还是有很大提升,起码对于我的智能体而言整体体验是变好了的,这两款模型整体体验下来是 qwen优于doubao,但是调用和生成速度不如doubao。doubao虽然次点但也是十分优秀,所以我选择react部分(非规划模式)交给doubao2.0,比较严谨考验模型能力的plan(规划模式)交给qwen3.5plus。至于工具部分就将原来的即梦4.0更新为即梦4.5 将nanobanana更新为nanobanana2。 其实这个智能体还是有些缺陷,比如我只做了历史没做上下文工程,所以实际体验下来他其实是会忘记上一轮的对话的,这一部分是需要改进的点,还有提示词比较臃肿,不规范。还有随着ai的发展,发展出了一些新技术比如response api和agent skill,这些在我的项目里面也可以做一下更新。之后还打算把工具部分给用户选择,让用户自由选择调用什么工具,类似于下图。

想法总结
不知不觉我已经大三下了,也到了实习的阶段,近期的话还算是在备考,有点时间就搞搞我的项目。对未来的规划其实我想着边备考边找实习,因为现在春招嘛,可能是个比较好的时机,但是又受学历限制,想找这部分岗位可能比较难,先写了简历投了试试看把 这个项目这几天上线还是因为我妈他们需要催我,我才爆肝三天搞定的,因为我把图库下了,所以他们那些功能没得用比较难受。不得不说部署上线是真的麻烦,搞域名 搞备案 搞cdn 搞dns 搞反代 搞这搞那的,还好之前有些部署的经验才能这么快,不然估计都搞不定,还要再花好几天,这个部署我打算下期就搞这个,包含从0-1项目的部署教程 域名 cdn 备案 防护等,还有刚才说的国外图片加载慢的问题也会在这里得到解决。 其实我一直都是有很多的想法想去做 想去实现,很多时候受制于不敢或者说段位太低,而不去做也没有人,现在的话我希望去做一些更理想化的事,因为感觉现在已经有一些能力了,而且输了就输了嘛也没啥,至于技术方面我也会慢慢去探索,ai的发展太快了,我的这套框架在半年前还是感觉很不错 很新奇,现在看来就已经感觉落后了,所以才需要不断学习啊。 下面是我的微信,非常欢迎各位朋友来和我进行技术交流还有一些想法的(可能平时有事比较慢回)

