swarms 7.9.7__py3-none-any.whl → 7.9.8__py3-none-any.whl

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.
@@ -1,22 +1,71 @@
1
- from collections import Counter
1
+ """
2
+ Self-Consistency Agent Implementation
3
+
4
+ This module implements the SelfConsistencyAgent, a specialized agent that leverages the
5
+ self-consistency technique to improve reasoning reliability and accuracy. The agent generates
6
+ multiple independent responses to a given task and aggregates them into a single, consistent
7
+ final answer using majority voting and sophisticated aggregation techniques.
8
+
9
+ The self-consistency approach is based on the research paper:
10
+ "Self-Consistency Improves Chain of Thought Reasoning in Language Models"
11
+ by Wang et al. (2022) - https://arxiv.org/abs/2203.07870
12
+
13
+ Key Features:
14
+ - Concurrent generation of multiple independent responses
15
+ - Majority voting aggregation with detailed analysis
16
+ - Evaluation mode for answer validation
17
+ - Configurable output formats
18
+ - Thread-safe execution
19
+
20
+ Author: Swarms Team
21
+ License: MIT
22
+ """
23
+
2
24
  from concurrent.futures import ThreadPoolExecutor, as_completed
3
- from typing import List
25
+ from typing import List, Optional, Union, Dict, Any
4
26
 
5
27
  from loguru import logger
6
28
 
7
29
  from swarms.structs.agent import Agent
8
30
  from swarms.structs.conversation import Conversation
9
- from swarms.structs.malt import majority_voting_prompt
10
31
  from swarms.utils.output_types import OutputType
11
32
  from swarms.utils.any_to_str import any_to_str
12
33
  from swarms.utils.history_output_formatter import (
13
34
  history_output_formatter,
14
35
  )
15
36
 
37
+ # System prompt for the reasoning agent that generates individual responses
16
38
  CONSISTENCY_SYSTEM_PROMPT = """
17
39
  You are a reasoning agent designed for complex problem-solving and decision-making. Your objective is to provide clear and reliable responses through structured reasoning. Begin by thoroughly understanding the problem, rephrasing it for clarity, and identifying key components. Develop a logical plan that breaks the problem into manageable steps, detailing your approach and any assumptions made. Validate your information with reliable sources and assess the accuracy of your calculations. Explore multiple solutions, weighing their pros and cons, and maintain transparency by documenting your reasoning process, uncertainties, and biases. Summarize your findings in a concise final answer that reflects your thorough analysis, ensuring it is well-organized and accessible. Adapt your reasoning to the context of the problem, integrating new information as needed, and implement error-handling strategies to address any issues that arise. Finally, reflect on your reasoning process to identify areas for improvement and ensure consistency across all reasoning paths.
18
40
  """
19
41
 
