diff --git a/.cursorrules b/.cursorrules index 64bdd49..c042f3c 100644 --- a/.cursorrules +++ b/.cursorrules @@ -17,10 +17,11 @@ Agentic Coding should be a collaboration between Human System Design and Agent I | 1. Requirements | ★★★ High | ★☆☆ Low | Humans understand the requirements and context. | | 2. Flow | ★★☆ Medium | ★★☆ Medium | Humans specify the high-level design, and the AI fills in the details. | | 3. Utilities | ★★☆ Medium | ★★☆ Medium | Humans provide available external APIs and integrations, and the AI helps with implementation. | -| 4. Node | ★☆☆ Low | ★★★ High | The AI helps design the node types and data handling based on the flow. | -| 5. Implementation | ★☆☆ Low | ★★★ High | The AI implements the flow based on the design. | -| 6. Optimization | ★★☆ Medium | ★★☆ Medium | Humans evaluate the results, and the AI helps optimize. | -| 7. Reliability | ★☆☆ Low | ★★★ High | The AI writes test cases and addresses corner cases. | +| 4. Data | ★☆☆ Low | ★★★ High | AI designs the data schema, and humans verify. | +| 5. Node | ★☆☆ Low | ★★★ High | The AI helps design the node based on the flow. | +| 6. Implementation | ★☆☆ Low | ★★★ High | The AI implements the flow based on the design. | +| 7. Optimization | ★★☆ Medium | ★★☆ Medium | Humans evaluate the results, and the AI helps optimize. | +| 8. Reliability | ★☆☆ Low | ★★★ High | The AI writes test cases and addresses corner cases. | 1. **Requirements**: Clarify the requirements for your project, and evaluate whether an AI system is a good fit. - Understand AI systems' strengths and limitations: @@ -85,11 +86,13 @@ Agentic Coding should be a collaboration between Human System Design and Agent I prompt = "What is the meaning of life?" print(call_llm(prompt)) ``` - - > **Sometimes, design Utilies before Flow:** For example, for an LLM project to automate a legacy system, the bottleneck will likely be the available interface to that system. Start by designing the hardest utilities for interfacing, and then build the flow around them. + - > **Sometimes, design Utilities before Flow:** For example, for an LLM project to automate a legacy system, the bottleneck will likely be the available interface to that system. Start by designing the hardest utilities for interfacing, and then build the flow around them. {: .best-practice } + - > **Avoid Exception Handling in Utilities**: If a utility function is called from a Node's `exec()` method, avoid using `try...except` blocks within the utility. Let the Node's built-in retry mechanism handle failures. + {: .warning } -4. **Node Design**: Plan how each node will read and write data, and use utility functions. - - One core design principle for PocketFlow is to use a [shared store](./core_abstraction/communication.md), so start with a shared store design: +4. **Data Design**: Design the shared store that nodes will use to communicate. + - One core design principle for PocketFlow is to use a well-designed [shared store](./core_abstraction/communication.md)—a data contract that all nodes agree upon to retrieve and store data. - For simple systems, use an in-memory dictionary. - For more complex systems or when persistence is required, use a database. - **Don't Repeat Yourself**: Use in-memory references or foreign keys. @@ -106,16 +109,18 @@ Agentic Coding should be a collaboration between Human System Design and Agent I "results": {} # Empty dict to store outputs } ``` + +5. **Node Design**: Plan how each node will read and write data, and use utility functions. - For each [Node](./core_abstraction/node.md), describe its type, how it reads and writes data, and which utility function it uses. Keep it specific but high-level without codes. For example: - `type`: Regular (or Batch, or Async) - `prep`: Read "text" from the shared store - - `exec`: Call the embedding utility function + - `exec`: Call the embedding utility function. **Avoid exception handling here**; let the Node's retry mechanism manage failures. - `post`: Write "embedding" to the shared store -5. **Implementation**: Implement the initial nodes and flows based on the design. +6. **Implementation**: Implement the initial nodes and flows based on the design. - 🎉 If you've reached this step, humans have finished the design. Now *Agentic Coding* begins! - **"Keep it simple, stupid!"** Avoid complex features and full-scale type checking. - - **FAIL FAST**! Avoid `try` logic so you can quickly identify any weak points in the system. + - **FAIL FAST**! Leverage the built-in [Node](./core_abstraction/node.md) retry and fallback mechanisms to handle failures gracefully. This helps you quickly identify weak points in the system. - Add logging throughout the code to facilitate debugging. 7. **Optimization**: @@ -807,6 +812,7 @@ A **Node** is the smallest building block. Each Node has 3 steps `prep->exec->po - Examples: *(mostly) LLM calls, remote APIs, tool use*. - ⚠️ This shall be only for compute and **NOT** access `shared`. - ⚠️ If retries enabled, ensure idempotent implementation. + - ⚠️ Defer exception handling to the Node's built-in retry mechanism. - Return `exec_res`, which is passed to `post()`. 3. `post(shared, prep_res, exec_res)` @@ -888,7 +894,6 @@ print("Action returned:", action_result) # "default" print("Summary stored:", shared["summary"]) ``` - ================================================ File: docs/core_abstraction/parallel.md ================================================ diff --git a/docs/core_abstraction/node.md b/docs/core_abstraction/node.md index bf3360d..4d0f811 100644 --- a/docs/core_abstraction/node.md +++ b/docs/core_abstraction/node.md @@ -23,6 +23,7 @@ A **Node** is the smallest building block. Each Node has 3 steps `prep->exec->po - Examples: *(mostly) LLM calls, remote APIs, tool use*. - ⚠️ This shall be only for compute and **NOT** access `shared`. - ⚠️ If retries enabled, ensure idempotent implementation. + - ⚠️ Defer exception handling to the Node's built-in retry mechanism. - Return `exec_res`, which is passed to `post()`. 3. `post(shared, prep_res, exec_res)` diff --git a/docs/guide.md b/docs/guide.md index f045633..1b45bdc 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -17,10 +17,11 @@ Agentic Coding should be a collaboration between Human System Design and Agent I | 1. Requirements | ★★★ High | ★☆☆ Low | Humans understand the requirements and context. | | 2. Flow | ★★☆ Medium | ★★☆ Medium | Humans specify the high-level design, and the AI fills in the details. | | 3. Utilities | ★★☆ Medium | ★★☆ Medium | Humans provide available external APIs and integrations, and the AI helps with implementation. | -| 4. Node | ★☆☆ Low | ★★★ High | The AI helps design the node types and data handling based on the flow. | -| 5. Implementation | ★☆☆ Low | ★★★ High | The AI implements the flow based on the design. | -| 6. Optimization | ★★☆ Medium | ★★☆ Medium | Humans evaluate the results, and the AI helps optimize. | -| 7. Reliability | ★☆☆ Low | ★★★ High | The AI writes test cases and addresses corner cases. | +| 4. Data | ★☆☆ Low | ★★★ High | AI designs the data schema, and humans verify. | +| 5. Node | ★☆☆ Low | ★★★ High | The AI helps design the node based on the flow. | +| 6. Implementation | ★☆☆ Low | ★★★ High | The AI implements the flow based on the design. | +| 7. Optimization | ★★☆ Medium | ★★☆ Medium | Humans evaluate the results, and the AI helps optimize. | +| 8. Reliability | ★☆☆ Low | ★★★ High | The AI writes test cases and addresses corner cases. | 1. **Requirements**: Clarify the requirements for your project, and evaluate whether an AI system is a good fit. - Understand AI systems' strengths and limitations: @@ -87,9 +88,11 @@ Agentic Coding should be a collaboration between Human System Design and Agent I ``` - > **Sometimes, design Utilities before Flow:** For example, for an LLM project to automate a legacy system, the bottleneck will likely be the available interface to that system. Start by designing the hardest utilities for interfacing, and then build the flow around them. {: .best-practice } + - > **Avoid Exception Handling in Utilities**: If a utility function is called from a Node's `exec()` method, avoid using `try...except` blocks within the utility. Let the Node's built-in retry mechanism handle failures. + {: .warning } -4. **Node Design**: Plan how each node will read and write data, and use utility functions. - - One core design principle for PocketFlow is to use a [shared store](./core_abstraction/communication.md), so start with a shared store design: +4. **Data Design**: Design the shared store that nodes will use to communicate. + - One core design principle for PocketFlow is to use a well-designed [shared store](./core_abstraction/communication.md)—a data contract that all nodes agree upon to retrieve and store data. - For simple systems, use an in-memory dictionary. - For more complex systems or when persistence is required, use a database. - **Don't Repeat Yourself**: Use in-memory references or foreign keys. @@ -106,16 +109,18 @@ Agentic Coding should be a collaboration between Human System Design and Agent I "results": {} # Empty dict to store outputs } ``` + +5. **Node Design**: Plan how each node will read and write data, and use utility functions. - For each [Node](./core_abstraction/node.md), describe its type, how it reads and writes data, and which utility function it uses. Keep it specific but high-level without codes. For example: - `type`: Regular (or Batch, or Async) - `prep`: Read "text" from the shared store - - `exec`: Call the embedding utility function + - `exec`: Call the embedding utility function. **Avoid exception handling here**; let the Node's retry mechanism manage failures. - `post`: Write "embedding" to the shared store -5. **Implementation**: Implement the initial nodes and flows based on the design. +6. **Implementation**: Implement the initial nodes and flows based on the design. - 🎉 If you've reached this step, humans have finished the design. Now *Agentic Coding* begins! - **"Keep it simple, stupid!"** Avoid complex features and full-scale type checking. - - **FAIL FAST**! Avoid `try` logic so you can quickly identify any weak points in the system. + - **FAIL FAST**! Leverage the built-in [Node](./core_abstraction/node.md) retry and fallback mechanisms to handle failures gracefully. This helps you quickly identify weak points in the system. - Add logging throughout the code to facilitate debugging. 7. **Optimization**: