网站首页 > 技术文章 正文
我写程序通常会力求简洁,而不追求完美,因为在资源和实力都有限的情况下,有自知之明是很重要的。骑着自行车一直瞪着房车里的这样那样,这个我想要,那个我也想要,也是不行。
但是一旦你写出一个简单的程序,你就会发现这里要加一点,那里要改一下,可能就越改越复杂,偏离了初衷。所以要点就在于,怎样改进程序代码,使之更好的同时变得更简单?
今天我们就以之前发的聊天助手为实际的案例,分享一下优化代码的过程。
一、 去掉重复的代码。
最近我写的很多程序都用到了 Markdown,每次我都要把相同的代码复制来复制去,这很麻烦,且容易出错。如果你有什么好的改进,只会在一个程序里起作用,其他程序你还得一个个再去改一遍,这很容易出错。
于是我将这些相同的代码放进了一个库文件,然后在 aardio 中新增了一个库 web.form.simpleMarkdown 。
二、把大问题分解成独立的小问题。
web.form.simpleMarkdown 这个库很简单,它只负责一件事:Markdown 格式的解析与呈现。其他与此无关的代码不要放进去。这就使我们面对的复杂问题被拆解成了独立的、简单的小问题,小问题再怎么难搞也比一大堆问题挤在一起更容易解决,写出来的代码质量通常也会更好。
然后我又增加了一个新的库 web.form.chat 。
web.form.chat 主要是处理与维护 AI 聊天时产生的消息队列( 上下文 ),并且将这些消息队列显示在页面上。
web.form.chat 提供了简洁的接口,主要是三个函数:
- system 函数用于写入系统提示词。
- user 函数用于写入用户提示词。
- assistant 函数写入 AI 的回复。
web.form.chat 还负责在页面上显示用户、AI 的图标,在等待 AI 回复时显示加载进度:
三、调整方向与思路。
在我做完这些以后,发现程序突然变得很卡。
这就奇怪了,我没改啥呀,经过反复检查,我发现是 AI 回复打字到页面上,然后我同步到了一个滚动到页面底部的操作,这让程序变得非常卡。
于是我更换了思路,写了一个定时器,每隔 0.5 秒移动一次滚动条。这样一改,不但滚动条变流畅了,打字速度也快了好几倍,程序也不卡了。
过度密集的滚动本是无意义的,还会因为代码堆积与资源浪费导致的卡顿,实际产生的滚动次数会更少。
这只是一个很简单的例子,在实际的编程过程中,你需要经常这样去调整思路与方向。
大道殊途同归,写代码和做人是一回事。一条道走到黑,不知道变通的人,根本不可能写出好的程序。
有些小白和编程外行,总喜欢把程序员脑补成执着而不知变通的木脑袋,其实不知真正的木脑袋是他自己。编程只有习惯于灵活变通才能走下去,不然三天就会摔得鼻青脸肿,走不下去的。
四、重构主程序。
这时候我们的主程序就简单了。
我们去掉了重复的代码,主程序的代码大幅减少。
我们把大问题分解成小问题,并且逐一提前解决。那么主程序需要解决的问题就少了。
下面是主程序的完整代码。代码同样适用 DeepSeek (或者其他大模型)。DeepSeek 也是非常优秀的,我昨天说的那个问题,今天问 DeepSeek 多次,写出来的代码都是对的。
import win.ui;
/*DSG{{*/
var winform = win.form(text="调用大模型 API 实现 AI 聊天助手";right=973;bottom=607)
winform.add(
btnSend={cls="button";text="问 AI";left=801;top=569;right=918;bottom=604;db=1;dr=1;z=2};
editPrompt={cls="edit";left=8;top=452;right=965;bottom=567;db=1;dl=1;dr=1;edge=1;multiline=1;z=3};
promptTool={cls="syslink";text="提示词生成器";left=161;top=574;right=373;bottom=603;db=1;dl=1;z=5};
splitter={cls="splitter";left=8;top=446;right=965;bottom=451;db=1;dl=1;dr=1;frame=1;horz=1;z=4};
wndBrowser={cls="custom";text="自定义控件";left=8;top=5;right=965;bottom=442;db=1;dl=1;dr=1;dt=1;z=1}
)
/*}}*/
import web.form.chat;
var wb = web.form.chat(winform.wndBrowser);
//输入系统提示词
wb.system(
"你是 aardio 编程助手,擅长 aardio 编程。你会解答 aardio 编程问题,并且帮助生成或修改 aardio 代码。"
);
//响应按键事件
winform.btnSend.oncommand = function(id,event){
//输入 AI 提示词
wb.prompt( winform.editPrompt.text )
//创建多线程
thread.invoke(
function(winform,wb){
import web.rest.jsonClient;
var client = web.rest.jsonClient();
//请输入大模型 API 接口的令牌( Key )
client.setAuthToken("sk-gkX9OxBrGNGU6mWY69Ca14E347844cBbA32064E746E691Cf")
var bot = client.api("https://api.*******.ai/v1")
//调用接口
var ok,err = bot.chat.completions({
model = "claude-sonnet-3.5",
messages = wb.chatMessage,
temperature = 0.4,//温度
stream = true,//启用 SSE 事件流( text/event-stream )
max_tokens = 500,//限制 AI 生成的 token 数
},function(eventStream){ //如果不是流式推送则不需要用回调函数接收
//输出 AI 应答( 打字效果输出 )
wb.assistant(eventStream.data.choices);
} )
if(err){
wb.errorMessage(err)
}
},winform,wb
)
}
//拆分界面
winform.splitter.split(winform.wndBrowser,winform.editPrompt);
//默认设置输入框焦点
winform.editPrompt.setFocus();
winform.promptTool.link = "https://www.aardio.com/zh-cn/doc/?q=/zh-cn/ai/prompt/"
winform.show();
win.loopMessage();
运行效果:
我还挺佩服他居然会用 aardio 里的 win.ui.grid 。
猜你喜欢
- 2024-12-24 Excel VBA 用户窗体设置/一步一步代你设计EXCEL用户+密码登录界面
- 2024-12-24 家庭收支理财管理系统 Access数据库系统课程设计制作实例
- 2024-12-24 Qt 2D绘图:图形视图框架的事件处理与传播
- 2024-12-24 MFC界面库BCGControlBar v32.1 - 可视化管理器和主题升级
- 2024-12-24 DJYGUI系列文章九:GDD消息系统 gd信息
- 2024-12-24 Qt设备识别(简单的密钥生成器) qt设备管理系统
- 2024-12-24 Access开发的《财务经济管理系统》
- 2024-12-24 初级开发人员告诉我:OO 设计模式太复杂而且没用
- 2024-12-24 从零开始学Qt(89):UDP单播和广播
- 2024-12-24 Qt入门阶段之事件 qtc间期延长的临床意义
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)