| # Recursive Implementation Example |
|
|
| This document provides a detailed example of how the recursive cognitive architecture works in Multi-Agent Debate. We'll walk through the complete lifecycle of a market decision, from data ingestion to trade execution, highlighting the recursive patterns and interpretability mechanisms at each stage. |
|
|
| ## Overview |
|
|
| <div align="center"> |
| <img src="assets/images/recursive_flow_detailed.png" alt="Recursive Flow Detailed" width="800"/> |
| </div> |
|
|
| In this example, we'll follow a complete decision cycle focused on analyzing Tesla (TSLA) stock, showing how multiple philosophical agents evaluate the same data through different lenses, form consensus, and generate a final decision with full attribution. |
|
|
| ## 1. Data Ingestion |
|
|
| The process begins with market data ingestion from Yahoo Finance: |
|
|
| ```python |
| from multi_agent_debate.market.environment import MarketEnvironment |
| |
| # Initialize market environment |
| market = MarketEnvironment(data_source="yahoo", tickers=["TSLA"]) |
| |
| # Get current market data |
| market_data = market.get_current_market_data() |
| ``` |
|
|
| The market data includes: |
| - Price history |
| - Volume data |
| - Fundamental metrics |
| - Recent news sentiment |
| - Technical indicators |
|
|
| ## 2. Agent-Specific Processing |
|
|
| Each philosophical agent processes this data through its unique cognitive lens. Let's look at three agents: |
|
|
| ### Graham (Value) Agent |
|
|
| ```python |
| # Graham Agent processing |
| graham_agent = GrahamAgent(reasoning_depth=3) |
| graham_processed = graham_agent.process_market_data(market_data) |
| ``` |
|
|
| The Graham agent focuses on intrinsic value calculation: |
|
|
| ```python |
| # Internal implementation of Graham's intrinsic value calculation |
| def _calculate_intrinsic_value(self, fundamentals, ticker_data): |
| eps = fundamentals.get('eps', 0) |
| book_value = fundamentals.get('book_value_per_share', 0) |
| growth_rate = fundamentals.get('growth_rate', 0) |
| |
| # Graham's formula: IV = EPS * (8.5 + 2g) * 4.4 / Y |
| bond_yield = ticker_data.get('economic_indicators', {}).get('aaa_bond_yield', 0.045) |
| bond_factor = 4.4 / max(bond_yield, 0.01) |
| |
| growth_adjusted_pe = 8.5 + (2 * growth_rate) |
| earnings_value = eps * growth_adjusted_pe * bond_factor if eps > 0 else 0 |
| |
| # Calculate book value with margin |
| book_value_margin = book_value * 1.5 |
| |
| # Use the lower of the two values for conservatism |
| if earnings_value > 0 and book_value_margin > 0: |
| intrinsic_value = min(earnings_value, book_value_margin) |
| else: |
| intrinsic_value = earnings_value if earnings_value > 0 else book_value_margin |
| |
| return max(intrinsic_value, 0) |
| ``` |
|
|
| The agent calculates a margin of safety: |
|
|
| ``` |
| Ticker: TSLA |
| Current Price: $242.15 |
| Intrinsic Value: $180.32 |
| Margin of Safety: -34.3% (negative margin indicates overvaluation) |
| Analysis: TSLA appears overvalued compared to traditional value metrics. |
| Recommendation: SELL |
| Confidence: 0.78 |
| ``` |
|
|
| ### Wood (Innovation) Agent |
|
|
| ```python |
| # Wood Agent processing |
| wood_agent = WoodAgent(reasoning_depth=4) |
| wood_processed = wood_agent.process_market_data(market_data) |
| ``` |
|
|
| The Wood agent focuses on disruptive innovation and growth potential: |
|
|
| ```python |
| # Internal implementation of growth potential analysis |
| def _analyze_growth_potential(self, ticker_data, market_context): |
| # Analyze innovation factors |
| innovation_score = self._calculate_innovation_score(ticker_data) |
| |
| # Analyze addressable market |
| tam = self._calculate_total_addressable_market(ticker_data, market_context) |
| |
| # Project future growth |
| growth_projection = self._project_exponential_growth( |
| ticker_data, innovation_score, tam |
| ) |
| |
| return { |
| "innovation_score": innovation_score, |
| "total_addressable_market": tam, |
| "growth_projection": growth_projection, |
| } |
| ``` |
|
|
| The agent's analysis shows: |
|
|
| ``` |
| Ticker: TSLA |
| Innovation Score: 0.87 |
| Total Addressable Market: $4.2T |
| 5-Year CAGR Projection: 28.3% |
| Analysis: TSLA is well-positioned in multiple disruptive fields including EVs, energy storage, AI, and robotics. |
| Recommendation: BUY |
| Confidence: 0.82 |
| ``` |
|
|
| ### Dalio (Macro) Agent |
|
|
| ```python |
| # Dalio Agent processing |
| dalio_agent = DalioAgent(reasoning_depth=3) |
| dalio_processed = dalio_agent.process_market_data(market_data) |
| ``` |
|
|
| The Dalio agent examines macroeconomic factors: |
|
|
| ```python |
| # Internal implementation of macroeconomic analysis |
| def _analyze_macro_environment(self, ticker_data, economic_indicators): |
| # Analyze interest rate impact |
| interest_impact = self._calculate_interest_sensitivity(ticker_data, economic_indicators) |
| |
| # Analyze inflation impact |
| inflation_impact = self._calculate_inflation_impact(ticker_data, economic_indicators) |
| |
| # Analyze growth cycle position |
| cycle_position = self._determine_economic_cycle_position(economic_indicators) |
| |
| # Assess geopolitical risks |
| geopolitical_risk = self._assess_geopolitical_risk(economic_indicators) |
| |
| return { |
| "interest_impact": interest_impact, |
| "inflation_impact": inflation_impact, |
| "cycle_position": cycle_position, |
| "geopolitical_risk": geopolitical_risk, |
| } |
| ``` |
|
|
| The agent's analysis shows: |
|
|
| ``` |
| Ticker: TSLA |
| Interest Rate Sensitivity: -0.65 (high negative sensitivity) |
| Inflation Impact: -0.32 (moderate negative impact) |
| Economic Cycle Position: Late Expansion |
| Analysis: TSLA will face headwinds from high interest rates and potential economic slowdown. |
| Recommendation: HOLD |
| Confidence: 0.65 |
| ``` |
|
|
| ## 3. Reasoning Graph Execution |
|
|
| Each agent's reasoning process is executed via a LangGraph reasoning structure. Here's a simplified view of the Wood agent's reasoning graph: |
|
|
| ```python |
| def _configure_reasoning_graph(self) -> None: |
| """Configure the reasoning graph for disruptive innovation analysis.""" |
| # Add custom reasoning nodes |
| self.reasoning_graph.add_node( |
| "innovation_analysis", |
| self._innovation_analysis |
| ) |
| |
| self.reasoning_graph.add_node( |
| "growth_projection", |
| self._growth_projection |
| ) |
| |
| self.reasoning_graph.add_node( |
| "competition_analysis", |
| self._competition_analysis |
| ) |
| |
| self.reasoning_graph.add_node( |
| "valuation_adjustment", |
| self._valuation_adjustment |
| ) |
| |
| # Configure reasoning flow |
| self.reasoning_graph.set_entry_point("innovation_analysis") |
| self.reasoning_graph.add_edge("innovation_analysis", "growth_projection") |
| self.reasoning_graph.add_edge("growth_projection", "competition_analysis") |
| self.reasoning_graph.add_edge("competition_analysis", "valuation_adjustment") |
| ``` |
|
|
| Each reasoning node executes and passes state to the next node, building up a complete reasoning trace: |
|
|
| ``` |
| Step 1: Innovation Analysis |
| - Assessed disruptive potential in key markets |
| - Analyzed R&D pipeline and technological moats |
| - Identified 4 significant innovation vectors |
| |
| Step 2: Growth Projection |
| - Projected TAM expansion in core markets |
| - Calculated penetration rates and growth curves |
| - Estimated revenue CAGR of 28.3% over 5 years |
| |
| Step 3: Competition Analysis |
| - Assessed competitive positioning in EV market |
| - Analyzed first-mover advantages in energy storage |
| - Identified emerging threats in autonomous driving |
| |
| Step 4: Valuation Adjustment |
| - Applied growth-adjusted valuation metrics |
| - Discounted future cash flows with risk adjustment |
| - Compared valuation to traditional metrics |
| ``` |
|
|
| ## 4. Signal Generation |
|
|
| Each agent generates investment signals based on its reasoning: |
|
|
| ```python |
| # Generate signals from each agent |
| graham_signals = graham_agent.generate_signals(graham_processed) |
| wood_signals = wood_agent.generate_signals(wood_processed) |
| dalio_signals = dalio_agent.generate_signals(dalio_processed) |
| ``` |
|
|
| Each signal includes: |
| - Action recommendation (buy/sell/hold) |
| - Confidence level |
| - Quantity recommendation |
| - Complete reasoning chain |
| - Value basis (philosophical foundation) |
| - Attribution trace (causal links to evidence) |
|
|
| Example of Wood agent's signal: |
|
|
| ```json |
| { |
| "ticker": "TSLA", |
| "action": "buy", |
| "confidence": 0.82, |
| "quantity": 41, |
| "reasoning": "Tesla shows strong innovation potential across multiple verticals including EVs, energy storage, AI, and robotics. Their R&D pipeline demonstrates continued technological leadership with high growth potential in the coming decade.", |
| "intent": "Capitalize on long-term disruptive innovation growth", |
| "value_basis": "Disruptive innovation creates exponential growth and market expansion that traditional metrics fail to capture", |
| "attribution_trace": { |
| "innovation_score": 0.35, |
| "growth_projection": 0.25, |
| "competition_analysis": 0.20, |
| "valuation_adjustment": 0.20 |
| }, |
| "drift_signature": { |
| "interest_rates": -0.05, |
| "regulation": -0.03, |
| "competition": -0.02 |
| } |
| } |
| ``` |
|
|
| ## 5. Meta-Agent Arbitration |
|
|
| The portfolio meta-agent receives signals from all philosophical agents: |
|
|
| ```python |
| # Create portfolio manager (meta-agent) |
| portfolio = PortfolioManager( |
| agents=[graham_agent, wood_agent, dalio_agent], |
| arbitration_depth=2, |
| show_trace=True |
| ) |
| |
| # Process market data through meta-agent |
| meta_result = portfolio.process_market_data(market_data) |
| ``` |
|
|
| ### Consensus Formation |
|
|
| The meta-agent first attempts to find consensus on non-conflicting signals: |
|
|
| ```python |
| def _consensus_formation(self, state) -> Dict[str, Any]: |
| """Form consensus from agent signals.""" |
| # Extract signals by ticker |
| ticker_signals = state.context.get("ticker_signals", {}) |
| |
| # Form consensus for each ticker |
| consensus_decisions = [] |
| |
| for ticker, signals in ticker_signals.items(): |
| # Collect buy/sell/hold signals |
| buy_signals = [] |
| sell_signals = [] |
| hold_signals = [] |
| |
| for item in signals: |
| signal = item.get("signal", {}) |
| action = signal.action.lower() |
| |
| if action == "buy": |
| buy_signals.append((item, signal)) |
| elif action == "sell": |
| sell_signals.append((item, signal)) |
| elif action == "hold": |
| hold_signals.append((item, signal)) |
| |
| # Skip if conflicting signals (handle in conflict resolution) |
| if (buy_signals and sell_signals) or (not buy_signals and not sell_signals and not hold_signals): |
| continue |
| |
| # Form consensus for non-conflicting signals |
| if buy_signals: |
| # Form buy consensus |
| consensus = self._form_action_consensus(ticker, "buy", buy_signals) |
| if consensus: |
| consensus_decisions.append(consensus) |
| |
| elif sell_signals: |
| # Form sell consensus |
| consensus = self._form_action_consensus(ticker, "sell", sell_signals) |
| if consensus: |
| consensus_decisions.append(consensus) |
| |
| return { |
| "context": { |
| **state.context, |
| "consensus_decisions": consensus_decisions, |
| "consensus_tickers": [decision.get("ticker") for decision in consensus_decisions], |
| }, |
| "output": { |
| "consensus_decisions": consensus_decisions, |
| } |
| } |
| ``` |
|
|
| ### Conflict Resolution |
|
|
| For TSLA, we have a conflict: Graham (SELL) vs. Wood (BUY) vs. Dalio (HOLD). The meta-agent resolves this conflict: |
|
|
| ```python |
| def _resolve_ticker_conflict(self, ticker: str, action_signals: Dict[str, List[Tuple[Dict[str, Any], Any]]]) -> Optional[Dict[str, Any]]: |
| """Resolve conflict for a specific ticker.""" |
| # Calculate total weight for each action |
| action_weights = {} |
| action_confidences = {} |
| |
| for action, signals in action_signals.items(): |
| total_weight = 0.0 |
| weighted_confidence = for action, signals in action_signals.items(): |
| total_weight = 0.0 |
| weighted_confidence = 0.0 |
| |
| for item, signal in signals: |
| agent_id = item.get("agent_id", "") |
| |
| # Skip if missing agent ID |
| if not agent_id: |
| continue |
| |
| # Get agent weight |
| agent_weight = self.agent_weights.get(agent_id, 0) |
| |
| # Add to weighted confidence |
| weighted_confidence += signal.confidence * agent_weight |
| total_weight += agent_weight |
| |
| # Store action weight and confidence |
| if total_weight > 0: |
| action_weights[action] = total_weight |
| action_confidences[action] = weighted_confidence / total_weight |
| |
| # Choose action with highest weight |
| if not action_weights: |
| return None |
| |
| best_action = max(action_weights.items(), key=lambda x: x[1])[0] |
| |
| # Check confidence threshold |
| if action_confidences.get(best_action, 0) < self.consensus_threshold: |
| return None |
| |
| # Get signals for best action |
| best_signals = action_signals.get(best_action, []) |
| |
| # Form consensus for best action |
| return self._form_action_consensus(ticker, best_action, best_signals) |
| ``` |
|
|
| In our case, after attributing current agent weights (based on historical performance): |
| - Graham agent: 0.25 (weight) × 0.78 (confidence) = 0.195 (weighted confidence) |
| - Wood agent: 0.40 (weight) × 0.82 (confidence) = 0.328 (weighted confidence) |
| - Dalio agent: 0.35 (weight) × 0.65 (confidence) = 0.228 (weighted confidence) |
|
|
| The Wood agent's BUY signal has the highest weighted confidence, so the meta-agent forms consensus around it. |
|
|
| ### Position Sizing |
|
|
| The meta-agent determines position size based on confidence and attribution: |
|
|
| ```python |
| def _calculate_position_size(self, ticker: str, action: str, confidence: float, |
| attribution: Dict[str, float], portfolio_value: float) -> float: |
| """Calculate position size based on confidence and attribution.""" |
| # Base position size as percentage of portfolio |
| base_size = self.min_position_size + (confidence * (self.max_position_size - self.min_position_size)) |
| |
| # Calculate attribution-weighted size |
| if attribution: |
| # Calculate agent performance scores |
| performance_scores = {} |
| for agent_id, weight in attribution.items(): |
| # Find agent |
| agent = None |
| for a in self.agents: |
| if a.id == agent_id: |
| agent = a |
| break |
| |
| if agent: |
| # Use consistency score as proxy for performance |
| performance_score = agent.state.consistency_score |
| performance_scores[agent_id] = performance_score |
| |
| # Calculate weighted performance score |
| weighted_score = 0 |
| total_weight = 0 |
| |
| for agent_id, weight in attribution.items(): |
| if agent_id in performance_scores: |
| weighted_score += performance_scores[agent_id] * weight |
| total_weight += weight |
| |
| # Adjust base size by performance |
| if total_weight > 0: |
| performance_factor = weighted_score / total_weight |
| base_size *= (0.5 + (0.5 * performance_factor)) |
| |
| # Calculate currency amount |
| target_size = portfolio_value * base_size |
| |
| return target_size |
| ``` |
|
|
| For TSLA: |
| - Base position size: 0.01 + (0.82 × (0.20 - 0.01)) = 0.165 (16.5% of portfolio) |
| - Adjusted for agent performance: 16.5% × 1.1 = 18.2% of portfolio |
| - For a $1,000,000 portfolio: $182,000 position size |
| - At current price of $242.15: 751 shares |
|
|
| ### Meta Reflection |
|
|
| The meta-agent performs a final reflection on its decision process: |
|
|
| ```python |
| def _meta_reflection(self, state) -> Dict[str, Any]: |
| """Perform meta-reflection on decision process.""" |
| # Extract decisions |
| sized_decisions = state.context.get("sized_decisions", []) |
| |
| # Update meta state with arbitration record |
| arbitration_record = { |
| "id": str(uuid.uuid4()), |
| "decisions": sized_decisions, |
| "timestamp": datetime.datetime.now().isoformat(), |
| } |
| |
| self.meta_state["arbitration_history"].append(arbitration_record) |
| |
| # Update agent weights based on performance |
| self._update_agent_weights() |
| |
| # Calculate meta-confidence |
| meta_confidence = sum(decision.get("confidence", 0) for decision in sized_decisions) / len(sized_decisions) if sized_decisions else 0.5 |
| |
| # Return final output |
| return { |
| "output": { |
| "consensus_decisions": sized_decisions, |
| "meta_confidence": meta_confidence, |
| "agent_weights": self.agent_weights, |
| "timestamp": datetime.datetime.now().isoformat(), |
| }, |
| "confidence": meta_confidence, |
| } |
| ``` |
|
|
| The meta-agent final reflection includes: |
| - Consensus tracking |
| - Agent weight adjustment |
| - Meta-confidence calculation |
| - Temporal memory update |
|
|
| ## 6. Trade Execution |
|
|
| The final step is trade execution: |
|
|
| ```python |
| # Execute trades based on consensus decisions |
| consensus_decisions = meta_result.get("meta_agent", {}).get("consensus_decisions", []) |
| execution_results = portfolio.execute_trades(consensus_decisions) |
| ``` |
|
|
| The execution includes: |
| - Position sizing |
| - Order placement |
| - Confirmation handling |
| - Portfolio state update |
|
|
| ```json |
| { |
| "trades": [ |
| { |
| "ticker": "TSLA", |
| "action": "buy", |
| "quantity": 751, |
| "price": 242.15, |
| "cost": 181853.65, |
| "timestamp": "2024-04-17T14:23:45.123456" |
| } |
| ], |
| "errors": [], |
| "portfolio_update": { |
| "timestamp": "2024-04-17T14:23:45.654321", |
| "portfolio_value": 1000000.00, |
| "cash": 818146.35, |
| "positions": { |
| "TSLA": { |
| "ticker": "TSLA", |
| "quantity": 751, |
| "entry_price": 242.15, |
| "current_price": 242.15, |
| "market_value": 181853.65, |
| "allocation": 0.182, |
| "unrealized_gain": 0.0, |
| "entry_date": "2024-04-17T14:23:45.123456" |
| } |
| }, |
| "returns": { |
| "total_return": 0.0, |
| "daily_return": 0.0 |
| }, |
| "allocation": { |
| "cash": 0.818, |
| "TSLA": 0.182 |
| } |
| } |
| } |
| ``` |
|
|
| ## 7. Attribution Tracing |
|
|
| Throughout this process, complete attribution tracing is maintained: |
|
|
| ```python |
| # Generate attribution report |
| attribution_report = portfolio.tracer.generate_attribution_report(meta_result.get("meta_agent", {}).get("consensus_decisions", [])) |
| ``` |
|
|
| The attribution report shows the complete decision provenance: |
|
|
| ```json |
| { |
| "agent_name": "PortfolioMetaAgent", |
| "timestamp": "2024-04-17T14:23:46.123456", |
| "signals": 1, |
| "attribution_summary": { |
| "Wood": 0.45, |
| "Dalio": 0.35, |
| "Graham": 0.20 |
| }, |
| "confidence_summary": { |
| "mean": 0.82, |
| "median": 0.82, |
| "min": 0.82, |
| "max": 0.82 |
| }, |
| "top_factors": [ |
| { |
| "source": "innovation_score", |
| "weight": 0.35 |
| }, |
| { |
| "source": "growth_projection", |
| "weight": 0.25 |
| }, |
| { |
| "source": "economic_cycle_position", |
| "weight": 0.15 |
| }, |
| { |
| "source": "competition_analysis", |
| "weight": 0.10 |
| }, |
| { |
| "source": "intrinsic_value_calculation", |
| "weight": 0.10 |
| } |
| ], |
| "shell_patterns": [ |
| { |
| "pattern": "v07 CIRCUIT-FRAGMENT", |
| "count": 1, |
| "frequency": 1.0 |
| } |
| ] |
| } |
| ``` |
|
|
| ## 8. Visualization |
|
|
| The system provides multiple visualization tools for interpretability: |
|
|
| ### Consensus Graph |
|
|
| ```python |
| # Generate consensus graph |
| consensus_graph = portfolio.visualize_consensus_graph() |
| ``` |
|
|
| The consensus graph shows the flow of influence between agents and decisions: |
|
|
| ```json |
| { |
| "nodes": [ |
| { |
| "id": "meta", |
| "label": "Portfolio Meta-Agent", |
| "type": "meta", |
| "size": 20 |
| }, |
| { |
| "id": "agent-1", |
| "label": "Graham Agent", |
| "type": "agent", |
| "philosophy": "Value investing focused on margin of safety", |
| "size": 15, |
| "weight": 0.20 |
| }, |
| { |
| "id": "agent-2", |
| "label": "Wood Agent", |
| "type": "agent", |
| "philosophy": "Disruptive innovation investing", |
| "size": 15, |
| "weight": 0.45 |
| }, |
| { |
| "id": "agent-3", |
| "label": "Dalio Agent", |
| "type": "agent", |
| "philosophy": "Macroeconomic-based investing", |
| "size": 15, |
| "weight": 0.35 |
| }, |
| { |
| "id": "position-TSLA", |
| "label": "TSLA", |
| "type": "position", |
| "size": 10, |
| "value": 181853.65 |
| } |
| ], |
| "links": [ |
| { |
| "source": "agent-1", |
| "target": "meta", |
| "value": 0.20, |
| "type": "influence" |
| }, |
| { |
| "source": "agent-2", |
| "target": "meta", |
| "value": 0.45, |
| "type": "influence" |
| }, |
| { |
| "source": "agent-3", |
| "target": "meta", |
| "value": 0.35, |
| "type": "influence" |
| }, |
| { |
| "source": "meta", |
| "target": "position-TSLA", |
| "value": 1.0, |
| "type": "allocation" |
| }, |
| { |
| "source": "agent-2", |
| "target": "position-TSLA", |
| "value": 0.45, |
| "type": "attribution" |
| }, |
| { |
| "source": "agent-3", |
| "target": "position-TSLA", |
| "value": 0.35, |
| "type": "attribution" |
| }, |
| { |
| "source": "agent-1", |
| "target": "position-TSLA", |
| "value": 0.20, |
| "type": "attribution" |
| } |
| ], |
| "timestamp": "2024-04-17T14:23:46.987654" |
| } |
| ``` |
|
|
| ### Agent Conflict Map |
|
|
| ```python |
| # Generate agent conflict map |
| conflict_map = portfolio.visualize_agent_conflict_map() |
| ``` |
|
|
| The conflict map visualizes the specific disagreements between agents: |
|
|
| ```json |
| { |
| "nodes": [ |
| { |
| "id": "agent-1", |
| "label": "Graham Agent", |
| "type": "agent", |
| "philosophy": "Value investing focused on margin of safety", |
| "size": 15 |
| }, |
| { |
| "id": "agent-2", |
| "label": "Wood Agent", |
| "type": "agent", |
| "philosophy": "Disruptive innovation investing", |
| "size": 15 |
| }, |
| { |
| "id": "agent-3", |
| "label": "Dalio Agent", |
| "type": "agent", |
| "philosophy": "Macroeconomic-based investing", |
| "size": 15 |
| }, |
| { |
| "id": "position-TSLA", |
| "label": "TSLA", |
| "type": "position", |
| "size": 10 |
| } |
| ], |
| "links": [ |
| { |
| "source": "agent-1", |
| "target": "agent-2", |
| "value": 1.0, |
| "type": "conflict", |
| "ticker": "TSLA" |
| }, |
| { |
| "source": "agent-2", |
| "target": "agent-3", |
| "value": 1.0, |
| "type": "conflict", |
| "ticker": "TSLA" |
| }, |
| { |
| "source": "agent-1", |
| "target": "agent-3", |
| "value": 1.0, |
| "type": "conflict", |
| "ticker": "TSLA" |
| } |
| ], |
| "conflict_zones": [ |
| { |
| "id": "conflict-1", |
| "ticker": "TSLA", |
| "agents": ["agent-1", "agent-2", "agent-3"], |
| "resolution": "resolved", |
| "timestamp": "2024-04-17T14:23:44.567890" |
| } |
| ], |
| "timestamp": "2024-04-17T14:23:47.654321" |
| } |
| ``` |
|
|
| ### Shell Failure Map |
|
|
| ```python |
| # Create shell diagnostics |
| shell_diagnostics = ShellDiagnostics( |
| agent_id="portfolio", |
| agent_name="Portfolio", |
| tracing_tools=TracingTools( |
| agent_id="portfolio", |
| agent_name="Portfolio", |
| tracing_mode=TracingMode.DETAILED, |
| ) |
| ) |
| |
| # Create shell failure map |
| failure_map = ShellFailureMap() |
| |
| # Analyze each agent's state for shell failures |
| for agent in [graham_agent, wood_agent, dalio_agent]: |
| agent_state = agent.get_state_report() |
| |
| # Simulate shell failures based on agent state |
| for shell_pattern in [ShellPattern.CIRCUIT_FRAGMENT, ShellPattern.META_FAILURE]: |
| failure_data = shell_diagnostics.simulate_shell_failure( |
| shell_pattern=shell_pattern, |
| context=agent_state, |
| ) |
| |
| # Add to failure map |
| failure_map.add_failure( |
| agent_id=agent.id, |
| agent_name=agent.name, |
| shell_pattern=shell_pattern, |
| failure_data=failure_data, |
| ) |
| |
| # Generate visualization |
| shell_failure_viz = failure_map.generate_failure_map_visualization() |
| ``` |
|
|
| The shell failure map visualizes interpretability patterns detected in the agents: |
|
|
| ```json |
| { |
| "nodes": [ |
| { |
| "id": "agent-1", |
| "label": "Graham Agent", |
| "type": "agent", |
| "size": 15, |
| "failure_count": 1 |
| }, |
| { |
| "id": "agent-2", |
| "label": "Wood Agent", |
| "type": "agent", |
| "size": 15, |
| "failure_count": 2 |
| }, |
| { |
| "id": "agent-3", |
| "label": "Dalio Agent", |
| "type": "agent", |
| "size": 15, |
| "failure_count": 1 |
| }, |
| { |
| "id": "v07 CIRCUIT-FRAGMENT", |
| "label": "CIRCUIT-FRAGMENT", |
| "type": "pattern", |
| "size": 10, |
| "failure_count": 3 |
| }, |
| { |
| "id": "v10 META-FAILURE", |
| "label": "META-FAILURE", |
| "type": "pattern", |
| "size": 10, |
| "failure_count": 1 |
| }, |
| { |
| "id": "failure-1", |
| "label": "Failure 3f4a9c", |
| "type": "failure", |
| "size": 5, |
| "timestamp": "2024-04-17T14:23:48.123456" |
| }, |
| { |
| "id": "failure-2", |
| "label": "Failure b7d5e2", |
| "type": "failure", |
| "size": 5, |
| "timestamp": "2024-04-17T14:23:48.234567" |
| }, |
| { |
| "id": "failure-3", |
| "label": "Failure 9c6f1a", |
| "type": "failure", |
| "size": 5, |
| "timestamp": "2024-04-17T14:23:48.345678" |
| }, |
| { |
| "id": "failure-4", |
| "label": "Failure 2e8d7f", |
| "type": "failure", |
| "size": 5, |
| "timestamp": "2024-04-17T14:23:48.456789" |
| } |
| ], |
| "links": [ |
| { |
| "source": "agent-1", |
| "target": "failure-1", |
| "type": "agent_failure" |
| }, |
| { |
| "source": "v07 CIRCUIT-FRAGMENT", |
| "target": "failure-1", |
| "type": "pattern_failure" |
| }, |
| { |
| "source": "agent-2", |
| "target": "failure-2", |
| "type": "agent_failure" |
| }, |
| { |
| "source": "v07 CIRCUIT-FRAGMENT", |
| "target": "failure-2", |
| "type": "pattern_failure" |
| }, |
| { |
| "source": "agent-2", |
| "target": "failure-3", |
| "type": "agent_failure" |
| }, |
| { |
| "source": "v10 META-FAILURE", |
| "target": "failure-3", |
| "type": "pattern_failure" |
| }, |
| { |
| "source": "agent-3", |
| "target": "failure-4", |
| "type": "agent_failure" |
| }, |
| { |
| "source": "v07 CIRCUIT-FRAGMENT", |
| "target": "failure-4", |
| "type": "pattern_failure" |
| } |
| ], |
| "timestamp": "2024-04-17T14:23:49.000000" |
| } |
| ``` |
|
|
| ## 9. Agent Memory & Learning |
|
|
| After each trading cycle, agents update their internal state: |
|
|
| ```python |
| # Update agent states based on market feedback |
| market_feedback = { |
| 'portfolio_value': execution_results['portfolio_update']['portfolio_value'], |
| 'performance': {'TSLA': 0.02}, # Example: 2% return |
| 'decisions': consensus_decisions, |
| 'avg_confidence': 0.82, |
| } |
| |
| # Update each agent's state |
| for agent in [graham_agent, wood_agent, dalio_agent]: |
| agent.update_state(market_feedback) |
| ``` |
|
|
| Each agent processes the feedback differently based on its philosophy: |
|
|
| ### Wood Agent Memory Update |
|
|
| ```python |
| def _update_beliefs(self, market_feedback: Dict[str, Any]) -> None: |
| """Update agent's belief state based on market feedback.""" |
| # Extract relevant signals |
| if 'performance' in market_feedback: |
| performance = market_feedback['performance'] |
| |
| # Record decision outcomes |
| if 'decisions' in market_feedback: |
| for decision in market_feedback['decisions']: |
| self.state.decision_history.append({ |
| 'decision': decision, |
| 'outcome': performance.get(decision.get('ticker'), 0), |
| 'timestamp': datetime.datetime.now() |
| }) |
| |
| # For Wood Agent, reinforce innovation beliefs on positive outcomes |
| if performance.get(decision.get('ticker'), 0) > 0: |
| ticker = decision.get('ticker') |
| # Strengthen innovation belief |
| current_belief = self.state.belief_state.get(f"{ticker}_innovation", 0.5) |
| self.state.belief_state[f"{ticker}_innovation"] = min(1.0, current_belief + 0.05) |
| |
| # Update industry trend belief |
| industry = self._get_ticker_industry(ticker) |
| if industry: |
| industry_belief = self.state.belief_state.get(f"{industry}_trend", 0.5) |
| self.state.belief_state[f"{industry}_trend"] = min(1.0, industry_belief + 0.03) |
| |
| # Update general belief state based on performance |
| for ticker, perf in performance.items(): |
| general_belief_key = f"{ticker}_general" |
| current_belief = self.state.belief_state.get(general_belief_key, 0.5) |
| |
| # Wood Agent weights positive outcomes more heavily for innovative companies |
| if self._is_innovative_company(ticker): |
| update_weight = 0.3 # Higher weight for innovative companies |
| else: |
| update_weight = 0.1 # Lower weight for traditional companies |
| |
| # Update belief |
| updated_belief = current_belief * (1 - update_weight) + np.tanh(perf) * update_weight |
| self.state.belief_state[general_belief_key] = updated_belief |
| |
| # Track belief drift |
| if general_belief_key in self.state.belief_state: |
| drift = updated_belief - current_belief |
| self.state.drift_vector[general_belief_key] = drift |
| |
| # Wood Agent's drift pattern analysis |
| self._analyze_drift_pattern(ticker, drift) |
| ``` |
|
|
| ## 10. Command Interface |
|
|
| Throughout the system, the symbolic command interface enables deeper introspection: |
|
|
| ```python |
| # Get a reflection trace from the Graham agent |
| reflection_trace = graham_agent.execute_command( |
| command="reflect.trace", |
| depth=3 |
| ) |
| |
| # Generate signals from alternative sources |
| alt_signals = wood_agent.execute_command( |
| command="fork.signal", |
| source="beliefs" |
| ) |
| |
| # Check for decision collapse |
| collapse_check = dalio_agent.execute_command( |
| command="collapse.detect", |
| threshold=0.7, |
| reason="consistency" |
| ) |
| |
| # Attribute weight to a justification |
| attribution = portfolio.execute_command( |
| command="attribute.weight", |
| justification="Tesla's innovation in AI and robotics represents a paradigm shift that traditional valuation metrics fail to capture." |
| ) |
| |
| # Track belief drift |
| drift_observation = wood_agent.execute_command( |
| command="drift.observe", |
| vector={"TSLA_innovation": 0.05, "AI_trend": 0.03, "EV_market": 0.02}, |
| bias=0.01 |
| ) |
| ``` |
|
|
| These commands form the foundation of the system's interpretability architecture, enabling detailed tracing and analysis of decision processes. |
|
|
| ## Conclusion |
|
|
| This example demonstrates the recursive cognitive architecture of Multi-Agent Debate in action. From market data ingestion to trade execution, the system maintains complete transparency and interpretability through: |
|
|
| 1. Agent-specific cognitive lenses |
| 2. Recursive reasoning graphs |
| 3. Attribution tracing |
| 4. Meta-agent arbitration |
| 5. Position sizing |
| 6. Trade execution |
| 7. Memory and learning |
|
|
| Each component is designed to enable deeper introspection into the decision-making process, creating a truly transparent and interpretable multi-agent market cognition system. |
|
|
| The symbolic command interface and visualization tools provide multiple ways to understand and analyze the system's behavior, making it both effective and explainable. |
|
|
|
|
|
|
|
|
|
|
|
|