使用 CLI 进行嵌入#

LLM 提供了命令行工具,用于计算和存储内容片段的嵌入向量。

llm embed#

使用 llm embed 命令可以计算一个字符串内容的嵌入向量。这些向量可以直接返回到终端,存储在 SQLite 数据库中,或者两者兼有。

将嵌入向量返回到终端#

使用此命令最简单的方法是通过 -c/--content 选项向其传递内容,例如

llm embed -c 'This is some content' -m 3-small

-m 3-small 指定 OpenAI 的 text-embedding-3-small 模型。您需要先使用 llm keys set openai 设置 OpenAI API 密钥,此功能才能正常工作。

您可以安装插件来访问其他模型。例如 llm-sentence-transformers 插件可用于在您自己的笔记本电脑上运行模型,例如 MiniLM-L6 模型

llm install llm-sentence-transformers
llm embed -c 'This is some content' -m sentence-transformers/all-MiniLM-L6-v2

llm embed 命令将一个浮点数 JSON 数组直接返回到终端

[0.123, 0.456, 0.789...]

如果您设置了默认嵌入模型,则可以省略 -m/--model 选项。

您也可以设置 LLM_EMBEDDING_MODEL 环境变量,为当前 shell 会话中的所有 llm embed 命令设置默认模型

export LLM_EMBEDDING_MODEL=3-small
llm embed -c 'This is some content'

LLM 还提供了一种用于嵌入向量的二进制存储格式,详见嵌入存储格式

您可以使用 --format blob 将嵌入向量以原始字节形式输出,使用 --format hex 以十六进制形式输出,或使用 --format base64 以 Base64 形式输出

llm embed -c 'This is some content' -m 3-small --format base64

这将输出

8NGzPFtdgTqHcZw7aUT6u+++WrwwpZo8XbSxv...

一些模型,例如 llm-clip,可以处理二进制数据。您可以使用 -i--binary 选项传递二进制数据

llm embed --binary -m clip -i image.jpg

或者像这样从标准输入读取

cat image.jpg | llm embed --binary -m clip -i -

将嵌入向量存储在 SQLite 中#

如果您将嵌入向量存储在某处,它们会更有用,这样您以后就可以计算不同嵌入向量之间的相似度分数。

LLM 包含了集合的概念。一个集合将使用相同模型创建的一组存储的嵌入向量分组,每个嵌入向量在该集合中具有唯一的 ID。

嵌入向量还存储了被嵌入内容的哈希值。此哈希值稍后用于避免为相同内容计算重复的嵌入向量。

首先,我们将设置一个默认模型,这样就不必重复输入了

llm embed-models default 3-small

llm embed 命令可以直接将结果存储在命名集合中,例如这样

llm embed quotations philkarlton-1 -c \
  'There are only two hard things in Computer Science: cache invalidation and naming things'

这会将给定文本以键 philkarlton-1 存储到 quotations 集合中。

您也可以将内容通过管道输送到标准输入,例如这样

cat one.txt | llm embed files one

这会将 one.txt 文件内容的嵌入向量以键 one 存储到 files 集合中。

当您第一次提到一个集合时,它将被创建。

集合具有固定的嵌入模型,即用于存储该集合中第一个嵌入向量的模型。

在上面的示例中,这将是运行该命令时默认的嵌入模型。

以下示例将字符串“my happy hound”的嵌入向量存储在一个名为 phrases 的集合中,键为 hound,并使用 3-small 模型

llm embed phrases hound -m 3-small -c 'my happy hound'

默认情况下,用于存储嵌入向量的 SQLite 数据库是 LLM 管理的用户内容目录中的 embeddings.db 文件。

您可以通过运行 llm collections path 查看该目录的路径。

您可以通过使用 llm embed-d/--database 选项传递路径,将嵌入向量存储在不同的 SQLite 数据库中。如果该文件尚不存在,命令将创建它

llm embed phrases hound -d my-embeddings.db -c 'my happy hound'

这将在当前目录中创建一个名为 my-embeddings.db 的数据库文件。

存储内容和元数据#

默认情况下,数据库表中只存储条目 ID 和嵌入向量。

您可以通过传递 --store 选项,将原始文本的副本存储在 content 列中

llm embed phrases hound -c 'my happy hound' --store

您也可以通过传递 --metadata 选项,在 metadata 列中存储一个包含任意元数据的 JSON 对象。此示例同时使用了 --store--metadata 选项

