99

GitHub
4.5k 228 简单 1 次阅读 今天Agent插件
AI 解读 由 AI 自动生成,仅供参考

99 是一款专为 Neovim 打造的 AI 智能体客户端,旨在将程序员的手写代码能力与大语言模型的强大算力完美融合。它并非要取代开发者,而是作为得力助手,通过增强而非替代的方式提升编码效率。

99 主要解决了传统 AI 插件仅能片段式替换代码的局限,转而聚焦于更宏观的“搜索”与“工作流”代理模式。它能帮助开发者在复杂的代码库中快速定位信息、理解上下文,并执行连贯的开发任务,让 AI 真正融入日常编程习惯。

这款工具特别适合热爱 Neovim、重视手写代码价值且愿意尝试前沿工作流的资深开发者。如果你希望在使用 AI 辅助的同时,依然保持对代码逻辑的完全掌控,99 是理想之选。

其独特亮点在于高度可定制的规则系统(支持自定义 SKILL.md)和灵活的文件上下文发现机制,能够根据项目结构智能加载相关文档。此外,99 目前处于测试阶段,作者正积极探索"AI+ 传统编码”的最佳实践,虽然 API 可能随版本迭代有所调整,但其核心理念始终是为那些享受编码乐趣的人提供最原生的 Neovim AI 体验。

使用场景

一位资深后端工程师正在 Neovim 中重构一个遗留的 Python 微服务模块,需要理解复杂的调用链并安全地替换过时的异步逻辑。

没有 99 时

  • 上下文切换频繁:为了理清函数依赖关系,不得不频繁离开编辑器去查阅文档或在终端运行 grep 搜索,打断心流。
  • 手动整合困难:从 AI 网页端复制代码片段后,需手动调整缩进和变量名以适应现有项目规范,容易引入格式错误。
  • 缺乏项目感知:通用 AI 助手不了解项目特有的目录结构和自定义工具类,生成的代码往往无法直接运行,需要大量二次修改。
  • 调试成本高:遇到生成代码报错时,需人工逐行比对差异,难以快速定位是逻辑错误还是环境权限问题。

使用 99 后

  • 沉浸式代理工作流:99 直接在 Neovim 内通过 searchwork 命令分析整个代码库,自动梳理调用链并在缓冲区呈现结果,无需切换窗口。
  • 智能代码融合:基于项目内的 SKILL.md 自定义规则,99 生成的代码自动符合团队规范,并利用 @files 补全功能精准引用相关模块。
  • 深度项目感知:99 理解当前 Git 仓库结构及外部工具权限配置,生成的重构方案能直接调用项目内部的工具类,大幅减少适配工作。
  • 实时追踪与反馈:内置的日志机制将请求追踪写入本地文件,出现错误时可立即回溯 Agent 的决策过程,快速修复权限或逻辑问题。

99 将 AI 从“外部聊天机器人”转变为 Neovim 内的“结对编程代理”,在保留手写代码控制权的同时,极大提升了复杂重构任务的效率与准确性。

运行环境要求

操作系统
  • Linux
  • macOS
  • Windows
GPU

未说明

内存

未说明

依赖
notes该工具是 Neovim 的 Lua 插件,而非独立的 Python AI 模型。运行核心需求是安装 Neovim 编辑器。它本身不消耗大量本地算力,而是作为代理工作流客户端,调用外部的 AI 编码工具(如 OpenCode 或 Claude Code)来执行任务。因此,具体的 GPU、内存和 Python 环境需求取决于你所选择连接的后端 AI 服务或本地运行的外部工具,而非此插件本身。配置中涉及临时目录权限问题,需参考相关外部工具的文档进行设置。
python未说明
Neovim
OpenCode (外部工具)
Claude Code (外部工具)
99 hero image

快速开始

99

Neovim 应得的 AI 客户端,由那些依然热爱编码的人打造。

如果你是从 YouTube 视频 来的

很多事情都发生了变化。所以请务必小心!

警告 :: 当前 API 正在变化

