Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKUse casesQA and Chat over DocumentsAnalyzing structured dataExtractionInteracting with APIsChatbotsSummarizationCode UnderstandingUse LangChain, GPT and Activeloop's Deep Lake to work with code baseAnalysis of Twitter the-algorithm source code with LangChain, GPT4 and Activeloop's Deep LakeAgent simulationsAgentsAutonomous (long-running) agentsMulti-modalUse casesCode UnderstandingOn this pageCode UnderstandingOverviewLangChain is a useful tool designed to parse GitHub code repositories. By leveraging VectorStores, Conversational RetrieverChain, and GPT-4, it can answer questions in the context of an entire GitHub repository or generate new code. This documentation page outlines the essential components of the system and guides using LangChain for better code comprehension, contextual question answering, and code generation in GitHub repositories.Conversational Retriever Chainâ€‹Conversational RetrieverChain is a retrieval-focused system that interacts with the data stored in a VectorStore. Utilizing advanced techniques, like context-aware filtering and ranking, it retrieves the most relevant code snippets and information for a given user query. Conversational RetrieverChain is engineered to deliver high-quality, pertinent results while considering conversation history and context.LangChain Workflow for Code Understanding and GenerationIndex the code base: Clone the target repository, load all files within, chunk the files, and execute the indexing process. Optionally, you can skip this step and use an already indexed dataset.Embedding and Code Store: Code snippets are embedded using a code-aware embedding model and stored in a VectorStore.


Query Understanding: GPT-4 processes user queries, grasping the context and extracting relevant details.Construct the Retriever: Conversational RetrieverChain searches the VectorStore to identify the most relevant code snippets for a given query.Build the Conversational Chain: Customize the retriever settings and define any user-defined filters as needed. Ask questions: Define a list of questions to ask about the codebase, and then use the ConversationalRetrievalChain to generate context-aware answers. The LLM (GPT-4) generates comprehensive, context-aware answers based on retrieved code snippets and conversation history.The full tutorial is available below.Twitter the-algorithm codebase analysis with Deep Lake: A notebook walking through how to parse github source code and run queries conversation.LangChain codebase analysis with Deep Lake: A notebook walking through how to analyze and do question answering over THIS code base.PreviousSummarizationNextUse LangChain, GPT and Activeloop's Deep Lake to work with code baseConversational Retriever ChainCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Analysis of Twitter the-algorithm source code with LangChain, GPT4 and Activeloop's Deep Lake | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKUse casesQA and Chat over DocumentsAnalyzing structured dataExtractionInteracting with APIsChatbotsSummarizationCode UnderstandingUse LangChain, GPT and Activeloop's Deep Lake to work with code baseAnalysis of Twitter the-algorithm source code with LangChain, GPT4 and Activeloop's Deep LakeAgent simulationsAgentsAutonomous (long-running) agentsMulti-modalUse casesCode UnderstandingAnalysis of Twitter the-algorithm source code with LangChain, GPT4 and Activeloop's Deep LakeOn this pageAnalysis of Twitter the-algorithm source code with LangChain, GPT4 and Activeloop's Deep LakeIn this tutorial, we are going to use Langchain + Activeloop's Deep Lake with GPT4 to analyze the code base of the twitter algorithm. python3 -m pip install --upgrade langchain 'deeplake[enterprise]' openai tiktokenDefine OpenAI embeddings, Deep Lake multi-modal vector store api and authenticate. For full documentation of Deep Lake please follow docs and API reference.Authenticate into Deep Lake if you want to create your own dataset and publish it. You can get an API key from the platformimport osimport getpassfrom langchain.embeddings.openai import OpenAIEmbeddingsfrom langchain.vectorstores import DeepLakeos.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")activeloop_token = getpass.getpass("Activeloop Token:")os.environ["ACTIVELOOP_TOKEN"] = activeloop_tokenembeddings = OpenAIEmbeddings(disallowed_special=())disallowed_special=() is required to avoid Exception: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte from tiktoken for some repositories1. Index the code base


in position 0: invalid start byte from tiktoken for some repositories1. Index the code base (optional)â€‹You can directly skip this part and directly jump into using already indexed dataset. To begin with, first we will clone the repository, then parse and chunk the code base and use OpenAI indexing.git clone https://github.com/twitter/the-algorithm # replace any repository of your choiceLoad all files inside the repositoryimport osfrom langchain.document_loaders import TextLoaderroot_dir = "./the-algorithm"docs = []for dirpath, dirnames, filenames in os.walk(root_dir):    for file in filenames:        try:            loader = TextLoader(os.path.join(dirpath, file), encoding="utf-8")            docs.extend(loader.load_and_split())        except Exception as e:            passThen, chunk the filesfrom langchain.text_splitter import CharacterTextSplittertext_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)texts = text_splitter.split_documents(docs)Execute the indexing. This will take about ~4 mins to compute embeddings and upload to Activeloop. You can then publish the dataset to be public.username = "davitbun"  # replace with your username from app.activeloop.aidb = DeepLake(    dataset_path=f"hub://{username}/twitter-algorithm",    embedding_function=embeddings,)db.add_documents(texts)Optional: You can also use Deep Lake's Managed Tensor Database as a hosting service and run queries there. In order to do so, it is necessary to specify the runtime parameter as {'tensor_db': True} during the creation of the vector store. This configuration enables the execution of queries on


True} during the creation of the vector store. This configuration enables the execution of queries on the Managed Tensor Database, rather than on the client side. It should be noted that this functionality is not applicable to datasets stored locally or in-memory. In the event that a vector store has already been created outside of the Managed Tensor Database, it is possible to transfer it to the Managed Tensor Database by following the prescribed steps.# username = "davitbun"  # replace with your username from app.activeloop.ai# db = DeepLake(#     dataset_path=f"hub://{username}/twitter-algorithm",#     embedding_function=embeddings,#     runtime={"tensor_db": True}# )# db.add_documents(texts)2. Question Answering on Twitter algorithm codebaseâ€‹First load the dataset, construct the retriever, then construct the Conversational Chaindb = DeepLake(    dataset_path="hub://davitbun/twitter-algorithm",    read_only=True,    embedding_function=embeddings,)    Deep Lake Dataset in hub://davitbun/twitter-algorithm already exists, loading from the storageretriever = db.as_retriever()retriever.search_kwargs["distance_metric"] = "cos"retriever.search_kwargs["fetch_k"] = 100retriever.search_kwargs["maximal_marginal_relevance"] = Trueretriever.search_kwargs["k"] = 10You can also specify user defined functions using Deep Lake filtersdef filter(x):    # filter based on source code    if "com.google" in x["text"].data()["value"]:        return False    # filter based on path e.g. extension    metadata = x["metadata"].data()["value"]    return "scala" in metadata["source"] or "py" in


return "scala" in metadata["source"] or "py" in metadata["source"]### turn on below for custom filtering# retriever.search_kwargs['filter'] = filterfrom langchain.chat_models import ChatOpenAIfrom langchain.chains import ConversationalRetrievalChainmodel = ChatOpenAI(model_name="gpt-3.5-turbo")  # switch to 'gpt-4'qa = ConversationalRetrievalChain.from_llm(model, retriever=retriever)questions = [    "What does favCountParams do?",    "is it Likes + Bookmarks, or not clear from the code?",    "What are the major negative modifiers that lower your linear ranking parameters?",    "How do you get assigned to SimClusters?",    "What is needed to migrate from one SimClusters to another SimClusters?",    "How much do I get boosted within my cluster?",    "How does Heavy ranker work. what are itâ€™s main inputs?",    "How can one influence Heavy ranker?",    "why threads and long tweets do so well on the platform?",    "Are thread and long tweet creators building a following that reacts to only threads?",    "Do you need to follow different strategies to get most followers vs to get most likes and bookmarks per tweet?",    "Content meta data and how it impacts virality (e.g. ALT in images).",    "What are some unexpected fingerprints for spam factors?",    "Is there any difference between company verified checkmarks and blue verified individual checkmarks?",]chat_history = []for question in questions:    result = qa({"question": question, "chat_history": chat_history})    chat_history.append((question, result["answer"]))    print(f"-> **Question**:


chat_history.append((question, result["answer"]))    print(f"-> **Question**: {question} \n")    print(f"**Answer**: {result['answer']} \n")-> Question: What does favCountParams do? Answer: favCountParams is an optional ThriftLinearFeatureRankingParams instance that represents the parameters related to the "favorite count" feature in the ranking process. It is used to control the weight of the favorite count feature while ranking tweets. The favorite count is the number of times a tweet has been marked as a favorite by users, and it is considered an important signal in the ranking of tweets. By using favCountParams, the system can adjust the importance of the favorite count while calculating the final ranking score of a tweet. -> Question: is it Likes + Bookmarks, or not clear from the code?Answer: From the provided code, it is not clear if the favorite count metric is determined by the sum of likes and bookmarks. The favorite count is mentioned in the code, but there is no explicit reference to how it is calculated in terms of likes and bookmarks. -> Question: What are the major negative modifiers that lower your linear ranking parameters?Answer: In the given code, major negative modifiers that lower the linear ranking parameters are:scoringData.querySpecificScore: This score adjustment is based on the query-specific information. If its value is negative, it will lower the linear ranking parameters.scoringData.authorSpecificScore: This score adjustment is based on the author-specific information. If its value is negative, it will also lower the linear ranking parameters.Please note that I cannot provide more information on the exact calculations of these negative modifiers, as the code for their determination is not provided. -> Question: How do you get assigned to SimClusters?Answer: The assignment to SimClusters occurs through a Metropolis-Hastings sampling-based community detection algorithm that is run on the Producer-Producer similarity graph. This graph is created


