Skip to content

Day 3 - Module 7: Solutions

These are the solutions or discussion points for the exercises in Module 7.

Solution 7.1: Changing the Coding Task (Multi-Agent)

Modify src/07-multi-agent-collaboration/coding-agents.py:

# ... (imports, state, nodes, graph definition remain the same) ...

if __name__ == "__main__":
    # ... (LLM setup) ...

    # --- Modified Query --- 
    query = "Write a Python function that takes a list of numbers and returns the sum of squares."
    # --------------------

    # Initial code (can be empty or a basic structure)
    initial_code = """
def sum_of_squares(numbers):
    # TODO: Implement function
    pass
"""

    # ... (workflow compilation) ...

    # Invoke the graph
    inputs = GraphState(
        objective=query,
        code=initial_code,
        feedback="",
        history=[],
        iteration=0,
        specialization="python",
        final_code="",
        rating=""
    )

    # ... (invocation and printing results) ...

Expected Output: The execution trace should show the Coder agent attempting to implement the sum_of_squares function. The Reviewer provides feedback on correctness (e.g., using a loop or list comprehension), handling empty lists, or style. The process aims to converge to a correct implementation like:

def sum_of_squares(numbers):
    """Calculates the sum of the squares of numbers in a list."""
    if not isinstance(numbers, list):
        raise TypeError("Input must be a list of numbers.")
    return sum(x**2 for x in numbers)

Solution 7.2: Adjusting Review Criteria (Multi-Agent)

Modify src/07-multi-agent-collaboration/coding-agents.py:

# ... (imports, state, nodes, graph definition remain the same) ...

# --- Modified Reviewer Prompt --- 
reviewer_start = PromptTemplate.from_template(
    """You are a senior software engineer acting as a reviewer. Your goal is to ensure the code is production-ready.\
    Review the code provided based on the objective: {objective}.\
    Provide constructive feedback to the coder, focusing on correctness, style (PEP8), efficiency, and potential bugs.\
    **Ensure that all functions include type hints.** \
    If the code is satisfactory and meets all criteria, respond with 'Code approved'. Otherwise, provide specific feedback for improvement."
    """
)
# ------------------------------

# ... (rest of the script, including node definitions using the prompt) ...

Expected Output: When running with this modified prompt, the Reviewer agent should now explicitly check for type hints in the code generated by the Coder. If the Coder submits code like def sum_of_squares(numbers):, the Reviewer's feedback should include a point about missing type hints (e.g., "Feedback: Add type hints to the function signature (e.g., numbers: list[int]) and return type (e.g., -> int)."). This will force the Coder to add type hints in the subsequent revision.

Solution 7.3: Comparing Single vs. Multi-Agent Output

This requires running both scripts with the same query and comparing the results manually.

Example Comparison (Task: Sum of Squares function):

  • coding-agents.py (Multi-Agent): Produces well-commented, type-hinted code with basic error handling (like checking for list input) after a few review cycles. reasoning-coder.py (Single Agent - o1-mini):* Produces a functional implementation quickly, but often without comments, type hints, or extensive error handling unless specifically prompted. The quality depends heavily on the o1-mini model\'s training and reasoning ability for coding tasks.

Discussion Points:* The multi-agent approach allows for enforcing specific standards (via the reviewer) that are not inherent in the single agent\\'s default behavior. The single reasoning agent is faster for simpler tasks if its baseline quality is high. * The multi-agent system provides more transparency into the refinement process (seeing the feedback cycles).

Solution 7.4 (Conceptual): Designing a Trip Planning Graph

This involves sketching a potential graph structure.

Potential GraphState:

class TripState(TypedDict):
    origin: str
    destination: str
    start_date: str
    end_date: str
    budget: Optional[float]
    interests: Optional[list[str]]
    flight_options: Optional[list[dict]]
    hotel_options: Optional[list[dict]]
    activity_options: Optional[list[dict]]
    chosen_flight: Optional[dict]
    chosen_hotel: Optional[dict]
    chosen_activities: Optional[list[dict]]
    itinerary: Optional[str]
    user_feedback: Optional[str]
    last_agent: str # To track who spoke last for conditional logic

Potential Workflow Sketch:

  1. Entry Point: GetUserPrefs (Node using UserInteraction agent, possibly interrupting to get destination, dates, budget, interests). -> Updates state.
  2. Parallel Search: Edges from GetUserPrefs to FindFlights (Node using FlightFinder), FindHotels (Node using HotelFinder), FindActivities (Node using ActivityPlanner). These run in parallel.
  3. Present Options: Edges from search nodes to PresentOptions (Node using UserInteraction). This node formats the found options.
  4. Interrupt for User Choice: PresentOptions interrupts, showing flight, hotel, and activity options, asking the user to choose or provide feedback. -> Updates state with user_feedback or chosen_flight, chosen_hotel, etc.
  5. Conditional Edge: Based on user_feedback:
    • If user chose options: Go to CompileItinerary.
    • If user asked for refinement (e.g., "cheaper hotels"): Go back to FindHotels (passing user_feedback).
    • If user wants different destination: Go back to GetUserPrefs.
  6. CompileItinerary: (Node using ItineraryCompiler) Takes chosen flight, hotel, activities and creates a structured itinerary. -> Updates itinerary in state.
  7. PresentFinalItinerary: (Node using UserInteraction) Shows the final itinerary to the user.
  8. END

This sketch highlights the use of parallel execution, interrupts for user input, and conditional branching based on that input, which are key features of LangGraph for building complex, interactive multi-agent systems.