API 可能会消失或被更改。抱歉,这是一款 BETA 产品。

项目方向

这个仓库旨在成为我探索将 AI 与传统编程结合使用的试验场。

我相信手工编码仍然非常重要,而当今我所知的最佳产品依然坚持这一点(参见 opencode 与 claude code)。

警告

  1. 提示目前是临时的,未来可以大幅改进。
  2. 正式处于 Beta 阶段,但 API 仍可能发生变化。不过现在不太可能了。

99

AI 的 Neovim 使用体验

_99

99 是一种代理式工作流,旨在将当前程序员的能力与大型语言模型的强大功能相结合。它并不是要取代程序员,而是用来增强程序员的工作。

目前,99 的发展方向是推进代理式编程和信息的呈现。最初以及最初的 YouTube 视频中提到的是用 AI 替换特定的代码片段。然而,随着我对 99 的使用越来越深入,我逐渐意识到它更好的用途在于“搜索”和“工作”。

基本设置

	{
		"ThePrimeagen/99",
		config = function()
			local _99 = require("99")

            -- 用于日志记录,如果希望追踪请求以报告 bug,建议不要依赖此方式,而是使用 99 内置的日志机制。此配置主要用于调试目的。
            local cwd = vim.uv.cwd()
            local basename = vim.fs.basename(cwd)
			_99.setup({
                -- provider = _99.Providers.ClaudeCodeProvider,  -- 默认:OpenCodeProvider
				logger = {
					level = _99.DEBUG,
					path = "/tmp/" .. basename .. ".99.debug",
					print_on_error = true,
				},
                -- 当设置为非当前工作目录的路径时,例如 claude code 或 opencode,可能会出现权限问题,导致生成失败。请参考相关工具的文档来解决:
                -- https://opencode.ai/docs/permissions/#external-directories
                -- https://code.claude.com/docs/en/permissions#read-and-edit
                tmp_dir = "./tmp",

                --- 补全功能:提示缓冲区中的 #rules 和 @files
                completion = {
                    -- 我暂时禁用这些功能,直到更好地理解问题所在。光标规则中还包含应用规则,这意味着需要以不同的方式应用它们。
                    -- cursor_rules = "<自定义光标规则路径>"

                    --- 包含您自己的 SKILL.md 文件的文件夹列表
                    --- 预期格式:
                    --- /path/to/dir/<skill_name>/SKILL.md
                    ---
                    --- 示例:
                    --- 输入路径:
                    --- "scratch/custom_rules/"
                    ---
                    --- 输出规则:
                    --- {path = "scratch/custom_rules/vim/SKILL.md", name = "vim"},
                    --- ... 该目录下的其他规则 ...
                    ---
                    custom_rules = {
                      "scratch/custom_rules/",
                    },

                    --- 配置 @file 补全(所有字段可选,有合理默认值)
                    files = {
                        -- enabled = true,
                        -- max_file_size = 102400,     -- 字节,跳过大于此大小的文件
                        -- max_files = 5000,            -- 总发现文件数上限
                        -- exclude = { ".env", ".env.*", "node_modules", ".git", ... },
                    },
                    --- 文件发现:
                    --- - 在 Git 仓库中:使用 `git ls-files`,自动尊重 .gitignore 文件。
                    --- - 非 Git 仓库:回退到文件系统扫描,并手动排除指定文件。
                    --- - 两种方法都会在 .gitignore 的基础上应用配置的 `exclude` 列表。

                    --- 使用哪种自动补全引擎。未指定时,默认使用原生(内置)引擎。
                    source = "native", -- "native"(默认)、"cmp" 或 "blink"
                },

                --- 警告:如果更改当前工作目录,此功能很可能失效
                --- 我可能会在后续更新中修复这个问题。
                ---
                --- md_files 是一个文件列表,系统会根据原始请求的位置自动查找并添加这些文件。也就是说,如果你位于 /foo/bar/baz.lua,
                --- 系统会自动查找:
                --- /foo/bar/AGENT.md
                --- /foo/AGENT.md
                --- 假设 /foo 是项目根目录(基于当前工作目录)。
				md_files = {
					"AGENT.md",
				},
			})

            -- 请注意,我在视觉模式下才进行操作
            -- 实际上,无论你上次选择的是什么内容,都会被使用
            -- 因此我将其设置为视觉模式,以免误用之前的视觉选择。
            --
            -- 未来可能会增加模式检查,并断言必须处于视觉模式
            -- 所以现在就做好准备吧。
			vim.keymap.set("v", "<leader>9v", function()
				_99.visual()
			end)

            --- 如果你有一个请求不想再继续,可以直接取消它。
			vim.keymap.set("n", "<leader>9x", function()
				_99.stop_all_requests()
			end)

			vim.keymap.set("n", "<leader>9s", function()
				_99.search()
			end)
		end,
	},