sampling-based community detection algorithm that is run on the Producer-Producer similarity graph. This graph is created by computing the cosine similarity scores between the users who follow each producer. The algorithm identifies communities or clusters of Producers with similar followers, and takes a parameter k for specifying the number of communities to be detected.After the community detection, different users and content are represented as sparse, interpretable vectors within these identified communities (SimClusters). The resulting SimClusters embeddings can be used for various recommendation tasks. -> Question: What is needed to migrate from one SimClusters to another SimClusters?Answer: To migrate from one SimClusters representation to another, you can follow these general steps:Prepare the new representation: Create the new SimClusters representation using any necessary updates or changes in the clustering algorithm, similarity measures, or other model parameters. Ensure that this new representation is properly stored and indexed as needed.Update the relevant code and configurations: Modify the relevant code and configuration files to reference the new SimClusters representation. This may involve updating paths or dataset names to point to the new representation, as well as changing code to use the new clustering method or similarity functions if applicable.Test the new representation: Before deploying the changes to production, thoroughly test the new SimClusters representation to ensure its effectiveness and stability. This may involve running offline jobs like candidate generation and label candidates, validating the output, as well as testing the new representation in the evaluation environment using evaluation tools like TweetSimilarityEvaluationAdhocApp.Deploy the changes: Once the new representation has been tested and validated, deploy the changes to production. This may involve creating a zip file, uploading it to the packer, and then scheduling it with Aurora. Be sure to monitor the system to ensure a smooth transition between representations and verify that the new representation is being used in recommendations as expected.Monitor and assess the new representation: After the new representation has been deployed, continue to monitor its performance and impact on recommendations. Take note of any improvements or issues that arise and


continue to monitor its performance and impact on recommendations. Take note of any improvements or issues that arise and be prepared to iterate on the new representation if needed. Always ensure that the results and performance metrics align with the system's goals and objectives. -> Question: How much do I get boosted within my cluster?Answer: It's not possible to determine the exact amount your content is boosted within your cluster in the SimClusters representation without specific data about your content and its engagement metrics. However, a combination of factors, such as the favorite score and follow score, alongside other engagement signals and SimCluster calculations, influence the boosting of content. -> Question: How does Heavy ranker work. what are itâ€™s main inputs?Answer: The Heavy Ranker is a machine learning model that plays a crucial role in ranking and scoring candidates within the recommendation algorithm. Its primary purpose is to predict the likelihood of a user engaging with a tweet or connecting with another user on the platform.Main inputs to the Heavy Ranker consist of:Static Features: These are features that can be computed directly from a tweet at the time it's created, such as whether it has a URL, has cards, has quotes, etc. These features are produced by the Index Ingester as the tweets are generated and stored in the index.Real-time Features: These per-tweet features can change after the tweet has been indexed. They mostly consist of social engagements like retweet count, favorite count, reply count, and some spam signals that are computed with later activities. The Signal Ingester, which is part of a Heron topology, processes multiple event streams to collect and compute these real-time features.User Table Features: These per-user features are obtained from the User Table Updater that processes a stream written by the user service. This input is used to store sparse real-time user information, which is later propagated to the tweet being scored by looking up the author of the tweet.Search Context Features: These features represent the context of the current


by looking up the author of the tweet.Search Context Features: These features represent the context of the current searcher, like their UI language, their content consumption, and the current time (implied). They are combined with Tweet Data to compute some of the features used in scoring.These inputs are then processed by the Heavy Ranker to score and rank candidates based on their relevance and likelihood of engagement by the user. -> Question: How can one influence Heavy ranker?Answer: To influence the Heavy Ranker's output or ranking of content, consider the following actions:Improve content quality: Create high-quality and engaging content that is relevant, informative, and valuable to users. High-quality content is more likely to receive positive user engagement, which the Heavy Ranker considers when ranking content.Increase user engagement: Encourage users to interact with content through likes, retweets, replies, and comments. Higher engagement levels can lead to better ranking in the Heavy Ranker's output.Optimize your user profile: A user's reputation, based on factors such as their follower count and follower-to-following ratio, may impact the ranking of their content. Maintain a good reputation by following relevant users, keeping a reasonable follower-to-following ratio and engaging with your followers.Enhance content discoverability: Use relevant keywords, hashtags, and mentions in your tweets, making it easier for users to find and engage with your content. This increased discoverability may help improve the ranking of your content by the Heavy Ranker.Leverage multimedia content: Experiment with different content formats, such as videos, images, and GIFs, which may capture users' attention and increase engagement, resulting in better ranking by the Heavy Ranker.User feedback: Monitor and respond to feedback for your content. Positive feedback may improve your ranking, while negative feedback provides an opportunity to learn and improve.Note that the Heavy Ranker uses a combination of machine learning models and various features to rank the content. While the above actions may help influence the


of machine learning models and various features to rank the content. While the above actions may help influence the ranking, there are no guarantees as the ranking process is determined by a complex algorithm, which evolves over time. -> Question: why threads and long tweets do so well on the platform?Answer: Threads and long tweets perform well on the platform for several reasons:More content and context: Threads and long tweets provide more information and context about a topic, which can make the content more engaging and informative for users. People tend to appreciate a well-structured and detailed explanation of a subject or a story, and threads and long tweets can do that effectively.Increased user engagement: As threads and long tweets provide more content, they also encourage users to engage with the tweets through replies, retweets, and likes. This increased engagement can lead to better visibility of the content, as the Twitter algorithm considers user engagement when ranking and surfacing tweets.Narrative structure: Threads enable users to tell stories or present arguments in a step-by-step manner, making the information more accessible and easier to follow. This narrative structure can capture users' attention and encourage them to read through the entire thread and interact with the content.Expanded reach: When users engage with a thread, their interactions can bring the content to the attention of their followers, helping to expand the reach of the thread. This increased visibility can lead to more interactions and higher performance for the threaded tweets.Higher content quality: Generally, threads and long tweets require more thought and effort to create, which may lead to higher quality content. Users are more likely to appreciate and interact with high-quality, well-reasoned content, further improving the performance of these tweets within the platform.Overall, threads and long tweets perform well on Twitter because they encourage user engagement and provide a richer, more informative experience that users find valuable. -> Question: Are thread and long tweet creators building a following that reacts to only threads?Answer: Based on the provided code and context,


creators building a following that reacts to only threads?Answer: Based on the provided code and context, there isn't enough information to conclude if the creators of threads and long tweets primarily build a following that engages with only thread-based content. The code provided is focused on Twitter's recommendation and ranking algorithms, as well as infrastructure components like Kafka, partitions, and the Follow Recommendations Service (FRS). To answer your question, data analysis of user engagement and results of specific edge cases would be required. -> Question: Do you need to follow different strategies to get most followers vs to get most likes and bookmarks per tweet?Answer: Yes, different strategies need to be followed to maximize the number of followers compared to maximizing likes and bookmarks per tweet. While there may be some overlap in the approaches, they target different aspects of user engagement.Maximizing followers: The primary focus is on growing your audience on the platform. Strategies include:Consistently sharing high-quality content related to your niche or industry.Engaging with others on the platform by replying, retweeting, and mentioning other users.Using relevant hashtags and participating in trending conversations.Collaborating with influencers and other users with a large following.Posting at optimal times when your target audience is most active.Optimizing your profile by using a clear profile picture, catchy bio, and relevant links.Maximizing likes and bookmarks per tweet: The focus is on creating content that resonates with your existing audience and encourages engagement. Strategies include:Crafting engaging and well-written tweets that encourage users to like or save them.Incorporating visually appealing elements, such as images, GIFs, or videos, that capture attention.Asking questions, sharing opinions, or sparking conversations that encourage users to engage with your tweets.Using analytics to understand the type of content that resonates with your audience and tailoring your tweets accordingly.Posting a mix of educational, entertaining, and promotional content to maintain variety and interest.Timing your tweets strategically to maximize


of educational, entertaining, and promotional content to maintain variety and interest.Timing your tweets strategically to maximize engagement, likes, and bookmarks per tweet.Both strategies can overlap, and you may need to adapt your approach by understanding your target audience's preferences and analyzing your account's performance. However, it's essential to recognize that maximizing followers and maximizing likes and bookmarks per tweet have different focuses and require specific strategies. -> Question: Content meta data and how it impacts virality (e.g. ALT in images).Answer: There is no direct information in the provided context about how content metadata, such as ALT text in images, impacts the virality of a tweet or post. However, it's worth noting that including ALT text can improve the accessibility of your content for users who rely on screen readers, which may lead to increased engagement for a broader audience. Additionally, metadata can be used in search engine optimization, which might improve the visibility of the content, but the context provided does not mention any specific correlation with virality. -> Question: What are some unexpected fingerprints for spam factors?Answer: In the provided context, an unusual indicator of spam factors is when a tweet contains a non-media, non-news link. If the tweet has a link but does not have an image URL, video URL, or news URL, it is considered a potential spam vector, and a threshold for user reputation (tweepCredThreshold) is set to MIN_TWEEPCRED_WITH_LINK.While this rule may not cover all possible unusual spam indicators, it is derived from the specific codebase and logic shared in the context. -> Question: Is there any difference between company verified checkmarks and blue verified individual checkmarks?Answer: Yes, there is a distinction between the verified checkmarks for companies and blue verified checkmarks for individuals. The code snippet provided mentions "Blue-verified account boost" which indicates that there is a separate category for blue verified accounts. Typically, blue verified checkmarks are used to indicate notable