llm embed phrases hound \
  -m 3-small \
  -c 'my happy hound' \
  --metadata '{"name": "Hound"}' \
  --store

以这种方式存储的数据将由 llm similar 调用返回,例如

llm similar phrases -c 'hound'
{"id": "hound", "score": 0.8484683588631485, "content": "my happy hound", "metadata": {"name": "Hound"}}

llm embed-multi#

llm embed 命令一次只嵌入一个字符串。

llm embed-multi 可用于一次嵌入多个字符串,利用嵌入模型在处理多个字符串时可能提供的任何效率。

此命令可以通过以下三种方式之一调用

  1. 使用 CSV、TSV、JSON 或以换行符分隔的 JSON 文件

  2. 使用 SQLite 数据库和 SQL 查询

  3. 使用一个或多个目录路径,每个路径附带一个 glob 模式

所有三种机制都支持以下选项

  • -m model_id 用于指定要使用的嵌入模型

  • -d database.db 用于指定不同的数据库文件来存储嵌入向量

  • --store 用于在嵌入表中存储原始内容以及嵌入向量

  • --prefix 用于在每个条目的存储 ID 前添加前缀

  • --prepend 用于在嵌入之前向内容前添加一个字符串

  • --batch-size SIZE 用于按指定大小的批次处理嵌入向量

--prepend 选项对于需要您在嵌入内容之前添加特殊 token 的嵌入模型非常有用。例如,nomic-embed-text-v2-moe 要求文档前添加 'search_document: ',而搜索查询前添加 'search_query: '

从 CSV、TSV 或 JSON 文件嵌入数据#

您可以通过将 CSV、TSV 或 JSON 文件作为第二个选项(在集合名称之后)传递给命令来嵌入文件中的数据。

您的文件必须至少包含两列。第一列预计包含条目的 ID,后续列将被视为包含要嵌入的内容。

一个 CSV 示例文件可能如下所示

id,content
one,This is the first item
two,This is the second item

TSV 将使用制表符代替逗号。

JSON 文件可以结构化如下

[
  {"id": "one", "content": "This is the first item"},
  {"id": "two", "content": "This is the second item"}
]

或者像这样以换行符分隔的 JSON 格式

{"id": "one", "content": "This is the first item"}
{"id": "two", "content": "This is the second item"}

在上述每种情况下,文件都可以像这样传递给 llm embed-multi

llm embed-multi items mydata.csv

第一个参数是集合的名称,第二个是文件名。

您也可以使用 - 将内容通过管道输送到工具的标准输入

cat mydata.json | llm embed-multi items -

LLM 将尝试自动检测您的数据格式。如果不起作用,您可以使用 --format 选项指定格式。如果您通过管道将以换行符分隔的 JSON 输送到标准输入,这是必需的。

cat mydata.json | llm embed-multi items - --format nl

其他支持的 --format 选项包括 csvtsvjson

此示例将 JSON 文件中的数据嵌入到名为 items 的集合中,数据库文件为 docs.db,使用 3-small 模型,并将原始内容也存储在 embeddings 表中,同时为每个 ID 添加前缀 my-items/

llm embed-multi items mydata.json \
  -d docs.db \
  -m 3-small \
  --prefix my-items/ \
  --store

从 SQLite 数据库嵌入数据#

您可以使用 --sql 从 SQLite 数据库嵌入数据,可选择结合 --attach 附加一个额外的数据库。

如果您将嵌入向量存储在与源数据相同的数据库中,您可以这样做

llm embed-multi docs \
  -d docs.db \
  --sql 'select id, title, content from documents' \
  -m 3-small

这里的 docs.db 数据库包含一个 documents 表,我们想嵌入该表的 titlecontent 列,并将结果存储回同一个数据库。

要从用于存储嵌入向量的数据库以外的其他数据库加载内容,请使用 --attach 选项附加它,并在 SQLite 查询中使用 alias.table

llm embed-multi docs \
  -d embeddings.db \
  --attach other other.db \
  --sql 'select id, title, content from other.documents' \
  -m 3-small

从目录中的文件嵌入数据#

LLM 可以嵌入指定目录中每个文本文件的内容,并使用文件的路径和名称作为 ID。

考虑以下目录结构

docs/aliases.md
docs/contributing.md
docs/embeddings/binary.md
docs/embeddings/cli.md
docs/embeddings/index.md
docs/index.md
docs/logging.md
docs/plugins/directory.md
docs/plugins/index.md

要嵌入所有这些文档,您可以运行以下命令

