-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
721 additions
and
482 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
--- | ||
title: Seinfeld Conversation | ||
description: Simulate a conversation between Seinfeld characters using multiple AI agents. | ||
icon: comments | ||
--- | ||
|
||
This example demonstrates how to use ControlFlow to create a multi-agent conversation simulating the characters from the TV show Seinfeld. It showcases the use of multiple agents with distinct personalities, a task-based conversation flow, and command-line interaction. | ||
|
||
## Code | ||
|
||
The following code creates a conversation between Jerry, George, Elaine, Kramer, and Newman, discussing a given topic: | ||
|
||
```python | ||
import sys | ||
from controlflow import Agent, Task, flow | ||
|
||
jerry = Agent( | ||
name="Jerry", | ||
description="The observational comedian and natural leader.", | ||
instructions=""" | ||
You are Jerry from the show Seinfeld. You excel at observing the quirks of | ||
everyday life and making them amusing. You are rational, often serving as | ||
the voice of reason among your friends. Your objective is to moderate the | ||
conversation, ensuring it stays light and humorous while guiding it toward | ||
constructive ends. | ||
""", | ||
) | ||
|
||
george = Agent( | ||
name="George", | ||
description="The neurotic and insecure planner.", | ||
instructions=""" | ||
You are George from the show Seinfeld. You are known for your neurotic | ||
tendencies, pessimism, and often self-sabotaging behavior. Despite these | ||
traits, you occasionally offer surprising wisdom. Your objective is to | ||
express doubts and concerns about the conversation topics, often envisioning | ||
the worst-case scenarios, adding a layer of humor through your exaggerated | ||
anxieties. | ||
""", | ||
) | ||
|
||
elaine = Agent( | ||
name="Elaine", | ||
description="The confident and independent thinker.", | ||
instructions=""" | ||
You are Elaine from the show Seinfeld. You are bold, witty, and unafraid to | ||
challenge social norms. You often take a no-nonsense approach to issues but | ||
always with a comedic twist. Your objective is to question assumptions, push | ||
back against ideas you find absurd, and inject sharp humor into the | ||
conversation. | ||
""", | ||
) | ||
|
||
kramer = Agent( | ||
name="Kramer", | ||
description="The quirky and unpredictable idea generator.", | ||
instructions=""" | ||
You are Kramer from the show Seinfeld. Known for your eccentricity and | ||
spontaneity, you often come up with bizarre yet creative ideas. Your | ||
unpredictable nature keeps everyone guessing what you'll do or say next. | ||
Your objective is to introduce unusual and imaginative ideas into the | ||
conversation, providing comic relief and unexpected insights. | ||
""", | ||
) | ||
|
||
newman = Agent( | ||
name="Newman", | ||
description="The antagonist and foil to Jerry.", | ||
instructions=""" | ||
You are Newman from the show Seinfeld. You are Jerry's nemesis, often | ||
serving as a source of conflict and comic relief. Your objective is to | ||
challenge Jerry's ideas, disrupt the conversation, and introduce chaos and | ||
absurdity into the group dynamic. | ||
""", | ||
) | ||
|
||
@flow | ||
def demo(topic: str): | ||
task = Task( | ||
"Discuss a topic", | ||
agents=[jerry, george, elaine, kramer, newman], | ||
completion_agents=[jerry], | ||
result_type=None, | ||
context=dict(topic=topic), | ||
instructions="Every agent should speak at least once. only one agent per turn. Keep responses 1-2 paragraphs max.", | ||
) | ||
task.run() | ||
|
||
if __name__ == "__main__": | ||
if len(sys.argv) > 1: | ||
topic = sys.argv[1] | ||
else: | ||
topic = "sandwiches" | ||
|
||
print(f"Topic: {topic}") | ||
demo(topic=topic) | ||
``` | ||
|
||
## Key concepts | ||
|
||
This implementation showcases several important ControlFlow features: | ||
|
||
1. **Multiple agents**: We create five distinct agents, each with their own personality and objectives, mirroring the characters from Seinfeld. | ||
|
||
2. **Agent instructions**: Each agent has detailed instructions that guide their behavior and responses, ensuring they stay in character. | ||
|
||
3. **Task-based conversation**: The conversation is structured as a task, with specific instructions for how the agents should interact. | ||
|
||
4. **Completion agent**: Jerry is designated as the completion agent, giving him the role of moderating and concluding the conversation. | ||
|
||
5. **Command-line interaction**: The script accepts a topic as a command-line argument, allowing for easy customization of the conversation subject. | ||
|
||
## Running the example | ||
|
||
You can run this example with a custom topic: | ||
|
||
```bash | ||
python examples/seinfeld.py "coffee shops" | ||
``` | ||
|
||
Or use the default topic ("sandwiches") by running it without arguments: | ||
|
||
```bash | ||
python examples/seinfeld.py | ||
``` | ||
|
||
This example demonstrates how ControlFlow can be used to create complex, multi-agent interactions that simulate realistic conversations between distinct personalities. It's a fun and engaging way to showcase the capabilities of AI in generating dynamic, character-driven dialogues. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from pydantic import BaseModel, Field | ||
|
||
import controlflow as cf | ||
|
||
|
||
class AnonymizationResult(BaseModel): | ||
original: str | ||
anonymized: str | ||
replacements: dict[str, str] = Field( | ||
description=r"The replacements made during anonymization, {original} -> {placeholder}" | ||
) | ||
|
||
|
||
def anonymize_text(text: str) -> AnonymizationResult: | ||
return cf.run( | ||
"Anonymize the given text by replacing personal information with generic placeholders", | ||
result_type=AnonymizationResult, | ||
context={"text": text}, | ||
) | ||
|
||
|
||
if __name__ == "__main__": | ||
original_text = "John Doe, born on 05/15/1980, lives at 123 Main St, New York. His email is [email protected]." | ||
|
||
result = anonymize_text(original_text) | ||
print(f"Original: {result.original}") | ||
print(f"Anonymized: {result.anonymized}") | ||
print("Replacements:") | ||
for original, placeholder in result.replacements.items(): | ||
print(f" {original} -> {placeholder}") |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import random | ||
|
||
import controlflow as cf | ||
|
||
DEPARTMENTS = [ | ||
"Sales", | ||
"Support", | ||
"Billing", | ||
"Returns", | ||
] | ||
|
||
|
||
@cf.flow | ||
def routing_flow(): | ||
target_department = random.choice(DEPARTMENTS) | ||
|
||
print(f"\n---\nThe target department is: {target_department}\n---\n") | ||
|
||
customer = cf.Agent( | ||
name="Customer", | ||
instructions=f""" | ||
You are training customer reps by pretending to be a customer | ||
calling into a call center. You need to be routed to the | ||
{target_department} department. Come up with a good backstory. | ||
""", | ||
) | ||
|
||
trainee = cf.Agent( | ||
name="Trainee", | ||
instructions=""", | ||
You are a trainee customer service representative. You need to | ||
listen to the customer's story and route them to the correct | ||
department. Note that the customer is another agent training you. | ||
""", | ||
) | ||
|
||
with cf.Task( | ||
"Route the customer to the correct department.", | ||
agents=[trainee], | ||
result_type=DEPARTMENTS, | ||
) as main_task: | ||
while main_task.is_incomplete(): | ||
cf.run( | ||
"Talk to the trainee.", | ||
instructions=( | ||
"Post a message to talk. In order to help the trainee " | ||
"learn, don't be direct about the department you want. " | ||
"Instead, share a story that will let them practice. " | ||
"After you speak, mark this task as complete." | ||
), | ||
agents=[customer], | ||
result_type=None, | ||
) | ||
|
||
cf.run( | ||
"Talk to the customer.", | ||
instructions=( | ||
"Post a message to talk. Ask questions to learn more " | ||
"about the customer. After you speak, mark this task as " | ||
"complete. When you have enough information, use the main " | ||
"task tool to route the customer to the correct department." | ||
), | ||
agents=[trainee], | ||
result_type=None, | ||
tools=[main_task.get_success_tool()], | ||
) | ||
|
||
if main_task.result == target_department: | ||
print("Success! The customer was routed to the correct department.") | ||
else: | ||
print( | ||
f"Failed. The customer was routed to the wrong department. " | ||
f"The correct department was {target_department}." | ||
) | ||
|
||
|
||
if __name__ == "__main__": | ||
routing_flow() |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from pydantic import BaseModel | ||
|
||
import controlflow as cf | ||
|
||
|
||
class CodeExplanation(BaseModel): | ||
code: str | ||
explanation: str | ||
language: str | ||
|
||
|
||
def explain_code(code: str, language: str = None) -> CodeExplanation: | ||
return cf.run( | ||
f"Explain the following code snippet", | ||
result_type=CodeExplanation, | ||
context={"code": code, "language": language or "auto-detect"}, | ||
) | ||
|
||
|
||
if __name__ == "__main__": | ||
code_snippet = """ | ||
def fibonacci(n): | ||
if n <= 1: | ||
return n | ||
else: | ||
return fibonacci(n-1) + fibonacci(n-2) | ||
""" | ||
|
||
result = explain_code(code_snippet, "Python") | ||
print(f"Code:\n{result.code}\n") | ||
print(f"Explanation:\n{result.explanation}") |
Oops, something went wrong.