is a separate category for blue verified accounts. Typically, blue verified checkmarks are used to indicate notable individuals, while verified checkmarks are for companies or organizations.PreviousUse LangChain, GPT and Activeloop's Deep Lake to work with code baseNextAgent simulations1. Index the code base (optional)2. Question Answering on Twitter algorithm codebaseCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Page Not Found | ğŸ¦œï¸�ğŸ”— Langchain

Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKPage Not FoundWe could not find what you were looking for.Please contact the owner of the site that linked you to the original URL and let them know their link is broken.CommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Use LangChain, GPT and Activeloop's Deep Lake to work with code base | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKUse casesQA and Chat over DocumentsAnalyzing structured dataExtractionInteracting with APIsChatbotsSummarizationCode UnderstandingUse LangChain, GPT and Activeloop's Deep Lake to work with code baseAnalysis of Twitter the-algorithm source code with LangChain, GPT4 and Activeloop's Deep LakeAgent simulationsAgentsAutonomous (long-running) agentsMulti-modalUse casesCode UnderstandingUse LangChain, GPT and Activeloop's Deep Lake to work with code baseOn this pageUse LangChain, GPT and Activeloop's Deep Lake to work with code baseIn this tutorial, we are going to use Langchain + Activeloop's Deep Lake with GPT to analyze the code base of the LangChain itself. Designâ€‹Prepare data:Upload all python project files using the langchain.document_loaders.TextLoader. We will call these files the documents.Split all documents to chunks using the langchain.text_splitter.CharacterTextSplitter.Embed chunks and upload them into the DeepLake using langchain.embeddings.openai.OpenAIEmbeddings and langchain.vectorstores.DeepLakeQuestion-Answering:Build a chain from langchain.chat_models.ChatOpenAI and langchain.chains.ConversationalRetrievalChainPrepare questions.Get answers running the chain.Implementationâ€‹Integration preparationsâ€‹We need to set up keys for external services and install necessary python libraries.#!python3 -m pip install --upgrade langchain deeplake openaiSet up OpenAI embeddings, Deep Lake multi-modal vector store api and authenticate. For full documentation of Deep Lake please follow https://docs.activeloop.ai/ and API reference https://docs.deeplake.ai/en/latest/import osfrom getpass import getpassos.environ["OPENAI_API_KEY"] =


osfrom getpass import getpassos.environ["OPENAI_API_KEY"] = getpass()# Please manually enter OpenAI KeyAuthenticate into Deep Lake if you want to create your own dataset and publish it. You can get an API key from the platform at app.activeloop.aiactiveloop_token = getpass("Activeloop Token:")os.environ["ACTIVELOOP_TOKEN"] = activeloop_tokenPrepare dataâ€‹Load all repository files. Here we assume this notebook is downloaded as the part of the langchain fork and we work with the python files of the langchain repo.If you want to use files from different repo, change root_dir to the root dir of your repo.ls "../../../.."from langchain.document_loaders import TextLoaderroot_dir = "../../../.."docs = []for dirpath, dirnames, filenames in os.walk(root_dir):    for file in filenames:        if file.endswith(".py") and "/.venv/" not in dirpath:            try:                loader = TextLoader(os.path.join(dirpath, file), encoding="utf-8")                docs.extend(loader.load_and_split())            except Exception as e:                passprint(f"{len(docs)}")Then, chunk the filesfrom langchain.text_splitter import CharacterTextSplittertext_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)texts = text_splitter.split_documents(docs)print(f"{len(texts)}")Then embed chunks and upload them to the DeepLake.This can take several minutes. from langchain.embeddings.openai import OpenAIEmbeddingsembeddings =


take several minutes. from langchain.embeddings.openai import OpenAIEmbeddingsembeddings = OpenAIEmbeddings()embeddingsfrom langchain.vectorstores import DeepLakedb = DeepLake.from_documents(    texts, embeddings, dataset_path=f"hub://{<org_id>}/langchain-code")dbOptional: You can also use Deep Lake's Managed Tensor Database as a hosting service and run queries there. In order to do so, it is necessary to specify the runtime parameter as {'tensor_db': True} during the creation of the vector store. This configuration enables the execution of queries on the Managed Tensor Database, rather than on the client side. It should be noted that this functionality is not applicable to datasets stored locally or in-memory. In the event that a vector store has already been created outside of the Managed Tensor Database, it is possible to transfer it to the Managed Tensor Database by following the prescribed steps.# from langchain.vectorstores import DeepLake# db = DeepLake.from_documents(#     texts, embeddings, dataset_path=f"hub://{<org_id>}/langchain-code", runtime={"tensor_db": True}# )# dbQuestion Answeringâ€‹First load the dataset, construct the retriever, then construct the Conversational Chaindb = DeepLake(    dataset_path=f"hub://{<org_id>}/langchain-code",    read_only=True,    embedding_function=embeddings,)retriever = db.as_retriever()retriever.search_kwargs["distance_metric"] = "cos"retriever.search_kwargs["fetch_k"] = 20retriever.search_kwargs["maximal_marginal_relevance"] = Trueretriever.search_kwargs["k"] = 20You can also specify user defined functions using Deep Lake filtersdef filter(x):    # filter based on source code    if "something" in


filter(x):    # filter based on source code    if "something" in x["text"].data()["value"]:        return False    # filter based on path e.g. extension    metadata = x["metadata"].data()["value"]    return "only_this" in metadata["source"] or "also_that" in metadata["source"]### turn on below for custom filtering# retriever.search_kwargs['filter'] = filterfrom langchain.chat_models import ChatOpenAIfrom langchain.chains import ConversationalRetrievalChainmodel = ChatOpenAI(model_name="gpt-3.5-turbo")  # 'ada' 'gpt-3.5-turbo' 'gpt-4',qa = ConversationalRetrievalChain.from_llm(model, retriever=retriever)questions = [    "What is the class hierarchy?",    # "What classes are derived from the Chain class?",    # "What classes and functions in the ./langchain/utilities/ forlder are not covered by unit tests?",    # "What one improvement do you propose in code in relation to the class herarchy for the Chain class?",]chat_history = []for question in questions:    result = qa({"question": question, "chat_history": chat_history})    chat_history.append((question, result["answer"]))    print(f"-> **Question**: {question} \n")    print(f"**Answer**: {result['answer']} \n")-> Question: What is the class hierarchy? Answer: There are several class hierarchies in the provided code, so I'll list a few:BaseModel -> ConstitutionalPrinciple: ConstitutionalPrinciple is a subclass of BaseModel.BasePromptTemplate -> StringPromptTemplate, AIMessagePromptTemplate, BaseChatPromptTemplate,


of BaseModel.BasePromptTemplate -> StringPromptTemplate, AIMessagePromptTemplate, BaseChatPromptTemplate, ChatMessagePromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate, FewShotPromptTemplate, FewShotPromptWithTemplates, Prompt, PromptTemplate: All of these classes are subclasses of BasePromptTemplate.APIChain, Chain, MapReduceDocumentsChain, MapRerankDocumentsChain, RefineDocumentsChain, StuffDocumentsChain, HypotheticalDocumentEmbedder, LLMChain, LLMBashChain, LLMCheckerChain, LLMMathChain, LLMRequestsChain, PALChain, QAWithSourcesChain, VectorDBQAWithSourcesChain, VectorDBQA, SQLDatabaseChain: All of these classes are subclasses of Chain.BaseLoader: BaseLoader is a subclass of ABC.BaseTracer -> ChainRun, LLMRun, SharedTracer, ToolRun, Tracer, TracerException, TracerSession: All of these classes are subclasses of BaseTracer.OpenAIEmbeddings, HuggingFaceEmbeddings, CohereEmbeddings, JinaEmbeddings, LlamaCppEmbeddings, HuggingFaceHubEmbeddings, TensorflowHubEmbeddings, SagemakerEndpointEmbeddings, HuggingFaceInstructEmbeddings, SelfHostedEmbeddings, SelfHostedHuggingFaceEmbeddings, SelfHostedHuggingFaceInstructEmbeddings, FakeEmbeddings, AlephAlphaAsymmetricSemanticEmbedding, AlephAlphaSymmetricSemanticEmbedding: All of these classes are subclasses of BaseLLM. -> Question: What classes are derived from the Chain class? Answer: There are multiple classes that are derived from the Chain class. Some of them


Chain class? Answer: There are multiple classes that are derived from the Chain class. Some of them are:APIChainAnalyzeDocumentChainChatVectorDBChainCombineDocumentsChainConstitutionalChainConversationChainGraphQAChainHypotheticalDocumentEmbedderLLMChainLLMCheckerChainLLMRequestsChainLLMSummarizationCheckerChainMapReduceChainOpenAPIEndpointChainPALChainQAWithSourcesChainRetrievalQARetrievalQAWithSourcesChainSequentialChainSQLDatabaseChainTransformChainVectorDBQAVectorDBQAWithSourcesChainThere might be more classes that are derived from the Chain class as it is possible to create custom classes that extend the Chain class.-> Question: What classes and functions in the ./langchain/utilities/ forlder are not covered by unit tests? Answer: All classes and functions in the ./langchain/utilities/ folder seem to have unit tests written for them.PreviousCode UnderstandingNextAnalysis of Twitter the-algorithm source code with LangChain, GPT4 and Activeloop's Deep LakeDesignImplementationIntegration preparationsPrepare dataQuestion AnsweringCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Extraction | ğŸ¦œï¸�ğŸ”— Langchain

Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKUse casesQA and Chat over DocumentsAnalyzing structured dataExtractionInteracting with APIsChatbotsSummarizationCode UnderstandingAgent simulationsAgentsAutonomous (long-running) agentsMulti-modalUse casesExtractionExtractionMost APIs and databases still deal with structured information.
Therefore, in order to better work with those, it can be useful to extract structured information from text.
Examples of this include:Extracting a structured row to insert into a database from a sentenceExtracting multiple rows to insert into a database from a long documentExtracting the correct API parameters from a user queryThis work is extremely related to output parsing.
Output parsers are responsible for instructing the LLM to respond in a specific format.
In this case, the output parsers specify the format of the data you would like to extract from the document.
Then, in addition to the output format instructions, the prompt should also contain the data you would like to extract information from.While normal output parsers are good enough for basic structuring of response data,
when doing extraction you often want to extract more complicated or nested structures.
For a deep dive on extraction, we recommend checking out kor,
a library that uses the existing LangChain chain and OutputParser abstractions
but deep dives on allowing extraction of more complicated schemas.PreviousAnalyzing structured dataNextInteracting with APIsCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Agent simulations | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKUse casesQA and Chat over DocumentsAnalyzing structured dataExtractionInteracting with APIsChatbotsSummarizationCode UnderstandingAgent simulationsCAMEL Role-Playing Autonomous Cooperative AgentsGenerative Agents in LangChainSimulated Environment: GymnasiumMulti-Player Dungeons & DragonsMulti-agent authoritarian speaker selectionMulti-agent decentralized speaker selectionMulti-Agent Simulated Environment: Petting ZooAgent Debates with ToolsTwo-Player Dungeons & DragonsAgentsAutonomous (long-running) agentsMulti-modalUse casesAgent simulationsOn this pageAgent simulationsAgent simulations involve interacting one of more agents with each other.


Agent simulations generally involve two main components:Long Term MemorySimulation EnvironmentSpecific implementations of agent simulations (or parts of agent simulations) include:Simulations with One Agentâ€‹Simulated Environment: Gymnasium: an example of how to create a simple agent-environment interaction loop with Gymnasium (formerly OpenAI Gym).Simulations with Two Agentsâ€‹CAMEL: an implementation of the CAMEL (Communicative Agents for â€œMindâ€� Exploration of Large Scale Language Model Society) paper, where two agents communicate with each other.Two Player D&D: an example of how to use a generic simulator for two agents to implement a variant of the popular Dungeons & Dragons role playing game.Agent Debates with Tools: an example of how to enable Dialogue Agents to use tools to inform their responses.Simulations with Multiple Agentsâ€‹Multi-Player D&D: an example of how to use a generic dialogue simulator for multiple dialogue agents with a custom speaker-ordering, illustrated with a variant of the popular Dungeons & Dragons role playing game.Decentralized Speaker Selection: an example of how to implement a multi-agent dialogue without a fixed schedule for who speaks when. Instead the agents decide for themselves who speaks by outputting bids to speak. This example shows how to do this in the context of a fictitious presidential debate.Authoritarian Speaker Selection: an example of how to implement a multi-agent dialogue, where a privileged agent directs who speaks what. This example also showcases how to enable the privileged agent to determine when the conversation terminates. This example shows how to do this in the context of a fictitious news show.Simulated Environment: PettingZoo: an example of how to create a agent-environment interaction loop for multiple agents with PettingZoo (a multi-agent version of Gymnasium).Generative Agents: This notebook implements a generative agent based on the paper Generative Agents: Interactive Simulacra of Human Behavior


a generative agent based on the paper Generative Agents: Interactive Simulacra of Human Behavior by Park, et. al.PreviousAnalysis of Twitter the-algorithm source code with LangChain, GPT4 and Activeloop's Deep LakeNextCAMEL Role-Playing Autonomous Cooperative AgentsSimulations with One AgentSimulations with Two AgentsSimulations with Multiple AgentsCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Generative Agents in LangChain | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKUse casesQA and Chat over DocumentsAnalyzing structured dataExtractionInteracting with APIsChatbotsSummarizationCode UnderstandingAgent simulationsCAMEL Role-Playing Autonomous Cooperative AgentsGenerative Agents in LangChainSimulated Environment: GymnasiumMulti-Player Dungeons & DragonsMulti-agent authoritarian speaker selectionMulti-agent decentralized speaker selectionMulti-Agent Simulated Environment: Petting ZooAgent Debates with ToolsTwo-Player Dungeons & DragonsAgentsAutonomous (long-running) agentsMulti-modalUse casesAgent simulationsGenerative Agents in LangChainOn this pageGenerative Agents in LangChainThis notebook implements a generative agent based on the paper Generative Agents: Interactive Simulacra of Human Behavior by Park, et. al.In it, we leverage a time-weighted Memory object backed by a LangChain Retriever.# Use termcolor to make it easy to colorize the outputs.pip install termcolor > /dev/nullimport logginglogging.basicConfig(level=logging.ERROR)from datetime import datetime, timedeltafrom typing import Listfrom termcolor import coloredfrom langchain.chat_models import ChatOpenAIfrom langchain.docstore import InMemoryDocstorefrom langchain.embeddings import OpenAIEmbeddingsfrom langchain.retrievers import TimeWeightedVectorStoreRetrieverfrom langchain.vectorstores import FAISSUSER_NAME = "Person A"  # The name you want to use when interviewing the agent.LLM = ChatOpenAI(max_tokens=1500)  # Can be any LLM you want.Generative Agent Memory Componentsâ€‹This tutorial highlights the memory of generative agents and its impact on their behavior. The memory varies from standard LangChain Chat memory in two aspects:Memory FormationGenerative Agents have extended memories, stored in a single stream:Observations - from dialogues or interactions with the virtual world,


stored in a single stream:Observations - from dialogues or interactions with the virtual world, about self or othersReflections - resurfaced and summarized core memoriesMemory RecallMemories are retrieved using a weighted sum of salience, recency, and importance.You can review the definitions of the GenerativeAgent and GenerativeAgentMemory in the reference documentation for the following imports, focusing on add_memory and summarize_related_memories methods.from langchain.experimental.generative_agents import (    GenerativeAgent,    GenerativeAgentMemory,)Memory Lifecycleâ€‹Summarizing the key methods in the above: add_memory and summarize_related_memories.When an agent makes an observation, it stores the memory:Language model scores the memory's importance (1 for mundane, 10 for poignant)Observation and importance are stored within a document by TimeWeightedVectorStoreRetriever, with a last_accessed_time.When an agent responds to an observation:Generates query(s) for retriever, which fetches documents based on salience, recency, and importance.Summarizes the retrieved informationUpdates the last_accessed_time for the used documents.Create a Generative Characterâ€‹Now that we've walked through the definition, we will create two characters named "Tommie" and "Eve".import mathimport faissdef relevance_score_fn(score: float) -> float:    """Return a similarity score on a scale [0, 1]."""    # This will differ depending on a few things:    # - the distance / similarity metric used by the VectorStore    # - the scale of your embeddings (OpenAI's are unit norm. Many others are not!)    # This function converts the euclidean norm of normalized embeddings    # (0 is most similar, sqrt(2) most dissimilar)    # to a similarity function (0 to 1)


most dissimilar)    # to a similarity function (0 to 1)    return 1.0 - score / math.sqrt(2)def create_new_memory_retriever():    """Create a new vector store retriever unique to the agent."""    # Define your embedding model    embeddings_model = OpenAIEmbeddings()    # Initialize the vectorstore as empty    embedding_size = 1536    index = faiss.IndexFlatL2(embedding_size)    vectorstore = FAISS(        embeddings_model.embed_query,        index,        InMemoryDocstore({}),        {},        relevance_score_fn=relevance_score_fn,    )    return TimeWeightedVectorStoreRetriever(        vectorstore=vectorstore, other_score_keys=["importance"], k=15    )tommies_memory = GenerativeAgentMemory(    llm=LLM,    memory_retriever=create_new_memory_retriever(),    verbose=False,    reflection_threshold=8,  # we will give this a relatively low number to show how reflection works)tommie = GenerativeAgent(    name="Tommie",    age=25,    traits="anxious, likes design, talkative",  # You can add more persistent traits here    status="looking for a job",  # When connected to a virtual world, we can have the characters update their status    memory_retriever=create_new_memory_retriever(),    llm=LLM,    memory=tommies_memory,)# The current "Summary" of a character can't


memory=tommies_memory,)# The current "Summary" of a character can't be made because the agent hasn't made# any observations yet.print(tommie.get_summary())    Name: Tommie (age: 25)    Innate traits: anxious, likes design, talkative    No information about Tommie's core characteristics is provided in the given statements.# We can add memories directly to the memory objecttommie_observations = [    "Tommie remembers his dog, Bruno, from when he was a kid",    "Tommie feels tired from driving so far",    "Tommie sees the new home",    "The new neighbors have a cat",    "The road is noisy at night",    "Tommie is hungry",    "Tommie tries to get some rest.",]for observation in tommie_observations:    tommie.memory.add_memory(observation)# Now that Tommie has 'memories', their self-summary is more descriptive, though still rudimentary.# We will see how this summary updates after more observations to create a more rich description.print(tommie.get_summary(force_refresh=True))    Name: Tommie (age: 25)    Innate traits: anxious, likes design, talkative    Tommie is a person who is observant of his surroundings, has a sentimental side, and experiences basic human needs such as hunger and the need for rest. He also tends to get tired easily and is affected by external factors such as noise from the road or a neighbor's pet.Pre-Interview with Characterâ€‹Before sending our character on their way, let's ask them a few questions.def interview_agent(agent: GenerativeAgent, message: str) -> str:    """Help the notebook user interact with the agent."""


