rcrewai 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1014 @@
1
+ ---
2
+ layout: tutorial
3
+ title: Advanced Agent Configuration
4
+ description: Master advanced agent features including memory, custom reasoning, delegation, and performance optimization
5
+ ---
6
+
7
+ # Advanced Agent Configuration
8
+
9
+ This tutorial covers advanced agent configuration techniques including memory systems, custom reasoning loops, delegation patterns, performance optimization, and specialized agent behaviors.
10
+
11
+ ## Table of Contents
12
+ 1. [Agent Memory Systems](#agent-memory-systems)
13
+ 2. [Custom Reasoning Loops](#custom-reasoning-loops)
14
+ 3. [Manager Agents and Delegation](#manager-agents-and-delegation)
15
+ 4. [Performance Optimization](#performance-optimization)
16
+ 5. [Specialized Agent Behaviors](#specialized-agent-behaviors)
17
+ 6. [Agent Communication Patterns](#agent-communication-patterns)
18
+ 7. [Error Handling and Recovery](#error-handling-and-recovery)
19
+
20
+ ## Agent Memory Systems
21
+
22
+ Agents in RCrewAI have sophisticated memory systems that allow them to learn and improve over time.
23
+
24
+ ### Short-term and Long-term Memory
25
+
26
+ ```ruby
27
+ require 'rcrewai'
28
+
29
+ # Create agent with enhanced memory capabilities
30
+ analyst = RCrewAI::Agent.new(
31
+ name: "data_analyst",
32
+ role: "Senior Data Analyst",
33
+ goal: "Analyze data patterns and learn from past analyses",
34
+ backstory: "Expert analyst who improves with each analysis",
35
+ verbose: true
36
+ )
37
+
38
+ # Memory is automatically created and managed
39
+ memory = analyst.memory
40
+
41
+ # After task execution, memory stores:
42
+ # - Successful patterns and strategies
43
+ # - Tool usage that worked well
44
+ # - Context that led to good results
45
+ # - Failed approaches to avoid
46
+
47
+ # Access memory statistics
48
+ stats = memory.stats
49
+ puts "Total executions: #{stats[:total_executions]}"
50
+ puts "Success rate: #{stats[:success_rate]}%"
51
+ puts "Most used tools: #{stats[:top_tools]}"
52
+ puts "Average execution time: #{stats[:avg_execution_time]}s"
53
+
54
+ # Memory influences future reasoning
55
+ # Agent will prefer successful patterns from memory
56
+ ```
57
+
58
+ ### Custom Memory Persistence
59
+
60
+ ```ruby
61
+ class PersistentMemoryAgent < RCrewAI::Agent
62
+ def initialize(**options)
63
+ super
64
+ load_memory_from_storage
65
+ end
66
+
67
+ def execute_task(task)
68
+ result = super
69
+ save_memory_to_storage
70
+ result
71
+ end
72
+
73
+ private
74
+
75
+ def load_memory_from_storage
76
+ if File.exist?("#{name}_memory.json")
77
+ memory_data = JSON.parse(File.read("#{name}_memory.json"))
78
+ @memory.restore(memory_data)
79
+ end
80
+ end
81
+
82
+ def save_memory_to_storage
83
+ File.write("#{name}_memory.json", @memory.to_json)
84
+ end
85
+ end
86
+
87
+ # Agent that remembers across sessions
88
+ persistent_agent = PersistentMemoryAgent.new(
89
+ name: "persistent_researcher",
90
+ role: "Research Specialist",
91
+ goal: "Build knowledge over time"
92
+ )
93
+ ```
94
+
95
+ ### Memory-Enhanced Learning
96
+
97
+ ```ruby
98
+ # Create a learning agent that improves over time
99
+ learning_agent = RCrewAI::Agent.new(
100
+ name: "learning_assistant",
101
+ role: "Adaptive Assistant",
102
+ goal: "Learn from each interaction to provide better assistance",
103
+ backstory: "An AI that continuously improves through experience",
104
+ tools: [RCrewAI::Tools::WebSearch.new, RCrewAI::Tools::FileWriter.new]
105
+ )
106
+
107
+ # Track performance over multiple executions
108
+ 10.times do |i|
109
+ task = RCrewAI::Task.new(
110
+ name: "research_task_#{i}",
111
+ description: "Research topic #{i}",
112
+ agent: learning_agent
113
+ )
114
+
115
+ result = task.execute
116
+
117
+ # Agent automatically learns:
118
+ # - Which search queries work best
119
+ # - How to structure research
120
+ # - Optimal tool usage patterns
121
+
122
+ puts "Iteration #{i}: Success=#{task.status == :completed}"
123
+ end
124
+
125
+ # Check improvement
126
+ puts "Learning progress: #{learning_agent.memory.learning_curve}"
127
+ ```
128
+
129
+ ## Custom Reasoning Loops
130
+
131
+ Advanced agents can have customized reasoning processes for specialized tasks.
132
+
133
+ ### Custom Reasoning Agent
134
+
135
+ ```ruby
136
+ class AnalyticalReasoningAgent < RCrewAI::Agent
137
+ def reasoning_loop(task, context)
138
+ iteration = 0
139
+ hypotheses = []
140
+
141
+ loop do
142
+ iteration += 1
143
+
144
+ # Phase 1: Generate hypotheses
145
+ if iteration == 1
146
+ hypotheses = generate_hypotheses(task, context)
147
+ @logger.info "Generated #{hypotheses.length} hypotheses"
148
+ end
149
+
150
+ # Phase 2: Test hypotheses
151
+ if iteration > 1 && iteration <= hypotheses.length + 1
152
+ hypothesis = hypotheses[iteration - 2]
153
+ result = test_hypothesis(hypothesis, context)
154
+
155
+ if result[:valid]
156
+ return formulate_conclusion(hypothesis, result)
157
+ end
158
+ end
159
+
160
+ # Phase 3: Synthesize findings
161
+ if iteration > hypotheses.length + 1
162
+ return synthesize_findings(hypotheses, context)
163
+ end
164
+
165
+ break if iteration > max_iterations
166
+ end
167
+ end
168
+
169
+ private
170
+
171
+ def generate_hypotheses(task, context)
172
+ prompt = build_hypothesis_prompt(task, context)
173
+ response = llm_client.chat(messages: [{ role: 'user', content: prompt }])
174
+ parse_hypotheses(response[:content])
175
+ end
176
+
177
+ def test_hypothesis(hypothesis, context)
178
+ # Use tools to validate hypothesis
179
+ if tools.any? { |t| t.name == 'websearch' }
180
+ evidence = use_tool('websearch', query: hypothesis[:query])
181
+ { valid: evidence.include?(hypothesis[:expected]), evidence: evidence }
182
+ else
183
+ { valid: false, evidence: nil }
184
+ end
185
+ end
186
+
187
+ def formulate_conclusion(hypothesis, result)
188
+ "Conclusion: #{hypothesis[:statement]} is supported by evidence: #{result[:evidence]}"
189
+ end
190
+
191
+ def synthesize_findings(hypotheses, context)
192
+ "Unable to validate hypotheses. Best assessment based on available data..."
193
+ end
194
+ end
195
+
196
+ # Use the analytical reasoning agent
197
+ analyst = AnalyticalReasoningAgent.new(
198
+ name: "hypothesis_tester",
199
+ role: "Scientific Analyst",
200
+ goal: "Test hypotheses systematically",
201
+ tools: [RCrewAI::Tools::WebSearch.new]
202
+ )
203
+ ```
204
+
205
+ ### Multi-Stage Reasoning
206
+
207
+ ```ruby
208
+ class MultiStageReasoningAgent < RCrewAI::Agent
209
+ REASONING_STAGES = [
210
+ :understand,
211
+ :analyze,
212
+ :plan,
213
+ :execute,
214
+ :verify,
215
+ :conclude
216
+ ]
217
+
218
+ def reasoning_loop(task, context)
219
+ current_stage_index = 0
220
+ stage_results = {}
221
+
222
+ while current_stage_index < REASONING_STAGES.length
223
+ stage = REASONING_STAGES[current_stage_index]
224
+
225
+ @logger.info "Reasoning stage: #{stage}"
226
+
227
+ result = case stage
228
+ when :understand
229
+ understand_requirements(task, context)
230
+ when :analyze
231
+ analyze_problem(task, context, stage_results[:understand])
232
+ when :plan
233
+ create_action_plan(stage_results[:analyze])
234
+ when :execute
235
+ execute_plan(stage_results[:plan])
236
+ when :verify
237
+ verify_results(stage_results[:execute])
238
+ when :conclude
239
+ formulate_conclusion(stage_results)
240
+ end
241
+
242
+ stage_results[stage] = result
243
+
244
+ # Allow stage retry on failure
245
+ if result[:success]
246
+ current_stage_index += 1
247
+ elsif result[:retry]
248
+ @logger.info "Retrying stage: #{stage}"
249
+ else
250
+ break
251
+ end
252
+ end
253
+
254
+ stage_results[:conclude] || "Reasoning incomplete"
255
+ end
256
+ end
257
+ ```
258
+
259
+ ## Manager Agents and Delegation
260
+
261
+ Manager agents coordinate teams and delegate tasks intelligently.
262
+
263
+ ### Creating a Manager Agent
264
+
265
+ ```ruby
266
+ # Create a manager with delegation capabilities
267
+ manager = RCrewAI::Agent.new(
268
+ name: "team_manager",
269
+ role: "Engineering Manager",
270
+ goal: "Coordinate team to deliver projects efficiently",
271
+ backstory: "Experienced manager who knows how to leverage team strengths",
272
+ manager: true, # Mark as manager
273
+ allow_delegation: true, # Enable delegation
274
+ tools: [RCrewAI::Tools::FileWriter.new], # Manager tools
275
+ verbose: true
276
+ )
277
+
278
+ # Create specialist team members
279
+ backend_dev = RCrewAI::Agent.new(
280
+ name: "backend_developer",
281
+ role: "Backend Engineer",
282
+ goal: "Build robust backend systems",
283
+ tools: [RCrewAI::Tools::FileWriter.new]
284
+ )
285
+
286
+ frontend_dev = RCrewAI::Agent.new(
287
+ name: "frontend_developer",
288
+ role: "Frontend Engineer",
289
+ goal: "Create excellent user interfaces",
290
+ tools: [RCrewAI::Tools::FileWriter.new]
291
+ )
292
+
293
+ qa_engineer = RCrewAI::Agent.new(
294
+ name: "qa_engineer",
295
+ role: "QA Engineer",
296
+ goal: "Ensure software quality",
297
+ tools: [RCrewAI::Tools::FileReader.new]
298
+ )
299
+
300
+ # Build team hierarchy
301
+ manager.add_subordinate(backend_dev)
302
+ manager.add_subordinate(frontend_dev)
303
+ manager.add_subordinate(qa_engineer)
304
+
305
+ # Manager will automatically delegate tasks to appropriate team members
306
+ ```
307
+
308
+ ### Advanced Delegation Strategies
309
+
310
+ ```ruby
311
+ class StrategicManager < RCrewAI::Agent
312
+ def delegate_task(task, target_agent = nil)
313
+ if target_agent.nil?
314
+ # Intelligent agent selection based on multiple factors
315
+ target_agent = select_best_agent(task)
316
+ end
317
+
318
+ # Create delegation context with strategic guidance
319
+ delegation_context = {
320
+ priority: assess_priority(task),
321
+ deadline: calculate_deadline(task),
322
+ resources: allocate_resources(task),
323
+ success_criteria: define_success_criteria(task),
324
+ escalation_path: define_escalation(task)
325
+ }
326
+
327
+ # Enhanced delegation with context
328
+ @logger.info "Delegating #{task.name} to #{target_agent.name}"
329
+ @logger.info "Context: #{delegation_context}"
330
+
331
+ super(task, target_agent)
332
+ end
333
+
334
+ private
335
+
336
+ def select_best_agent(task)
337
+ # Score each subordinate for task fit
338
+ scores = subordinates.map do |agent|
339
+ score = 0
340
+
341
+ # Factor 1: Role match
342
+ role_match = calculate_role_match(task, agent)
343
+ score += role_match * 0.4
344
+
345
+ # Factor 2: Current workload
346
+ workload = assess_workload(agent)
347
+ score += (1.0 - workload) * 0.3
348
+
349
+ # Factor 3: Past performance
350
+ performance = agent.memory.stats[:success_rate] || 0.5
351
+ score += performance * 0.2
352
+
353
+ # Factor 4: Tool availability
354
+ tool_match = calculate_tool_match(task, agent)
355
+ score += tool_match * 0.1
356
+
357
+ { agent: agent, score: score }
358
+ end
359
+
360
+ # Select highest scoring agent
361
+ best = scores.max_by { |s| s[:score] }
362
+ best[:agent]
363
+ end
364
+
365
+ def calculate_role_match(task, agent)
366
+ task_keywords = extract_keywords(task.description)
367
+ role_keywords = extract_keywords(agent.role)
368
+
369
+ common = (task_keywords & role_keywords).length
370
+ total = [task_keywords.length, role_keywords.length].max
371
+
372
+ common.to_f / total
373
+ end
374
+
375
+ def assess_workload(agent)
376
+ # Return workload between 0 (idle) and 1 (overloaded)
377
+ active_tasks = @delegated_tasks[agent.name] || []
378
+ active_tasks.count { |t| t.status == :running } / 5.0
379
+ end
380
+ end
381
+ ```
382
+
383
+ ### Cross-Team Coordination
384
+
385
+ ```ruby
386
+ # Multiple managers coordinating
387
+ engineering_manager = RCrewAI::Agent.new(
388
+ name: "eng_manager",
389
+ role: "Engineering Manager",
390
+ manager: true,
391
+ allow_delegation: true
392
+ )
393
+
394
+ product_manager = RCrewAI::Agent.new(
395
+ name: "product_manager",
396
+ role: "Product Manager",
397
+ manager: true,
398
+ allow_delegation: true
399
+ )
400
+
401
+ # Managers can coordinate through shared context
402
+ shared_context = {
403
+ project_goals: "Launch new feature by Q2",
404
+ constraints: "Limited to 3 engineers",
405
+ priorities: ["Performance", "User Experience", "Security"]
406
+ }
407
+
408
+ # Create tasks that require cross-team coordination
409
+ feature_task = RCrewAI::Task.new(
410
+ name: "new_feature",
411
+ description: "Implement new dashboard feature",
412
+ context_data: shared_context
413
+ )
414
+
415
+ # Both managers will coordinate their teams
416
+ ```
417
+
418
+ ## Performance Optimization
419
+
420
+ Optimize agent performance for production workloads.
421
+
422
+ ### Parallel Agent Execution
423
+
424
+ ```ruby
425
+ # Configure agents for parallel execution
426
+ fast_researcher = RCrewAI::Agent.new(
427
+ name: "fast_researcher",
428
+ role: "Research Specialist",
429
+ goal: "Quickly gather information",
430
+ max_iterations: 3, # Limit iterations
431
+ max_execution_time: 60, # 1 minute timeout
432
+ tools: [RCrewAI::Tools::WebSearch.new(timeout: 10)] # Fast timeout
433
+ )
434
+
435
+ # Create parallel tasks
436
+ parallel_tasks = 5.times.map do |i|
437
+ RCrewAI::Task.new(
438
+ name: "research_#{i}",
439
+ description: "Research topic #{i}",
440
+ agent: fast_researcher,
441
+ async: true # Mark for async execution
442
+ )
443
+ end
444
+
445
+ # Execute in parallel
446
+ crew = RCrewAI::Crew.new("parallel_crew")
447
+ crew.add_agent(fast_researcher)
448
+ parallel_tasks.each { |t| crew.add_task(t) }
449
+
450
+ results = crew.execute(async: true, max_concurrency: 5)
451
+ ```
452
+
453
+ ### Resource-Optimized Agents
454
+
455
+ ```ruby
456
+ class ResourceOptimizedAgent < RCrewAI::Agent
457
+ def initialize(**options)
458
+ super
459
+ @resource_monitor = ResourceMonitor.new
460
+ end
461
+
462
+ def execute_task(task)
463
+ # Check resources before execution
464
+ if @resource_monitor.memory_usage > 0.8
465
+ @logger.warn "High memory usage, optimizing..."
466
+ optimize_memory
467
+ end
468
+
469
+ # Use chunked processing for large tasks
470
+ if task.estimated_size > 1_000_000
471
+ execute_chunked(task)
472
+ else
473
+ super
474
+ end
475
+ end
476
+
477
+ private
478
+
479
+ def execute_chunked(task)
480
+ chunks = split_task(task)
481
+ results = []
482
+
483
+ chunks.each_with_index do |chunk, i|
484
+ @logger.info "Processing chunk #{i+1}/#{chunks.length}"
485
+
486
+ # Process chunk with resource limits
487
+ result = with_resource_limits do
488
+ process_chunk(chunk)
489
+ end
490
+
491
+ results << result
492
+
493
+ # Clear memory between chunks
494
+ GC.start if i % 5 == 0
495
+ end
496
+
497
+ merge_results(results)
498
+ end
499
+
500
+ def with_resource_limits(&block)
501
+ Thread.new do
502
+ Thread.current[:memory_limit] = 100_000_000 # 100MB
503
+ Thread.current[:time_limit] = 30 # 30 seconds
504
+
505
+ Timeout::timeout(Thread.current[:time_limit]) do
506
+ yield
507
+ end
508
+ end.value
509
+ end
510
+ end
511
+ ```
512
+
513
+ ### Caching and Memoization
514
+
515
+ ```ruby
516
+ class CachedAgent < RCrewAI::Agent
517
+ def initialize(**options)
518
+ super
519
+ @cache = {}
520
+ @cache_ttl = options[:cache_ttl] || 3600 # 1 hour default
521
+ end
522
+
523
+ def use_tool(tool_name, **params)
524
+ cache_key = "#{tool_name}_#{params.hash}"
525
+
526
+ # Check cache first
527
+ if cached = get_cached(cache_key)
528
+ @logger.info "Cache hit for #{tool_name}"
529
+ return cached
530
+ end
531
+
532
+ # Execute and cache
533
+ result = super
534
+ set_cached(cache_key, result)
535
+ result
536
+ end
537
+
538
+ private
539
+
540
+ def get_cached(key)
541
+ return nil unless @cache[key]
542
+
543
+ entry = @cache[key]
544
+ if Time.now - entry[:time] < @cache_ttl
545
+ entry[:value]
546
+ else
547
+ @cache.delete(key)
548
+ nil
549
+ end
550
+ end
551
+
552
+ def set_cached(key, value)
553
+ @cache[key] = {
554
+ value: value,
555
+ time: Time.now
556
+ }
557
+
558
+ # Limit cache size
559
+ if @cache.size > 100
560
+ oldest = @cache.min_by { |k, v| v[:time] }
561
+ @cache.delete(oldest[0])
562
+ end
563
+ end
564
+ end
565
+ ```
566
+
567
+ ## Specialized Agent Behaviors
568
+
569
+ Create agents with specialized behaviors for specific use cases.
570
+
571
+ ### Research Specialist Agent
572
+
573
+ ```ruby
574
+ class ResearchSpecialistAgent < RCrewAI::Agent
575
+ def initialize(**options)
576
+ super(options.merge(
577
+ tools: [
578
+ RCrewAI::Tools::WebSearch.new(max_results: 20),
579
+ RCrewAI::Tools::FileWriter.new,
580
+ RCrewAI::Tools::FileReader.new
581
+ ]
582
+ ))
583
+
584
+ @research_depth = options[:research_depth] || 3
585
+ @citation_style = options[:citation_style] || :apa
586
+ end
587
+
588
+ def execute_task(task)
589
+ # Enhanced research methodology
590
+ research_plan = create_research_plan(task)
591
+ sources = gather_sources(research_plan)
592
+ validated_sources = validate_sources(sources)
593
+ synthesis = synthesize_findings(validated_sources)
594
+
595
+ # Format with citations
596
+ format_research_output(synthesis, validated_sources)
597
+ end
598
+
599
+ private
600
+
601
+ def create_research_plan(task)
602
+ {
603
+ primary_queries: extract_key_topics(task.description),
604
+ secondary_queries: generate_related_queries(task.description),
605
+ depth_level: @research_depth,
606
+ quality_threshold: 0.7
607
+ }
608
+ end
609
+
610
+ def gather_sources(plan)
611
+ sources = []
612
+
613
+ # Primary research
614
+ plan[:primary_queries].each do |query|
615
+ results = use_tool('websearch', query: query, max_results: 10)
616
+ sources.concat(parse_search_results(results))
617
+ end
618
+
619
+ # Deep research for important topics
620
+ if @research_depth > 1
621
+ plan[:secondary_queries].each do |query|
622
+ results = use_tool('websearch', query: query, max_results: 5)
623
+ sources.concat(parse_search_results(results))
624
+ end
625
+ end
626
+
627
+ sources
628
+ end
629
+
630
+ def validate_sources(sources)
631
+ sources.select do |source|
632
+ score = calculate_source_credibility(source)
633
+ score > 0.5
634
+ end
635
+ end
636
+
637
+ def format_research_output(content, sources)
638
+ output = "# Research Report\n\n"
639
+ output += content
640
+ output += "\n\n## References\n\n"
641
+
642
+ sources.each_with_index do |source, i|
643
+ output += format_citation(source, i + 1)
644
+ end
645
+
646
+ output
647
+ end
648
+ end
649
+ ```
650
+
651
+ ### Code Review Agent
652
+
653
+ ```ruby
654
+ class CodeReviewAgent < RCrewAI::Agent
655
+ REVIEW_CATEGORIES = [
656
+ :syntax,
657
+ :style,
658
+ :security,
659
+ :performance,
660
+ :maintainability,
661
+ :testing
662
+ ]
663
+
664
+ def initialize(**options)
665
+ super(options.merge(
666
+ role: "Senior Code Reviewer",
667
+ goal: "Ensure code quality and best practices"
668
+ ))
669
+
670
+ @review_strictness = options[:strictness] || :medium
671
+ @languages = options[:languages] || [:ruby, :python, :javascript]
672
+ end
673
+
674
+ def review_code(code, language = :ruby)
675
+ review_results = {}
676
+
677
+ REVIEW_CATEGORIES.each do |category|
678
+ review_results[category] = review_category(code, category, language)
679
+ end
680
+
681
+ generate_review_report(review_results, code)
682
+ end
683
+
684
+ private
685
+
686
+ def review_category(code, category, language)
687
+ case category
688
+ when :syntax
689
+ check_syntax(code, language)
690
+ when :style
691
+ check_style_compliance(code, language)
692
+ when :security
693
+ security_scan(code)
694
+ when :performance
695
+ analyze_performance(code)
696
+ when :maintainability
697
+ assess_maintainability(code)
698
+ when :testing
699
+ check_test_coverage(code)
700
+ end
701
+ end
702
+
703
+ def generate_review_report(results, code)
704
+ report = "## Code Review Report\n\n"
705
+
706
+ # Overall score
707
+ overall_score = calculate_overall_score(results)
708
+ report += "**Overall Score: #{overall_score}/10**\n\n"
709
+
710
+ # Category breakdown
711
+ results.each do |category, findings|
712
+ report += "### #{category.to_s.capitalize}\n"
713
+ report += format_findings(findings)
714
+ report += "\n"
715
+ end
716
+
717
+ # Recommendations
718
+ report += "### Recommendations\n"
719
+ report += generate_recommendations(results)
720
+
721
+ report
722
+ end
723
+ end
724
+ ```
725
+
726
+ ## Agent Communication Patterns
727
+
728
+ Enable sophisticated communication between agents.
729
+
730
+ ### Message Passing Between Agents
731
+
732
+ ```ruby
733
+ class CommunicatingAgent < RCrewAI::Agent
734
+ attr_accessor :message_queue
735
+
736
+ def initialize(**options)
737
+ super
738
+ @message_queue = []
739
+ @subscribers = []
740
+ end
741
+
742
+ def send_message(recipient, message)
743
+ if recipient.respond_to?(:receive_message)
744
+ recipient.receive_message(self, message)
745
+ @logger.info "Sent message to #{recipient.name}: #{message[:type]}"
746
+ end
747
+ end
748
+
749
+ def receive_message(sender, message)
750
+ @message_queue << {
751
+ from: sender.name,
752
+ message: message,
753
+ timestamp: Time.now
754
+ }
755
+
756
+ # Process immediately if high priority
757
+ if message[:priority] == :high
758
+ process_message(message)
759
+ end
760
+ end
761
+
762
+ def broadcast(message)
763
+ @subscribers.each do |subscriber|
764
+ send_message(subscriber, message)
765
+ end
766
+ end
767
+
768
+ def subscribe(agent)
769
+ @subscribers << agent unless @subscribers.include?(agent)
770
+ end
771
+
772
+ private
773
+
774
+ def process_message(message)
775
+ case message[:type]
776
+ when :request_help
777
+ provide_assistance(message)
778
+ when :share_findings
779
+ incorporate_findings(message)
780
+ when :coordinate
781
+ coordinate_action(message)
782
+ end
783
+ end
784
+ end
785
+
786
+ # Create communicating agents
787
+ lead_analyst = CommunicatingAgent.new(
788
+ name: "lead_analyst",
789
+ role: "Lead Data Analyst"
790
+ )
791
+
792
+ junior_analyst = CommunicatingAgent.new(
793
+ name: "junior_analyst",
794
+ role: "Junior Analyst"
795
+ )
796
+
797
+ # Set up communication
798
+ junior_analyst.subscribe(lead_analyst)
799
+
800
+ # Agents can now communicate during execution
801
+ junior_analyst.send_message(lead_analyst, {
802
+ type: :request_help,
803
+ priority: :high,
804
+ content: "Need help with statistical analysis"
805
+ })
806
+ ```
807
+
808
+ ### Collaborative Decision Making
809
+
810
+ ```ruby
811
+ class CollaborativeAgent < RCrewAI::Agent
812
+ def make_collaborative_decision(decision_context, collaborators)
813
+ # Gather input from all collaborators
814
+ inputs = collaborators.map do |agent|
815
+ {
816
+ agent: agent.name,
817
+ opinion: get_agent_opinion(agent, decision_context),
818
+ confidence: get_confidence_level(agent, decision_context)
819
+ }
820
+ end
821
+
822
+ # Synthesize decision
823
+ synthesize_collaborative_decision(inputs, decision_context)
824
+ end
825
+
826
+ private
827
+
828
+ def get_agent_opinion(agent, context)
829
+ # Request opinion from agent
830
+ prompt = "Given context: #{context}, what is your recommendation?"
831
+
832
+ # Simulate agent providing opinion based on expertise
833
+ if agent.respond_to?(:provide_opinion)
834
+ agent.provide_opinion(context)
835
+ else
836
+ "No opinion"
837
+ end
838
+ end
839
+
840
+ def synthesize_collaborative_decision(inputs, context)
841
+ # Weight opinions by confidence
842
+ weighted_opinions = inputs.map do |input|
843
+ {
844
+ opinion: input[:opinion],
845
+ weight: input[:confidence]
846
+ }
847
+ end
848
+
849
+ # Find consensus or synthesize
850
+ if unanimous?(weighted_opinions)
851
+ weighted_opinions.first[:opinion]
852
+ else
853
+ create_consensus(weighted_opinions, context)
854
+ end
855
+ end
856
+ end
857
+ ```
858
+
859
+ ## Error Handling and Recovery
860
+
861
+ Advanced error handling strategies for robust agent operation.
862
+
863
+ ### Graceful Degradation
864
+
865
+ ```ruby
866
+ class ResilientAgent < RCrewAI::Agent
867
+ def execute_task(task)
868
+ attempt_with_fallbacks(task)
869
+ end
870
+
871
+ private
872
+
873
+ def attempt_with_fallbacks(task)
874
+ strategies = [
875
+ -> { execute_with_all_tools(task) },
876
+ -> { execute_with_essential_tools(task) },
877
+ -> { execute_with_no_tools(task) },
878
+ -> { provide_best_effort_response(task) }
879
+ ]
880
+
881
+ strategies.each_with_index do |strategy, i|
882
+ begin
883
+ @logger.info "Attempting strategy #{i + 1}"
884
+ return strategy.call
885
+ rescue => e
886
+ @logger.warn "Strategy #{i + 1} failed: #{e.message}"
887
+ next
888
+ end
889
+ end
890
+
891
+ "Unable to complete task after all strategies"
892
+ end
893
+
894
+ def execute_with_essential_tools(task)
895
+ # Disable non-essential tools
896
+ essential_tools = tools.select { |t| t.essential? }
897
+ with_tools(essential_tools) do
898
+ super(task)
899
+ end
900
+ end
901
+
902
+ def execute_with_no_tools(task)
903
+ # Pure reasoning without tools
904
+ with_tools([]) do
905
+ super(task)
906
+ end
907
+ end
908
+ end
909
+ ```
910
+
911
+ ### Self-Healing Agents
912
+
913
+ ```ruby
914
+ class SelfHealingAgent < RCrewAI::Agent
915
+ def initialize(**options)
916
+ super
917
+ @health_monitor = HealthMonitor.new(self)
918
+ @recovery_strategies = {}
919
+ end
920
+
921
+ def execute_task(task)
922
+ @health_monitor.check_health
923
+
924
+ begin
925
+ result = super
926
+ @health_monitor.record_success
927
+ result
928
+ rescue => e
929
+ @health_monitor.record_failure(e)
930
+
931
+ if @health_monitor.needs_healing?
932
+ perform_self_healing
933
+ retry
934
+ else
935
+ raise
936
+ end
937
+ end
938
+ end
939
+
940
+ private
941
+
942
+ def perform_self_healing
943
+ @logger.info "Performing self-healing procedures"
944
+
945
+ # Clear corrupted memory
946
+ if @health_monitor.memory_corrupted?
947
+ @memory.clear_corrupted_entries
948
+ end
949
+
950
+ # Reset tool connections
951
+ if @health_monitor.tools_failing?
952
+ reset_tool_connections
953
+ end
954
+
955
+ # Adjust parameters
956
+ if @health_monitor.performance_degraded?
957
+ optimize_parameters
958
+ end
959
+
960
+ @health_monitor.reset
961
+ end
962
+
963
+ def optimize_parameters
964
+ # Dynamically adjust agent parameters
965
+ self.max_iterations = [max_iterations - 2, 3].max
966
+ self.max_execution_time = max_execution_time * 1.5
967
+
968
+ @logger.info "Adjusted parameters for better performance"
969
+ end
970
+ end
971
+ ```
972
+
973
+ ## Best Practices
974
+
975
+ ### 1. **Agent Design Principles**
976
+ - Single Responsibility: Each agent should have one clear role
977
+ - Clear Goals: Define specific, measurable goals
978
+ - Rich Backstories: Provide context that guides behavior
979
+ - Appropriate Tools: Equip agents with necessary tools only
980
+
981
+ ### 2. **Performance Guidelines**
982
+ - Set reasonable iteration limits (5-10 for most tasks)
983
+ - Use timeouts to prevent hanging (60-300 seconds typical)
984
+ - Cache expensive operations when possible
985
+ - Use async execution for independent tasks
986
+
987
+ ### 3. **Memory Management**
988
+ - Implement memory cleanup for long-running agents
989
+ - Persist valuable memory across sessions
990
+ - Limit memory size to prevent bloat
991
+ - Use memory statistics for optimization
992
+
993
+ ### 4. **Delegation Best Practices**
994
+ - Managers should have broad understanding, not deep expertise
995
+ - Delegate based on agent strengths and availability
996
+ - Provide clear context in delegations
997
+ - Monitor delegation success rates
998
+
999
+ ### 5. **Error Handling**
1000
+ - Implement graceful degradation strategies
1001
+ - Log errors with context for debugging
1002
+ - Use retry logic with exponential backoff
1003
+ - Provide fallback responses
1004
+
1005
+ ## Next Steps
1006
+
1007
+ Now that you understand advanced agent configuration:
1008
+
1009
+ 1. Try the [Custom Tools Development]({{ site.baseurl }}/tutorials/custom-tools) tutorial
1010
+ 2. Learn about [Working with Multiple Crews]({{ site.baseurl }}/tutorials/multiple-crews)
1011
+ 3. Explore [Production Deployment]({{ site.baseurl }}/tutorials/deployment) strategies
1012
+ 4. Review [API Documentation]({{ site.baseurl }}/api/) for detailed reference
1013
+
1014
+ Advanced agents are the key to building sophisticated AI systems that can handle complex, real-world tasks with reliability and efficiency.