用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多年代码的老程序员,如果大家想学习编程,可以关注公众号:入职啦,我会分享更多的编程实战经验。

相关推荐
仙逆GPT3 小时前
ChatGPT、Codex趋势:为什么AI时代最重要的能力,不是写代码,而是定义问题?
chatgpt·codex·ai agent·chatgpt plus·chatgpt pro·ai coding
AI导出鸭6 小时前
怎么让文心做表格?AI导出鸭苹果版将文心输出的管道表格智能解析为二维结构,一键导出为Excel或Word标准表格
人工智能·chatgpt·word·excel·ai导出鸭
wujian831121 小时前
AI手机版怎么直接生成word?用“AI 导出鸭”把碎片时间变成专业文档
人工智能·ai·chatgpt·智能手机·word·ai导出鸭
枫叶丹41 天前
MCP、A2A、AG-UI:一篇讲清 Agent 协议栈
人工智能·ui·chatgpt·agent·codex
AI导出鸭1 天前
怎么让Grok做表格?AI导出鸭苹果版通过专属解析引擎,将Grok输出的管道表格智能还原为二维结构,一键导出Excel或Word标准表格。
人工智能·chatgpt·word·excel·ai导出鸭
精彩AI说1 天前
ChatGPT生成内容总是重复怎么办?答案啰嗦、观点重复与提示词优化方法
chatgpt·ai写作·提示词·内容去重
江畔柳前堤1 天前
LLM + Agent 模型效果评估:从入门到工业级体系构建的完整指南
开发语言·人工智能·自然语言处理·chatgpt·架构·json·batch
精彩AI说1 天前
ChatGPT识别图片不准确怎么办?文字遗漏、表格识别与截图模糊排查
chatgpt·表格识别·ai工具·图片识别
盼小辉丶1 天前
PyTorch强化学习实战——用预训练语言模型和ChatGPT玩转文本游戏
pytorch·深度学习·语言模型·chatgpt·强化学习
JavaPub-rodert1 天前
Codex 从 0 开始:安装 ChatGPT,并接入 DeepSeek
人工智能·gpt·chatgpt