llm icon indicating copy to clipboard operation
llm copied to clipboard

Use condense_json() to make response logging more efficient

Open simonw opened this issue 9 months ago • 1 comments

Most database log entries currently contain both the prompt and the response twice:

llm logs -c --json
[
  {
    "id": "01jmddkan06b0568gjk90k134t",
    "model": "gpt-4o-mini",
    "prompt": "say hi",
    "system": null,
    "prompt_json": {
      "messages": [
        {
          "role": "user",
          "content": "say hi"
        }
      ]
    },
    "options_json": {},
    "response": "Hi there! How can I assist you today?",
    "response_json": {
      "content": "Hi there! How can I assist you today?",
      "finish_reason": "stop",

My new https://github.com/simonw/condense-json library - initially built for #617 - could help here.

simonw avatar Feb 18 '25 20:02 simonw

With this prototype:

diff --git a/llm/models.py b/llm/models.py
index fbc5dd1..bf28d1c 100644
--- a/llm/models.py
+++ b/llm/models.py
@@ -1,5 +1,6 @@
 import asyncio
 import base64
+from condense_json import condense_json
 from dataclasses import dataclass, field
 import datetime
 from .errors import NeedsKeyException
@@ -395,14 +396,22 @@ class _BaseResponse:
             "model": self.model.model_id,
             "prompt": self.prompt._prompt,
             "system": self.prompt._system,
-            "prompt_json": self._prompt_json,
+            "prompt_json": condense_json(
+                self._prompt_json,
+                {
+                    "prompt": self.prompt._prompt,
+                    "system": self.prompt._system,
+                },
+            ),
             "options_json": {
                 key: value
                 for key, value in dict(self.prompt.options).items()
                 if value is not None
             },
             "response": self.text_or_raise(),
-            "response_json": self.json(),
+            "response_json": condense_json(
+                self.json(), {"response": self.text_or_raise()}
+            ),
             "conversation_id": conversation.id,
             "duration_ms": self.duration_ms(),
             "datetime_utc": self.datetime_utc(),
diff --git a/setup.py b/setup.py
index 98452d7..3bb4051 100644
--- a/setup.py
+++ b/setup.py
@@ -49,6 +49,7 @@ setup(
         "pip",
         "pyreadline3; sys_platform == 'win32'",
         "puremagic",
+        "condense-json",
     ],
     extras_require={
         "test": [

I run this:

llm 'say hi' -s 'in french'

And get this:

[
  {
    "id": "01jmddtxc1sqee3yxgrh9d0h1d",
    "model": "gpt-4o-mini",
    "prompt": "say hi",
    "system": "in french",
    "prompt_json": {
      "messages": [
        {
          "role": "system",
          "content": {
            "$": "system"
          }
        },
        {
          "role": "user",
          "content": {
            "$": "prompt"
          }
        }
      ]
    },
    "options_json": {},
    "response": "Salut ! Comment \u00e7a va ?",
    "response_json": {
      "content": {
        "$": "response"
      },
      "finish_reason": "stop",

simonw avatar Feb 18 '25 21:02 simonw