首頁  >  文章  >  後端開發  >  我的第一個開源貢獻

我的第一個開源貢獻

DDD
DDD原創
2024-09-19 10:17:00920瀏覽

提交問題

對於我的第一個貢獻,我提交了一個問題以向另一個項目添加新功能,即添加一個新的標誌選項來顯示用於提示和完成生成的令牌。

My first open source contribution 功能:聊天完成令牌資訊標誌選項 #8

My first open source contribution
克萊布恩特拉 發佈於

描述

一個標誌選項,為使用者提供發送和接收的令牌計數。 我認為這是一個重要的功能,可以引導用戶在發出聊天完成請求時保持在代幣預算之內!

實作

為此,我們需要添加另一個選項標誌,可以是 -t 和 --token-usage。當使用者在命令中包含此標誌時,它應該清楚地詳細顯示在生成完成過程中使用了多少個令牌,以及在提示中使用了多少個令牌。

在 GitHub 上查看

我選擇為fadingNA 的開源專案chat-minal 做出貢獻,這是一個用Python 編寫的CLI 工具,允許您利用OpenAI 來做各種事情,例如使用它生成程式碼審查、檔案轉換、產生Markdown文本和摘要文本。

我的拉取請求

我以前用Python寫過程式碼,但這不是我最強的技能。因此,為這個專案做出貢獻為我提供了具有挑戰性但良好的學習經驗。
挑戰在於我必須閱讀和理解別人的程式碼,並以不破壞程式碼設計的方式提供正確的解決方案。理解流程至關重要,這樣我就可以有效地添加功能,而無需對程式碼進行大的更改並保持程式碼一致。

My first open source contribution FEAT:代幣使用標誌 #9

My first open source contribution
克萊布恩特拉 發佈於

功能

新增了為使用者新增 --token_usage 標誌選項的功能。 此選項向使用者提供用於提示和產生完成的令牌數量的資訊。

實作

我根據程式碼設計提出的解決方案是檢查 token_usage 標誌是否存在。 如果未使用 token_usage 標誌,我不希望程式碼檢查任何不必要的 if 語句,因此我製作了兩個單獨的相同循環邏輯,不同之處在於檢查區塊內是否存在 use_metadata。

if token_usage:
    for chunk in runnable.stream({"input_text": input_text}):
        print(chunk.content, end="", flush=True)
        answer.append(chunk.content)

        if chunk.usage_metadata:
            completion_tokens = chunk.usage_metadata.get('output_tokens')
            prompt_tokens = chunk.usage_metadata.get('input_tokens')
else:
    for chunk in runnable.stream({"input_text": input_text}):
        print(chunk.content, end="", flush=True)
        answer.append(chunk.content)
進入全螢幕模式 退出全螢幕模式

顯示

At the end of the execution of get_completions() method, a check for the flag token_usage is added, which then displays the token usage details to stderr if the flag was used.

if token_usage:
    logger.error(f"Tokens used for completion: <span class="pl-s1"><span class="pl-kos">{completion_tokens}</span>"</span>)
    logger.error(f"Tokens used for prompt: <span class="pl-s1"><span class="pl-kos">{prompt_tokens}</span>"</span>)
Enter fullscreen mode Exit fullscreen mode
View on GitHub

My solution

Retrieving the token usage

if token_usage:
    for chunk in runnable.stream({"input_text": input_text}):
        print(chunk.content, end="", flush=True)
        answer.append(chunk.content)

        if chunk.usage_metadata:
            completion_tokens = chunk.usage_metadata.get('output_tokens')
            prompt_tokens = chunk.usage_metadata.get('input_tokens')
else:
    for chunk in runnable.stream({"input_text": input_text}):
        print(chunk.content, end="", flush=True)
        answer.append(chunk.content)

Originally, the code only had one for loop which retrieves the content from a stream and appends it to an array which forms the response of the completion.

Why did I write it this way?

My reasoning behind duplicating the for while adding the distinct if block is to prevent the code from repeatedly checking the if block even if the user is not using the newly added --token_usage flag. So instead, I check for the existence of the flag firstly, and then decide which for loop to execute.

Realization

Even though my pull request has been accepted by the project owner, I realized late that this way adds complexity to the code's maintainability. For example, if there are changes required in the for loop for processing the stream, that means modifying the code twice since there are two identical for loops.

What I think I could do as an improvement for it is to make it into a function so that any changes required can be done in one function only, keeping the maintainability of the code. This just proves that even if I wrote the code with optimization in mind, there are still other things that I can miss which is crucial to a project, which in this case, is maintainability.

Receiving a pull request

My tool, genereadme, also received a contribution. I received a PR from Mounayer, which is to add the same feature to my project.

My first open source contribution feat: added a new flag that displays the number of tokens sent in prompt and received in completion #13

My first open source contribution
Mounayer posted on

Description

Closes #12.

  • Added a new flag --token-usage which when given, prints the number of tokens that were sent in the prompt and the number of tokens that were returned in the completion to `stderr.

This simply required the addition for another flag check --token-usage:

   .option("--token-usage", "Show prompt and completion token usage")
Enter fullscreen mode Exit fullscreen mode

I've also made sure to keep your naming conventions/formatting style consistent, in the for loop that does the chat completion for each file processed, I have accumulated the total tokens sent and received:

    promptTokens += response.usage.prompt_tokens;
    completionTokens += response.usage.completion_tokens;
Enter fullscreen mode Exit fullscreen mode

which I then display at the end of program run-time if the --token-usage flag is provided as such:

    if (program.opts().tokenUsage) {
      console.error(`Prompt tokens: <span class="pl-s1"><span class="pl-kos">${promptTokens}</span>`</span>);
      console.error(`Completion tokens: <span class="pl-s1"><span class="pl-kos">${completionTokens}</span>`</span>);
    }
Enter fullscreen mode Exit fullscreen mode
  • Updated README.md to explain the new flag.

Testing

Test 1

genereadme examples/sum.js --token-usage
Enter fullscreen mode Exit fullscreen mode

This should display something like:

My first open source contribution

Test 2

You can try it out with multiple files too, i.e.:

genereadme examples/sum.js examples/createUser.js --token-usage
Enter fullscreen mode Exit fullscreen mode
View on GitHub

This time, instead of having to read someone else's code, someone had to read mine and contribute to it. It is nice knowing that someone is able to contribute to my project. To me, it means that they understood how my code works, so they were able to add the feature without breaking anything or adding any complexity to the code base.
With that being mentioned, reading code is also a skill that is not to be underestimated. My code is nowhere near perfect and I know there are still places I can improve on, so credit is also due to being able to read and understand code.

This specific pull request did not really require any back and forth changes as the code that was written by Mounayer is what I would have written myself.

以上是我的第一個開源貢獻的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn