LLPhant icon indicating copy to clipboard operation
LLPhant copied to clipboard

Store the last response object from OpenAI

Open ezimuel opened this issue 9 months ago • 6 comments

This PR adds the possibility to store the last response from OpenAI to get advanced information like the token usage, fixing #109.

Here an example:

$config = new OpenAIConfig();
$chat = new OpenAIChat($config);

$answer = $chat->generateText('here the question');
$response = $chat->getLastResponse();
printf("Tokens in prompt: %d\n", $response->usage->promptTokens);
printf("Tokens in response: %d\n", $response->usage->completionTokens);
printf("Total tokens: %d\n", $response->usage->totalTokens);

All the JSON properties from the OpenAI original HTTP response are available. Here an example of HTTP response (taken from the original OpenAI documentation):

{
    "id": "chatcmpl-123",
    "object": "chat.completion",
    "created": 1677652288,
    "model": "gpt-3.5-turbo-0125",
    "system_fingerprint": "fp_44709d6fcb",
    "choices": [{
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "\n\nHello there, how may I assist you today?"
      },
      "logprobs": null,
      "finish_reason": "stop"
    }],
    "usage": {
      "prompt_tokens": 9,
      "completion_tokens": 12,
      "total_tokens": 21
    }
}

ezimuel avatar May 07 '24 17:05 ezimuel

Hey @ezimuel , did you see this PR from @samuelgjekic ? Maybe having some typing/objetcs for the usage is a good idea and for the rest your approach is pragmatic

MaximeThoonsen avatar May 07 '24 21:05 MaximeThoonsen

Ops! I didn't see PR #110 sorry for that :-( I'll have a look and check the differences.

ezimuel avatar May 08 '24 06:05 ezimuel

@MaximeThoonsen, @samuelgjekic I did a look at #110 and the approach is similar. My proposal adds the full response object from OpenAI and not only the token usage. Moreover, I didn't add a specific class like TokenUsage since the types are already defined in the openai-php/client library.

Another difference, I stored the OpenAI response in generateText and generateTextOrReturnFunctionCalled. The PR #110 added in generate and generateChat. I think the last approach is better since the generate is used in generateText and generateTextOrReturnFunctionCalled. I'll change this.

@MaximeThoonsen do you think make sense to store the entire OpenAI response instead of just the token usage? Do you prefer having dedicated types, like a OpenAIResponse class that maps all the properties or reuse the existing OpenAI\Responses\Chat\CreateResponse class?

ezimuel avatar May 08 '24 06:05 ezimuel

@ezimuel well after looking at your solution i will have to say that i feel like you did take a better approach with the lastResponse solution as it its clearer to the user what it does. @MaximeThoonsen can decide what to do here 🙂

samuelgjekic avatar May 08 '24 08:05 samuelgjekic

Thanks @samuelgjekic for your feedback. In the meantime, I moved the lastResponse in generate() and generateText() functions. If @MaximeThoonsen approves the approach proposed in this PR I'll resolve the conflicts with the #110 PR. We still need to add the documentation for this feature. Should I add it in docusaurus/docs/usage.md ?

ezimuel avatar May 08 '24 08:05 ezimuel

Ok to store in a lastResponse object. Maybe add a small helper so that people can get the usage in an easy way?

Should I add it in docusaurus/docs/usage.md ?

This would be perfect

MaximeThoonsen avatar May 09 '24 13:05 MaximeThoonsen

I added a getTotalTokens() function that adds the total token usage from sequential calls. Here an example (form the documentation included):

$chat = new OpenAIChat();

$answer = $chat->generateText('what is one + one ?');
printf("%s\n", $answer); # One plus one equals two
printf("Total tokens usage: %d\n", $chat->getTotalTokens()); # 19

$answer = $chat->generateText('And what is two + two ?');
printf("%s\n", $answer); # Two plus two equals four
printf("Total tokens usage: %d\n", $chat->getTotalTokens()); # 39

I think this function can be useful to take track of the API cost from OpenAI. I also added the documentation and removed the TokenUsage class introduced in #110.

@MaximeThoonsen and @samuelgjekic let me know WDYT, thanks!

ezimuel avatar May 10 '24 17:05 ezimuel

thanks a lot @ezimuel and @samuelgjekic . I really like the solution!

MaximeThoonsen avatar May 12 '24 09:05 MaximeThoonsen