42
+ # Detailed prompt for the majority voting aggregation agent
43
+ majority_voting_prompt = """
44
+ Engage in a comprehensive and exhaustive majority voting analysis of the following conversation, ensuring a deep and thoughtful examination of the responses provided by each agent. This analysis should not only summarize the responses but also critically engage with the content, context, and implications of each agent's input.
45
+
46
+ Please adhere to the following detailed guidelines:
47
+
48
+ 1. **Identification of Dominant Responses:**
49
+ - Identify the most prevalent answer or recommendation across all agents. Provide a thorough rationale for its dominance, including an exploration of the factors that may have contributed to its acceptance among the agents. Discuss the context in which this consensus emerged and any relevant historical or theoretical frameworks that support this conclusion.
50
+
51
+ 2. **Exploration of Disparities:**
52
+ - Delve into any significant disparities or contrasting viewpoints between agents. Explore the underlying reasons for these differences, considering aspects such as differing methodologies, assumptions, or interpretations of the task at hand. Analyze how these contrasting perspectives may reflect broader debates within the field and what implications they hold for the overall understanding of the topic.
53
+
54
+ 3. **Consensus and Disagreement Analysis:**
55
+ - Highlight key areas of consensus and disagreement among the agents. Discuss the implications of these findings on the overall argument, including how consensus can strengthen certain claims while disagreement may indicate areas of uncertainty or contention. Provide examples from the conversation to illustrate these points and consider how they might influence future discussions or research directions.
56
+
57
+ 4. **Critical Evaluation of Majority Opinion:**
58
+ - Critically evaluate the strength of the majority opinion, considering factors such as the reasoning behind it and its mathematical validity if applicable. Assess whether the majority opinion is well-supported by evidence and logical reasoning, and discuss any potential weaknesses or oversights that may undermine its credibility.
59
+
60
+ 5. **Insights from Minority Viewpoints:**
61
+ - Note any unique insights from minority viewpoints, assessing their potential contributions to a more nuanced understanding of the topic. Discuss how these minority perspectives can enrich the conversation and provide alternative angles that may have been overlooked by the majority. Consider the value of dissent in academic discourse and how it can lead to more robust conclusions.
62
+
63
+ 6. **Synthesis of Recommendations:**
64
+ - Provide a final synthesized recommendation based on the majority consensus, ensuring that it reflects a thorough consideration of all perspectives and is grounded in sound reasoning. This recommendation should not only summarize the majority view but also integrate insights from minority opinions, creating a comprehensive and balanced conclusion that acknowledges the complexity of the discussion.
65
+
66
+ Throughout your analysis, focus on uncovering clear patterns while being attentive to the subtleties and complexities inherent in the responses. Pay particular attention to the nuances of mathematical contexts where algorithmic thinking may be required, ensuring that your examination is both rigorous and accessible to a diverse audience.
67
+ """
68
+
20
69
 
