支持多轮工具调用
This commit is contained in:
@@ -0,0 +1,180 @@
|
|||||||
|
# AI Terminal Assistant
|
||||||
|
|
||||||
|
**由 kurihada 开发**
|
||||||
|
|
||||||
|
一个运行在终端中的 AI 编程助手,基于 Claude API 构建。可以帮助您读取和写入文件、执行 bash 命令、搜索代码和文件、回答编程问题等。
|
||||||
|
|
||||||
|
## ✨ 特性
|
||||||
|
|
||||||
|
- 🚀 **终端原生体验**:直接在终端中与 AI 交互
|
||||||
|
- 🔧 **强大的工具集**:
|
||||||
|
- 文件读写操作
|
||||||
|
- Bash 命令执行
|
||||||
|
- 目录列表和文件搜索
|
||||||
|
- 代码分析和建议
|
||||||
|
- 🛡️ **安全第一**:在执行可能有风险的命令前会请求确认
|
||||||
|
- 💬 **两种模式**:
|
||||||
|
- 交互模式:持续对话
|
||||||
|
- 单次提问模式:快速获取答案
|
||||||
|
- ⚙️ **可配置**:支持多种 AI 模型和参数配置
|
||||||
|
|
||||||
|
## 📦 安装
|
||||||
|
|
||||||
|
### 前提条件
|
||||||
|
- Node.js 18+
|
||||||
|
- Anthropic API Key
|
||||||
|
|
||||||
|
### 全局安装
|
||||||
|
```bash
|
||||||
|
npm install -g .
|
||||||
|
```
|
||||||
|
|
||||||
|
### 本地开发
|
||||||
|
```bash
|
||||||
|
# 克隆项目
|
||||||
|
git clone <your-repo-url>
|
||||||
|
cd ai-terminal-assistant
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# 构建项目
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# 链接到全局
|
||||||
|
npm link
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### 1. 初始化配置
|
||||||
|
```bash
|
||||||
|
ai-assist init
|
||||||
|
```
|
||||||
|
按照提示设置您的 Anthropic API Key。
|
||||||
|
|
||||||
|
### 2. 启动交互模式
|
||||||
|
```bash
|
||||||
|
ai-assist
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 单次提问模式
|
||||||
|
```bash
|
||||||
|
ai-assist ask "如何读取当前目录下的所有文件?"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 使用示例
|
||||||
|
|
||||||
|
### 文件操作
|
||||||
|
```
|
||||||
|
用户:读取 package.json 文件
|
||||||
|
AI:正在读取 package.json...
|
||||||
|
(显示文件内容)
|
||||||
|
用户:修改版本号为 1.0.1
|
||||||
|
AI:确认要修改 package.json 吗? (y/n)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 代码分析
|
||||||
|
```
|
||||||
|
用户:帮我分析 src/index.ts 中的主要功能
|
||||||
|
AI:正在读取文件...
|
||||||
|
(分析代码结构,解释主要功能)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 系统命令
|
||||||
|
```
|
||||||
|
用户:查看当前目录的文件列表
|
||||||
|
AI:正在执行 ls -la...
|
||||||
|
(显示目录内容)
|
||||||
|
用户:安装 lodash 包
|
||||||
|
AI:确认要执行 npm install lodash 吗? (y/n)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 配置
|
||||||
|
|
||||||
|
### 环境变量
|
||||||
|
创建 `.env` 文件(参考 `.env.example`):
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Anthropic API Key (必需)
|
||||||
|
ANTHROPIC_API_KEY=sk-ant-xxxxx
|
||||||
|
|
||||||
|
# 可选配置
|
||||||
|
AI_MODEL=claude-sonnet-4-20250514
|
||||||
|
AI_MAX_TOKENS=4096
|
||||||
|
```
|
||||||
|
|
||||||
|
### 支持的 AI 模型
|
||||||
|
- `claude-sonnet-4-20250514` (默认)
|
||||||
|
- `claude-haiku-3-20251120`
|
||||||
|
- 其他 Claude 模型
|
||||||
|
|
||||||
|
## 📁 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
ai-terminal-assistant/
|
||||||
|
├── src/
|
||||||
|
│ ├── core/ # 核心代理逻辑
|
||||||
|
│ ├── tools/ # 工具函数
|
||||||
|
│ │ ├── bash.ts # Bash 命令工具
|
||||||
|
│ │ ├── file.ts # 文件操作工具
|
||||||
|
│ │ └── index.ts # 工具导出
|
||||||
|
│ ├── ui/ # 用户界面
|
||||||
|
│ ├── utils/ # 工具函数
|
||||||
|
│ └── index.ts # 主入口文件
|
||||||
|
├── dist/ # 编译输出
|
||||||
|
├── package.json
|
||||||
|
├── tsconfig.json
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ 开发
|
||||||
|
|
||||||
|
### 构建项目
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 开发模式
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### 代码检查
|
||||||
|
```bash
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚠️ 安全注意事项
|
||||||
|
|
||||||
|
1. **API Key 安全**:不要将 `.env` 文件提交到版本控制
|
||||||
|
2. **命令确认**:AI 在执行修改文件或运行系统命令前会请求确认
|
||||||
|
3. **权限管理**:确保 AI 助手只有必要的文件访问权限
|
||||||
|
|
||||||
|
## 📝 许可证
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
## 🤝 贡献
|
||||||
|
|
||||||
|
欢迎提交 Issue 和 Pull Request!
|
||||||
|
|
||||||
|
## 🐛 问题反馈
|
||||||
|
|
||||||
|
如果您遇到任何问题,请:
|
||||||
|
1. 检查 API Key 是否正确配置
|
||||||
|
2. 确保有足够的 API 额度
|
||||||
|
3. 查看终端错误信息
|
||||||
|
4. 在 GitHub 上提交 Issue
|
||||||
|
|
||||||
|
## 📚 相关技术
|
||||||
|
|
||||||
|
- [Claude API](https://docs.anthropic.com/claude/reference/getting-started-with-the-api)
|
||||||
|
- [Node.js](https://nodejs.org/)
|
||||||
|
- [TypeScript](https://www.typescriptlang.org/)
|
||||||
|
- [Commander.js](https://github.com/tj/commander.js) - CLI 框架
|
||||||
|
- [Inquirer.js](https://github.com/SBoudrias/Inquirer.js) - 交互式命令行界面
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**提示**:AI 助手会尽力帮助您,但请始终审查它建议的代码更改和命令执行,特别是在生产环境中。
|
||||||
+3
-1
@@ -1,6 +1,6 @@
|
|||||||
import { createAnthropic } from '@ai-sdk/anthropic';
|
import { createAnthropic } from '@ai-sdk/anthropic';
|
||||||
import { createDeepSeek } from '@ai-sdk/deepseek';
|
import { createDeepSeek } from '@ai-sdk/deepseek';
|
||||||
import { generateText, streamText, type ModelMessage, type Tool as AITool, type LanguageModel } from 'ai';
|
import { generateText, streamText, stepCountIs, type ModelMessage, type Tool as AITool, type LanguageModel } from 'ai';
|
||||||
import type { Tool, ToolResult, Message, AgentConfig, ProviderType } from '../types/index.js';
|
import type { Tool, ToolResult, Message, AgentConfig, ProviderType } from '../types/index.js';
|
||||||
import { buildZodSchema } from '../types/index.js';
|
import { buildZodSchema } from '../types/index.js';
|
||||||
|
|
||||||
@@ -82,6 +82,7 @@ export class Agent {
|
|||||||
messages: this.conversationHistory,
|
messages: this.conversationHistory,
|
||||||
tools: vercelTools,
|
tools: vercelTools,
|
||||||
maxOutputTokens: this.config.maxTokens,
|
maxOutputTokens: this.config.maxTokens,
|
||||||
|
stopWhen: stepCountIs(10), // 允许最多 10 轮工具调用
|
||||||
onChunk: ({ chunk }) => {
|
onChunk: ({ chunk }) => {
|
||||||
if (chunk.type === 'tool-call') {
|
if (chunk.type === 'tool-call') {
|
||||||
onStream(`\n[调用工具: ${chunk.toolName}]\n`);
|
onStream(`\n[调用工具: ${chunk.toolName}]\n`);
|
||||||
@@ -114,6 +115,7 @@ export class Agent {
|
|||||||
messages: this.conversationHistory,
|
messages: this.conversationHistory,
|
||||||
tools: vercelTools,
|
tools: vercelTools,
|
||||||
maxOutputTokens: this.config.maxTokens,
|
maxOutputTokens: this.config.maxTokens,
|
||||||
|
stopWhen: stepCountIs(10), // 允许最多 10 轮工具调用
|
||||||
});
|
});
|
||||||
|
|
||||||
fullResponse = result.text;
|
fullResponse = result.text;
|
||||||
|
|||||||
Reference in New Issue
Block a user