基于原生deepseek开发的智能终端工具Nuwa Terminal

基于原生deepseek开发的智能终端工具Nuwa Terminal

基于生成式AI可以重构一切传统软件的思路,我产生了一种想法就是使用AI大模型,来开发一款更加智能的终端工具。于是Nuwa Terminal诞生了。

nuwa-terminal 是一个在终端中与大语言模型(LLM)聊天的程序,该工具基于LLM,旨在使终端更加智能。这个终端可以帮助用户使用自然语言
执行命令或任务,同时它还可以作为终端智能助手,你可以询问任何关于软件开发的任何问题。

为什么需要Nuwa Terminal智能终端

作为程序员,实际上我们只有少部分时间在写代码,大部分的时间在分析需求、阅读文档、调试代码、解决bug、沟通交流等。过程中有相当一部分
时间是在使用终端来完成一些任务,比如:

  • 使用git命令提交代码。
  • 使用docker或者K8S命令部署项目并进行测试。
  • 调试应用程序。
  • 使用Linux系统命令调查各种系统问题。

这些任务中,大部分都是重复性的工作,同时程序员需要查阅各种文档,Linux map page等等,这些都大大降低了我们的工作效率。
多个上下文的切换,降低了同一任务的专注度。尤其对于复杂的任务来说,如果是要编写shell脚本的话(shell 并不是每天都在使
用的编程语言,只有在需要的时候,尤其是测试的时候使用),并不是每个人都擅长。这需要花更多的时间学习来完成。

然而,大语言模型存储了大量的知识,有些模型尤其擅长软件开发,Linux及开源软件的知识。通过大语言模型,可以轻松的使用自然
语言来生成Linux命令行或者shell脚本。

因此使用AI大模型的能力来赋能终端,可以让程序员的工作更加容易,同时专注在当前任务上。

Nuwa terminal的架构

nuwa terminal 的架构非常简单,它使用langchaingo作为基础库和大模型进行交互,langchaingo是langchain的golang复刻版本,
nuwa terminal 是基于单个AI agent的架构,通过调用命令和脚本来完成任务。

Nuwa terminal 目前支持的功能特性

  • 基于终端的AI运维助力。
  • 使用自然语言生成shell命令并执行。
  • 使用自然语言生成shell脚本并执行。
  • 使用智能体模式执行复杂任务或者故障排查。
  • 支持执行自然语言编写的脚本。
  • 支持和bash之间进行自由切换。

如何使用 Nuwa Terminal

Nuwa Terminal 的使用文档可以参考这里

安装前准备

安装和使用

# 构建并安装 nuwa-terminal-chat
git clone https://github.com/darmenliu/nuwa-terminal-chat.git
cd nuwa-terminal-chat
make

# 使用 sed 将 LLM_API_KEY=apikey 替换为真实的 api key
sed -i 's/LLM_API_KEY=apikey/LLM_API_KEY=<你的 api key>/g' envs.sh
source envs.sh

# 运行 nuwa-terminal-chat
(base) $ ./nuwa-terminal
███    ██ ██    ██ ██     ██  █████      ████████ ███████ ██████  ███    ███ ██ ███    ██  █████  ██
████   ██ ██    ██ ██     ██ ██   ██        ██    ██      ██   ██ ████  ████ ██ ████   ██ ██   ██ ██
██ ██  ██ ██    ██ ██  █  ██ ███████        ██    █████   ██████  ██ ████ ██ ██ ██ ██  ██ ███████ ██
██  ██ ██ ██    ██ ██ ███ ██ ██   ██        ██    ██      ██   ██ ██  ██  ██ ██ ██  ██ ██ ██   ██ ██
██   ████  ██████   ███ ███  ██   ██        ██    ███████ ██   ██ ██      ██ ██ ██   ████ ██   ██ ███████

/home/bob>>> 你是谁?
你: 你是谁?
NUWA: 我是NUWA,一个终端聊天工具。我可以通过生成代码、执行命令和回答问题来帮助你进行软件开发。我有三种模式:

* **聊天模式:** 用于一般聊天和代码生成。
* **命令模式:** 用于执行Linux命令。
* **任务模式:** 用于生成shell脚本并执行Linux命令。

你可以使用以下命令在模式之间切换: chatmode, cmdmode, 和 taskmode。

今天我能为你做些什么?

/home/bob>>> 你能为我做什么?
你: 你能为我做什么?
NUWA: 我是NUWA,你友好的软件工程师聊天机器人。我可以帮助你完成各种任务,包括:

**聊天模式:**
* 回答你关于软件开发概念、最佳实践等问题。
* 根据你的指示生成各种编程语言的代码片段。

**命令模式:**
* 直接在我们的聊天中执行Linux命令。

**任务模式:**
* 创建根据你需求定制的shell脚本。
* 在任务上下文中执行Linux命令。

