Important
大语言模型插件,让你在Neovim中与大模型交互
-
支持任意一款大模型,比如GPT,GLM,Kimi、DeepSeek、Gemini、Qwen或者本地运行的大模型(比如ollama)
-
支持定义属于你自己的AI工具,且不同工具可以使用不同的模型
-
最重要的一点,你可以使用任何平台提供的免费模型(比如
Copilot,Github models,siliconflow、openrouter,Cloudflare或者其他的平台)
Note
不同大模型的配置(比如ollama, deepseek)、 界面的配置、以及AI工具的配置(包括代码补全) 请先查阅 examples. 这里有你想知道的大部分内容。在使用插件之前,应该确保你的LLM_KEY是有效的,并且该环境变量已经生效。
用户QQ群:1037412539
按?显示快捷键帮助窗口
- 浮动风格
- 分屏风格
enable_cword_context = true: normal模式下翻译当前光标下的文本
一次性,不保留历史记录
你可以配置 inline_assistant 来决定是否展示diff (默认按'd'展示)
你可以配置 inline_assistant 来决定是否展示diff (默认按'd'展示)
/buffer | /file | @web_search
disposable_ask_handler、attach_to_chat_handler、side_by_side_handler和action_handler均可以开启该特性:
diagnostic = { min = vim.diagnostic.severity.HINT },
-- or
-- diagnostic = { vim.diagnostic.severity.WARN, vim.diagnostic.severity.ERROR },
-- see `:h diagnostic-severity`Note
新特性,还在持续迭代
disposable_ask_handler、attach_to_chat_handler和action_handler均可以开启该特性:
lsp = {
cpp = { methods = { "definition", "declaration" } },
python = { methods = { "definition" } },
lua = { methods = { "definition", "declaration" } },
root_dir = { {'pyproject.toml', 'setup.py' }, ".git" },
},
curl: 请自行安装fzf >= 0.37.0: 可选的,split风格预览会话历史以及图像识别工具选择图片会依赖fzf(作者用的0.39.0)render-markdown.nvim: 可选的。更好的markdown预览依赖此插件。
{
"MeanderingProgrammer/render-markdown.nvim",
dependencies = {
{
"nvim-treesitter/nvim-treesitter",
branch = "main",
config = function()
vim.api.nvim_create_autocmd("FileType", {
pattern = { "llm", "markdown" },
callback = function()
vim.treesitter.start(0, "markdown")
end,
})
end,
},
"nvim-mini/mini.icons",
}, -- if you use standalone mini plugins
ft = { "markdown", "llm" },
config = function()
require("render-markdown").setup({
restart_highlighter = true,
heading = {
enabled = true,
sign = false,
position = "overlay", -- inline | overlay
icons = { " ", " ", " ", " ", " ", " " },
signs = { " " },
width = "block",
left_margin = 0,
left_pad = 0,
right_pad = 0,
min_width = 0,
border = false,
border_virtual = false,
border_prefix = false,
above = "▄",
below = "▀",
backgrounds = {},
foregrounds = {
"RenderMarkdownH1",
"RenderMarkdownH2",
"RenderMarkdownH3",
"RenderMarkdownH4",
"RenderMarkdownH5",
"RenderMarkdownH6",
},
},
dash = {
enabled = true,
icon = "─",
width = 0.5,
left_margin = 0.5,
highlight = "RenderMarkdownDash",
},
code = { style = "normal" },
})
end,
}-
在官网注册并获取你的API Key (Cloudflare 需要额外获取你的 account).
-
在你的
zshrc或者bashrc中设置LLM_KEY环境变量(Cloudflare 需要额外设置ACCOUNT)
export LLM_KEY=<Your API_KEY>
export ACCOUNT=<Your ACCOUNT> # just for cloudflareExpand the table.
| 平台 | 获取API Key的链接 | 备注 |
|---|---|---|
| Cloudflare | https://dash.cloudflare.com/ | 你可以在这里看到cloudflare的所有模型, 其中标注beta的是免费模型. |
| ChatGLM(智谱清言) | https://open.bigmodel.cn/ | |
| Kimi(月之暗面) | Moonshot AI 开放平台 | |
| Github Models | Github Token | |
| siliconflow (硅基流动) | siliconflow | 你可以在这里看到硅基流动上所有的模型,选择只看免费可以看到所有的免费模型 |
| Deepseek | https://platform.deepseek.com/api_keys | |
| Openrouter | https://openrouter.ai/ | |
| Chatanywhere | https://api.chatanywhere.org/v1/oauth/free/render | 每天200次免费调用GPT-4o-mini. |
对于本地大模型, 在zshrc or bashrc中设置 LLM_KEY 为 NONE.
- lazy.nvim
{
"Kurama622/llm.nvim",
dependencies = { "nvim-lua/plenary.nvim", "MunifTanjim/nui.nvim"},
cmd = { "LLMSessionToggle", "LLMSelectedTextHandler", "LLMAppHandler" },
config = function()
require("llm").setup({
url = "https://models.inference.ai.azure.com/chat/completions",
model = "gpt-4o-mini",
api_type = "openai"
})
end,
keys = {
{ "<leader>ac", mode = "n", "<cmd>LLMSessionToggle<cr>" },
},
}- Mini.deps
require("mini.deps").setup()
MiniDeps.add({
source = "Kurama622/llm.nvim",
depends = { "nvim-lua/plenary.nvim", "MunifTanjim/nui.nvim" },
cmd = { "LLMSessionToggle", "LLMSelectedTextHandler", "LLMAppHandler" },
})
require("llm").setup({
url = "https://models.inference.ai.azure.com/chat/completions",
model = "gpt-4o-mini",
api_type = "openai"
})| Cmd | Description |
|---|---|
LLMSessionToggle |
打开/隐藏聊天界面 |
LLMSelectedTextHandler |
处理所选文本,其处理方式取决于您输入的提示词 |
LLMAppHandler |
调用AI工具 |
Expand the table.
| Parameter | Description | Value |
|---|---|---|
| url | 请求地址 | String |
| model | 模型名 | String |
| api_type | 输出解析格式 | workers-ai | zhipu|openai | ollama|deepseek | copilot |lmstudio |
| timeout | 响应最大超时时间 (单位: 秒) | Number |
| proxy | Curl请求代理 | String (noproxy|<ip>:<port>) | nil |
| fetch_key | API KEY或者返回API KEY的函数 | Function | String |
| max_tokens | 响应的最大token数 | Number |
| temperature | 取值范围0到1。值越小,回复越贴近主题; 值越大,回复越发散,但太高的值也容易使回复偏离主题 | Number |
| top_p | 取值范围0到1。值越高,回复越多样化,重复性越低。(也越容易产生偏离主题的回复) | Number |
| enable_thinking | 启用thinking功能 (模型本身需要支持thinking) | Boolean |
| thinking_budget | 思考过程的最大token长度 (仅在 enable_thinking 为真时生效) |
Number |
| schema | Function-calling 所需的函数参数描述 | Table |
| functions_tbl | Function-calling 所需的函数字典 | Table |
| keep_alive | 保持连接 (一般用于ollama) | see keep_alive/OLLAMA_KEEP_ALIVE |
| streaming_handler | 自定义流式输出的解析格式 | Function |
| parse_handler | 自定义非流式输出的解析格式 | Function |
Expand the table.
| Style | Keyname | Description | Default: [mode] keymap |
Window |
|---|---|---|---|---|
| float | Input:Submit | 提交问题 | [i] ctrl+g |
Input |
| float | Input:Cancel | 中止对话请求 | [i] ctrl+c |
Input |
| float | Input:Resend | 重新请求 | [i] ctrl+r |
Input |
| float | Input:HistoryNext | 选择下一个历史会话 | [i] ctrl+j |
Input |
| float | Input:HistoryPrev | 选择上一个历史会话 | [i] ctrl+k |
Input |
| float | Input:ModelsNext | 选择下一个模型 | [i] ctrl+shift+j |
Input |
| float | Input:ModelsPrev | 选择上一个模型 | [i] ctrl+shift+k |
Input |
| split | Output:Ask | 打开输入窗口。normal 模式下, 按回车提交问题 | [n] i |
Output |
| split | Output:Cancel | 中止对话请求 | [n] ctrl+c |
Output |
| split | Output:Resend | 重新请求 | [n] ctrl+r |
Output |
| float/split | Session:Toggle | 打开/隐藏聊天界面 | [n] <leader>ac |
Input+Output |
| float/split | Session:Close | 关闭聊天界面 | [n] <esc> |
float: Input+Outputsplit: Output |
| float/split | Session:New | 创建一个新的会话 | [n] <C-n> |
float: Input+Outputsplit: Output |
| float/split | Session:Models | 打开模型列表窗口 | [n] ctrl+m |
float: App input windowsplit: Output |
| split | Session:History | 打开会话历史窗口: 移动遵循fzf的配置, <cr> 确认选择, <esc>关闭 |
[n] ctrl+h |
Output |
| float | Focus:Input | 从输出窗口切换到输入窗口 | - | Output |
| float | Focus:Output | 从输入窗口切换到输出窗口 | - | Input |
| float | PageUp | 输出窗口向上翻页 | [n/i] Ctrl+b |
Input |
| float | PageDown | 输出窗口向下翻页 | [n/i] Ctrl+f |
Input |
| float | HalfPageUp | 输出窗口向上翻半页 | [n/i] Ctrl+u |
Input |
| float | HalfPageDown | 输出窗口向下翻半页 | [n/i] Ctrl+d |
Input |
| float | JumpToTop | 定位到输出窗口顶部 | [n] gg |
Input |
| float | JumpToBottom | 定位到输出窗口低部 | [n] G |
Input |
| Handler name | Description |
|---|---|
| side_by_side_handler | 用两个并排的窗口来展示结果 |
| action_handler | 在原文件中展示AI建议代码和原代码的diff |
| qa_handler | 单轮对话的问答 |
| flexi_handler | 结果将在一个弹性窗口中显示(窗口大小根据输出文本的量自动计算) |
| disposable_ask_handler | 灵活的提问,您可以选择一段代码进行提问,或者直接提问(当前缓冲区是上下文) |
| attach_to_chat_handler | 将选择的文本附加到Chat会话的上下文 |
| completion_handler | 代码补全 |
| curl_request_handler | 与LLM之间最简单的交互通常用于查询账户余额或可用的模型列表等 |
每个handler的具体参数参考docs/tools.
示例: AI 工具配置
对于流式输出,我们使用自定义的streaming_handler;对于一次性返回输出结果的AI工具,我们使用自定义的parse_handler
下面是ollama运行llama3.2:1b的样例
展开代码
local function local_llm_streaming_handler(chunk, ctx, F)
if not chunk then
return ctx.assistant_output
end
local tail = chunk:sub(-1, -1)
if tail:sub(1, 1) ~= "}" then
ctx.line = ctx.line .. chunk
else
ctx.line = ctx.line .. chunk
local status, data = pcall(vim.json.decode, ctx.line)
if not status or not data.message.content then
return ctx.assistant_output
end
ctx.assistant_output = ctx.assistant_output .. data.message.content
F.WriteContent(ctx.bufnr, ctx.winid, data.message.content)
ctx.line = ""
end
return ctx.assistant_output
end
local function local_llm_parse_handler(chunk)
local assistant_output = chunk.message.content
return assistant_output
end
return {
{
"Kurama622/llm.nvim",
dependencies = { "nvim-lua/plenary.nvim", "MunifTanjim/nui.nvim" },
cmd = { "LLMSessionToggle", "LLMSelectedTextHandler" },
config = function()
require("llm").setup({
url = "http://localhost:11434/api/chat", -- your url
model = "llama3.2:1b",
streaming_handler = local_llm_streaming_handler,
app_handler = {
WordTranslate = {
handler = tools.flexi_handler,
prompt = "Translate the following text to Chinese, please only return the translation",
opts = {
parse_handler = local_llm_parse_handler,
exit_on_move = true,
enter_flexible_window = false,
},
},
}
})
end,
keys = {
{ "<leader>ac", mode = "n", "<cmd>LLMSessionToggle<cr>" },
},
}
}以下开源项目为llm.nvim提供了宝贵的灵感和参考:
- olimorris/codecompanion.nvim: diff的显示风格以及大模型提示词
- SmiteshP/nvim-navbuddy: 部分界面设计
- milanglacier/minuet-ai.nvim: 代码补全功能
