llm embed-multi documentation \
  -m 3-small \
  --files docs '**/*.md' \
  -d documentation.db \
  --store

这里的 --files docs '**/*.md' 指定应该扫描 docs 目录中匹配 **/*.md glob 模式的文件 - 这将匹配任何嵌套目录中的 Markdown 文件。

上述命令的结果是一个 embeddings 表,其中包含以下 ID

aliases.md
contributing.md
embeddings/binary.md
embeddings/cli.md
embeddings/index.md
index.md
logging.md
plugins/directory.md
plugins/index.md

每个 ID 对应于相应文件的嵌入内容。

可以使用 --prefix 选项为每个 ID 添加前缀

llm embed-multi documentation \
  -m 3-small \
  --files docs '**/*.md' \
  -d documentation.db \
  --store \
  --prefix llm-docs/

这将导致以下 ID

llm-docs/aliases.md
llm-docs/contributing.md
llm-docs/embeddings/binary.md
llm-docs/embeddings/cli.md
llm-docs/embeddings/index.md
llm-docs/index.md
llm-docs/logging.md
llm-docs/plugins/directory.md
llm-docs/plugins/index.md

文件被假定为 utf-8 编码,但如果遇到编码错误,LLM 将回退到 latin-1。您可以使用 --encoding 选项指定不同的编码集合。

此示例将首先尝试 utf-16,然后尝试 mac_roman,最后回退到 latin-1

llm embed-multi documentation \
  -m 3-small \
  --files docs '**/*.md' \
  -d documentation.db \
  --encoding utf-16 \
  --encoding mac_roman \
  --encoding latin-1

如果文件无法读取,它将被记录到标准错误中,但脚本将继续运行。

如果您正在嵌入二进制内容(例如用于 CLIP 的图像),请添加 --binary 选项

llm embed-multi photos \
  -m clip \
  --files photos/ '*.jpeg' --binary

llm similar#

llm similar 命令在嵌入向量集合中搜索与给定内容或条目 ID 最相似的条目,基于余弦相似度

这目前使用的是一种缓慢的暴力搜索方法,对于大型集合来说扩展性不佳。关于通过插件提供的向量索引添加更具扩展性的方法的计划,请参阅问题 216

要在 quotations 集合中搜索与 'computer science' 语义相似的条目

llm similar quotations -c 'computer science'

这将嵌入提供的字符串,并返回一个以换行符分隔的 JSON 对象列表,如下所示

{"id": "philkarlton-1", "score": 0.8323904531677017, "content": null, "metadata": null}

使用 -p/--plain 以纯文本而非 JSON 格式获取结果

llm -similar quotations -c 'computer science' -p

示例输出

philkarlton-1 (0.8323904531677017)

您可以使用 -i filename 与文件中存储的文本进行比较

llm similar quotations -i one.txt

或者使用 -i - 将文本输入到标准输入

echo 'computer science' | llm similar quotations -i -

使用 CLIP 等模型时,您可以使用 -i filename--binary 找到与输入图像相似的图像

llm similar photos -i image.jpg --binary

llm embed-models#

要列出所有可用的嵌入模型,包括插件提供的模型,请运行此命令

llm embed-models

输出应该类似于这样

OpenAIEmbeddingModel: text-embedding-ada-002 (aliases: ada, ada-002)
OpenAIEmbeddingModel: text-embedding-3-small (aliases: 3-small)
OpenAIEmbeddingModel: text-embedding-3-large (aliases: 3-large)
...

添加一个或多个 -q 来搜索匹配这些术语的模型

llm embed-models -q 3-small

llm embed-models default#

此命令可用于获取和设置默认嵌入模型。

这将返回当前默认模型的名称

llm embed-models default

您可以像这样设置不同的默认模型

llm embed-models default 3-small

这将把默认模型设置为 OpenAI 的 3-small 模型。

任何支持的模型别名都可以传递给此命令。

您可以使用 --remove-default 取消设置默认模型

llm embed-models default --remove-default

未设置默认模型时,llm embedllm embed-multi 命令将要求使用 -m/--model 指定模型。

llm collections list#

要列出嵌入数据库中的所有集合,请运行此命令

llm collections list

添加 --json 以获取 JSON 输出

llm collections list --json

添加 -d/--database 以指定不同的数据库文件

llm collections list -d my-embeddings.db

llm collections delete#

要从数据库中删除集合,请运行此命令

llm collections delete collection-name

传递 -d 以指定不同的数据库文件

llm collections delete collection-name -d my-embeddings.db