21
70
  def aggregation_agent(
22
71
  responses: List[str],
@@ -24,7 +73,27 @@ def aggregation_agent(
24
73
  model_name: str = "gpt-4o-mini",
25
74
  ) -> str:
26
75
  """
27
- Aggregates a list of responses into a single final answer.
76
+ Aggregates a list of responses into a single final answer using an AI-powered aggregation agent.
77
+
78
+ This function creates a specialized agent that analyzes multiple responses and synthesizes
79
+ them into a coherent final answer. The aggregation process considers consensus, disagreements,
80
+ and minority viewpoints to produce a well-reasoned conclusion.
81
+
82
+ Args:
83
+ responses (List[str]): List of responses to be aggregated
84
+ prompt (str, optional): Custom prompt for the aggregation agent.
85
+ Defaults to the majority_voting_prompt.
86
+ model_name (str, optional): Model to use for aggregation.
87
+ Defaults to "gpt-4o-mini".
88
+
89
+ Returns:
90
+ str: The aggregated final answer
91
+
92
+ Example:
93
+ >>> responses = ["Answer A", "Answer B", "Answer A"]
94
+ >>> final_answer = aggregation_agent(responses)
95
+ >>> print(final_answer)
96
+ "Based on the majority consensus..."
28
97
  """
29
98
  task = any_to_str(responses)
30
99
 
@@ -41,69 +110,174 @@ def aggregation_agent(
41
110
  return final_answer
42
111
 
43
112
 
44
- class SelfConsistencyAgent(Agent):
113
+ class SelfConsistencyAgent:
114
+ """
115
+ A specialized agent that implements self-consistency for improved reasoning reliability.
116
+
117
+ The SelfConsistencyAgent generates multiple independent responses to a given task and
118
+ aggregates them into a single, consistent final answer. This approach is based on the
119
+ research paper "Self-Consistency Improves Chain of Thought Reasoning in Language Models"
120
+ by Wang et al. (2022).
121
+
122
+ Key Features:
123
+ - Concurrent generation of multiple independent responses
124
+ - Majority voting aggregation with detailed analysis
125
+ - Evaluation mode for answer validation
126
+ - Configurable output formats
127
+ - Thread-safe execution
128
+
129
+ The self-consistency technique works by:
130
+ 1. Generating multiple independent reasoning paths for the same problem
131
+ 2. Analyzing the consistency and agreement among these paths
132
+ 3. Aggregating the results using majority voting or consensus building
133
+ 4. Producing a final answer that reflects the most reliable consensus
134
+
135
+ This approach helps mitigate issues like:
136
+ - Random errors in individual reasoning paths
137
+ - Biases in single reasoning approaches
138
+ - Inconsistencies in complex problem-solving
139
+
140
+ Reference:
141
+ Wang, Y., Dong, W., Han, J., & Wang, W. (2022). Self-Consistency Improves Chain of
142
+ Thought Reasoning in Language Models. arXiv preprint arXiv:2203.07870.
143
+ https://arxiv.org/abs/2203.07870
144
+
145
+ Example:
146
+ >>> agent = SelfConsistencyAgent(
147
+ ... name="Math-Reasoning-Agent",
148
+ ... model_name="gpt-4o-mini",
149
+ ... num_samples=5,
150
+ ... max_loops=1
151
+ ... )
152
+ >>> result = agent.run("What is the 40th prime number?")
153
+ >>> print(result)
154
+ """
155
+
45
156
  def __init__(
46
157
  self,
47
158
  name: str = "Self-Consistency-Agent",
48
159
  description: str = "An agent that uses self consistency to generate a final answer.",
160
+ model_name: str = "gpt-4o-mini",
49
161
  system_prompt: str = CONSISTENCY_SYSTEM_PROMPT,
50
162
  num_samples: int = 5,
51
163
  max_loops: int = 1,
52
- majority_voting_prompt: str = None,
164
+ majority_voting_prompt: Optional[
165
+ str
166
+ ] = majority_voting_prompt,
53
167
  eval: bool = False,
54
168
  output_type: OutputType = "dict",
169
+ random_models_on: bool = False,
170
+ *args,
55
171
  **kwargs,
56
172
  ):
57
173
  """
58
- Initializes the SelfConsistencyAgent.
174
+ Initialize the SelfConsistencyAgent.
59
175
 
60
176
  Args:
61
- num_samples (int): Number of independent responses to sample.
62
- **kwargs: Other keyword arguments passed to the base Agent.
177
+ name (str, optional): Name of the agent. Defaults to "Self-Consistency-Agent".
178
+ description (str, optional): Description of the agent's purpose.
179
+ Defaults to "An agent that uses self consistency to generate a final answer.".
180
+ model_name (str, optional): The underlying language model to use.
181
+ Defaults to "gpt-4o-mini".
182
+ system_prompt (str, optional): System prompt for the reasoning agent.
183
+ Defaults to CONSISTENCY_SYSTEM_PROMPT.
184
+ num_samples (int, optional): Number of independent responses to generate.
185
+ Defaults to 5.
186
+ max_loops (int, optional): Maximum number of reasoning loops per sample.
187
+ Defaults to 1.
188
+ majority_voting_prompt (Optional[str], optional): Custom prompt for majority voting.
189
+ Defaults to None.
190
+ eval (bool, optional): Enable evaluation mode for answer validation.
191
+ Defaults to False.
192
+ output_type (OutputType, optional): Format of the output.
193
+ Defaults to "dict".
194
+ random_models_on (bool, optional): Enable random model selection for diversity.
195
+ Defaults to False.
196
+ **kwargs: Additional keyword arguments passed to the base Agent class.
197
+
198
+ Note:
199
+ The num_samples parameter determines how many independent reasoning paths
200
+ will be generated. Higher values generally lead to more reliable results
201
+ but increase computational cost and time.
63
202
  """
64
- super().__init__(
65
- name=name,
66
- description=description,
67
- **kwargs,
68
- )
203
+ self.name = name
204
+ self.description = description
205
+ self.model_name = model_name
69
206
  self.num_samples = num_samples
70
- self.conversation = Conversation()
71
207
  self.max_loops = max_loops
72
208
  self.majority_voting_prompt = majority_voting_prompt
73
209
  self.eval = eval
74
210
  self.output_type = output_type
75
211
  self.system_prompt = system_prompt
212
+ self.random_models_on = random_models_on
213
+ self.conversation = Conversation()
214
+ self.args = args
215
+ self.kwargs = kwargs
76
216
 
77
217
  def run(
78
- self, task: str, answer: str = None, *args, **kwargs
79
- ) -> str:
218
+ self,
219
+ task: str,
220
+ img: Optional[str] = None,
221
+ answer: Optional[str] = None,
222
+ *args,
223
+ **kwargs,
224
+ ) -> Union[str, Dict[str, Any]]:
80
225
  """
81
- Generates multiple responses for the given prompt and aggregates them concurrently.
226
+ Generate multiple responses for the given task and aggregate them concurrently.
227
+
228
+ This method implements the core self-consistency algorithm:
229
+ 1. Generates multiple independent responses using concurrent execution
230
+ 2. Optionally validates responses against a known answer (if eval=True)
231
+ 3. Aggregates responses using an AI-powered aggregation agent
232
+ 4. Returns the final result in the specified output format
82
233
 
83
234
  Args:
84
- task (str): The input prompt.
235
+ task (str): The input prompt or task to be solved
236
+ answer (Optional[str], optional): Expected answer for validation (if eval=True).
237
+ Defaults to None.
238
+ *args: Additional positional arguments passed to the base agent's run method
239
+ **kwargs: Additional keyword arguments passed to the base agent's run method
85
240
 
86
241
  Returns:
87
- str: The aggregated final answer.
242
+ Union[str, Dict[str, Any]]: The aggregated final answer in the specified format
243
+
244
+ Raises:
245
+ RuntimeError: If evaluation mode is enabled and the expected answer is not found
246
+ in any of the generated responses
247
+
248
+ Example:
249
+ >>> agent = SelfConsistencyAgent(num_samples=3)
250
+ >>> result = agent.run("What is 2 + 2?")
251
+ >>> print(result)
252
+
253
+ >>> # With evaluation mode
254
+ >>> result = agent.run("What is 2 + 2?", answer="4", eval=True)
88
255
  """
89
256
  responses = []
90
- logger.info(
91
- f"Generating {self.num_samples} responses concurrently..."
92
- )
93
257
 
94
258
  self.conversation.add(role="User", content=task)
95
259
 
260
+ # Generate multiple independent responses concurrently
261
+ reasoning_agent = self._create_reasoning_agent()
262
+
96
263
  with ThreadPoolExecutor() as executor:
97
264
  futures = {
98
- executor.submit(super().run, task, *args, **kwargs): i
265
+ executor.submit(
266
+ reasoning_agent.run,
267
+ task=task,
268
+ img=img,
269
+ *args,
270
+ **kwargs,
271
+ ): i
99
272
  for i in range(self.num_samples)
100
273
  }
101
274
  for future in as_completed(futures):
102
275
  response = future.result()
103
276
  responses.append(response)
104
277
 
105
- self.conversation.add(role=self.agent_name, content=responses)
278
+ self.conversation.add(role=self.name, content=responses)
106
279
 
280
+ # Optional evaluation against known answer
107
281
  if self.eval:
108
282
  if answer is not None:
109
283
  correct = self.check_responses_for_answer(
@@ -116,9 +290,7 @@ class SelfConsistencyAgent(Agent):
116
290
  )
117
291
  return None
118
292
 
119
- # Aggregation agent
120
- # final_answer = self.aggregation_agent(responses)
121
-
293
+ # Aggregate responses using AI-powered aggregation
122
294
  final_answer = aggregation_agent(responses)
123
295
 
124
296
  self.conversation.add(
@@ -129,39 +301,46 @@ class SelfConsistencyAgent(Agent):
129
301
  self.conversation, self.output_type
130
302
  )
131
303
 
132
- def aggregate(self, responses: List[str]) -> str:
304
+ def _create_reasoning_agent(self) -> Agent:
133
305
  """
134
- Aggregates a list of responses into a single final answer.
135
-
136
- Here we use a simple majority vote (most common answer) as an example. Depending on
137
- the task, you might need a more sophisticated aggregation (e.g., weighting, consensus reasoning, etc.).
138
-
139
- Args:
140
- responses (list of str): The list of responses.
306
+ Create a reasoning agent instance for generating individual responses.
141
307
 
142
308
  Returns:
143
- str: The aggregated answer.
309
+ Agent: A configured Agent instance for reasoning tasks
144
310
  """
145
- # Count the frequency of each response.
146
- counts = Counter(responses)
147
- most_common, freq = counts.most_common(1)[0]
148
- logger.info(
149
- f"Aggregation complete. Most common response (appeared {freq} times):"
311
+ return Agent(
312
+ agent_name=self.name,
313
+ description=self.description,
314
+ model_name=self.model_name,
315
+ system_prompt=self.system_prompt,
316
+ max_loops=self.max_loops,
317
+ random_models_on=self.random_models_on,
318
+ output_type="str-all-except-first",
319
+ **self.kwargs,
150
320
  )
151
- return most_common
152
321
 
153
322
  def check_responses_for_answer(
154
323
  self, responses: List[str], answer: str
155
324
  ) -> bool:
156
325
  """
157
- Checks if the specified answer is present in any of the provided responses.
326
+ Check if the specified answer is present in any of the provided responses.
327
+
328
+ This method performs a simple string matching to determine if the expected
329
+ answer appears in any of the generated responses. It's useful for validation
330
+ and evaluation purposes.
158
331
 
159
332
  Args:
160
- responses (List[str]): A list of responses to check.
161
- answer (str): The answer to look for in the responses.
333
+ responses (List[str]): List of responses to check
334
+ answer (str): The answer to look for in the responses
162
335
 
163
336
  Returns:
164
- bool: True if the answer is found in any response, False otherwise.
337
+ bool: True if the answer is found in any response, False otherwise
338
+
339
+ Example:
340
+ >>> agent = SelfConsistencyAgent()
341
+ >>> responses = ["The answer is 42", "I think it's 42", "Not sure"]
342
+ >>> found = agent.check_responses_for_answer(responses, "42")
343
+ >>> print(found) # True
165
344
  """
166
345
  for response in responses:
167
346
  if answer in response:
@@ -181,27 +360,30 @@ class SelfConsistencyAgent(Agent):
181
360
 
182
361
  def batched_run(
183
362
  self, tasks: List[str], *args, **kwargs
184
- ) -> List[str]:
363
+ ) -> List[Union[str, Dict[str, Any]]]:
185
364
  """
186
- Runs the agent in a batched manner.
365
+ Run the agent on multiple tasks in batch.
366
+
367
+ This method processes multiple tasks sequentially, applying the self-consistency
368
+ approach to each task independently. It's useful for processing large datasets
369
+ or multiple related problems.
370
+
371
+ Args:
372
+ tasks (List[str]): List of tasks to be processed
373
+ *args: Additional positional arguments passed to the run method
374
+ **kwargs: Additional keyword arguments passed to the run method
375
+
376
+ Returns:
377
+ List[Union[str, Dict[str, Any]]]: List of results for each task
378
+
379
+ Example:
380
+ >>> agent = SelfConsistencyAgent()
381
+ >>> tasks = ["What is 2+2?", "What is 3+3?", "What is 4+4?"]
382
+ >>> results = agent.batched_run(tasks)
383
+ >>> print(len(results)) # 3
187
384
  """
188
385
  responses = []
189
386
  for task in tasks:
190
387
  response = self.run(task, *args, **kwargs)
191
388
  responses.append(response)
192
389
  return responses
193
-
194
-
195
- # # Example usage:
196
- # if __name__ == "__main__":
197
- # agent = SelfConsistencyAgent(
198
- # agent_name="Reasoning-Agent",
199
- # model_name="gpt-4o-mini",
200
- # max_loops=1,
201
- # num_samples=5, # Number of samples for self consistency
202
- # )
203
-
204
- # prompt = "What is the 40th prime number?"
205
- # final_answer = agent.run(prompt)
206
- # print("\nFinal aggregated answer:")
207
- # print(final_answer)