要开始,告诉我你想进入哪种模式:
* **chatmode** 用于一般软件开发聊天
* **cmdmode** 用于运行Linux命令
* **taskmode** 用于创建和运行shell脚本

今天你想做什么?

/home/bob>>>

Nuwa Terminal 的工作模式

Nuwa 有四种工作模式,分别是:

  • 聊天模式:用于一般聊天和代码生成。
  • 命令模式:用于执行Linux命令。
  • 任务模式:用于创建和运行shell脚本。
  • 智能体模式:用于执行复杂任务或者故障排查。

聊天模式相当于Nuwa是一个智能运维助手,你可以和它进行聊天,询问各种问题,它可以帮助你回答问题,并生成代码或者shell命令。
在命令模式下,你可以通过自然语言生成Linux命令,并执行。同样任务模式下,你可以通过自然语言生成shell脚本,并执行。智能体
模式还是一个实验性的功能,在智能体模式下,Nuwa可以执行更加复杂的任务,比如:寻找系统高负载的原因,并找出相应的进程。

以下可以提供一些使用示例:


# 使用聊天模式,生成一个查询所有指定namespace下k8s pods日志的脚本
nuwa-terminal-chat@ 帮我生成查询所有指定namespace下k8s pods日志的脚本,
You: 帮我生成查询所有指定namespace下k8s pods日志的脚本,
NUWA: 好的,我可以帮你生成一个查询指定 Kubernetes 命名空间下所有 Pods 日志的脚本。这个脚本将使用 kubectl 命令来获取日志。

@get_pods_logs.sh@
#!/bin/bash

# 检查是否提供了命名空间参数
if [ -z "$1" ]; then
  echo "Usage: $0 "
  exit 1
fi

NAMESPACE=$1

# 获取指定命名空间下的所有 Pods
PODS=$(kubectl get pods -n $NAMESPACE -o jsonpath='{.items[*].metadata.name}')

# 遍历每个 Pod 并获取日志
for POD in $PODS; do
  echo "Fetching logs for pod: $POD"
  kubectl logs $POD -n $NAMESPACE
done

### 使用方法:
1. 将上述脚本保存为 get_pods_logs.sh。
2. 赋予脚本执行权限:chmod +x get_pods_logs.sh。
3. 运行脚本并指定命名空间:./get_pods_logs.sh <namespace>。

这个脚本会输出指定命名空间下所有 Pods 的日志。如果你需要进一步处理这些日志,可以在脚本中添加相应的逻辑。
# 默认是聊天模式,切换到命令模式,执行命令时以自然语言描述
nuwa-terminal-chat@ cmdmode
You: cmdmode
2025-01-11 21:26:03 INFO  NUWA TERMINAL: Mode is cmdmode
nuwa-terminal-chat# 获取当前系统cpu占用较高的进程
You: 获取当前系统cpu占用较高的进程
NUWA: execute command: ps aux --sort=-%cpu | head -n 10
time=2025-01-11T21:26:47.635+08:00 level=INFO msg=Matched: "match content"="ps aux --sort=-%cpu | head -n 10"
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      245519  2.1  0.1 6258356 30852 pts/5   Sl+  21:25   0:01 ./nuwa-terminal
root           1  1.0  0.0 167020 12400 ?        Ss   11:33   6:03 /sbin/init
root         781  0.4  0.2  43388 36800 ?        S    11:33   2:37 python3 /snap/ubuntu-desktop-installer/1286/usr/bin/cloud-init status --wait
# 切换到任务模式,生成一个shell脚本,并执行
# taskmode
You: taskmode
2025-01-11 21:31:09 INFO  NUWA TERMINAL: Mode is taskmode
nuwa-terminal-chat> 查询当前内存使用情况,找出系统中占用内存较高的前5进程
You: 查询当前内存使用情况,找出系统中占用内存较高的前5进程
NUWA: 以下是一个用于查询当前内存使用情况并找出系统中占用内存较高的前5进程的Shell脚本:

#!/bin/bash

# 获取内存使用情况并排序,显示前5个进程
ps aux --sort=-%mem | head -n 6

### 解释:
- ps aux:显示所有进程的详细信息。
- --sort=-%mem:按照内存使用率(%MEM)降序排序。
- head -n 6:显示前6行(包括标题行),即前5个进程。

运行此脚本后,您将看到系统中占用内存最高的前5个进程及其详细信息。
time=2025-01-11T21:33:12.748+08:00 level=INFO msg="Adding file to source file dict" content="`` shell\n#!/bin/bash\n\n# 获取内存使用情况并排序,显示前5个进程\nps aux --sort=-%mem | head -n 6\n``"
time=2025-01-11T21:33:12.748+08:00 level=INFO msg=Matched: "match_content "="#!/bin/bash\n\n# 获取内存使用情况并排序,显示前5个进程\nps aux --sort=-%mem | head -n 6"
2025-01-11 21:33:12 INFO  NUWA TERMINAL: script file saved to
                      │   .nuwa-terminal/scripts/39ea4f03-79d9-4cc4-8ea4-1cb338ce9314.sh
