这篇教程就是带大家完整的手搓一个 ai-cli,可以调用硅基流动的AI模型,实现一个AI对话的命令行工具。
什么是 cli?
CLI 是 Command-Line Interface(命令行界面)的缩写。它是一种通过文本命令与计算机程序交互的方式,比如你在终端里输入的 git clone、npm install、python script.py 都属于 CLI 程序。
与之相对的是 GUI(图形用户界面),也就是你用鼠标点击窗口、按钮的那种交互方式。
特点
- 高效 熟练后操作速度远超鼠标点击
- 可脚本化 可以写 Shell 脚本批量执行命令
- 资源占用少 不需要渲染图形界面
- 远程友好 通过 SSH 连接服务器后,只能使用 CLI
- 学习曲线 需要记忆命令和参数
一个 CLI 程序的基本组成
一个典型的 CLI 工具通常包含:
-
入口点:用户输入的命令名称,比如 mycli
-
参数解析:处理用户输入的选项(--help、-v)和参数(input.txt)
-
核心逻辑:实际执行的功能
-
输出:打印结果到终端(stdout / stderr)
-
退出码:0 表示成功,非 0 表示失败(方便脚本判断)
使用场景
几乎每一个开发者、运维、数据科学家都会用到 CLI。常见场景包括:
-
开发工具 ● 代码版本控制(git) ● 包管理(npm, pip, go mod) ● 构建编译(make, webpack, tsc) ● 代码检查与测试(eslint, pytest)
-
服务器运维 ● 通过 SSH 连接远程 Linux 服务器后,只有 CLI 可用 ● 管理进程、查看日志、配置网络、定时任务(cron)
-
数据处理 ● 用 grep, awk, sed 处理文本日志 ● 用 ffmpeg 命令行转码视频 ● 用 jq 处理 JSON 数据
-
AI / 大模型调用 ● 很多 AI 服务提供 CLI 工具,比如 ollama run llama3 ● 你可以自己写一个 CLI,调用 OpenAI / 硅基流动的 API,实现"对话式编程"
-
自动化脚本 ● 每天凌晨自动备份数据库 ● 批量重命名 1000 个文件 ● 自动部署项目到服务器
-
你自制的工具 ● 一个"代码生成器":输入需求描述,自动调用 AI 生成代码文件 ● 一个"图片压缩工具":imgmin input.png output.jpg ● 一个"日报生成器":report --date 2026-04-16
如何开发一个 CLI?
开发一个 CLI 程序,本质上就是写一个接收命令行参数的程序,然后把它变成可以直接在终端敲命令运行。 核心步骤:
- 选择一门语言(Node.js / Python / Go / Rust / Shell 等)
- 解析命令行参数(用户输入的 --name、-v 等)
- 实现核心逻辑(你要让这个命令做什么)
- 输出结果到终端(console.log / print / fmt.Println)
- 打包成可执行命令(让它在任何目录都能被调用)
最终效果预览
js
# 安装后,在任何目录执行
ai-cli ask "什么是闭包?"
ai-cli code "用Python写一个快速排序"
ai-cli chat --model qwen --system "你是一个幽默的助手"
第一步:环境准备
确保你已经安装了:
- Node.js(v18 或更高,建议 v20)
- npm(通常随 Node 安装)
检查方法:
node -v
npm -v
如果没有,去 nodejs.org 下载安装。
第二步:创建项目
打开终端,创建一个新文件夹并初始化:
js
mkdir ai-cli
cd ai-cli
npm init -y
然后安装必要的依赖:
js
npm install typescript @types/node ts-node --save-dev
npm install commander chalk ora openai dotenv
commander:解析命令行参数chalk:彩色输出ora:显示加载动画openai:调用 OpenAI 兼容的 API(硅基流动)dotenv:读取.env文件中的 API Key
第三步:配置 TypeScript
创建 tsconfig.json:
js
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
第四步:创建源代码目录和文件
js
mkdir src
cd src
touch index.ts
第五步:编写核心代码
在 src/index.ts 中写入以下代码:
js
#!/usr/bin/env node
import { Command } from 'commander';
import chalk from 'chalk';
import ora from 'ora';
import OpenAI from 'openai';
import dotenv from 'dotenv';
import { readFileSync } from 'fs';
import { join } from 'path';
// 加载 .env 文件
dotenv.config();
// 初始化 OpenAI 客户端(兼容硅基流动)
const openai = new OpenAI({
baseURL: 'https://api.siliconflow.cn/v1', // 硅基流动的 API 地址
apiKey: process.env.SILICONFLOW_API_KEY || '',
});
const program = new Command();
program
.name('ai-cli')
.description('你的 AI 命令行助手')
.version('1.0.0');
// 子命令:ask
program
.command('ask <question>')
.description('向 AI 提问')
.option('-m, --model <model>', '模型名称', 'Qwen/Qwen2.5-7B-Instruct')
.action(async (question, options) => {
const spinner = ora(chalk.blue('AI 正在思考...')).start();
try {
const completion = await openai.chat.completions.create({
model: options.model,
messages: [
{ role: 'user', content: question }
],
temperature: 0.7,
});
spinner.stop();
const answer = completion.choices[0]?.message?.content || '无回复';
console.log(chalk.green('\n🤖 回答:\n'));
console.log(answer);
} catch (error: any) {
spinner.stop();
console.error(chalk.red('❌ 出错了:'), error.message);
}
});
// 子命令:code(专门生成代码)
program
.command('code <prompt>')
.description('让 AI 生成代码')
.option('-l, --lang <language>', '编程语言', 'python')
.action(async (prompt, options) => {
const systemPrompt = `你是一个专业的程序员。请只输出代码,不要解释。代码语言:${options.lang}。`;
const spinner = ora(chalk.blue('正在生成代码...')).start();
try {
const completion = await openai.chat.completions.create({
model: 'Qwen/Qwen2.5-7B-Instruct',
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: prompt }
],
temperature: 0.5,
});
spinner.stop();
const code = completion.choices[0]?.message?.content || '// 无法生成代码';
console.log(chalk.cyan('\n💻 代码:\n'));
console.log(code);
} catch (error: any) {
spinner.stop();
console.error(chalk.red('❌ 出错了:'), error.message);
}
});
// 子命令:chat(交互式对话,带 system 提示)
program
.command('chat')
.description('进入交互式对话模式')
.option('-m, --model <model>', '模型', 'Qwen/Qwen2.5-7B-Instruct')
.option('-s, --system <prompt>', '系统提示词', '你是一个有用的助手。')
.action(async (options) => {
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
console.log(chalk.yellow(`\n进入对话模式(模型:${options.model}),输入 exit 退出\n`));
const messages = [
{ role: 'system', content: options.system }
];
const askQuestion = () => {
rl.question(chalk.blue('你:'), async (input: string) => {
if (input.toLowerCase() === 'exit') {
console.log(chalk.yellow('再见!'));
rl.close();
return;
}
messages.push({ role: 'user', content: input });
const spinner = ora('AI 正在回复...').start();
try {
const completion = await openai.chat.completions.create({
model: options.model,
messages: messages,
temperature: 0.7,
});
const reply = completion.choices[0]?.message?.content || '无回复';
spinner.stop();
console.log(chalk.green(`\n🤖 AI:${reply}\n`));
messages.push({ role: 'assistant', content: reply });
askQuestion();
} catch (error: any) {
spinner.stop();
console.error(chalk.red('出错:'), error.message);
askQuestion();
}
});
};
askQuestion();
});
program.parse();
第六步:配置 API Key
在项目根目录创建 .env 文件:
ini
SILICONFLOW_API_KEY=你的硅基流动API密钥
如果你还没有 API Key,去 siliconflow.cn 注册,在"API Keys"页面生成一个。新用户有免费额度。
为了安全,把 .env 添加到 .gitignore(如果你会用 git)。
第七步:在本地测试运行
先用 ts-node 直接测试:
bash
npx ts-node src/index.ts ask "你好,请介绍一下你自己"
应该能看到 AI 的回答。
测试 code 子命令:
css
npx ts-node src/index.ts code "快速排序" --lang javascript
测试交互模式:
bash
npx ts-node src/index.ts chat
第八步:打包成全局 CLI 命令
修改 package.json,添加 bin 字段和 build 脚本:
json
{
"name": "ai-cli",
"version": "1.0.0",
"description": "AI 命令行助手",
"main": "dist/index.js",
"bin": {
"ai-cli": "./dist/index.js"
},
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "ts-node src/index.ts"
},
// ... 其余内容保持不变
}
然后编译 TypeScript:
arduino
npm run build
这会生成 dist/index.js 文件。
最后,将命令链接到全局(在项目根目录执行):
bash
npm link
如果提示权限问题,可能需要 sudo npm link(不推荐),或者配置 npm 全局目录。一般普通用户下 npm link 即可。
现在,你可以在任何终端输入:
arduino
ai-cli ask "什么是闭包?"
回顾:完整流程图
css
用户输入: ai-cli ask "你好" --model Qwen/Qwen2.5-7B-Instruct
↓
program.parse() 解析 process.argv
↓
找到子命令 "ask"
↓
提取位置参数 question = "你好"
↓
提取选项 options = { model: "Qwen/Qwen2.5-7B-Instruct" }
↓
调用 action(question, options)
↓
执行你写的业务逻辑(调用 AI API)
↓
输出结果到终端
总结
你现在拥有一个属于自己的 AI 命令行助手了!你可以:
- 随时在终端问问题
- 生成代码片段
- 进入交互式对话
如果想让其他人也能 npm install -g ai-cli 安装使用,你可以把它发布到 npm。