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

相关推荐
阿文和她的Key3 小时前
GPT-5.6 降价后, API 账单的三层漏斗该怎么拆
人工智能·gpt·ai·chatgpt
总捣什么乱13 小时前
ChatGpt 系列文章——编码与智能体
人工智能·chatgpt
LXT7124 小时前
2026职称申报冲刺期:ChatGPT、Claude、Kimi、雷小兔同题横评
人工智能·chatgpt
weixin_429615999 小时前
快速生成流程图
人工智能·chatgpt·aigc·流程图
TunerT_TQ10 小时前
GitHub深度工程评测:AI 系统提示词泄露知识库深度评测:6万星system_prompts_leaks情报资产背后,藏着什么?
人工智能·chatgpt·github·提示词工程·#valhalla静态工程审阅·systemprompt·大模型工程
吨吨ai13 小时前
# 2026年8月更新:ChatGPT、Codex、Plus、Pro 与 Semantic CI/CD(GPT-5.6 智能变更流水线技术分享)
人工智能·gpt·chatgpt
天天有money1 天前
API中转站在社媒矩阵里的价值:多平台文案如何统一改写
gpt·线性代数·ai·chatgpt·矩阵
LDZKKJ1 天前
OpenAI暂停GPT-6训练:AI行业从“竞速“到“刹车“的分水岭
人工智能·gpt·语言模型·chatgpt·transformer
仙逆GPT1 天前
Codex定时任务怎么设置?ChatGPT Plus用Worktree自动巡检项目
chatgpt·定时任务·codex·git worktree·chatgpt plus
gptAI_plus1 天前
TypeScript 7.0 已发布:大型项目迁移别只看提速,这 8 个兼容性问题更关键
chatgpt·openai