paint-brush
効果的かつスケーラブルなソフトウェア開発のためにLLMを活用する办法 に@bishalbaral
490 測定値
490 測定値

効果的かつスケーラブルなソフトウェア開発のためにLLMを活用する方法

Bishal11m2024/08/04
Read on Terminal Reader

長すぎる; 読むには

YCombinator の CEO である Garry Tan 氏は、Claude 3.5 Sonnet を使用したコード記述に関する YCombinator Reddit コミュニティ メンバーの投稿をツイートしました。この投稿では、日常的な LLM の使用の重要な部分として、適切なアーキテクチャとインフラストラクチャの決定を行うことの重要性が強調されています。
featured image - 効果的かつスケーラブルなソフトウェア開発のためにLLMを活用する方法
Bishal HackerNoon profile picture
0-item
1-item
近些年、X と Reddit のユーザーから、Claude 3.5 Sonnet でコードを記述すると「比较に強力になった」と感じられるという報告がありました。特に注目を集めた文章投稿の 1 つは、YCombinator の CEO、Garry Tan 氏のツイートでした。


Garry は、YCombinator Reddit コミュニティのメンバーの 1 人による次の发表を一共しました。その发表では、Claude 3.5 Sonnet を使用的することで、人気の機能を実装しながら生産性が 10 倍に往右した步骤について説明しています。


この期刊投稿では、LLM の每天的な选用の重点な部门として、適切なアーキテクチャとインフラストラクチャの決定を行うことの重点性も強調されています。


Claude 3.5 のような LLM は優れた利点を给出しますが、メモリとコンテキストの維持に関して仍旧として制限があります。これらの制限に対処するために、いくつかの開発戦略を应用できます。これらの戦略は、すべての開発者が経験を積んで磨きをかけるソフトウェア開発の基礎を中心局に展開されますが、平易な英語で LLM を促すと見落とされがちです。


開発者が平时的に运用する同じ大体原則 (Reddit の著者がアーキテクチャ上の決定と呼んでいるもの) を LLM のやり取りに適用すると、宽度にモジュール化され、スケーラブルで、非常的に文書化されたコードが制作されます。


这は、LLM 对口支援ソフトウェア開発に適用できる最主要なコーディング原則と開発プラクティス、および Python の実際の例です。
例のすべてのプロンプトは、Claude Sonnet 3.5 で食用されました。

コンポーネントベースのアーキテクチャ

各論理コンポーネントを LLM に簡単に記述し、正確なコンポーネントを达成するには、コードベースを小さく明確に定義されたコンポーネントに切割します。
 # database.py class Database: def __init__(self, sql_connection_string): .... def query(self, sql): .... # user_service.py class UserService: def __init__(self, database): self.db = database def get_user(self, user_id): return self.db.query(f"SELECT * FROM users WHERE id = {user_id}") # main.py db = Database("sql_connection_string") user_service = UserService(db) user = user_service.get_user(123)

抽象化レイヤー

複雑な実装を隠すには、抽象主义性化レイヤーを运用的し、旅途中で記録された各コンポーネントの詳細を运用的して、より高レベルの抽象主义性化に主焦点を当てます。
 # top-level abstraction class BankingSystem: def __init__(self): self._account_manager = AccountManager() self._transaction_processor = TransactionProcessor() def create_account(self, acct_number: str, owner: str) -> None: self._account_manager.create_account(acct_number, owner) def process_transaction(self, acct_number: str, transaction_type: str, amount: float) -> None: account = self._account_manager.get_account(acct_number) self._transaction_processor.process(account, transaction_type, amount) # mid-level abstractions class AccountManager: def __init__(self): def create_account(self, acct_number: str, owner: str) -> None: def get_account(self, acct_number: str) -> 'Account': class TransactionProcessor: def process(self, account: 'Account', transaction_type: str, amount: float) -> None: # lower-level abstractions class Account(ABC): .... class Transaction(ABC): .... # concrete implementations class SavingsAccount(Account): .... class CheckingAccount(Account): .... class DepositTransaction(Transaction): .... class WithdrawalTransaction(Transaction): .... # lowest-level abstraction class TransactionLog: .... # usage focuses on the high-level abstraction cart = ShoppingCart() cart.add_item(Item("Book", 15)) cart.add_item(Item("Pen", 2)) total = cart.get_total()

クリーンなインターフェース定義

LLM の协助を求める際にタスクをより控制しやすくするには、各コンポーネントの明確なインターフェースを定義し、すべてを個別に実装することに要点を置きます。
 class PaymentProcessor(ABC): @abstractmethod def process_payment(self, amount: float, card_no: str) -> bool: .... class StripeProcessor(PaymentProcessor): # stripe specific implementation def process_payment(self, amount: float, card_no: str) -> bool: .... class PayPalProcessor(PaymentProcessor): # paypal specific implementation def process_payment(self, amount: float, card_no: str) -> bool: ....

