将日志记录到 SQLite#

llm 默认将所有提示和响应记录到 SQLite 数据库中。

您可以使用 llm logs path 命令找到该数据库的位置

llm logs path

在我的 Mac 上输出如下

/Users/simon/Library/Application Support/io.datasette.llm/logs.db

这在其他操作系统上会有所不同。

要避免记录单个提示,请向命令传递 --no-log-n

llm 'Ten names for cheesecakes' -n

要默认关闭日志记录功能

llm logs off

如果您已关闭日志记录功能,仍然可以通过添加 --log 来记录单个提示和响应

llm 'Five ambitious names for a pet pterodactyl' --log

要默认重新开启日志记录功能

llm logs on

要查看日志数据库的状态,请运行此命令

llm logs status

示例输出

Logging is ON for all prompts
Found log database at /Users/simon/Library/Application Support/io.datasette.llm/logs.db
Number of conversations logged: 33
Number of responses logged:     48
Database file size:             19.96MB

查看日志#

您可以使用 llm logs 命令查看日志

llm logs

这将以 Markdown 格式输出最近的三个日志条目,显示使用 Markdown 格式化的提示和响应。

要仅获取最近的纯文本提示响应,请添加 -r/--response

llm logs -r

使用 -x/--extract 提取并返回所选日志条目中的第一个围栏代码块

llm logs --extract

或使用 --xl/--extract-last 获取最后一个围栏代码块

llm logs --extract-last

添加 --json 以获取 JSON 格式的日志消息

llm logs --json

添加 -n 10 查看最近的十个条目

llm logs -n 10

或添加 -n 0 查看所有已记录的条目

llm logs -n 0

您可以使用 -t/--truncate 选项截断提示和响应的显示。这有助于提高 JSON 输出的可读性 - 尽管 --short 选项通常更好。

llm logs -n 1 -t --json

示例输出

[
  {
    "id": "01jm8ec74wxsdatyn5pq1fp0s5",
    "model": "anthropic/claude-3-haiku-20240307",
    "prompt": "hi",
    "system": null,
    "prompt_json": null,
    "response": "Hello! How can I assist you today?",
    "conversation_id": "01jm8ec74taftdgj2t4zra9z0j",
    "duration_ms": 560,
    "datetime_utc": "2025-02-16T22:34:30.374882+00:00",
    "input_tokens": 8,
    "output_tokens": 12,
    "token_details": null,
    "conversation_name": "hi",
    "conversation_model": "anthropic/claude-3-haiku-20240307",
    "attachments": []
  }
]

-s/–short 模式#

使用 -s/--short 查看带有截断提示且无响应的缩短版 YAML 日志

llm logs -n 2 --short

示例输出

- model: deepseek-reasoner
  datetime: '2025-02-02T06:39:53'
  conversation: 01jk2pk05xq3d0vgk0202zrsg1
  prompt:  H01 There are five huts. H02 The Scotsman lives in the purple hut. H03 The Welshman owns the parrot. H04 Kombucha is...
- model: o3-mini
  datetime: '2025-02-02T19:03:05'
  conversation: 01jk40qkxetedzpf1zd8k9bgww
  system: Formatting re-enabled. Write a detailed README with extensive usage examples.
  prompt: <documents> <document index="1"> <source>./Cargo.toml</source> <document_content> [package] name = "py-limbo" version...

包含 -u/--usage 以包含 token 使用信息

llm logs -n 1 --short --usage

示例输出

- model: o3-mini
  datetime: '2025-02-16T23:00:56'
  conversation: 01jm8fxxnef92n1663c6ays8xt
  system: Produce Python code that demonstrates every possible usage of yaml.dump
    with all of the arguments it can take, especi...
  prompt: <documents> <document index="1"> <source>./setup.py</source> <document_content>
    NAME = 'PyYAML' VERSION = '7.0.0.dev0...
  usage:
    input: 74793
    output: 3550
    details:
      completion_tokens_details:
        reasoning_tokens: 2240

对话日志#

要查看与模型最近一次 对话 的日志,请使用 -c

llm logs -c

要根据对话 ID 查看特定对话的日志,请使用 --cid ID--conversation ID

llm logs --cid 01h82n0q9crqtnzmf13gkyxawg

搜索日志#

您可以在 promptresponse 列中搜索日志条目。

llm logs -q 'cheesecake'

最相关的条目将显示在输出的底部。