使用方法

我强烈推荐尝试 search 功能,因为这是该库的发展方向。

_99.search()

更多详情请参阅搜索部分。

描述

名称 类型 默认值
setup fun(opts?: _99.Options): nil -
search fun(opts: _99.ops.SearchOpts): _99.TraceID -
vibe fun(opts?: _99.ops.Opts): _99.TraceID | nil -
open fun(): nil -
visual fun(opts: _99.ops.Opts): _99.TraceID -
view_logs fun(): nil -
stop_all_requests fun(): nil -
clear_previous_requests fun(): nil -
Extensions _99.Extensions -

API

setup

设置 _99。必须调用此函数,库才能正常工作。通过它我们可以设置正在进行的请求加载动画、设定默认值,并使补全功能按你期望的方式运行。

search

根据你提供的提示,在你的项目中执行搜索,并返回一个包含注释的位置列表,这些位置将被添加到快速修复列表中。

vibe

无描述。

open

打开一个选择窗口,供你选择最近的一次交互进行打开,并以适合其类型的方式显示内容。对于 search 和 vibe,会打开 qfix 窗口;对于 tutorial,则会打开教程窗口。

visual

获取当前选中的内容并连同提供的提示一起发送,然后用结果替换当前的视觉选区。

view_logs

查看最近的日志,并配置机器以便查看更早和更新的日志。目前这部分还比较粗糙,未来会有较大改动。

stop_all_requests

停止所有正在进行的请求。这意味着底层进程(OpenCode)会被终止,任何已产生的结果都将被丢弃。

clear_previous_requests

清除所有之前的搜索和视觉操作记录。

扩展

请查看 Worker,它为 search 和 vibe 提供了很酷的抽象层。

_99.Extensions.Worker

一种持久化的工单跟踪方式。

这很可能是未来开发的重点方向。我希望将其扩展到工作树的范畴,从而能够非常流畅地在不同任务之间切换。

在此之前,它只是一个简单的工单系统:你可以提供任务描述,然后使用 search 来查找尚未完成的工作。

描述

名称 类型 默认值
set_work fun(opts?: _99.WorkOpts): nil -
search fun(): nil -

API

set_work

为项目设置工单。如果 opts 中提供了描述,则无需再次输入工单描述。

search

将使用 _99.search 来查找该工单中尚未完成的部分,直到工单被视为已完成。

_99.Options

无描述。

描述

名称 类型 默认值
logger _99.Logger.Options | nil -
model string | nil -
in_flight_options _99.InFlight.Opts | nil -
md_files string[] | nil -
provider _99.Providers.BaseProvider | nil -
display_errors boolean | nil -
auto_add_skills boolean | nil -
completion _99.Completion | nil -
tmp_dir string | nil -

API

logger

无描述。

model

无描述。

in_flight_options

无描述。

md_files

无描述。

provider

无描述。

display_errors

无描述。

auto_add_skills

无描述。

completion

无描述。

tmp_dir

无描述。

_99.ops.Opts

这些选项用于与 99 进行的所有交互,包括 search、visual 等操作。

描述

名称 类型 默认值
additional_prompt string | nil -
additional_rules _99.Agents.Rule[] | nil -

API

additional_prompt

通过提供 additional_prompt,你就不需要再单独提供提示。这样可以根据 remap 定义不同的操作。

remap("n", "<leader>9d", function()
  --- 这个函数可以用来自动调试你的项目
  _99.search({
    additional_prompt = [[
运行 `make test` 并调试测试失败的原因,然后向我提供一套完整的步骤,说明测试在哪里出错 ]]
  })
end)

这段代码会启动一个后台搜索任务,运行你的测试。一旦发现失败,就会进行诊断,并将结果转移到快速修复列表中。

additional_rules

可用于提供额外的参数。如果你有一个名为 “cloudflare” 的技能,就可以提供相应的规则,这些规则及其上下文将被注入到你的请求中。

_99.ops.SearchOpts

更多信息请参阅 _99.opts.Opts

目前还没有具体属性。但我希望可以根据 opts 调整一些行为。

描述

名称 类型 默认值
- - -

API

无属性。

_99.WorkOpts

无描述。

描述

名称 类型 默认值
description string | nil -

API

description

无描述。

_99.Completion

无描述。

描述

名称 类型 默认值
source "cmp" | "blink" | nil -
custom_rules string[] -
files _99.Files.Config? -

API

source

无描述。

custom_rules

无描述。

files

无描述。

_99.InFlight.Opts

这是一个纯粹用于测试的类,有助于控制时间间隔。

描述

名称 类型 默认值
throbber_opts _99.Throbber.Opts | nil -
in_flight_interval number | nil -
enable boolean | nil -

API

throbber_opts

左上角加载动画的相关选项。

in_flight_interval

控制加载动画显示或隐藏的频率。

enable

默认为 true。

_99.Logger.Options

无描述。

描述

名称 类型 默认值
level number? -
type "print" | "void" | "file" | nil -
path string? -
print_on_error boolean | nil -
max_requests_cached number | nil -

API

level

无描述。

type

无描述。

path

无描述。

print_on_error

无描述。

max_requests_cached

无描述。

_99.Agents.Rule

无描述。

描述

名称 类型 默认值
name string -
path string -
absolute_path string? -

API

name

无描述。

path

无描述。

absolute_path

无描述。

补全功能

在输入提示时,你可以引用规则和文件来为你的请求增加上下文。

  • # 引用规则 — 在提示中输入 # 可以从你配置的规则目录中自动补全规则文件。
  • @ 引用文件 — 输入 @ 可以模糊搜索项目文件,但会排除 .gitignore 中列出的文件。

引用的内容会自动解析并注入到 AI 上下文中。默认情况下使用原生补全功能。如果使用 nvim-cmp 或 blink.cmp,则需设置 source = "cmp"source = "blink"

提供者

99 支持多种 AI CLI 后端。在你的配置中设置 provider 即可切换。如果你没有设置 model,则会使用提供者的默认模型。

提供者 CLI 工具 默认模型
OpenCodeProvider(默认) opencode opencode/claude-sonnet-4-5
ClaudeCodeProvider claude claude-sonnet-4-5
CursorAgentProvider cursor-agent sonnet-4.5
GeminiCLIProvider gemini auto
_99.setup({
    provider = _99.Providers.ClaudeCodeProvider,
    -- model 是可选的,会覆盖提供者的默认值
    model = "claude-sonnet-4-5",
})

扩展

Telescope 模型选择器

如果你安装了 telescope.nvim,可以通过 Telescope 选择器实时切换模型:

vim.keymap.set("n", "<leader>9m", function()
  require("99.extensions.telescope").select_model()
end)

所选模型将用于当前会话中的所有后续请求。

Telescope 提供者选择器

无需重启 Neovim 即可在 OpenCode、Claude、Cursor 和 Kiro 之间切换提供者。切换提供者时,模型也会重置为该提供者的默认值。

vim.keymap.set("n", "<leader>9p", function()
  require("99.extensions.telescope").select_provider()
end)

