用Rust实现免费调用ChatGPT的命令行工具 (二)

本文发表于入职啦(公众号: ruzhila) 大家可以访问入职啦学习更多的编程实战。

代码已经开源: fgpt 欢迎大家star⭐和fork

先看看今天达到的效果:

接着上一篇文章,我们继续实现fgpt命令行工具,之前已经实现了根据命令行参数返回ChatGPT的结果,这次我们要实现更多的功能,比如支持文件输入、交互式输入等。

Shell的管道输入

Unix/Linux 的Shell是非常强大的,它支持管道输入,比如下面的命令:

arduino 复制代码
git diff | fgpt "Write a git commit bief with follow diff"

这个命令,相当于把git diff的输出作为输入,传递给fgpt,然后fgpt返回一个git commit的描述。

根据之前的代码实现,是支持多段消息输入的方式, 从程序的数据流程上规划了多段消息的组成:

  • 第一部分: 作为系统提示, 在后续的Code模式上可以起作用,就是给ChatGPT设计一个角色
  • 第二部分: 作为用户输入, 主要是是命令行的输入, 也就是Write a git commit bief ... 这段文本
  • 第三部分: 作为文件或者管道输入, 也就是git diff的输出

对应就是要拼出一个这样的数据结构:

json 复制代码
[
    {
        "role": "system",
        "message": "Your are a developer", // 根据参数来确定
    },
    {
        "role": "user",
        "message": "Write a git commit bief with follow diff" // 从命令行输入
    },
    {
        "role": "user",
        "message": "......" // 从文件或者管道输入
    }
]

Code模式的实现

fgpt中,我们可以通过-c或者--code参数来指定Code模式,这个模式下,fgpt返回的是一段代码,而不是一段文本。

为了实现这个效果,我们需要在会话的第一部分添加一个Prompt, 具体可以见src/role.code.prompt的内容,这个文件会通过include_str!这个宏编译到代码中:

css 复制代码
let mut messages = vec![];
    if state.code {
        messages.push(Message {
            role: "system".to_string(),
            content: include_str!("./role.code.prompt").to_string(),
            content_type: "text".to_string(),
        });
    }

这样可以确保在Code模式下,会话的第一部分是一个角色设定,加上用户的输入,就可以返回一段代码了:

ruby 复制代码
mpi@mpis-Mac-mini fgpt % fgpt -c "Write python code to reverse a string"
def reverse_string(s):  
    return s[::-1]    
# Example usage:       
# original_string = "hello" 
# reversed_string = reverse_string(original_string)
# print(reversed_string) 

管道和文件输入

Linux的程序在运行过程中,要识别输入的来源,是来自于文件、管道还是终端,这个是通过stdin来实现的,可以通过std::io::stdin().is_terminal()来判断当前是管道还是终端

如果是管道输入,我们需要读取stdin的内容作为第三部分的输入:

css 复制代码
if !std::io::stdin().is_terminal() {
        // it may be a pipe or a file
        let mut content = String::new();
        std::io::stdin().read_to_string(&mut content)?;
        messages.push(Message {
            role: "user".to_string(),
            content,
            content_type: "text".to_string(),
        });
    }

交互式输入

交互式最典型的就是Python的REPL模式,用户可以输入一段代码,然后返回结果,这个模式在fgpt中也是支持的,只需要不带任何参数就可以进入交互式模式。

要实现这个效果,那么就需要依赖一个readline类似的库:rustyline, 这个库可以非常方便的实现交互式输入,比如下面的代码:

scss 复制代码
let mut rl = rustyline::Editor::<()>::new();
    loop {
        let readline = rl.readline(">> ");
        match readline {
            Ok(line) => {
                if line.is_empty() {
                    continue;
                }
                rl.add_history_entry(line.as_str());
                messages.push(Message {
                    role: "user".to_string(),
                    content: line,
                    content_type: "text".to_string(),
                });
            }
            Err(_) => break,
        }
    }

实现对话效果

根据Web API的协议规范,在同个device_id下,接最后一条消息的conversation_idmessage_id就可以完成对话的效果, 只需要记录最后一条消息的conversation_idmessage_id就可以了。

ini 复制代码
let mut conversation_id = None;
    let mut message_id = None;
    for message in messages.iter() {
        conversation_id = Some(message.conversation_id.clone());
        message_id = Some(message.message_id.clone());
    }

    // next request 
    let req = CompletionRequest {
        conversation_id,
        parent_message_id: message_id,
        ....
    };

总结

当前这个版本已经能支持对话和交互式输入了,下一步我们要实现一个Reverse Proxy的功能

但是还有很多优化空间,特别是配色的支持,还有要支持输出实时预览的,可以将输出的结果带颜色的输出到终端

我是一个写了20多年代码的老程序员,如果大家想学习编程,可以关注公众号:入职啦,我会分享更多的编程实战经验。

相关推荐
s_yellowfish2 小时前
Linux服务器pm2 运行chatgpt-on-wechat,搭建微信群ai机器人
linux·服务器·chatgpt
that's boy1 天前
突围边缘:OpenAI开源实时嵌入式API,AI触角延伸至微观世界
人工智能·gpt·chatgpt·开源·openai·midjourney
AIGC大时代1 天前
如何使用ChatGPT辅助文献综述,以及如何进行优化?一篇说清楚
人工智能·深度学习·chatgpt·prompt·aigc
hunteritself2 天前
AI Weekly『12月16-22日』:OpenAI公布o3,谷歌发布首个推理模型,GitHub Copilot免费版上线!
人工智能·gpt·chatgpt·github·openai·copilot
测试者家园2 天前
ChatGPT生成接口文档的方法与实践
软件测试·chatgpt·测试用例·接口测试·接口文档·ai赋能·用chatgpt做软件测试
小虚竹2 天前
如何利用ChatGPT生成不同类型的文章大纲
chatgpt
AI小欧同学3 天前
【AIGC-ChatGPT进阶副业提示词】育儿锦囊:化解日常育儿难题的实用指南
chatgpt·aigc
测试者家园3 天前
ChatGPT接口测试用例生成的流程
软件测试·chatgpt·测试用例·接口测试·测试图书·质量效能·用chatgpt做测试
m0_748256563 天前
如何使用Python WebDriver爬取ChatGPT内容(完整教程)
开发语言·python·chatgpt
测试者家园3 天前
ChatGPT与接口测试工具的协作
软件测试·测试工具·chatgpt·接口测试·ai赋能·用chatgpt做软件测试·测试图书