単一責任の原則

幻覚を防ぎ、範囲を制限するには、直接に 1 つの小さな那部分に焦聚を当て、各クラス/関数に単一の明確に定義された責任があることを確認します。生产されるコードをより細かく制御できるように、段階的に開発します。
 class UserManager: # user creation logic def create_user(self, username, email): ... class EmailService: # send welcome email logic def send_welcome_email(self, email): .... class NotificationService: # send sms notification def send_sms(self, username, email): ... # Usage user_manager = UserManager() email_svc = EmailService() user = user_manager.create_user("hacker", "[email protected]") email_svc.send_welcome_email("[email protected]")

一貫した命名規則

LLM へのコード構造の説明を簡素化し、その建议を表达するには、明確で一貫性のある名称規則を用到します。
 # classes: PascalCase class UserAccount: pass # functions and variables: snake_case def calculate_total_price(item_price, quantity): total_cost = item_price * quantity return total_cost # constants: UPPERCASE_WITH_UNDERSCORES MAX_LOGIN_ATTEMPTS = 3 # private methods/variables: prefix with underscore class DatabaseConnection: def __init__(self): self._connection = None def _connect_to_database(self): pass

コードテンプレート

要件に基づいて特定的の実装を转化するには、正常的なコード構造のスケルトン コードを制成し、それをスターター コードとして操作します。
 # Todo item - pydantic Model class TodoItem(BaseModel): id: Optional[int] = None title: str description: Optional[str] = None completed: bool = False todo_db = [<insert mock data>] @app.get("/todos", response_model=List[TodoItem]) async def get_todos(): # TODO: retrieve all todos @app.get("/todos/{todo_id}", response_model=TodoItem) async def get_todo(todo_id: int): # TODO: retrieve specific todo @app.post("/todos", response_model=TodoItem) async def create_todo(todo: TodoItem): # TODO: create todo @app.put("/todos/{todo_id}", response_model=TodoItem) async def update_todo(todo_id: int, todo: TodoItem): # TODO: update todo @app.delete("/todos/{todo_id}") async def delete_todo(todo_id: int): # TODO: delete todo

ドキュメント主導開発

LLM をガイドするために、実装前に各コンポーネントの簡潔なドキュメントを制作します。さらに、LLM 自体を采用して将プロンプトをガイドできる docstring を产生します。


プロンプト:

 Use a Documentation Driven Development approach to write clear, concise docstrings for the following python function calculate_discount(price, discount_percentage) takes in - price (float), original price of the item. - discount_percentage (float), discount percentage range(0-100). returns - price after discount (float) raises - ValueError, when discount_percentage is out of range example - calculate_discount(100, 10) -> 10.0


応答:

 def calculate_discount(price: float, discount_percent: float) -> float: """ Calculate the discounted price of an item. Args: price (float): original price for the item. discount_percentage (float): discount percentage range(0-100). Returns: float: The price after applying the discount. Raises: ValueError: If discount_percentage is not between 0 and 100. Example: >>> calculate_discount(100, 20) 80.0 """ if not 0 <= discount_percent <= 100: raise ValueError("Discount percent must be between 0 and 100") discount_amount = price * (discount_percent / 100) return price - discount_amount

テスト駆動開発

LLM の実装を增援し、特にエッジ ケースを処理するには、実際の関数を実装する前に、自分でテストを作为するか、LLM を选用してテストを作为します。LLM は企业内部でコードを実行しませんが、转为されたコードが関数の要件を満たしていることを確認するために事前事后にテストを行うことは、LLM で转为されたコードのバグを見つけるのに役立ちます。


テストケース:

 def is_palindrome(s: str) -> bool: """check if string is palindrome.""" return s == s[::-1] class TestPalindrome(unittest.TestCase): def test_palindrome(self): self.assertTrue(is_palindrome("racecar")) self.assertTrue(is_palindrome("A man a plan a canal Panama")) self.assertFalse(is_palindrome("hello")) self.assertTrue(is_palindrome("")) # Edge case: empty string


プロンプト:

 given the test case <insert test>, use Document Driven Development to write a function for TestPalindrome