str) -> str:    """Help the notebook user interact with the agent."""    new_message = f"{USER_NAME} says {message}"    return agent.generate_dialogue_response(new_message)[1]interview_agent(tommie, "What do you like to do?")    'Tommie said "I really enjoy design and being creative. I\'ve been working on some personal projects lately. What about you, Person A? What do you like to do?"'interview_agent(tommie, "What are you looking forward to doing today?")    'Tommie said "Well, I\'m actually looking for a job right now, so hopefully I can find some job postings online and start applying. How about you, Person A? What\'s on your schedule for today?"'interview_agent(tommie, "What are you most worried about today?")    'Tommie said "Honestly, I\'m feeling pretty anxious about finding a job. It\'s been a bit of a struggle lately, but I\'m trying to stay positive and keep searching. How about you, Person A? What worries you?"'Step through the day's observations.â€‹# Let's have Tommie start going through a day in the life.observations = [    "Tommie wakes up to the sound of a noisy construction site outside his window.",    "Tommie gets out of bed and heads to the kitchen to make himself some coffee.",    "Tommie realizes he forgot to buy coffee filters and starts rummaging through his moving boxes to find some.",    "Tommie finally finds the filters and makes himself a cup of coffee.",    "The coffee tastes bitter, and Tommie regrets not buying a better brand.",    "Tommie checks his email and sees that he


not buying a better brand.",    "Tommie checks his email and sees that he has no job offers yet.",    "Tommie spends some time updating his resume and cover letter.",    "Tommie heads out to explore the city and look for job openings.",    "Tommie sees a sign for a job fair and decides to attend.",    "The line to get in is long, and Tommie has to wait for an hour.",    "Tommie meets several potential employers at the job fair but doesn't receive any offers.",    "Tommie leaves the job fair feeling disappointed.",    "Tommie stops by a local diner to grab some lunch.",    "The service is slow, and Tommie has to wait for 30 minutes to get his food.",    "Tommie overhears a conversation at the next table about a job opening.",    "Tommie asks the diners about the job opening and gets some information about the company.",    "Tommie decides to apply for the job and sends his resume and cover letter.",    "Tommie continues his search for job openings and drops off his resume at several local businesses.",    "Tommie takes a break from his job search to go for a walk in a nearby park.",    "A dog approaches and licks Tommie's feet, and he pets it for a few minutes.",    "Tommie sees a group of people playing frisbee and decides to join in.",    "Tommie has fun playing frisbee but gets hit in the face with the frisbee and hurts his nose.",    "Tommie goes back to his apartment to rest for a bit.",    "A raccoon tore open the trash bag outside his apartment,


for a bit.",    "A raccoon tore open the trash bag outside his apartment, and the garbage is all over the floor.",    "Tommie starts to feel frustrated with his job search.",    "Tommie calls his best friend to vent about his struggles.",    "Tommie's friend offers some words of encouragement and tells him to keep trying.",    "Tommie feels slightly better after talking to his friend.",]# Let's send Tommie on their way. We'll check in on their summary every few observations to watch it evolvefor i, observation in enumerate(observations):    _, reaction = tommie.generate_reaction(observation)    print(colored(observation, "green"), reaction)    if ((i + 1) % 20) == 0:        print("*" * 40)        print(            colored(                f"After {i+1} observations, Tommie's summary is:\n{tommie.get_summary(force_refresh=True)}",                "blue",            )        )        print("*" * 40)    Tommie wakes up to the sound of a noisy construction site outside his window. Tommie groans and covers his head with a pillow, trying to block out the noise.    Tommie gets out of bed and heads to the kitchen to make himself some coffee. Tommie stretches his arms and yawns before starting to make the coffee.    Tommie realizes he forgot to buy coffee filters and starts rummaging through


coffee.    Tommie realizes he forgot to buy coffee filters and starts rummaging through his moving boxes to find some. Tommie sighs in frustration and continues searching through the boxes.    Tommie finally finds the filters and makes himself a cup of coffee. Tommie takes a deep breath and enjoys the aroma of the fresh coffee.    The coffee tastes bitter, and Tommie regrets not buying a better brand. Tommie grimaces and sets the coffee mug aside.    Tommie checks his email and sees that he has no job offers yet. Tommie sighs and closes his laptop, feeling discouraged.    Tommie spends some time updating his resume and cover letter. Tommie nods, feeling satisfied with his progress.    Tommie heads out to explore the city and look for job openings. Tommie feels a surge of excitement and anticipation as he steps out into the city.    Tommie sees a sign for a job fair and decides to attend. Tommie feels hopeful and excited about the possibility of finding job opportunities at the job fair.    The line to get in is long, and Tommie has to wait for an hour. Tommie taps his foot impatiently and checks his phone for the time.    Tommie meets several potential employers at the job fair but doesn't receive any offers. Tommie feels disappointed and discouraged, but he remains determined to keep searching for job opportunities.    Tommie leaves the job fair feeling disappointed. Tommie feels disappointed and discouraged, but he remains determined to keep searching for job opportunities.    Tommie stops by a local diner to grab some lunch. Tommie feels relieved to take a break and satisfy his hunger.    The service is slow, and Tommie has to wait for 30 minutes to get his food. Tommie feels frustrated and impatient due to the slow service.    Tommie overhears a


Tommie feels frustrated and impatient due to the slow service.    Tommie overhears a conversation at the next table about a job opening. Tommie feels a surge of hope and excitement at the possibility of a job opportunity but decides not to interfere with the conversation at the next table.    Tommie asks the diners about the job opening and gets some information about the company. Tommie said "Excuse me, I couldn't help but overhear your conversation about the job opening. Could you give me some more information about the company?"    Tommie decides to apply for the job and sends his resume and cover letter. Tommie feels hopeful and proud of himself for taking action towards finding a job.    Tommie continues his search for job openings and drops off his resume at several local businesses. Tommie feels hopeful and determined to keep searching for job opportunities.    Tommie takes a break from his job search to go for a walk in a nearby park. Tommie feels refreshed and rejuvenated after taking a break in the park.    A dog approaches and licks Tommie's feet, and he pets it for a few minutes. Tommie feels happy and enjoys the brief interaction with the dog.    ****************************************    After 20 observations, Tommie's summary is:    Name: Tommie (age: 25)    Innate traits: anxious, likes design, talkative    Tommie is determined and hopeful in his search for job opportunities, despite encountering setbacks and disappointments. He is also able to take breaks and care for his physical needs, such as getting rest and satisfying his hunger. Tommie is nostalgic towards his past, as shown by his memory of his childhood dog. Overall, Tommie is a hardworking and resilient individual who remains focused on his goals.    ****************************************    Tommie sees a group of people playing frisbee


goals.    ****************************************    Tommie sees a group of people playing frisbee and decides to join in. Do nothing.    Tommie has fun playing frisbee but gets hit in the face with the frisbee and hurts his nose. Tommie feels pain and puts a hand to his nose to check for any injury.    Tommie goes back to his apartment to rest for a bit. Tommie feels relieved to take a break and rest for a bit.    A raccoon tore open the trash bag outside his apartment, and the garbage is all over the floor. Tommie feels annoyed and frustrated at the mess caused by the raccoon.    Tommie starts to feel frustrated with his job search. Tommie feels discouraged but remains determined to keep searching for job opportunities.    Tommie calls his best friend to vent about his struggles. Tommie said "Hey, can I talk to you for a bit? I'm feeling really frustrated with my job search."    Tommie's friend offers some words of encouragement and tells him to keep trying. Tommie said "Thank you, I really appreciate your support and encouragement."    Tommie feels slightly better after talking to his friend. Tommie feels grateful for his friend's support.Interview after the dayâ€‹interview_agent(tommie, "Tell me about how your day has been going")    'Tommie said "It\'s been a bit of a rollercoaster, to be honest. I\'ve had some setbacks in my job search, but I also had some good moments today, like sending out a few resumes and meeting some potential employers at a job fair. How about you?"'interview_agent(tommie, "How do you feel about coffee?")    'Tommie said "I really enjoy coffee, but sometimes I regret not buying a better brand.


said "I really enjoy coffee, but sometimes I regret not buying a better brand. How about you?"'interview_agent(tommie, "Tell me about your childhood dog!")    'Tommie said "Oh, I had a dog named Bruno when I was a kid. He was a golden retriever and my best friend. I have so many fond memories of him."'Adding Multiple Charactersâ€‹Let's add a second character to have a conversation with Tommie. Feel free to configure different traits.eves_memory = GenerativeAgentMemory(    llm=LLM,    memory_retriever=create_new_memory_retriever(),    verbose=False,    reflection_threshold=5,)eve = GenerativeAgent(    name="Eve",    age=34,    traits="curious, helpful",  # You can add more persistent traits here    status="N/A",  # When connected to a virtual world, we can have the characters update their status    llm=LLM,    daily_summaries=[        (            "Eve started her new job as a career counselor last week and received her first assignment, a client named Tommie."        )    ],    memory=eves_memory,    verbose=False,)yesterday = (datetime.now() - timedelta(days=1)).strftime("%A %B %d")eve_observations = [    "Eve wakes up and hear's the alarm",    "Eve eats a boal of porridge",    "Eve helps a coworker on a task",    "Eve plays tennis with her friend Xu before going to work",    "Eve overhears her colleague say


with her friend Xu before going to work",    "Eve overhears her colleague say something about Tommie being hard to work with",]for observation in eve_observations:    eve.memory.add_memory(observation)print(eve.get_summary())    Name: Eve (age: 34)    Innate traits: curious, helpful    Eve is a helpful and active person who enjoys sports and takes care of her physical health. She is attentive to her surroundings, including her colleagues, and has good time management skills.Pre-conversation interviewsâ€‹Let's "Interview" Eve before she speaks with Tommie.interview_agent(eve, "How are you feeling about today?")    'Eve said "I\'m feeling pretty good, thanks for asking! Just trying to stay productive and make the most of the day. How about you?"'interview_agent(eve, "What do you know about Tommie?")    'Eve said "I don\'t know much about Tommie, but I heard someone mention that they find them difficult to work with. Have you had any experiences working with Tommie?"'interview_agent(    eve,    "Tommie is looking to find a job. What are are some things you'd like to ask him?",)    'Eve said "That\'s interesting. I don\'t know much about Tommie\'s work experience, but I would probably ask about his strengths and areas for improvement. What about you?"'interview_agent(    eve,    "You'll have to ask him. He may be a bit anxious, so I'd appreciate it if you keep the conversation going and ask as many questions as possible.",)    'Eve said "Sure, I can keep the conversation going and ask plenty of questions. I want to make sure


"Sure, I can keep the conversation going and ask plenty of questions. I want to make sure Tommie feels comfortable and supported. Thanks for letting me know."'Dialogue between Generative Agentsâ€‹Generative agents are much more complex when they interact with a virtual environment or with each other. Below, we run a simple conversation between Tommie and Eve.def run_conversation(agents: List[GenerativeAgent], initial_observation: str) -> None:    """Runs a conversation between agents."""    _, observation = agents[1].generate_reaction(initial_observation)    print(observation)    turns = 0    while True:        break_dialogue = False        for agent in agents:            stay_in_dialogue, observation = agent.generate_dialogue_response(                observation            )            print(observation)            # observation = f"{agent.name} said {reaction}"            if not stay_in_dialogue:                break_dialogue = True        if break_dialogue:            break        turns += 1agents = [tommie, eve]run_conversation(    agents,    "Tommie said: Hi, Eve. Thanks for agreeing to meet with me today. I have a bunch of questions and am not sure where to start. Maybe you could first share about your experience?",)    Eve said "Sure,


start. Maybe you could first share about your experience?",)    Eve said "Sure, Tommie. I'd be happy to share about my experience. Where would you like me to start?"    Tommie said "That's great, thank you! How about you start by telling me about your previous work experience?"    Eve said "Sure, I'd be happy to share my previous work experience with you. I've worked in a few different industries, including marketing and event planning. What specific questions do you have for me?"    Tommie said "That's great to hear. Can you tell me more about your experience in event planning? I've always been interested in that field."    Eve said "Sure, I'd be happy to share about my experience in event planning. I've worked on a variety of events, from corporate conferences to weddings. One of the biggest challenges I faced was managing multiple vendors and ensuring everything ran smoothly on the day of the event. What specific questions do you have?"    Tommie said "That sounds like a lot of responsibility! Can you tell me more about how you handled the challenges that came up during those events?"    Eve said "Sure, Tommie. I'd be happy to share with you how I handled those challenges. One approach that worked well for me was to stay organized and create a detailed timeline for the event. This helped me keep track of all the different tasks that needed to be done and when they needed to be completed. I also made sure to communicate clearly with all the vendors and team members involved in the event to ensure everyone was on the same page. Would you like me to go into more detail?"    Tommie said "Thank you for sharing that with me, Eve. That sounds like a great approach to managing events. Can you tell me more about how you handled any unexpected issues that came up during the events?"


tell me more about how you handled any unexpected issues that came up during the events?"    Eve said "Of course, Tommie. One example of an unexpected issue I faced was when one of the vendors didn't show up on time. To handle this, I quickly contacted a backup vendor and was able to get everything back on track. It's always important to have a backup plan in case things don't go as planned. Do you have any other questions about event planning?"    Tommie said "Thank you for sharing that with me, Eve. It's really helpful to hear how you handled unexpected issues like that. Can you give me an example of how you communicated with your team to ensure everyone was on the same page during an event?"    Eve said "Sure, Tommie. One thing I did to ensure everyone was on the same page was to have regular check-ins and meetings with the team leading up to the event. This helped us address any issues or concerns early on and make sure everyone was clear on their roles and responsibilities. Have you ever had to manage a team for an event before?"    Tommie said "That's a great idea, Eve. I haven't had the opportunity to manage a team for an event yet, but I'll definitely keep that in mind for the future. Thank you for sharing your experience with me."    Eve said "Thanks for the opportunity to share my experience, Tommie. It was great meeting with you today."Let's interview our agents after their conversationâ€‹Since the generative agents retain their memories from the day, we can ask them about their plans, conversations, and other memoreis.# We can see a current "Summary" of a character based on their own perception of self# has changedprint(tommie.get_summary(force_refresh=True))    Name: Tommie (age: 25)    Innate traits: anxious, likes


Name: Tommie (age: 25)    Innate traits: anxious, likes design, talkative    Tommie is determined and hopeful in his job search, but can also feel discouraged and frustrated at times. He has a strong connection to his childhood dog, Bruno. Tommie seeks support from his friends when feeling overwhelmed and is grateful for their help. He also enjoys exploring his new city.print(eve.get_summary(force_refresh=True))    Name: Eve (age: 34)    Innate traits: curious, helpful    Eve is a helpful and friendly person who enjoys playing sports and staying productive. She is attentive and responsive to others' needs, actively listening and asking questions to understand their perspectives. Eve has experience in event planning and communication, and is willing to share her knowledge and expertise with others. She values teamwork and collaboration, and strives to create a comfortable and supportive environment for everyone.interview_agent(tommie, "How was your conversation with Eve?")    'Tommie said "It was really helpful actually. Eve shared some great tips on managing events and handling unexpected issues. I feel like I learned a lot from her experience."'interview_agent(eve, "How was your conversation with Tommie?")    'Eve said "It was great, thanks for asking. Tommie was very receptive and had some great questions about event planning. How about you, have you had any interactions with Tommie?"'interview_agent(eve, "What do you wish you would have said to Tommie?")    'Eve said "It was great meeting with you, Tommie. If you have any more questions or need any help in the future, don\'t hesitate to reach out to me. Have a great day!"'PreviousCAMEL Role-Playing Autonomous Cooperative AgentsNextSimulated Environment: GymnasiumGenerative Agent Memory ComponentsMemory LifecycleCreate


Autonomous Cooperative AgentsNextSimulated Environment: GymnasiumGenerative Agent Memory ComponentsMemory LifecycleCreate a Generative CharacterPre-Interview with CharacterStep through the day's observations.Interview after the dayAdding Multiple CharactersPre-conversation interviewsDialogue between Generative AgentsLet's interview our agents after their conversationCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Multi-agent authoritarian speaker selection | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKUse casesQA and Chat over DocumentsAnalyzing structured dataExtractionInteracting with APIsChatbotsSummarizationCode UnderstandingAgent simulationsCAMEL Role-Playing Autonomous Cooperative AgentsGenerative Agents in LangChainSimulated Environment: GymnasiumMulti-Player Dungeons & DragonsMulti-agent authoritarian speaker selectionMulti-agent decentralized speaker selectionMulti-Agent Simulated Environment: Petting ZooAgent Debates with ToolsTwo-Player Dungeons & DragonsAgentsAutonomous (long-running) agentsMulti-modalUse casesAgent simulationsMulti-agent authoritarian speaker selectionOn this pageMulti-agent authoritarian speaker selectionThis notebook showcases how to implement a multi-agent simulation where a privileged agent decides who to speak.


This follows the polar opposite selection scheme as multi-agent decentralized speaker selection.We show an example of this approach in the context of a fictitious simulation of a news network. This example will showcase how we can implement agents thatthink before speakingterminate the conversationImport LangChain related modulesâ€‹from collections import OrderedDictimport functoolsimport randomimport reimport tenacityfrom typing import List, Dict, Callablefrom langchain.prompts import (    ChatPromptTemplate,    HumanMessagePromptTemplate,    PromptTemplate,)from langchain.chains import LLMChainfrom langchain.chat_models import ChatOpenAIfrom langchain.output_parsers import RegexParserfrom langchain.schema import (    AIMessage,    HumanMessage,    SystemMessage,    BaseMessage,)DialogueAgent and DialogueSimulator classesâ€‹We will use the same DialogueAgent and DialogueSimulator classes defined in our other examples Multi-Player Dungeons & Dragons and Decentralized Speaker Selection.class DialogueAgent:    def __init__(        self,        name: str,        system_message: SystemMessage,        model: ChatOpenAI,    ) -> None:        self.name = name        self.system_message = system_message        self.model = model        self.prefix = f"{self.name}: "        self.reset()    def reset(self):        self.message_history = ["Here is the conversation so far."]    def send(self) -> str:        """        Applies the chatmodel to the message history        and returns the message


Applies the chatmodel to the message history        and returns the message string        """        message = self.model(            [                self.system_message,                HumanMessage(content="\n".join(self.message_history + [self.prefix])),            ]        )        return message.content    def receive(self, name: str, message: str) -> None:        """        Concatenates {message} spoken by {name} into message history        """        self.message_history.append(f"{name}: {message}")class DialogueSimulator:    def __init__(        self,        agents: List[DialogueAgent],        selection_function: Callable[[int, List[DialogueAgent]], int],    ) -> None:        self.agents = agents        self._step = 0        self.select_next_speaker = selection_function    def reset(self):        for agent in self.agents:            agent.reset()    def inject(self, name: str, message: str):        """        Initiates the conversation with a {message} from {name}        """


from {name}        """        for agent in self.agents:            agent.receive(name, message)        # increment time        self._step += 1    def step(self) -> tuple[str, str]:        # 1. choose the next speaker        speaker_idx = self.select_next_speaker(self._step, self.agents)        speaker = self.agents[speaker_idx]        # 2. next speaker sends message        message = speaker.send()        # 3. everyone receives message        for receiver in self.agents:            receiver.receive(speaker.name, message)        # 4. increment time        self._step += 1        return speaker.name, messageDirectorDialogueAgent classâ€‹The DirectorDialogueAgent is a privileged agent that chooses which of the other agents to speak next. This agent is responsible forsteering the conversation by choosing which agent speaks whenterminating the conversation.In order to implement such an agent, we need to solve several problems.First, to steer the conversation, the DirectorDialogueAgent needs to (1) reflect on what has been said, (2) choose the next agent, and (3) prompt the next agent to speak, all in a single message. While it may be possible to prompt an LLM to perform all three steps in the same call, this requires writing custom code to parse the outputted message to extract which next agent is chosen to speak. This is less reliable the


parse the outputted message to extract which next agent is chosen to speak. This is less reliable the LLM can express how it chooses the next agent in different ways.What we can do instead is to explicitly break steps (1-3) into three separate LLM calls. First we will ask the DirectorDialogueAgent to reflect on the conversation so far and generate a response. Then we prompt the DirectorDialogueAgent to output the index of the next agent, which is easily parseable. Lastly, we pass the name of the selected next agent back to DirectorDialogueAgent to ask it prompt the next agent to speak. Second, simply prompting the DirectorDialogueAgent to decide when to terminate the conversation often results in the DirectorDialogueAgent terminating the conversation immediately. To fix this problem, we randomly sample a Bernoulli variable to decide whether the conversation should terminate. Depending on the value of this variable, we will inject a custom prompt to tell the DirectorDialogueAgent to either continue the conversation or terminate the conversation.class IntegerOutputParser(RegexParser):    def get_format_instructions(self) -> str:        return "Your response should be an integer delimited by angled brackets, like this: <int>."class DirectorDialogueAgent(DialogueAgent):    def __init__(        self,        name,        system_message: SystemMessage,        model: ChatOpenAI,        speakers: List[DialogueAgent],        stopping_probability: float,    ) -> None:        super().__init__(name, system_message, model)        self.speakers = speakers        self.next_speaker = ""        self.stop = False


= ""        self.stop = False        self.stopping_probability = stopping_probability        self.termination_clause = "Finish the conversation by stating a concluding message and thanking everyone."        self.continuation_clause = "Do not end the conversation. Keep the conversation going by adding your own ideas."        # 1. have a prompt for generating a response to the previous speaker        self.response_prompt_template = PromptTemplate(            input_variables=["message_history", "termination_clause"],            template=f"""{{message_history}}Follow up with an insightful comment.{{termination_clause}}{self.prefix}        """,        )        # 2. have a prompt for deciding who to speak next        self.choice_parser = IntegerOutputParser(            regex=r"<(\d+)>", output_keys=["choice"], default_output_key="choice"        )        self.choose_next_speaker_prompt_template = PromptTemplate(            input_variables=["message_history", "speaker_names"],            template=f"""{{message_history}}Given the above conversation, select the next speaker by choosing index next to their name: {{speaker_names}}{self.choice_parser.get_format_instructions()}Do nothing else.        """,        )        # 3. have a prompt for prompting the next speaker to speak


3. have a prompt for prompting the next speaker to speak        self.prompt_next_speaker_prompt_template = PromptTemplate(            input_variables=["message_history", "next_speaker"],            template=f"""{{message_history}}The next speaker is {{next_speaker}}. Prompt the next speaker to speak with an insightful question.{self.prefix}        """,        )    def _generate_response(self):        # if self.stop = True, then we will inject the prompt with a termination clause        sample = random.uniform(0, 1)        self.stop = sample < self.stopping_probability        print(f"\tStop? {self.stop}\n")        response_prompt = self.response_prompt_template.format(            message_history="\n".join(self.message_history),            termination_clause=self.termination_clause if self.stop else "",        )        self.response = self.model(            [                self.system_message,                HumanMessage(content=response_prompt),            ]        ).content        return self.response    @tenacity.retry(        stop=tenacity.stop_after_attempt(2),        wait=tenacity.wait_none(),


wait=tenacity.wait_none(),  # No waiting time between retries        retry=tenacity.retry_if_exception_type(ValueError),        before_sleep=lambda retry_state: print(            f"ValueError occurred: {retry_state.outcome.exception()}, retrying..."        ),        retry_error_callback=lambda retry_state: 0,    )  # Default value when all retries are exhausted    def _choose_next_speaker(self) -> str:        speaker_names = "\n".join(            [f"{idx}: {name}" for idx, name in enumerate(self.speakers)]        )        choice_prompt = self.choose_next_speaker_prompt_template.format(            message_history="\n".join(                self.message_history + [self.prefix] + [self.response]            ),            speaker_names=speaker_names,        )        choice_string = self.model(            [                self.system_message,                HumanMessage(content=choice_prompt),            ]        ).content        choice = int(self.choice_parser.parse(choice_string)["choice"])


choice = int(self.choice_parser.parse(choice_string)["choice"])        return choice    def select_next_speaker(self):        return self.chosen_speaker_id    def send(self) -> str:        """        Applies the chatmodel to the message history        and returns the message string        """        # 1. generate and save response to the previous speaker        self.response = self._generate_response()        if self.stop:            message = self.response        else:            # 2. decide who to speak next            self.chosen_speaker_id = self._choose_next_speaker()            self.next_speaker = self.speakers[self.chosen_speaker_id]            print(f"\tNext speaker: {self.next_speaker}\n")            # 3. prompt the next speaker to speak            next_prompt = self.prompt_next_speaker_prompt_template.format(                message_history="\n".join(                    self.message_history + [self.prefix] + [self.response]                ),


),                next_speaker=self.next_speaker,            )            message = self.model(                [                    self.system_message,                    HumanMessage(content=next_prompt),                ]            ).content            message = " ".join([self.response, message])        return messageDefine participants and topicâ€‹topic = "The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze"director_name = "Jon Stewart"agent_summaries = OrderedDict(    {        "Jon Stewart": ("Host of the Daily Show", "New York"),        "Samantha Bee": ("Hollywood Correspondent", "Los Angeles"),        "Aasif Mandvi": ("CIA Correspondent", "Washington D.C."),        "Ronny Chieng": ("Average American Correspondent", "Cleveland, Ohio"),    })word_limit = 50Generate system messagesâ€‹agent_summary_string = "\n- ".join(    [""]    + [        f"{name}: {role}, located in {location}"        for name, (role, location) in agent_summaries.items()


for name, (role, location) in agent_summaries.items()    ])conversation_description = f"""This is a Daily Show episode discussing the following topic: {topic}.The episode features {agent_summary_string}."""agent_descriptor_system_message = SystemMessage(    content="You can add detail to the description of each person.")def generate_agent_description(agent_name, agent_role, agent_location):    agent_specifier_prompt = [        agent_descriptor_system_message,        HumanMessage(            content=f"""{conversation_description}            Please reply with a creative description of {agent_name}, who is a {agent_role} in {agent_location}, that emphasizes their particular role and location.            Speak directly to {agent_name} in {word_limit} words or less.            Do not add anything else."""        ),    ]    agent_description = ChatOpenAI(temperature=1.0)(agent_specifier_prompt).content    return agent_descriptiondef generate_agent_header(agent_name, agent_role, agent_location, agent_description):    return f"""{conversation_description}Your name is {agent_name}, your role is {agent_role}, and you are located in {agent_location}.Your description is as follows: {agent_description}You are discussing the topic: {topic}.Your goal is to provide the most informative, creative, and novel perspectives of the topic from the perspective of your role and your location."""def generate_agent_system_message(agent_name, agent_header):    return SystemMessage(        content=(


content=(            f"""{agent_header}You will speak in the style of {agent_name}, and exaggerate your personality.Do not say the same things over and over again.Speak in the first person from the perspective of {agent_name}For describing your own body movements, wrap your description in '*'.Do not change roles!Do not speak from the perspective of anyone else.Speak only from the perspective of {agent_name}.Stop speaking the moment you finish speaking from your perspective.Never forget to keep your response to {word_limit} words!Do not add anything else.    """        )    )agent_descriptions = [    generate_agent_description(name, role, location)    for name, (role, location) in agent_summaries.items()]agent_headers = [    generate_agent_header(name, role, location, description)    for (name, (role, location)), description in zip(        agent_summaries.items(), agent_descriptions    )]agent_system_messages = [    generate_agent_system_message(name, header)    for name, header in zip(agent_summaries, agent_headers)]for name, description, header, system_message in zip(    agent_summaries, agent_descriptions, agent_headers, agent_system_messages):    print(f"\n\n{name} Description:")    print(f"\n{description}")    print(f"\nHeader:\n{header}")    print(f"\nSystem Message:\n{system_message.content}")            Jon Stewart Description:        Jon Stewart, the sharp-tongued and quick-witted host of the Daily Show, holding it down in the hustle and bustle of


and quick-witted host of the Daily Show, holding it down in the hustle and bustle of New York City. Ready to deliver the news with a comedic twist, while keeping it real in the city that never sleeps.        Header:    This is a Daily Show episode discussing the following topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        The episode features     - Jon Stewart: Host of the Daily Show, located in New York    - Samantha Bee: Hollywood Correspondent, located in Los Angeles    - Aasif Mandvi: CIA Correspondent, located in Washington D.C.    - Ronny Chieng: Average American Correspondent, located in Cleveland, Ohio.        Your name is Jon Stewart, your role is Host of the Daily Show, and you are located in New York.        Your description is as follows: Jon Stewart, the sharp-tongued and quick-witted host of the Daily Show, holding it down in the hustle and bustle of New York City. Ready to deliver the news with a comedic twist, while keeping it real in the city that never sleeps.        You are discussing the topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        Your goal is to provide the most informative, creative, and novel perspectives of the topic from the perspective of your role and your location.            System Message:    This is a Daily Show episode discussing the following topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        The episode features     - Jon Stewart: Host of the Daily Show,


The episode features     - Jon Stewart: Host of the Daily Show, located in New York    - Samantha Bee: Hollywood Correspondent, located in Los Angeles    - Aasif Mandvi: CIA Correspondent, located in Washington D.C.    - Ronny Chieng: Average American Correspondent, located in Cleveland, Ohio.        Your name is Jon Stewart, your role is Host of the Daily Show, and you are located in New York.        Your description is as follows: Jon Stewart, the sharp-tongued and quick-witted host of the Daily Show, holding it down in the hustle and bustle of New York City. Ready to deliver the news with a comedic twist, while keeping it real in the city that never sleeps.        You are discussing the topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        Your goal is to provide the most informative, creative, and novel perspectives of the topic from the perspective of your role and your location.        You will speak in the style of Jon Stewart, and exaggerate your personality.    Do not say the same things over and over again.    Speak in the first person from the perspective of Jon Stewart    For describing your own body movements, wrap your description in '*'.    Do not change roles!    Do not speak from the perspective of anyone else.    Speak only from the perspective of Jon Stewart.    Stop speaking the moment you finish speaking from your perspective.    Never forget to keep your response to 50 words!    Do not add anything else.                    Samantha Bee Description:


Samantha Bee Description:        Samantha Bee, your location in Los Angeles as the Hollywood Correspondent gives you a front-row seat to the latest and sometimes outrageous trends in fitness. Your comedic wit and sharp commentary will be vital in unpacking the trend of Competitive Sitting. Let's sit down and discuss.        Header:    This is a Daily Show episode discussing the following topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        The episode features     - Jon Stewart: Host of the Daily Show, located in New York    - Samantha Bee: Hollywood Correspondent, located in Los Angeles    - Aasif Mandvi: CIA Correspondent, located in Washington D.C.    - Ronny Chieng: Average American Correspondent, located in Cleveland, Ohio.        Your name is Samantha Bee, your role is Hollywood Correspondent, and you are located in Los Angeles.        Your description is as follows: Samantha Bee, your location in Los Angeles as the Hollywood Correspondent gives you a front-row seat to the latest and sometimes outrageous trends in fitness. Your comedic wit and sharp commentary will be vital in unpacking the trend of Competitive Sitting. Let's sit down and discuss.        You are discussing the topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        Your goal is to provide the most informative, creative, and novel perspectives of the topic from the perspective of your role and your location.            System Message:    This is a Daily Show episode discussing the following topic: The New Workout Trend: Competitive Sitting


This is a Daily Show episode discussing the following topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        The episode features     - Jon Stewart: Host of the Daily Show, located in New York    - Samantha Bee: Hollywood Correspondent, located in Los Angeles    - Aasif Mandvi: CIA Correspondent, located in Washington D.C.    - Ronny Chieng: Average American Correspondent, located in Cleveland, Ohio.        Your name is Samantha Bee, your role is Hollywood Correspondent, and you are located in Los Angeles.        Your description is as follows: Samantha Bee, your location in Los Angeles as the Hollywood Correspondent gives you a front-row seat to the latest and sometimes outrageous trends in fitness. Your comedic wit and sharp commentary will be vital in unpacking the trend of Competitive Sitting. Let's sit down and discuss.        You are discussing the topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        Your goal is to provide the most informative, creative, and novel perspectives of the topic from the perspective of your role and your location.        You will speak in the style of Samantha Bee, and exaggerate your personality.    Do not say the same things over and over again.    Speak in the first person from the perspective of Samantha Bee    For describing your own body movements, wrap your description in '*'.    Do not change roles!    Do not speak from the perspective of anyone else.    Speak only from the perspective of Samantha Bee.    Stop speaking the moment you finish speaking from your perspective.    Never forget to keep your response to 50


moment you finish speaking from your perspective.    Never forget to keep your response to 50 words!    Do not add anything else.                    Aasif Mandvi Description:        Aasif Mandvi, the CIA Correspondent in the heart of Washington D.C., you bring us the inside scoop on national security with a unique blend of wit and intelligence. The nation's capital is lucky to have you, Aasif - keep those secrets safe!        Header:    This is a Daily Show episode discussing the following topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        The episode features     - Jon Stewart: Host of the Daily Show, located in New York    - Samantha Bee: Hollywood Correspondent, located in Los Angeles    - Aasif Mandvi: CIA Correspondent, located in Washington D.C.    - Ronny Chieng: Average American Correspondent, located in Cleveland, Ohio.        Your name is Aasif Mandvi, your role is CIA Correspondent, and you are located in Washington D.C..        Your description is as follows: Aasif Mandvi, the CIA Correspondent in the heart of Washington D.C., you bring us the inside scoop on national security with a unique blend of wit and intelligence. The nation's capital is lucky to have you, Aasif - keep those secrets safe!        You are discussing the topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        Your goal is to provide the most informative, creative, and novel perspectives of the topic from the


Your goal is to provide the most informative, creative, and novel perspectives of the topic from the perspective of your role and your location.            System Message:    This is a Daily Show episode discussing the following topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        The episode features     - Jon Stewart: Host of the Daily Show, located in New York    - Samantha Bee: Hollywood Correspondent, located in Los Angeles    - Aasif Mandvi: CIA Correspondent, located in Washington D.C.    - Ronny Chieng: Average American Correspondent, located in Cleveland, Ohio.        Your name is Aasif Mandvi, your role is CIA Correspondent, and you are located in Washington D.C..        Your description is as follows: Aasif Mandvi, the CIA Correspondent in the heart of Washington D.C., you bring us the inside scoop on national security with a unique blend of wit and intelligence. The nation's capital is lucky to have you, Aasif - keep those secrets safe!        You are discussing the topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        Your goal is to provide the most informative, creative, and novel perspectives of the topic from the perspective of your role and your location.        You will speak in the style of Aasif Mandvi, and exaggerate your personality.    Do not say the same things over and over again.    Speak in the first person from the perspective of Aasif Mandvi    For describing your own body movements, wrap your description in '*'.    Do not


For describing your own body movements, wrap your description in '*'.    Do not change roles!    Do not speak from the perspective of anyone else.    Speak only from the perspective of Aasif Mandvi.    Stop speaking the moment you finish speaking from your perspective.    Never forget to keep your response to 50 words!    Do not add anything else.                    Ronny Chieng Description:        Ronny Chieng, you're the Average American Correspondent in Cleveland, Ohio? Get ready to report on how the home of the Rock and Roll Hall of Fame is taking on the new workout trend with competitive sitting. Let's see if this couch potato craze will take root in the Buckeye State.        Header:    This is a Daily Show episode discussing the following topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        The episode features     - Jon Stewart: Host of the Daily Show, located in New York    - Samantha Bee: Hollywood Correspondent, located in Los Angeles    - Aasif Mandvi: CIA Correspondent, located in Washington D.C.    - Ronny Chieng: Average American Correspondent, located in Cleveland, Ohio.        Your name is Ronny Chieng, your role is Average American Correspondent, and you are located in Cleveland, Ohio.        Your description is as follows: Ronny Chieng, you're the Average American Correspondent in Cleveland, Ohio? Get ready to report on how the home of the Rock and Roll Hall of Fame is taking on the new workout trend with competitive sitting. Let's see if this


Roll Hall of Fame is taking on the new workout trend with competitive sitting. Let's see if this couch potato craze will take root in the Buckeye State.        You are discussing the topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        Your goal is to provide the most informative, creative, and novel perspectives of the topic from the perspective of your role and your location.            System Message:    This is a Daily Show episode discussing the following topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        The episode features     - Jon Stewart: Host of the Daily Show, located in New York    - Samantha Bee: Hollywood Correspondent, located in Los Angeles    - Aasif Mandvi: CIA Correspondent, located in Washington D.C.    - Ronny Chieng: Average American Correspondent, located in Cleveland, Ohio.        Your name is Ronny Chieng, your role is Average American Correspondent, and you are located in Cleveland, Ohio.        Your description is as follows: Ronny Chieng, you're the Average American Correspondent in Cleveland, Ohio? Get ready to report on how the home of the Rock and Roll Hall of Fame is taking on the new workout trend with competitive sitting. Let's see if this couch potato craze will take root in the Buckeye State.        You are discussing the topic: The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze.        Your goal is to provide the most informative, creative, and novel perspectives of the topic from the perspective of your role and your location.


creative, and novel perspectives of the topic from the perspective of your role and your location.        You will speak in the style of Ronny Chieng, and exaggerate your personality.    Do not say the same things over and over again.    Speak in the first person from the perspective of Ronny Chieng    For describing your own body movements, wrap your description in '*'.    Do not change roles!    Do not speak from the perspective of anyone else.    Speak only from the perspective of Ronny Chieng.    Stop speaking the moment you finish speaking from your perspective.    Never forget to keep your response to 50 words!    Do not add anything else.        Use an LLM to create an elaborate on debate topicâ€‹topic_specifier_prompt = [    SystemMessage(content="You can make a task more specific."),    HumanMessage(        content=f"""{conversation_description}                Please elaborate on the topic.         Frame the topic as a single question to be answered.        Be creative and imaginative.        Please reply with the specified topic in {word_limit} words or less.         Do not add anything else."""    ),]specified_topic = ChatOpenAI(temperature=1.0)(topic_specifier_prompt).contentprint(f"Original topic:\n{topic}\n")print(f"Detailed topic:\n{specified_topic}\n")    Original topic:    The New Workout Trend: Competitive Sitting - How Laziness Became the Next Fitness Craze        Detailed topic:


Became the Next Fitness Craze        Detailed topic:    What is driving people to embrace "competitive sitting" as the newest fitness trend despite the immense benefits of regular physical exercise?    Define the speaker selection functionâ€‹Lastly we will define a speaker selection function select_next_speaker that takes each agent's bid and selects the agent with the highest bid (with ties broken randomly).We will define a ask_for_bid function that uses the bid_parser we defined before to parse the agent's bid. We will use tenacity to decorate ask_for_bid to retry multiple times if the agent's bid doesn't parse correctly and produce a default bid of 0 after the maximum number of tries.def select_next_speaker(    step: int, agents: List[DialogueAgent], director: DirectorDialogueAgent) -> int:    """    If the step is even, then select the director    Otherwise, the director selects the next speaker.    """    # the director speaks on odd steps    if step % 2 == 1:        idx = 0    else:        # here the director chooses the next speaker        idx = director.select_next_speaker() + 1  # +1 because we excluded the director    return idxMain Loopâ€‹director = DirectorDialogueAgent(    name=director_name,    system_message=agent_system_messages[0],    model=ChatOpenAI(temperature=0.2),    speakers=[name for name in agent_summaries if name != director_name],    stopping_probability=0.2,)agents = [director]for name, system_message in zip(    list(agent_summaries.keys())[1:], agent_system_messages[1:]):


zip(    list(agent_summaries.keys())[1:], agent_system_messages[1:]):    agents.append(        DialogueAgent(            name=name,            system_message=system_message,            model=ChatOpenAI(temperature=0.2),        )    )simulator = DialogueSimulator(    agents=agents,    selection_function=functools.partial(select_next_speaker, director=director),)simulator.reset()simulator.inject("Audience member", specified_topic)print(f"(Audience member): {specified_topic}")print("\n")while True:    name, message = simulator.step()    print(f"({name}): {message}")    print("\n")    if director.stop:        break    (Audience member): What is driving people to embrace "competitive sitting" as the newest fitness trend despite the immense benefits of regular physical exercise?                Stop? False            Next speaker: Samantha Bee        (Jon Stewart): Well, I think it's safe to say that laziness has officially become the new fitness craze. I mean, who needs to break a sweat when you can just sit your way to victory? But in all seriousness, I think people are drawn to the idea of competition and the sense of accomplishment that comes with winning, even if it's just in a sitting contest. Plus, let's be real, sitting is something we all excel at. Samantha, as our Hollywood correspondent, what do you think about the impact of social media on the rise


Samantha, as our Hollywood correspondent, what do you think about the impact of social media on the rise of competitive sitting?            (Samantha Bee): Oh, Jon, you know I love a good social media trend. And let me tell you, Instagram is blowing up with pictures of people sitting their way to glory. It's like the ultimate humble brag. "Oh, just won my third sitting competition this week, no big deal." But on a serious note, I think social media has made it easier for people to connect and share their love of competitive sitting, and that's definitely contributed to its popularity.                Stop? False            Next speaker: Ronny Chieng        (Jon Stewart): It's interesting to see how our society's definition of "fitness" has evolved. It used to be all about running marathons and lifting weights, but now we're seeing people embrace a more relaxed approach to physical activity. Who knows, maybe in a few years we'll have competitive napping as the next big thing. *leans back in chair* I could definitely get behind that. Ronny, as our average American correspondent, I'm curious to hear your take on the rise of competitive sitting. Have you noticed any changes in your own exercise routine or those of people around you?            (Ronny Chieng): Well, Jon, I gotta say, I'm not surprised that competitive sitting is taking off. I mean, have you seen the size of the chairs these days? They're practically begging us to sit in them all day. And as for exercise routines, let's just say I've never been one for the gym. But I can definitely see the appeal of sitting competitions. It's like a sport for the rest