CLI-Anything ChromaDB CLI 实战:基于 ChromaDB v2 REST API 的向量子集、文档与语义检索命令行工具
【免费下载链接】CLI-Anything"CLI-Anything: Making ALL Software Agent-Native" -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything
CLI-Anything 为 ChromaDB 向量数据库提供了一个名为cli-anything-chromadb的命令行 harness(README)。它完全通过 ChromaDB 的 HTTP API v2 与服务器交互,默认目标为http://localhost:8000,覆盖服务器健康检查、集合(collection)管理、文档(document)增删查计以及语义检索四大命令组,并提供交互式 REPL 与--json机器可读输出。读完本文,你将掌握该 CLI 的完整命令参数、默认值与配置项,并理解其底层 URL 构造、REPL 分发机制与错误处理策略,便于将其接入脚本、CI 或 AI Agent 工作流。
一、定位与运行前提
从 SKILL.md 的描述看,该工具被定位为“面向 AI agent 与自动化脚本的无状态(stateless)ChromaDB 命令行接口”,其核心特征是:
- 不依赖 ChromaDB Python SDK:仅使用
requests直连 v2 REST API(见 chromadb_backend.py),因此对服务器所在语言/进程无要求; - 默认目标:服务器
http://localhost:8000,租户default_tenant,数据库default_database(README Configuration 一节与 backend 源码 一致); - 双交互模式:不带子命令直接运行进入交互式 REPL;带子命令则执行单条命令后退出。
运行前提:Python 3.10+(setup.py 中python_requires=">=3.10"),以及一台可达的 ChromaDB 服务器。
二、安装与可执行入口
按 README 安装:
cd agent-harness pip install -e .该命令实际安装的是 setup.py 定义的cli-anything-chromadb包(版本 1.0.0),其关键元数据如下:
- 入口点(console_scripts):
cli-anything-chromadb→cli_anything.chromadb.chromadb_cli:main(setup.py#L35-L38); - 运行依赖:
click>=8.0.0、prompt-toolkit>=3.0.0、requests>=2.28.0(setup.py#L24-L28),即 REPL 样式与补全能力来自 prompt_toolkit,HTTP 通信来自 requests; - 包数据:随包分发
skills/*.md,即上面提到的 Agent 技能说明文件。
除pip install外,仓库还提供模块方式运行:python -m cli_anything.chromadb,main.py 直接转调main(),适合未安装入口脚本的临时调试场景。
三、全局选项:--json、--host 与环境变量
所有子命令共享两个全局选项,定义在根 Click group 上(chromadb_cli.py#L17-L31):
| 选项 | 默认值 | 作用 |
|---|---|---|
--json | 关闭 | 所有命令输出改为 JSON(缩进 2 空格) |
--host | http://localhost:8000 | ChromaDB 服务器地址 |
两点源码层面的补充:
- 选项必须放在子命令之前。
--json/--host挂在根 group 上,因此正确写法是cli-anything-chromadb --json collection list,这与 README “Add--jsonbefore any subcommand” 的说明一致。 - 支持环境变量覆盖。
main()以cli(auto_envvar_prefix="CHROMADB_CLI")启动(chromadb_cli.py#L105-L107),Click 会自动读取CHROMADB_CLI_*环境变量作为选项的默认值来源(例如CHROMADB_CLI_HOST),这在无终端交互的 Agent/脚本环境中尤其方便,无需每次在命令行拼接--host。
--host的值最终传给ChromaDBBackend(base_url=host)(chromadb_cli.py#L27),backend 构造时会对 URL 做rstrip("/")去除尾斜杠(chromadb_backend.py#L18),单测 test_core.py 专门验证了这一行为,因此--host http://other:8000/与不带斜杠的写法等效。
四、命令全集参考
README 给出的命令总览如下(hub_knowledge为示例集合名):
# Server cli-anything-chromadb server heartbeat cli-anything-chromadb server version # Collections cli-anything-chromadb collection list cli-anything-chromadb collection info hub_knowledge cli-anything-chromadb collection create --name test_collection cli-anything-chromadb collection delete --name test_collection # Documents cli-anything-chromadb document count --collection hub_knowledge cli-anything-chromadb document get --collection hub_knowledge --limit 5 cli-anything-chromadb document add --collection hub_knowledge --id doc1 --document "Hello world" cli-anything-chromadb document delete --collection hub_knowledge --id doc1 # Semantic search cli-anything-chromadb query search --collection hub_knowledge --text "how does the pipeline work" --n-results 3下面逐组展开,并结合core/目录下的实现补充每个参数的取值约束与默认值。
4.1 server:健康检查与版本
实现在 core/server.py:
server heartbeat:GET/api/v2/heartbeat。成功时打印服务器存活信息及nanosecond_heartbeat时间戳;失败时(服务器不可达等)输出Server unreachable: ...并以退出码 1 结束(server.py#L16-L35)。--json模式下错误也输出为{"error": "..."},便于程序判断。server version:GET/api/v2/version,输出服务器版本字符串;--json模式下包装为{"version": ...}。
这两个命令是脚本接入时的典型前置检查。
4.2 collection:集合管理
实现在 core/collections.py:
| 子命令 | 参数 | 说明 |
|---|---|---|
list | 无 | 以表格列出 Name / ID / Metadata;空库时提示 "No collections found." |
create | --name(必填);--metadata(可选,JSON 字符串) | 创建集合并返回服务器分配的id;--metadata会经json.loads解析后随请求体下发(collections.py#L47-L69) |
delete | --name(必填) | 按名称删除集合,成功输出{"status": "deleted", "name": ...}(JSON 模式) |
info <name> | 位置参数 | 显示集合的 ID、Name、Metadata;注意此处名称是位置参数,而非--name选项 |
一个实用细节:ChromaDB 的文档级 API 使用集合ID(UUID),而用户习惯用名称操作。document与query命令内部都会先调用_resolve_collection_id()把名称解析成 ID(documents.py#L9-L12、query.py#L9-L12),使用者无需手动查 ID。
4.3 document:文档增删查计
实现在 core/documents.py。该组所有命令都要求--collection指定集合名称:
| 子命令 | 参数 | 说明 |
|---|---|---|
add | --id(必填,可重复);--document(必填,可重复);--metadata(可选,可重复的 JSON 字符串) | 批量写入。--id与--document通过多次出现实现批量,例如--id a --document "text A" --id b --document "text B";每个--metadata值会被独立json.loads解析为一份 metadata(documents.py#L22-L53) |
get | --id(可重复,可选);--limit(可选,int);--offset(可选,int) | 按 ID 精确取回或分页浏览;--limit/--offset透传给后端get请求体,适合大集合翻页(documents.py#L56-L98)。表格输出中文档正文超过 80 字符会截断加... |
delete | --id(必填,可重复) | 按 ID 批量删除 |
count | 无 | 返回集合中文档总数,JSON 模式输出{"collection": ..., "count": ...} |
README 示例覆盖了单文档写入与删除的最短路径;结合上表可知,批量操作与分页浏览是该组的完整能力边界。
4.4 query:语义检索
实现在 core/query.py:
cli-anything-chromadb query search --collection hub_knowledge \ --text "how does the pipeline work" --n-results 3--text(必填):查询文本,会以query_texts=[text]形式下发(单查询语义,query.py#L32-L38);--n-results:默认5(query.py#L25),控制返回的最近邻条数;- 输出:人类模式逐条展示排名、文档 ID、distance(距离值)、metadata 与正文预览(超过 120 字符截断);JSON 模式直接透传服务器返回的
ids/documents/distances/metadatas完整结构,方便下游程序做距离阈值过滤。
--json用法示例(来自 README):
cli-anything-chromadb --json collection list cli-anything-chromadb --json query search --collection hub_knowledge --text "pipeline" --n-results 3五、底层实现:ChromaDBBackend 与 v2 REST API 映射
chromadb_backend.py 是唯一的网络层,ChromaDBBackend用requests.Session(统一带Content-Type: application/json头)封装全部调用。所有集合级操作共享一个 URL 前缀(chromadb_backend.py#L24-L26):
{base_url}/api/v2/tenants/{tenant}/databases/{database}默认即http://localhost:8000/api/v2/tenants/default_tenant/databases/default_database。各方法到 HTTP 端点的映射如下:
| 方法 | HTTP 调用 | 说明 |
|---|---|---|
heartbeat() | GET{base_url}/api/v2/heartbeat | 服务器级端点,不走租户前缀 |
version() | GET{base_url}/api/v2/version | 同上 |
list_collections() | GET{prefix}/collections | — |
create_collection(name, metadata) | POST{prefix}/collections | metadata 可选 |
get_collection(name) | GET{prefix}/collections/{name} | 名称 → 集合对象(含 id) |
delete_collection(name) | DELETE{prefix}/collections/{name} | — |
add_documents(...) | POST{prefix}/collections/{cid}/add | 请求体含ids、documents,可选metadatas、embeddings |
get_documents(...) | POST{prefix}/collections/{cid}/get | 请求体按需含ids、limit、offset |
delete_documents(...) | POST{prefix}/collections/{cid}/delete | 请求体{"ids": [...]} |
count_documents(...) | POST{prefix}/collections/{cid}/count | — |
query(...) | POST{prefix}/collections/{cid}/query | 请求体{"query_texts": [...], "n_results": N} |
两点值得注意:
- 构造签名允许传入自定义
tenant/database(chromadb_backend.py#L15-L20),单测 test_core.py#L45-L48 也验证了自定义租户/数据库的 URL 拼装;但从 CLI 层面看,--host只暴露了服务器地址,租户与数据库在命令行上固定为默认值——若你的 ChromaDB 实例使用了非默认租户,从源码结构看需要扩展 CLI 参数或改用环境变量/直接调用 backend。 - 每个方法都会
raise_for_status(),任何 HTTP 错误都会以异常形式抛到命令层统一处理(见下节)。
六、REPL 模式:交互、分发与历史记录
直接运行cli-anything-chromadb不带子命令时,cli根 group 检测到ctx.invoked_subcommand is None,转入_run_repl()(chromadb_cli.py#L59-L102)。其机制值得展开:
- 统一皮肤 ReplSkin:REPL 外观(品牌横幅、彩色提示符、表格、状态色)由 utils/repl_skin.py 的
ReplSkin("chromadb", version="1.0.0")提供,这是 CLI-Anything 所有 harness 共用的终端界面层。横幅会展示当前 harness 的 skill 安装方式与全局 SKILL.md 路径,方便 AI agent 发现技能说明(repl_skin.py#L218-L243)。 - 输入经 shlex 拆分后回投 Click:每一行输入先
shlex.split解析(chromadb_cli.py#L87-L95),再以standalone_mode=False调用cli.main()。这意味着REPL 里能输入的就是命令行上能输入的子命令(如document add --collection x --id 1 --document "hi"),两者共用同一套参数解析与执行路径,不存在行为分叉。 - 命令帮助表:REPL 内输入
help/h/?展示内置命令清单(chromadb_cli.py#L42-L56),quit/exit/q退出。 - 历史与补全:
ReplSkin.create_prompt_session()创建 prompt_toolkit 会话,启用FileHistory与AutoSuggestFromHistory(repl_skin.py#L486-L508);历史文件默认落在~/.cli-anything-chromadb/history(repl_skin.py#L159-L165)。若 prompt_toolkit 不可用则自动退化为内置input(),因此 REPL 在最小依赖环境下也能使用。 - REPL 错误隔离:Click 的
SystemExit在 REPL 循环中被吞掉(chromadb_cli.py#L96-L102),单条命令失败不会中断会话,而是通过skin.error(...)打印后继续等待输入。
七、JSON 输出与错误处理约定
对脚本与 Agent 来说,可预测的输出契约比功能本身更关键。所有命令遵循同一套双模式约定(以 collections.py 与 query.py 的实现为准):
- 成功 +
--json:json.dumps(result, indent=2)输出服务器原始响应(heartbeat、collection 信息、查询结果等); - 成功 + 人类模式:由 ReplSkin 渲染为表格 / 状态行 / 成功提示(如
✓ Collection 'x' created); - 失败 +
--json:输出{"error": "<异常信息>"}; - 失败 + 人类模式:输出
✗ <错误>到 stderr,并以SystemExit(1)使进程退出码为 1(server.py#L30-L35)。
这套“退出码 + 统一 JSON 错误形状”的组合,使set -e脚本、CI 任务和 LLM 工具调用都能可靠地判断成败并解析失败原因。
八、配置小结与适用边界
汇总 README Configuration 一节并对照源码,可用配置项如下:
| 配置项 | 默认值 | 覆盖方式 |
|---|---|---|
| 服务器地址 | http://localhost:8000 | --host http://other:8000(需置于子命令前)或CHROMADB_CLI_HOST环境变量 |
| JSON 输出 | 关 | --json(置于子命令前)或CHROMADB_CLI_JSON环境变量 |
| 租户 | default_tenant | 仅 backend 构造参数,CLI 未暴露 |
| 数据库 | default_database | 同上 |
适用边界(基于当前仓库实现,版本 1.0.0):
- 需要一台独立运行的 ChromaDB 服务器(HTTP v2 API),非嵌入式本地模式;
- CLI 目前不暴露 embedding 相关参数:
add_documents虽在 backend 层接受embeddings参数(chromadb_backend.py#L76-L79),但document add命令未提供对应选项,向量由服务器端 embedding 函数生成; - 租户/数据库固定为默认值,多租户场景需直接实例化
ChromaDBBackend或扩展 CLI; query search为单查询文本(内部固定query_texts=[text]),多查询批量场景不在当前命令面内。
九、验证依据:测试与配套文件
- tests/test_core.py:全量 mock HTTP,验证 URL 构造(默认/自定义 base_url、尾斜杠去除、租户前缀拼接)、session 头、heartbeat/version 的端点地址与返回解析等,可在无 ChromaDB 环境时直接运行;
- tests/test_full_e2e.py 与 tests/TEST.md:端到端验证与测试说明;
- skills/SKILL.md:随包分发的 Agent 技能说明,含命令速查表,REPL 横幅也会指引 agent 读取该文件;
- CHROMADB.md:该 harness 在 agent-harness 层的设计文档。
总体而言,cli-anything-chromadb是一个薄而完整的 v2 API 命令行映射:Click 负责参数解析与命令树,ChromaDBBackend负责 REST 封装,ReplSkin负责人机/机机双输出。理解了“名称→ID 解析、统一错误契约、REPL 复用 Click 分发”这三条主线,就能把它稳妥地纳入自己的向量库运维与 Agent 工具链。
【免费下载链接】CLI-Anything"CLI-Anything: Making ALL Software Agent-Native" -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考