私が取り組んだすべてのプロジェクトでは、プロジェクトのスコープがタスク (チケット) のリストとして定義され、タスクのステータスを変更することで進捗状況が報告される、ある種のプロジェクト管理システムを使用しました。
このようなプロジェクト管理システムはさまざまなダッシュボードやレポートを提供しますが、エンジニアが作成した不可解なタイトルが付いたタスクの長いリストを解釈するのは簡単ではありません。プロジェクトのスポンサーと顧客に透明性を提供するために、手動でプロジェクト レポートを作成し、関連する質問に答える必要がありました。
代わりに LLM に助けを求めたらどうなるでしょうか?考え方は単純です。すべてのプロジェクト タスクを取得し、LLM にフィードしてレポートを要求します。その後、チャットを開始してさらに質問してください。
Jira は使いやすい REST API を備えた人気のあるツールであるため、この実験には Jira を使用します。レポートを作成するサンプル プロジェクトは非常に技術的です。コードが使用するものを検出し、ビルド システムに必要な命令を生成できるビルド スクリプトを作成することです。このようなプロジェクトには、不可解なタイトルが付いた技術的なタスクが必ず含まれます。
タスクの取得から始めましょう。セットアップ例のプロジェクトは、子チケット (タスク) のリストを持つ単一の親チケット (エピック) として表されます。タスクごとに完全な履歴を取得して、チケットのステータスが時間の経過とともにどのように変化するかを確認します。 Python の Jira クライアントを使用すると、実装は簡単です。 Jira の命名法では、コードに反映されている チケット の代わりに 課題 という用語が使用されていることに注意してください。
jira = JIRA(server=os.environ["JIRA_SERVER"], basic_auth=(os.environ["JIRA_USER"], os.environ["JIRA_TOKEN"])) def fetch_issues(epic_key): issues = [] print("Loading epic data...", end="", flush=True) issues.append(jira.issue(epic_key)) print("done") print("Loading tasks...", end="", flush=True) child_issues = jira.search_issues(f"parent = {epic_key}") for issue in child_issues: issues.append(jira.issue(issue.key, expand="changelog")) print("done") return issues
履歴を含むすべてのチケットを取得するには時間がかかるため、さらなる実験のためにこのデータをローカルに保存すると便利です。実装を試している間、以下の関数を使用してタスクをファイルに保存し、ファイルからロードしました。
def save_issues(filename, issues): with open(filename, "x") as file: file.write("[") file.write(",".join( json.dumps(issue.raw) for issue in issues)) file.write("]") def load_issues(filename): with open(filename, "r") as file: data = json.load(file) return [Issue(jira._options, jira._session, raw=raw_issue) for raw_issue in data]
次のステップは、LLM 用のデータを準備することです。 JSON 形式の生の Jira データは非常に冗長なので、これらの追加フィールドはすべて必要ありません。基本情報 (件名、説明、タイプ、ステータス、作成日) を抽出しましょう。履歴からは、チケットのステータスの変更とその日付および作成者のみが抽出され、他のフィールドへの変更は無視されます。
この情報はすべてプレーンテキストとして保存されます。 LLM 入力として JSON または XML を使用している人を見てきましたが、私の観察によると、LLM はプレーン テキスト データの解釈に非常に優れています。さらに、このアプローチを使用すると、テキスト フィールドを JSON または XML と互換性のある形式に設定することを心配する必要がなくなります。私が行う唯一の処理は、説明から空行を削除することです。主な理由は、結果を見やすくするためです。
def strip_empty_lines(s): return "".join(line for line in (s or "").splitlines() if line.strip()) def issue_to_str(issue): return f""" {issue.fields.issuetype}: {issue.key} Summary: {issue.fields.summary} Description: {strip_empty_lines(issue.fields.description)} Type: {issue.fields.issuetype} Status: {issue.fields.status} Created: {issue.fields.created} Priority: {issue.fields.priority} """ def changelog_to_str(changelog, changeitem): return f""" Author: {changelog.author.displayName} Date: {changelog.created} Status change from: {changeitem.fromString} to: {changeitem.toString} """ def history_to_str(issue): if issue.changelog is None or issue.changelog.total == 0: return "" history_description = "" for changelog in issue.changelog.histories: try: statuschange = next(filter(lambda i: i.field == "status", changelog.items)) history_description += changelog_to_str(changelog, statuschange) except StopIteration: pass return history_description #this function assumes the first issue is an epic followed by tasks. def describe_issues(issues): description = "Project details:" description += issue_to_str(issues[0]) description += "\nProject tasks:" for issue in issues[1:]: description += "\n" + issue_to_str(issue) description += f"History of changes for task {issue.key}:" description += history_to_str(issue) return description
この実験に使用するエピックには、履歴に 1 から 15 のステータス変更がある 30 個のタスクがあります。 description_issues 関数の出力全体を引用することはしませんが、それがどのように見えるかを示すために、短い抜粋をここに示します。
Project details: Epic: TKT-642 Summary: Create universal build script Description: Type: Epic Status: In Development Created: 2024-05-24T10:48:33.050+0200 Priority: P4 - Low Project tasks: Task: TKT-805 Summary: add test reporting for e2e tests Description: Type: Task Status: In Progress Created: 2024-09-06T09:56:33.919+0200 Priority: P4 - Low History of changes for task TKT-805: Author: Jane Doe Date: 2024-09-06T10:04:15.325+0200 Status change from: To Do to: In Progress Task: TKT-801 Summary: Sonar detection Description: * add sonar config file detection * Type: Task Status: In Progress Created: 2024-08-30T13:57:44.364+0200 Priority: P4 - Low History of changes for task TKT-801: Author: Jane Doe Date: 2024-08-30T13:57:58.450+0200 Status change from: To Do to: In Progress Task: TKT-799 Summary: Add check_tests step Description: Type: Task Status: Review Created: 2024-08-29T18:33:52.268+0200 Priority: P4 - Low History of changes for task TKT-799: Author: Jane Doe Date: 2024-08-29T18:40:35.305+0200 Status change from: In Progress to: Review Author: Jane Doe Date: 2024-08-29T18:33:57.095+0200 Status change from: To Do to: In Progress
使用するプロンプトは 2 つの部分で構成されます。まず、レポートに必要な具体的な情報を詳細に記載したレポートを作成する指示が与えられます。次に、前の段落で準備したチケット情報を挿入します。 LLM は冗長な応答をする傾向があるため、追加の説明を追加しないように特にお願いしています。実験はターミナル内で実行されるため、応答もターミナルフレンドリーにするように依頼します。
def create_prompt(isses_description): return f""" Using below information from jira generate executive report that focuses on what was done and what is remaining. Provide project progress information. Point out problematic tasks and what may be wrong. Use status change history to point out tasks that were worked on for too long or have been reopened many times. Check if you can detect other problems from tasks or their history. Provide only text content that can be displayed on terminal, without any additional explanation or markdown. {isses_description} """
この実験に使用する LLM は、Anthropic の Claude 3.5 Sonnet です。プロンプト メッセージの送信に加えて、ID も指定します。 ID はプロンプトの先頭に別の行として追加することもできますが、質問をフォローアップする (対話型チャットを作成する) 予定であるため、Claude のドキュメントでは、そのようなシナリオでは ID を別個のシステム パラメーターとして設定することを推奨しています。
def send_messages(messages): client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_KEY"]) identity = "You are a seasoned IT program manager. You have very good communication skills, your answers are concise and focus on key insights." message = client.messages.create( system=identity, max_tokens=2048, messages=messages, model="claude-3-5-sonnet-20240620" ) return message.content[0].text def generate_report(prompt): messages=[ { "role": "user", "content": prompt }] return send_messages(messages)
これを組み立てて実行しましょう:
if __name__=="__main__": issues = fetch_issues('TKT-642') descrption = describe_issues(issues) prompt = create_prompt(description) report = generate_report(prompt) print(report)
以下はクロードから受け取ったレポート全文です:
エグゼクティブレポート: ユニバーサル ビルド スクリプト プロジェクト (TKT-642)
プロジェクトの進捗状況:
- 24 タスク中 11 が完了しました (45.8%)
- 5 つのタスクが進行中またはレビュー中 (20.8%)
- まだ 8 つのタスクが開始されていません (33.3%)
主な成果:
- ビルダー用のプロトタイプ jinja テンプレートを作成しました
- 構成拡張と検証を実装しました
- 単体テストの実行ステップを追加しました
- ソナー スキャンの統合サポート
- 構成および技術スクリプトを構築するためのイメージを作成しました
進行中:
- e2e テストのテスト レポートを追加
- 環境およびソナー検出用のフィルタリング ロジックの実装
- 開発者向けドキュメントの開発
問題のある領域:
- Task TKT-734 (Add config extension) went through multiple status changes, indicating potential issues or complexity.
- Task TKT-697 (Add support for sonar scanning) has been reopened multiple times, suggesting implementation challenges.
- Task TKT-715 (Create developer documentation) has been in progress for an extended period without completion.
Upcoming Work:
- Integration of the build system into various services (authentication, database-api, shopping-cart, reporting, localization)
- Adding support for monorepos and custom jobs
- Creating user documentation
Recommendations:
- Review the implementation of config extension and sonar scanning to address recurring issues.
- Prioritize the completion of developer documentation to support team adoption.
- Begin planning for the integration of the build system into remaining services.
- Consider reassessing the priority of tasks that have remained in the "To Do" state for an extended period.
Overall, the project is making steady progress, with nearly half of the tasks completed. However, attention should be given to resolving recurring issues and completing in-progress tasks to maintain momentum.
The result is quite good. It did miscount tickets - in various runs I did it gave me a different number, but never a correct number of 30. Well, LLMs are known for not being able to count r's in the word strawberry. But the summary is correct, recommendations are also reasonable.
Now let's create an interactive session and ask some questions. We'll start with a pre-defined question which is the original prompt we used to generate the report. Then we will read the user's input and attach it to messages. Each response, along with the report is also recorded in the messages chain.
def interactive_session(prompt): messages = [] user_input = prompt while user_input != "exit": messages.append({ "role" : "user", "content" : user_input }) response = send_messages(messages) print(response) messages.append({ "role" : "assistant", "content" : response }) user_input = input("QUESTION: ") return messages
To run this, just replace generate_report in the main section of the script with interactive_session. Below is a recording of an example session I did. I omitted from the quote the first response which just prints out the report.
QUESTION: how many engineers the team counts?
Based on the information provided in the task histories, I can identify at least three distinct engineers working on this project:
- John Smith
- Jane Doe
- Mike Carpenter
These three names appear frequently in the status change histories for various tasks. However, it's important to note that this may not represent the full team size. There could be other team members who haven't made changes recorded in these specific task histories, or who are involved in the project in other capacities not reflected in this data.
To get an accurate count of the team size, you would need additional information beyond what's provided in these task histories.
QUESTION: is unit test execution task done yet?
Yes, the unit test execution task is completed. Specifically, task TKT-700 with the summary "Add unit tests execution step" is marked as Done. Here's the relevant information:
Task: TKT-700
Summary: Add unit tests execution step
Status: DoneThe history of changes for this task shows that it was moved to "Done" status on 2024-08-02, after going through the typical workflow stages (To Do -> In Progress -> Review -> PREPROD VERIFICATION -> READY FOR PRODUCTION -> Done).
QUESTION: does the scope include running some sort of static code analysis tool?
Yes, the project scope includes running static code analysis. Specifically, there's a task for implementing Sonar scanning, which is a popular static code analysis tool. Here are the details:
Task: TKT-697
Summary: Add support for sonar scanning
Status: DoneThis task was completed and moved to "Done" status on 2024-09-02. The implementation of Sonar scanning indicates that static code analysis is part of the universal build script project.
Additionally, there's another related task that's currently in progress:
Task: TKT-801
Summary: Sonar detection
Status: In ProgressThis task mentions "sonar detection" in its summary, which further confirms that Sonar (a static analysis tool) is being integrated into the build process.
These tasks demonstrate that static code analysis, particularly using Sonar, is included in the project scope and has been largely implemented.
QUESTION: what are the 3 biggest risks of the project?
Based on the provided information, the three biggest risks for this project appear to be:
Integrationsverzögerungen:
Mehrere Aufgaben zur Integration des Build-Systems in verschiedene Dienste (Lokalisierung, Reporting, Warenkorb, Authentifizierung, Datenbank-API) befinden sich noch im Status „To Do“. Dies birgt die Gefahr von Verzögerungen bei der weit verbreiteten Einführung des universellen Build-Skripts in verschiedenen Diensten. Wenn es nicht gelingt, alle vorgesehenen Dienste zu integrieren, könnte dies die Gesamtwirkung und den Wert des Projekts beeinträchtigen.Dokumentationsverzögerung:
Die Aufgabe zum Erstellen der Entwicklerdokumentation (TKT-715) wurde erst kürzlich auf „In Bearbeitung“ verschoben, nachdem sie längere Zeit in „Zu erledigen“ war. Darüber hinaus befindet sich die Benutzerdokumentationsaufgabe (TKT-714) immer noch im Status „Zu erledigen“. Diese Verzögerung bei der Dokumentationserstellung birgt die Gefahr, dass die Einführung, ordnungsgemäße Nutzung und Wartung des neuen Build-Systems behindert wird. Dies könnte aufgrund fehlender klarer Leitlinien zu Missbrauch, Ineffizienz oder Widerstand gegen die Einführung führen.Komplexität in der Umsetzung:
Bei mehreren Aufgaben, insbesondere im Zusammenhang mit dem Sonar-Scanning (TKT-697) und der Konfigurationserweiterung (TKT-734), wurden mehrere Statusänderungen zwischen „In Bearbeitung“ und „Überprüfen“ angezeigt. Dieses Muster deutet auf mögliche technische Herausforderungen oder Unsicherheiten bei der Umsetzung hin. Es besteht das Risiko, dass diese Komplexität in Zukunft zu Fehlern, Leistungsproblemen oder Wartungsschwierigkeiten führen kann, wenn sie nicht ordnungsgemäß behoben wird.Diese Risiken könnten möglicherweise Auswirkungen auf den Zeitplan, die Akzeptanzrate und den Gesamterfolg des Projekts haben, wenn sie nicht ordnungsgemäß verwaltet und gemindert werden.
Das war überraschend gut. Mir gefällt die Tatsache, dass das LLM zusätzlich zu den Eingabeaufforderungsdaten allgemeines Wissen verwendet, sodass es Fragen zum „statischen Code-Analysetool“ beantworten konnte, obwohl diese Begriffe in den Ticketdaten nicht erwähnt werden. Die Antworten sind etwas zu ausführlich, es sind weitere Experimente mit der Eingabeaufforderung erforderlich. Das Anhängen von Anweisungen an die Abfrage jedes Benutzers würde wahrscheinlich dazu beitragen, bessere Antworten zu erhalten.
Probleme wie das Fehlzählen von Tickets sollten leicht zu lösen sein, wir können Basisstatistiken berechnen und diese in die Eingabeaufforderung selbst einbeziehen.
以上がJira と LLM を使用したインタラクティブなプロジェクト レポートの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。