fzf-lua

如果你使用 fzf-lua 而不是 telescope,同样可以使用这些选择器:

vim.keymap.set("n", "<leader>9m", function()
  require("99.extensions.fzf_lua").select_model()
end)

vim.keymap.set("n", "<leader>9p", function()
  require("99.extensions.fzf_lua").select_provider()
end)

报告 bug

要报告 bug,请提供完整的运行调试日志。这可能需要多次沟通确认。

请勿提出功能需求。我们将在 Twitch 上公开讨论功能需求,这将比你单独提交大量请求后再被关闭要高效得多。如果你仍然提交功能请求,我将会立即关闭它。

日志

要查看上次运行的日志,请执行 :lua require("99").view_logs()

请注意

如果日志中包含敏感信息或其他需要删除的内容,请务必删除 query 的打印部分。这部分内容很可能包含你不希望公开的信息。

常见问题

相似工具推荐

openclaw

OpenClaw 是一款专为个人打造的本地化 AI 助手,旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚,能够直接接入你日常使用的各类通讯渠道,包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息,OpenClaw 都能即时响应,甚至支持在 macOS、iOS 和 Android 设备上进行语音交互,并提供实时的画布渲染功能供你操控。 这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地,用户无需依赖云端服务即可享受快速、私密的智能辅助,真正实现了“你的数据,你做主”。其独特的技术亮点在于强大的网关架构,将控制平面与核心助手分离,确保跨平台通信的流畅性与扩展性。 OpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者,以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力(支持 macOS、Linux 及 Windows WSL2),即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你

349.3k|★★★☆☆|2天前
Agent开发框架图像

stable-diffusion-webui

stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。

162.1k|★★★☆☆|3天前
开发框架图像Agent

everything-claude-code

everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上

144.7k|★★☆☆☆|今天
开发框架Agent语言模型

ComfyUI

ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。

107.9k|★★☆☆☆|2天前
开发框架图像Agent

markitdown

MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具,专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片(含 OCR)、音频(含语音转录)、HTML 乃至 YouTube 链接等多种格式的解析,能够精准提取文档中的标题、列表、表格和链接等关键结构信息。 在人工智能应用日益普及的今天,大语言模型(LLM)虽擅长处理文本,却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点,它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式,成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外,它还提供了 MCP(模型上下文协议)服务器,可无缝集成到 Claude Desktop 等 LLM 应用中。 这款工具特别适合开发者、数据科学家及 AI 研究人员使用,尤其是那些需要构建文档检索增强生成(RAG)系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性,但其核心优势在于为机器

93.4k|★★☆☆☆|昨天
插件开发框架

LLMs-from-scratch

LLMs-from-scratch 是一个基于 PyTorch 的开源教育项目,旨在引导用户从零开始一步步构建一个类似 ChatGPT 的大型语言模型(LLM)。它不仅是同名技术著作的官方代码库,更提供了一套完整的实践方案,涵盖模型开发、预训练及微调的全过程。 该项目主要解决了大模型领域“黑盒化”的学习痛点。许多开发者虽能调用现成模型,却难以深入理解其内部架构与训练机制。通过亲手编写每一行核心代码,用户能够透彻掌握 Transformer 架构、注意力机制等关键原理,从而真正理解大模型是如何“思考”的。此外,项目还包含了加载大型预训练权重进行微调的代码,帮助用户将理论知识延伸至实际应用。 LLMs-from-scratch 特别适合希望深入底层原理的 AI 开发者、研究人员以及计算机专业的学生。对于不满足于仅使用 API,而是渴望探究模型构建细节的技术人员而言,这是极佳的学习资源。其独特的技术亮点在于“循序渐进”的教学设计:将复杂的系统工程拆解为清晰的步骤,配合详细的图表与示例,让构建一个虽小但功能完备的大模型变得触手可及。无论你是想夯实理论基础,还是为未来研发更大规模的模型做准备

90.1k|★★★☆☆|2天前
语言模型图像Agent