# emb-cli **Repository Path**: cc123hh/emb-cli ## Basic Information - **Project Name**: emb-cli - **Description**: 命令行文本向量化与语义搜索:零依赖 Python 脚本,macOS/Linux/Windows 通用,支持任意 OpenAI 兼容的 /embeddings 接口 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-30 - **Last Updated**: 2026-11-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

emb

emb banner

python 3.8+ platform dependencies tests license

把文字变成向量,再按「意思」把东西找回来。
零依赖 · 跨平台 · 单文件索引 · 支持任何 OpenAI 兼容的 /embeddings 接口

--- ## 📑 目录 - [它解决什么问题](#-它解决什么问题) - [快速开始](#-快速开始) - [安装](#-安装) - [配置](#-配置) - [用法](#-用法) - [维护索引](#-维护索引) - [参数速查](#-参数速查) - [索引格式](#-索引格式) - [常见问题](#-常见问题) - [License](#license) ## 🎯 它解决什么问题 普通搜索是**按字匹配**: ``` 搜「电脑连不上网」 → 笔记里写的是「Clash 代理端口 7890」 → ❌ 一个字都对不上,搜不到 ``` `emb` 是**按意思匹配**: ``` 搜「电脑连不上网」 → 命中「先检查 Clash 是否开着」 → ✅ 搜「晚饭吃什么」 → 命中「隔夜饭适合做炒饭」 → ✅ ``` 原理:把每段文字交给 embedding 接口,转成一串数字(向量)。**意思相近的文字,数字也相近**。 于是「找相似的」就变成了「算距离」,正好是机器的强项。 ## 🚀 快速开始 ```console $ emb add ./notes -i notes.embindex 正在向量化 1-6 / 6 … 完成:新增 6 条,跳过 0 条,索引共 6 条(1024 维,模型 BAAI/bge-m3) $ emb search "电脑连不上网怎么办" -i notes.embindex -k 3 1. 0.7388 [notes/网络.md:1] 公司电脑连不上外网时,先检查 Clash 是否开着… 2. 0.5341 [notes/网络.md:2] 代理只对命令行生效的情况下,记得给 curl 加 -x 参数… 3. 0.4630 [notes/编程.md:2] 提交代码前先跑一遍测试… $ emb add ./notes -i notes.embindex # 再跑一次:只算新增 全部已存在:跳过 6 条,无需调用接口 ``` ## ✨ 特性 | | | |---|---| | 🪶 **零依赖** | 只用 Python 标准库;装了 numpy 会自动走矩阵加速,没装照样跑 | | 🖥️ **跨平台** | macOS / Linux / Windows,安装脚本与文档全覆盖 | | 📦 **单文件索引** | 一个 `.embindex` 装下向量 + 原文 + 来源,拷贝备份都方便 | | 🔁 **增量更新** | 重复执行 `add` 只计算新内容,按内容哈希去重 | | 🔍 **语义搜索** | 按意思找,不靠关键词 | | 🧰 **可维护** | 导出 / 删除 / 合并 / 清理 / 体检,一整套命令 | | 🌐 **接口通用** | 任何兼容 OpenAI `/embeddings` 的服务都能接 | | 🔒 **秘钥不落库** | 全部走环境变量,代码里搜不到 key | ## 📥 安装 > 前提:Python 3.8+(`python3 --version`;Windows 上 `python --version`) ### macOS / Linux ```bash git clone https://gitee.com/cc123hh/emb-cli.git cd emb-cli ./install.sh ``` ### Windows ```powershell git clone https://gitee.com/cc123hh/emb-cli.git cd emb-cli powershell -ExecutionPolicy Bypass -File .\install.ps1 ``` 免安装直接用:`emb.cmd similar "甲" "乙"` ### 所有平台(pipx) ```bash pipx install git+https://gitee.com/cc123hh/emb-cli.git ``` ## ⚙️ 配置 ```bash # 必需 export EMB_API_KEY="你的key" # 可选:接口地址(默认 OpenAI 官方) export EMB_BASE="https://api.openai.com/v1" # 可选:模型名(默认 text-embedding-3-small) export EMB_MODEL="BAAI/bge-m3" # 可选:代理 export EMB_PROXY="http://127.0.0.1:7890" ``` Windows: ```powershell setx EMB_API_KEY "你的key" setx EMB_BASE "https://api.openai.com/v1" setx EMB_MODEL "BAAI/bge-m3" ``` > ⚠️ **换模型必须重建索引**:不同模型维度不同(1024 / 1536 / 3072),不能混在一个文件里。 ## 📖 用法 ### 1. 临时向量化(不落盘) ```bash emb embed "今天天气不错" # 输出一行 JSON emb embed notes.txt -o notes.jsonl # 文件按行切 cat a.md | emb embed - # 从管道读 emb embed ./docs/ -o docs.jsonl # 目录批量(递归 .md/.txt/.markdown) ``` ### 2. 建索引 / 增量更新 ```bash emb add ./notes/ -i notes.embindex # 首次建库 emb add ./notes/ -i notes.embindex # 再跑:只算新增 emb add "临时补一条" -i notes.embindex --text ``` ### 3. 语义搜索 ```bash emb search "怎么配置代理" -i notes.embindex -k 5 emb search "怎么配置代理" -i notes.embindex --json # 管道友好 ``` ### 4. 比较两句话 ```bash $ emb similar "我喜欢吃白米饭" "我爱吃米饭" 0.9026 高度相似 $ emb similar "我喜欢吃白米饭" "Python 虚拟环境" 0.3643 基本无关 ``` ### 5. 查看索引 ```bash emb info -i notes.embindex ``` ## 🧰 维护索引 ```bash emb doctor -i notes.embindex # 体检:重复、空文本、失效来源 emb export -i notes.embindex -o notes.jsonl # 导出可读文件(备份 / 进 Git) emb export -i notes.embindex -o notes.csv --format csv emb remove -i notes.embindex --id a1b2c3d4e5f6 # 删一条 emb remove -i notes.embindex --source notes/旧.md # 删某来源(前缀匹配) emb remove -i notes.embindex --all # 清空 emb merge a.embindex b.embindex -o all.embindex # 合并(同模型同维度,内容去重) emb prune -i notes.embindex # 清理源文件已删除的条目 emb prune -i notes.embindex --dry-run # 先看看会删什么 ``` ## 📋 参数速查 | 参数 | 适用命令 | 说明 | |---|---|---| | `--text` | embed / add | 强制把参数当文本(即使像路径) | | `--paragraph` | embed / add | 按空行分段,而不是按行 | | `--max-chars` | embed / add | 单段最大字符数,默认 6000 | | `--batch-size` | embed / add | 每批请求条数,默认 32 | | `-k, --top-k` | search | 返回条数,默认 5 | | `--json` | search | 输出 JSON | | `--format` | export | `jsonl`(默认)或 `csv` | | `--id` / `--source` / `--all` | remove | 删除条件,至少一个 | | `--dry-run` | prune | 只显示,不改动 | | `--base/--model/--proxy/--timeout` | 全部 | 覆盖环境变量 | ## 💾 索引格式 单文件二进制:`魔数(8B) + 版本(2B) + meta长度(4B) + meta(JSON) + float32 向量区`。 写入采用临时文件 + 原子替换——中途失败不会毁掉旧索引。 | 条数 | 向量部分(1024 维) | 含原文约 | |---|---|---| | 1,000 | 4 MB | ≈ 4.3 MB | | 3,000 | 12 MB | ≈ 13 MB | | 10,000 | 40 MB | ≈ 43 MB | ## ❓ 常见问题
能不能不建索引直接搜? 搜索依赖持久化索引。临时比较两句话用 `emb similar`,不落盘。
换模型后提示维度不一致? 不同模型维度不同。删掉旧索引重新 `emb add`,或用 `emb export` 备份原文后再重建。
接口报 429 / 503 / 504? 工具会自动退避重试(1/2/4/8 秒,最多 4 次)。持续失败请调小 `--batch-size` 或稍后再试。
中文分句效果不好? 默认按行切。笔记建议一行一个知识点;长文可用 `--paragraph` 按空行分段。
支持图片向量吗? 暂不支持,当前只处理文本。
索引能不能进 Git? 二进制文件不适合 diff。建议把 `emb export` 出来的 jsonl 进 Git,索引本身丢进 `.gitignore`。
## 🤝 贡献 欢迎 Issue / PR。报告兼容性问题请附:操作系统、`python --version`、完整报错。 ## License [MIT](LICENSE)