2025-01-11 21:33:12 INFO  NUWA TERMINAL: script output
                      └ output: + ps aux --sort=-%mem
+ head -n 6
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

2025-01-11 21:33:12 INFO  NUWA TERMINAL: script file removed

未来的开发计划

  • 支持项目和解释代码
  • 支持分析日志和解释日志
  • 支持远程模式,通过ssh在远程主机上执行命令或者任务
  • 支持通过自然语言执行git 相关的操作

贡献者招募

Nuwa Terminal 是一个开源项目,是一个有趣的学习和尝试,通过AI大模型来重构终端工具,欢迎有兴趣的伙伴参与贡献,共同打造一个更加智能的终端工具。
如果感兴趣,可以联系我,一起交流。

如果你关注到这个项目,欢迎给个star,谢谢。

写在最后

我希望将Nuwa Terminal打造成一个更加智能的终端工具,也许它会成为程序员运维工作的好帮手。未来我会引进多智能体架构,使得该工具能够
更加智能和自主的完成任务,目前该工具还处于早期阶段,欢迎大家关注和使用,并提出宝贵的意见和建议。足够多的反馈,会让我
更有动力去完善它。

最后,感谢大家的关注和支持。

使用golang开发AI大模型应用-langchaingo介绍

使用golang开发AI大模型应用-langchaingo介绍

随着生成式大模型的发展,AI大模型应用的开发也变得越来越重要。由于Python语言在AI领域良好的生态和丰富的库,因此Python语言成为AIGC领域的绝对统治者。在AI领域,Python成为开发AI应用的首选语言。2024在tiobe编程语言排行榜中,Python成为霸榜的编程语言。

但是在后端服务及云原生领域,Golang却是首选语言,相比Python,Golang有更好的性能和并发性。因此,如果你想开发基于AI大模型的后端应用,Golang一定是个不错的选择。美中不足的是,Golang在AI领域的生态相对较弱,能够使用的现成的库并不是很多。

LangChain Go 简介

Langchain目前成为使用python开发AI智能应用的首选框架,它提供了一套工具、组件和接口,使开发人员能够更轻松地构建智能应用。

LangChain 框架包含以下主要组件:

  • Models: 作为基础构建块,提供语言理解和生成能力。
  • Prompts: 用于指导模型生成特定输出的模板。
  • Indexes: 用于高效检索和提取信息。
  • Chains: 将多个组件连接起来,实现复杂的任务流程。
  • Agents: 具有自主决策能力的智能体,可以根据任务选择合适的工具。
  • Memory: 为对话型应用提供历史记忆功能,确保对话的连贯性。

LangChain Go是用Go语言实现的langchain库,基本功能对标了Python版本的langchain库。
使用LangChain Go,开发者可以使用Golang语言快速的构建AI服务及应用。

Github 地址: https://github.com/tmc/langchaingo
开发文档:https://tmc.github.io/langchaingo/docs/
接口文档:https://pkg.go.dev/github.com/tmc/langchaingo

准备工作

在开始之前,你需要安装Go语言环境,可以参考Go语言官方文档进行安装。

由于Golang 也存在多钟版本,如果你需要从多个Golang版本之间进行切换时,可以使用 Glang version manager 进行管理。

使用Google 的Gemini模型

我个人开发过程中,起初使用的Google的Gemini 1.5模型,但是由于免费版本对于请求有一些限制,我后来使用国产的Deepseek模型,其价格非常便宜,性能也不错。

最近Google发布了最新的Gemini 2.0 模型,相比1.5版本,Gemini 2.0 模型在生成式任务上有了更好的表现。目前Gemini 2.0 Flash 版本对开发者提供免费使用,可以通过Google AI Studio申请API key: https://aistudio.google.com/apikey

以下代码示范如何使用LangChain Go调用Google Gemini 2.0模型生成文本:

编译以下代码需要添加go.mod文件:


