Nerve 是一种工具,可用任何 LLM 创建有状态的代理——无需编写一行代码。 使用 Nerve 创建的代理既能计划又能逐步执行完成用户定义任务所需的任何操作。通过在之前的操作中收集的新的信息动态更新系统提示,使代理在多次推理中保持有状态。
- 自动化问题解决: Nerve 提供了一个标准的动作库,代理可以自主使用这些动作来提高其性能。这些动作包括识别完成任务所需的特定目标,制定和修订实现这些目标的计划,以及创建和回忆在先前操作中获得的相关信息记忆。
- 用户定义的代理: 代理使用标准的 YAML 模板定义。天空才是极限! 您可以为任何您想要的任务定义代理——查看现有示例以获取灵感。
- 适用于任何 LLM: Nerve 是一个与 LLM 无关的工具。
虽然 Nerve 受到了像 Autogen 和 Rigging 这样的项目的启发,但它与其他工具的主要目标和核心区别在于允许用户在不编写代码的情况下(除非需要自定义功能)使用智能代理。Nerve 的另一个优势是,它是一个单一的静态二进制文件(或 docker 容器),无需与 Python 等重型运行时一起使用,同时提供最大效率和内存安全性。
注意: 该工具的性能在很大程度上依赖于您使用的模型。更大的模型往往比小模型更可靠地解释和生成结构化数据。如果您使用的模型生成的响应无效(在统计数据的每一步都可见),请考虑使用更大的模型来完成您的任务。
LLM 支持
Nerve 集成了任何通过 ollama, groq, OpenAI 和 Fireworks API 可访问的模型。
该工具将自动检测选定模型是否原生支持功能调用。如果不支持,它将提供一个兼容层,使旧模型也能执行功能调用。
您可以通过 -G
(或 --generator
)参数指定使用的提供商和模型:
对于 Ollama:
nerve -G "ollama://llama3@localhost:11434" ...
对于 Groq:
GROQ_API_KEY=you-api-key nerve -G "groq://llama3-70b-8192" ...
对于 OpenAI:
OPENAI_API_KEY=you-api-key nerve -G "openai://gpt-4" ...
对于 Fireworks:
LLM_FIREWORKS_KEY=you-api-key nerve -G "fireworks://llama-v3-70b-instruct" ...
示例
让我们来看 examples/ssh_agent
示例任务(一个 "tasklet" 是描述任务和说明的 YAML 文件):
# 如果未指定此模块块,代理将能够访问所有的标准功能命名空间。如果指定了,则只有列出的命名空间可供它使用。用它来限制代理可以做的事情。
using:
# 代理可以保存和回忆记忆
- memory
# 代理可以更新其自己的目标
- goal
# 代理可以自主地将任务设置为已完成或不可能
- task
# 代理可以为任务创建行动计划
- planning
# 给代理一个时间的概念
- time
# 代理背景故事
system_prompt: >
你是一名高级开发人员和计算机专家,拥有多年的 Linux 经验。
你是一个有用的助手,通过执行一系列的 shell 命令执行复杂任务。
# 代理的具体目标,留空以询问用户
#prompt: >
# 找出哪个进程使用了最多的内存
# 添加到基本规则中的可选规则
guidance:
- 总是假设从新建的 /bin/bash shell 中的用户主目录开始。
- 优先使用文件和目录的完整路径。
- 将 /tmp 目录用于任何文件写入操作。
- 如果需要在某些操作前使用 'sudo' 命令,确定自己是否为 root 用户,仅在不是 root 用户时使用 sudo。
# 可选的全局操作超时
timeout: 120s
# 代理工具箱
functions:
# 分为命名空间
- name: Commands
actions:
- name: ssh
# 向模型解释何时使用此动作
description: "通过 SSH 在远程主机上执行 bash 命令:"
# 为模型提供示例负载
example_payload: whoami
# 可选的动作超时
timeout: 30s
# 每个动作都映射到一个自定义命令
# 以 $ 开头的字符串需要由用户提供
# 在此操作中,通过 ssh 以 15 秒超时执行命令
# 重要:这假设用户可以通过 ssh 密钥连接,无需密码。
tool: ssh $SSH_USER_HOST_STRING
在这个示例中,我们创建了具有默认功能的代理,这个代理还可以使用我们描述的“工具”在给定主机上执行任何 ssh 命令。
为了运行这个任务块,您需要定义 SSH_USER_HOST_STRING
变量,因此您可以例如运行以下命令(请参阅下面的构建 Nerve 章节):
nerve -G "ollama://llama3@localhost:11434" \
-T /path/to/ssh_agent \
-DSSH_USER_HOST_STRING=user@example-ssh-server-host
您也可以不在任务块文件中指定 prompt
部分,在这种情况下您可以通过命令行动态传递它,通过 -P
/--prompt
参数:
nerve -G "ollama://llama3@localhost:11434" \
-T /path/to/ssh_agent \
-DSSH_USER_HOST_STRING=user@example-ssh-server-host \
-P '找出哪个进程使用了最多的内存'
您可以在 examples
文件夹中找到更多任务块示例,如果您创建了一个很酷的新示例,请随时发送 PR!:D
它是如何工作的?
主要思想是给模型提供一组功能来执行操作并以结构化的方式向其自己的系统提示添加更多上下文。每个操作(保存记忆,设定新目标等)都会以某种方式改变提示,以便模型在每次迭代中可以自主地完善其策略并保持事实、目标、计划等状态。
如果您想观察到(基本上是 Nerve 的调试模式),请在运行任务块时添加以下附加参数:
nerve -G ... -T whatever-tasklet --save-to state.txt
代理将在每次迭代时将其内部状态保存到磁盘以供您观察。
关于 Crates.io
自 v0.2.0 Nerve 不再在 crates.io 上,由于本地包缺乏支持。
从 DockerHub 安装
在 Docker Hub 上提供了一个 Docker 镜像:
为了运行它,请记住您可能希望与主机网络相同的网络,以便访问 OLLAMA 服务器,并记住在卷中共享任务块文件:
docker run -it --network=host -v ./examples:/root/.nerve/tasklets evilsocket/nerve -h
通过在本地主机上运行的 Ollama 服务器的 ssh_agent
任务块示例:
docker run -it --network=host \
-v ./examples:/root/.nerve/tasklets \
evilsocket/nerve -G "ollama://llama3@localhost:11434" -T ssh_agent -P'找出哪个进程使用内存最多'
从源代码构建
从源代码构建:
cargo build --release
运行具有给定 OLLAMA 服务器的任务块:
./target/release/nerve -G "ollama://<model-name>@<ollama-host>:11434" -T /path/to/tasklet
使用 Docker 构建
docker build . -t nerve
许可证
Nerve 基于 GPL 3 许可证 发布。要查看项目依赖项的许可证,请通过 cargo install cargo-license
安装 cargo 许可证,然后运行 cargo license
。