応答:

 def is_palindrome(s: str) -> bool: """ Check if a string is a palindrome. A palindrome is a word, phrase, number, or other sequence of characters that reads the same forward and backward, ignoring spaces, punctuation, and capitalization. Args: s (str): The input string to check. Returns: bool: True if the input is a palindrome, False otherwise. Examples: >>> is_palindrome("racecar") True >>> is_palindrome("A man a plan a canal Panama") True >>> is_palindrome("hello") False >>> is_palindrome("") True """ # Remove non-alphanumeric characters and convert to lowercase cleaned = ''.join(char.lower() for char in s if char.isalnum()) # Compare the cleaned string with its reverse return cleaned == cleaned[::-1]

デザインパターンライブラリ

LLM と複数の実装の詳細について話し合うために、参照物用によく采用される設計パターンのライブラリを維持します。
 # Singleton pattern class DatabaseConnection: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) # initialize database connection return cls._instance # Factory pattern class AnimalFactory: @staticmethod def create_animal(animal_type): if animal_type == "dog": return Dog() elif animal_type == "cat": return Cat() else: raise ValueError("Unknown animal type") # Observer pattern class Subject: def __init__(self): self._observers = [] def attach(self, observer): self._observers.append(observer) def detach(self, observer): self._observers.remove(observer) def notify(self): for observer in self._observers: observer.update() # Adapter pattern class LLMAdapter: def __init__(self, llm_service): self.llm_service = llm_service def generate_code(self, prompt): llm_response = self.llm_service.complete(prompt) return self.extract_code(llm_response) def extract_code(self, response): pass

コードレビューチェックリスト

品質と一貫性を確保するために、LLM で转换成されたコードを確認するためのチェックリストを制成します。
 # Code Review Checklist ## Functionality - [ ] Code performs the intended task correctly - [ ] Edge cases are handled appropriately ## Code Quality - [ ] Code follows project's style guide - [ ] Variable and function names are descriptive and consistent - [ ] No unnecessary comments or dead code ## Performance - [ ] Code is optimized for efficiency - [ ] No potential performance bottlenecks ## Security - [ ] Input validation is implemented - [ ] Sensitive data is handled securely ## Testing - [ ] Unit tests are included and pass - [ ] Edge cases are covered in tests ## Documentation - [ ] Functions and classes are properly documented - [ ] Complex logic is explained in comments

モジュラープロンプト

LLM は定義された構造で最も効果的に機能するため、コーディング タスクをより小さなプロンプトに拼接する戦略を立てます。系统的なアプローチに従うと、添加二维码されたコードを LLM に何度も再调整法させることなく、動作するコードを添加二维码できます。


プロンプト:

 I need to implement a function to calculate the Fibonacci number sequence using a Document Driven Development approach. 1. Purpose: function that generates the Fibonacci sequence up to a given number of terms. 2. Interface: def fibonacci_seq(n: int) -> List[int]: """ generate Fibonacci sequence up to n terms. Args: n (int): number of terms in the sequence Returns: List[int]: fibonacci sequence """ 3. Key Functionalities: - handle input validation (n should always be a positive integer) - generate the sequence starting with 0 and 1 - each subsequent number is the sum of two preceding ones - return the sequence as a list 4. Implementation Details: - use a loop to generate the sequence - store the sequence in a list - optimize for memory by only keeping the last two numbers in memory if needed 5. Test Cases: - fibonacci_seq(0) should return [] - fibonacci_seq(1) should return [0] - fibonacci_seq(5) should return [0, 1, 1, 2, 3]

上記の例はすべて単純に思えるかもしれませんが、モジュール アーキテクチャや効果的なプロンプト エンジニアリングなどの基本上的なプラクティスに従い、LLM 支持開発で堅実な構造化アプローチを採用すると、大規模な開発では大きな違いが生まれます。これらのプラクティスを実装することで、より多くの開発者が LLM を用するメリットを最主要限に活用でき、生産性とコード品質が向下します。


LLM は、見落としがちなソフトウェア エンジニアリングの原則に従っている場合に最も効果的に機能する強力なツールです。それらを習得することで、エレガントに弄成されたコードとランダムに转成されたの違いが生じる可以性があります。


この記事の目的意义は、開発者が LLM を食用して高品質のコードを弄成し、现在的に時間を節約する際に、常にこれらのプラクティスを念頭に置くように促すことです。LLM が改善され続けるにつれて、LLM を更大限に活用するには基礎がさらに比较重要になります。


ソフトウェア開発の原則をさらに深く理解するには、 Robert C. Martin 著の古典的な教科書「Clean Architecture: A Craftsman's Guide to Software Structure and Design」をご覧ください。


この記事がお役に立てば、LLM 协防開発の詳細なワークフローについて掘り下げる次の記事もお楽しみに。他に最重要と思われる定义があれば、ぜひコメントで公有してください。ありがとうございます。
바카라사이트 바카라사이트 온라인바카라