过滤特定 ID 之后的日志#

如果您想检索自特定响应 ID 以来记录的所有日志,可以使用以下选项

  • --id-gt $ID - ID 大于 $ID 的所有记录

  • --id-gte $ID - ID 大于或等于 $ID 的所有记录

ID 始终按时间升序发出,因此这提供了一种有用的方法来查看自特定记录以来发生的一切。

这在处理 schema 数据时特别有用,您可能希望访问使用特定 --schema 创建的所有记录,但排除之前已处理过的记录。

按模型过滤#

您可以使用 -m/--model 过滤特定模型(或模型别名)的日志

llm logs -m chatgpt

按使用了特定片段的提示过滤#

选项 -f/--fragment X 将只过滤使用指定的 片段 哈希、别名、URL 或文件名创建的响应。

片段在日志中显示为其哈希 ID。添加 -e/--expand 以将片段显示为其完整内容 - 此选项适用于默认 Markdown 和 --json 模式

llm logs -f https://llm.datasette.com.cn/robots.txt --expand

您可以使用 llm fragments show 命令显示特定片段哈希 ID(或别名)的内容

llm fragments show 993fd38d898d2b59fd2d16c811da5bdac658faa34f0f4d411edde7c17ebb0680

使用 schema 浏览收集的数据#

选项 --schema X 可用于查看使用指定 schema 的响应。这可以与 --data--data-array--data-key 结合使用,以仅提取返回的 JSON 数据 - 详细信息请参阅schema 文档

使用 Datasette 浏览日志#

您还可以使用 Datasette 像这样浏览您的日志

datasette "$(llm logs path)"

备份您的数据库#

您可以使用 llm logs backup 命令将日志备份到另一个文件

llm logs backup /tmp/backup.db

这在底层使用了 SQLite VACCUM INTO

SQL schema#

这是 logs.db 数据库使用的 SQL schema

CREATE TABLE [conversations] (
  [id] TEXT PRIMARY KEY,
  [name] TEXT,
  [model] TEXT
);
CREATE TABLE [schemas] (
  [id] TEXT PRIMARY KEY,
  [content] TEXT
);
CREATE TABLE "responses" (
  [id] TEXT PRIMARY KEY,
  [model] TEXT,
  [prompt] TEXT,
  [system] TEXT,
  [prompt_json] TEXT,
  [options_json] TEXT,
  [response] TEXT,
  [response_json] TEXT,
  [conversation_id] TEXT REFERENCES [conversations]([id]),
  [duration_ms] INTEGER,
  [datetime_utc] TEXT,
  [input_tokens] INTEGER,
  [output_tokens] INTEGER,
  [token_details] TEXT,
  [schema_id] TEXT REFERENCES [schemas]([id])
);
CREATE VIRTUAL TABLE [responses_fts] USING FTS5 (
  [prompt],
  [response],
  content=[responses]
);
CREATE TABLE [attachments] (
  [id] TEXT PRIMARY KEY,
  [type] TEXT,
  [path] TEXT,
  [url] TEXT,
  [content] BLOB
);
CREATE TABLE [prompt_attachments] (
  [response_id] TEXT REFERENCES [responses]([id]),
  [attachment_id] TEXT REFERENCES [attachments]([id]),
  [order] INTEGER,
  PRIMARY KEY ([response_id],
  [attachment_id])
);
CREATE TABLE [fragments] (
  [id] INTEGER PRIMARY KEY,
  [hash] TEXT,
  [content] TEXT,
  [datetime_utc] TEXT,
  [source] TEXT
);
CREATE TABLE [fragment_aliases] (
  [alias] TEXT PRIMARY KEY,
  [fragment_id] INTEGER REFERENCES [fragments]([id])
);
CREATE TABLE "prompt_fragments" (
  [response_id] TEXT REFERENCES [responses]([id]),
  [fragment_id] INTEGER REFERENCES [fragments]([id]),
  [order] INTEGER,
  PRIMARY KEY ([response_id],
  [fragment_id],
  [order])
);
CREATE TABLE "system_fragments" (
  [response_id] TEXT REFERENCES [responses]([id]),
  [fragment_id] INTEGER REFERENCES [fragments]([id]),
  [order] INTEGER,
  PRIMARY KEY ([response_id],
  [fragment_id],
  [order])
);

responses_fts 配置针对 responses 表中 promptresponse 列的 SQLite 全文搜索