版本: 1.0 | 日期: 2026-01-13
aicli 是一个基于 Go 语言开发的自然语言命令行工具,允许用户使用自然语言描述意图,通过大语言模型(LLM)服务将其转换为实际的 shell 命令并执行。
- 简单易用: 用户只需输入自然语言,无需记忆复杂的命令语法
- 安全可靠: 检测危险命令并要求用户确认
- 灵活可扩展: 支持多种 LLM 提供商,易于添加新功能
- 高性能: 命令转换和执行总时间 < 5 秒
- 跨平台: 支持 Linux、macOS、Windows
┌─────────────────────────────────────────────────────────────┐
│ 用户界面层 │
│ (cmd/aicli/main.go) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 命令行解析 (Cobra) │ │
│ │ - 参数解析 │ │
│ │ - 标志处理 (--verbose, --dry-run, --force) │ │
│ │ - 子命令 (--history, --retry) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 应用逻辑层 │
│ (internal/app/app.go) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 应用主逻辑 │ │
│ │ - 输入验证 │ │
│ │ - 上下文构建 │ │
│ │ - 流程编排 │ │
│ │ - 错误处理 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓ ↓ ↓ ↓
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ LLM │ │ 执行器 │ │ 安全检查 │ │ 历史 │
│ Provider│ │ Executor │ │ Checker │ │ History │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
↓ ↓ ↓ ↓
┌─────────────────────────────────────────────────────────────┐
│ 核心服务层 │
│ (pkg/*) │
│ │
│ ┌────────────────┐ ┌────────────────┐ ┌───────────────┐ │
│ │ LLM 服务 │ │ 命令执行服务 │ │ 安全检查服务 │ │
│ │ pkg/llm/ │ │ pkg/executor/ │ │ pkg/safety/ │ │
│ │ │ │ │ │ │ │
│ │ - OpenAI │ │ - Shell 检测 │ │ - 模式匹配 │ │
│ │ - Anthropic │ │ - 命令执行 │ │ - 风险评估 │ │
│ │ - Local Model │ │ - IO 处理 │ │ - 确认提示 │ │
│ │ - 工厂函数 │ │ │ │ │ │
│ └────────────────┘ └────────────────┘ └───────────────┘ │
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ 配置管理 │ │ 历史记录 │ │
│ │ pkg/config/ │ │ internal/ │ │
│ │ │ │ history/ │ │
│ │ - 加载/保存 │ │ - 增删查改 │ │
│ │ - 默认值 │ │ - 持久化 │ │
│ │ - 验证 │ │ - 搜索过滤 │ │
│ └────────────────┘ └────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 外部服务层 │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ OpenAI │ │ Anthropic │ │ Ollama │ │
│ │ API │ │ API │ │ (本地) │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ 操作系统 Shell │ │
│ │ bash / zsh / PowerShell / cmd │ │
│ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
职责:
- 解析命令行参数和标志
- 处理用户输入(自然语言、stdin)
- 调用应用逻辑层
- 格式化输出结果
关键组件:
main.go: 程序入口,Cobra 命令定义rootCmd: 根命令,处理自然语言输入- 子命令:
--history,--retry
职责:
- 编排整个执行流程
- 构建执行上下文
- 协调各个核心服务
- 处理业务逻辑错误
关键组件:
App: 应用主结构体Run(): 主执行逻辑Flags: 命令行标志定义confirm.go: 确认提示逻辑io.go: 输入输出处理
执行流程:
1. 验证输入
2. 构建执行上下文(OS、Shell、WorkDir、Stdin)
3. 调用 LLM 翻译命令
4. 安全检查(危险命令检测)
5. 用户确认(如需要)
6. 执行命令
7. 保存历史记录
8. 返回结果
职责:
- 定义 LLM 提供商接口
- 实现多种 LLM 提供商
- 构建和管理 Prompt
- 处理 LLM 响应
关键组件:
LLMProvider接口: 统一的提供商接口OpenAIProvider: OpenAI GPT 系列实现AnthropicProvider: Anthropic Claude 系列实现LocalModelProvider: 本地模型(Ollama)实现NewProvider(): 工厂函数,根据配置创建提供商BuildPrompt(): 构建提示词cleanCommand(): 清理命令输出
接口定义:
type LLMProvider interface {
Translate(ctx context.Context, input string, execCtx *ExecutionContext) (string, error)
Name() string
}职责:
- 检测系统 Shell
- 执行 Shell 命令
- 处理 stdin/stdout/stderr
- 管理命令超时
关键组件:
Executor: 命令执行器ShellAdapter: Shell 适配器DetectShell(): Shell 检测Execute(): 命令执行
Shell 支持:
- Linux/macOS: bash, zsh, sh
- Windows: PowerShell, cmd
职责:
- 定义危险命令模式
- 检测危险操作
- 评估风险等级
- 提供风险描述
关键组件:
SafetyChecker: 安全检查器DangerousPatterns: 危险模式列表IsDangerous(): 危险检测方法
检测模式:
- 文件删除:
rm -rf,del /S - 格式化:
mkfs,format - 权限操作:
chmod 777,chown - 网络危险:
curl | sh,wget | bash - 系统修改:
sudo,dd if=
职责:
- 加载和保存配置
- 提供默认配置
- 验证配置项
配置文件: ~/.aicli.json
配置结构:
type Config struct {
Version string
LLM LLMConfig // LLM 配置
Execution ExecutionConfig // 执行配置
Safety SafetyConfig // 安全配置
History HistoryConfig // 历史配置
Logging LoggingConfig // 日志配置
}职责:
- 记录命令执行历史
- 持久化到文件
- 提供查询和检索
- 支持命令重试
关键功能:
Add(): 添加历史记录List(): 列出所有记录Get(): 获取指定记录Search(): 搜索记录Save()/Load(): 持久化
用户输入 "列出当前目录的所有txt文件"
↓
[1. 输入验证]
↓
[2. 构建执行上下文]
OS: linux, Shell: bash, WorkDir: /home/user
↓
[3. 调用 LLM Provider]
System Prompt: "You are a command-line expert..."
User Input: "列出当前目录的所有txt文件"
Context: {OS, Shell, WorkDir}
↓
[4. LLM 返回命令]
"ls *.txt"
↓
[5. 安全检查]
IsDangerous("ls *.txt") → false
↓
[6. 执行命令]
Executor.Execute("ls *.txt")
↓
[7. 保存历史记录]
{Input, Command, Success, Output}
↓
[8. 返回结果]
file1.txt
file2.txt
notes.txt
cat file.txt | aicli "统计行数"
↓
[读取 stdin]
"line1\nline2\nline3"
↓
[构建上下文 with Stdin]
{OS, Shell, WorkDir, Stdin: "..."}
↓
[LLM 转换]
"wc -l"
↓
[执行命令 with stdin]
3
-
配置错误
- 配置文件不存在 → 使用默认配置
- API Key 缺失 → 返回明确错误
- 配置格式错误 → 返回解析错误
-
LLM 错误
- 网络超时 → 重试或提示用户
- API 错误 → 显示错误消息
- 返回空命令 → 提示用户重新描述
-
执行错误
- 命令不存在 → 显示错误信息
- 权限不足 → 提示用户
- 超时 → 可配置的超时时间
-
安全错误
- 危险命令未确认 → 拒绝执行
- 管道模式危险命令 → 需要 --force
底层错误 → 包装错误 → 用户友好错误
fmt.Errorf("wrap: %w", err)
- LLM API 调用 + 命令执行 < 5 秒
- 配置文件加载 < 10ms
- 命令执行启动 < 100ms
- HTTP 连接复用: 使用长连接
- 超时控制: Context 超时管理
- 并发控制: 使用 goroutine 但避免过度并发
- 缓存: 配置加载缓存(未实现)
- 危险命令检测: 正则表达式匹配
- 用户确认: 交互式确认提示
- 强制执行:
--force标志跳过确认 - 隐私保护:
--no-send-stdin不发送敏感数据 - 日志脱敏: 不记录完整 API Key
- 配置文件权限: 建议 600
- API Key 管理: 使用环境变量
- 命令审查: 执行前显示命令
- 实现
LLMProvider接口 - 在
factory.go中注册 - 添加测试
- 更新文档
type MyProvider struct { ... }
func (p *MyProvider) Translate(...) (string, error) {
// 实现逻辑
}
func (p *MyProvider) Name() string {
return "myprovider"
}遵循模块化设计原则:
- 新功能放在独立的包中
- 定义清晰的接口
- 编写单元测试
- 更新文档
github.com/spf13/cobra: CLI 框架- Go 标准库:
net/http,encoding/json,os/exec
cmd/aicli
↓
internal/app
↓
pkg/llm, pkg/executor, pkg/safety, pkg/config
- 单元测试: 每个包独立测试
- 集成测试: 跨包测试(tests/integration)
- E2E 测试: 完整流程测试(使用 Mock LLM)
MockLLMProvider: Mock LLM 响应httptest.Server: Mock HTTP APIos.Pipe(): Mock stdin/stdout
- 整体: ≥65%
- 核心包 (llm, executor, safety): ≥80%
aicli (可执行文件)
~/.aicli.json (配置)
~/.aicli_history.json (历史)
- Linux (amd64, arm64)
- macOS (amd64, arm64)
- Windows (amd64)
- 缓存机制: 缓存常见命令转换
- 插件系统: 支持自定义扩展
- Web UI: 可选的 Web 界面
- 团队协作: 共享历史和最佳实践
- 智能建议: 基于历史的命令建议
aicli 采用清晰的分层架构,核心是 LLM Provider 抽象层,通过工厂模式支持多种 LLM 服务。安全检查、命令执行、历史记录等模块各司其职,保证了系统的可维护性和可扩展性。