module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    cloud.google.com/go v0.114.0 // indirect
    cloud.google.com/go/ai v0.7.0 // indirect
    cloud.google.com/go/aiplatform v1.68.0 // indirect
    cloud.google.com/go/auth v0.5.1 // indirect
    cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
    cloud.google.com/go/compute/metadata v0.3.0 // indirect
    cloud.google.com/go/iam v1.1.8 // indirect
    cloud.google.com/go/longrunning v0.5.7 // indirect
    cloud.google.com/go/vertexai v0.12.0 // indirect
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/felixge/httpsnoop v1.0.4 // indirect
    github.com/go-logr/logr v1.4.1 // indirect
    github.com/go-logr/stdr v1.2.2 // indirect
    github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
    github.com/golang/protobuf v1.5.4 // indirect
    github.com/google/generative-ai-go v0.15.1 // indirect
    github.com/google/s2a-go v0.1.7 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
    github.com/googleapis/gax-go/v2 v2.12.4 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
    go.opencensus.io v0.24.0 // indirect
    go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect
    go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
    go.opentelemetry.io/otel v1.26.0 // indirect
    go.opentelemetry.io/otel/metric v1.26.0 // indirect
    go.opentelemetry.io/otel/trace v1.26.0 // indirect
    golang.org/x/crypto v0.23.0 // indirect
    golang.org/x/net v0.25.0 // indirect
    golang.org/x/oauth2 v0.21.0 // indirect
    golang.org/x/sync v0.7.0 // indirect
    golang.org/x/sys v0.20.0 // indirect
    golang.org/x/text v0.15.0 // indirect
    golang.org/x/time v0.5.0 // indirect
    google.golang.org/api v0.183.0 // indirect
    google.golang.org/genproto v0.0.0-20240528184218-531527333157 // indirect
    google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
    google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
    google.golang.org/grpc v1.64.0 // indirect
    google.golang.org/protobuf v1.34.1 // indirect
)

主函数:


package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/googleai"
)

func main() {
    ctx := context.Background()
    apiKey := os.Getenv("GOOGLE_API_KEY")
    llm, err := googleai.New(ctx, googleai.WithAPIKey(apiKey), googleai.WithDefaultModel("gemini-2.0-flash-exp"))
    if err != nil {
        log.Fatal(err)
    }

    prompt := "简单介绍下langchain go库?"
    answer, err := llms.GenerateFromSinglePrompt(ctx, llm, prompt)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(answer)

运行以上程序:


export GOOGLE_API_KEY="your-google-api-key"
go run main.go

使用OpenAI的模型生成内容

OpenAI几乎没有开放免费额度给开发者使用,同时国内用户也无法使用,这是比较可惜的。但是OpenAI的模型在生成式任务上表现非常优秀,因此很多开发者还是会选择使用OpenAI的模型。

go mod文件:


module module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
)

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    llm, err := openai.New(openai.WithModel("gpt-4o-mini"))
    if err != nil {
        log.Fatal(err)
    }
    ctx := context.Background()
    completion, err := llms.GenerateFromSinglePrompt(ctx,
        llm,
        "The first man to walk on the moon",
        llms.WithTemperature(0.8),
        llms.WithStopWords([]string{"Armstrong"}),
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("The first man to walk on the moon:")
    fmt.Println(completion)
}

运行以上程序:


export OPENAI_API_KEY="your-openai-api-key"
go run main.go

使用Deepseek的模型生成内容

Deepseek是国产模型,性能不错,价格也便宜。以下代码示范如何使用LangChain Go调用Deepseek模型生成文本,由于Deepseek支持OpenAI的接口标准,因此使用方法与OpenAI几乎一样。另外国产模型通义千问也是一种选择,但是目前langchang go并没有提供封装和支持,希望后续版本能够提供支持。

就在我发布该文章的第二天,deepseek发布了v3版本,性能相比v2有了大部的提升,强烈推荐国内的开发者使用deepseek模型。

申请API key: https://www.deepseek.com/

go mod文件:


module module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
)

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    apiKey := os.Getenv("DEEDSEEK_API_KEY")
    llm, err := openai.New(openai.WithModel("deepseek-coder"), openai.WithBaseURL("https://api.deepseek.com/beta"), openai.WithToken(apiKey))
    if err != nil {
        log.Fatal(err)
    }
    ctx := context.Background()
    completion, err := llms.GenerateFromSinglePrompt(ctx,
        llm,
        "介绍下docker",
        llms.WithTemperature(0.8),
        llms.WithStopWords([]string{"Armstrong"}),
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("The first man to walk on the moon:")
    fmt.Println(completion)
}

运行以上程序:


export DEEDSEEK_API_KEY="your-openai-api-key"
go run main.go

其他使用示例

本文只是介绍了最基本的示例,后续文章会提供更多的示例。

关于langchain go的其他使用示例,可以参考该项目提供的exampls目录,里面包含了一些常见的使用示例。

https://github.com/tmc/langchaingo/tree/main/examples

参考文档

https://eli.thegreenplace.net/2024/using-gemini-models-in-go-with-langchaingo/
https://eli.thegreenplace.net/2024/using-gemini-models-in-go-with-langchaingo/

本文系本站原创文章,著作版权属于作者,未经允许不得转载,如需转载或引用请注明出处或者联系作者。