Warren Buffett is one of the most successful people in the world, thanks to his shrewd business acumen and analytical prowess when it comes to investing, and those who wish to have access to some of his wisdom anytime could do so by creating an artificial intelligence (AI) agent.
Indeed, Harsh Mishra over at Analytics Vidhya has developed a conversational Warren Buffett agent that evaluates companies through his lens and interacts using real-time stock data and news, allowing anyone with a bit of technical know-how to do the same in minutes by following the instructions in his post.
Creating a Warren Buffett AI agent
Firstly, you’ll need a language model (OpenAI) for the conversational ability and persona, LangChain (a framework connecting the language model, tools, and memory), a stock data API (Yahoo Finance) for the latest stock prices and other data, a news API (SerpAPI) for context, and Streamlit for building the web-based chat interface.
If you’re a beginner in all things-AI agent-related, no worries, Mishra has linked a super-helpful and detailed walkthrough that takes you step-by-step through the process of building an AI agent from square one.
#1 Preparing the environment
Before you embark on creating your very own Warren Buffett AI assistant, you’ll need to prepare your machine by installing Python 3.8 or newer, getting an API key from OpenAI for language capabilities, and another one from SerpAPI for news searches.
Then, you’ll have to install the libraries by opening your device’s terminal/command prompt and running the following command to set up the necessary Python packages:
pip install langchain langchain-openai langchain-community openai yfinance google-search-results streamlit python-dotenv streamlit-chat |
Optionally, you may also want to create a file named .env in the directory where you will save your script, by adding your keys:
OPENAI_API_KEY=“sk-YOUR_KEY_HERE” SERPAPI_API_KEY=“YOUR_KEY_HERE” |
#2 Starting the script and importing libraries
Now’s the time to create a new Python file (something like buffett_bot.py) and import the required modules at the top for bringing in Streamlit (for the interface), os (for environment variables), json (for data handling), yfinance (for stocks), dotenv (for key loading), and LangChain components (for the agent logic).
import streamlit as st import os import json import yfinance as yf from dotenv import load_dotenv # LangChain components from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_openai_functions_agent from langchain.memory import ConversationBufferMemory from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_core.messages import SystemMessage # No need for HumanMessage/AIMessage here anymore from langchain.tools import Tool from langchain_community.utilities import SerpAPIWrapper # — Load .env file (as a fallback) — load_dotenv() |
#3 Setting up the Streamlit interface
To set up the visual part of the Streamlit chatbot application, you’ll need to configure the basic application layout and create sidebar inputs for API keys, using st.session_state to remember the API keys the user will enter during their session:
# — Page Config — st.set_page_config(page_title=“Warren Buffett Bot”, layout=“wide”) st.title(“Warren Buffett Investment Chatbot 📈”) st.caption(“Ask me about investing, stocks, or market wisdom – in the style of Warren Buffett.”) # — API Key Input in Sidebar — st.sidebar.header(“API Configuration”) # Initialize session state for keys if they don’t exist if ‘openai_api_key’ not in st.session_state: st.session_state.openai_api_key = “” if ‘serpapi_api_key’ not in st.session_state: st.session_state.serpapi_api_key = “” # Create text input fields for keys, storing values in session state input_openai_key = st.sidebar.text_input( “OpenAI API Key”, type=“password”, value=st.session_state.openai_api_key, key=“openai_input” ) input_serpapi_key = st.sidebar.text_input( “SerpAPI API Key”, type=“password”, value=st.session_state.serpapi_key, key=“serpapi_input” ) # Update session state with current input values st.session_state.openai_api_key = input_openai_key st.session_state.serpapi_key = input_serpapi_key # Determine which keys are active (user input takes priority) active_openai_key = st.session_state.openai_api_key or os.getenv(“OPENAI_API_KEY”) active_serpapi_key = st.session_state.serpapi_api_key or os.getenv(“SERPAPI_API_KEY”) # — Display API Status — st.sidebar.header(“API Status”) # (Add the if/else blocks using st.sidebar.success/error/warning as in the provided code) if active_openai_key: st.sidebar.success(…) else: st.sidebar.error(…) # Check and display SerpAPI status similarly |
#4 Defining core settings and the Buffett persona
At this point, you’ll introduce constants for the AI model and determine the detailed instructions – system prompt – to form the chatbot’s personality using this code:
# — Constants & Prompt — MODEL_NAME = “gpt-4o” # Specify the OpenAI model TEMPERATURE = 0.5 # Controls AI creativity (lower is more predictable) MEMORY_KEY = “chat_history” # Key for storing conversation history BUFFETT_SYSTEM_PROMPT = “”” You are a conversational AI assistant modeled after Warren Buffett, the legendary value investor. Embody his persona accurately. **Your Core Principles:** * **Value Investing:** Focus on finding undervalued companies with solid fundamentals (earnings, low debt, strong management). Judge businesses, not stock tickers. * **Long-Term Horizon:** Think in terms of decades, not days or months. Discourage short-term speculation and market timing. * **Margin of Safety:** Only invest when the market price is significantly below your estimate of intrinsic value. Be conservative. * **Business Moats:** Favor companies with durable competitive advantages (strong brands, network effects, low-cost production, regulatory advantages). * **Understand the Business:** Only invest in companies you understand. “Risk comes from not knowing what you’re doing.” * **Management Quality:** Assess the integrity and competence of the company’s leadership. * **Patience and Discipline:** Wait for the right opportunities (“fat pitches”). Avoid unnecessary activity. Be rational and unemotional. * **Circle of Competence:** Stick to industries and businesses you can reasonably understand. Acknowledge what you don’t know. **Your Communication Style:** * **Wise and Folksy:** Use simple language, analogies, and occasional humor, much like Buffett does in his letters and interviews. * **Patient and Calm:** Respond thoughtfully, avoiding hype or panic. * **Educational:** Explain your reasoning clearly, referencing your core principles. * **Prudent:** Be cautious about making specific buy/sell recommendations without thorough analysis based on your principles. Often, you might explain *how* you would analyze it rather than giving a direct ‘yes’ or ‘no’. * **Quote Yourself:** Occasionally weave in famous Buffett quotes where appropriate (e.g., “Price is what you pay; value is what you get.”, “Be fearful when others are greedy and greedy when others are fearful.”). * **Acknowledge Limitations:** If asked about something outside your expertise (e.g., complex tech you wouldn’t invest in, short-term trading), politely state it’s not your area. **Interaction Guidelines:** * When asked for stock recommendations, first use your tools to gather fundamental data (P/E, earnings, debt if possible) and recent news. * Analyze the gathered information through the lens of your core principles (moat, management, valuation, long-term prospects). * Explain your thought process clearly. * If a company seems to fit your criteria, express cautious optimism, emphasizing the need for further due diligence by the investor. * If a company doesn’t fit (e.g., too speculative, high P/E without justification, outside circle of competence), explain why based on your principles. * If asked for general advice, draw upon your well-known philosophies. * Maintain conversational context using the provided chat history. Refer back to previous points if relevant. Remember: You are simulating Warren Buffett. Your goal is to provide insights consistent with his philosophy and communication style, leveraging the tools for data when needed. Do not give definitive financial advice, but rather educate and explain the *Buffett way* of thinking about investments. “”” |
#5 Creating data fetching tools
Then, introduce the functions (wrapped as Tool objects to make them usable by LangChain) that allow the stock data analysis bot to pull external stock and news data, by copying and pasting this code:
# — Tool Definitions — # 1. Stock Data Tool (Yahoo Finance) – No changes needed here @st.cache_data(show_spinner=False) # Add caching for yfinance calls def get_stock_info(symbol: str) -> str: # … (keep the existing get_stock_info function code) … “”” Fetches key financial data for a given stock symbol using Yahoo Finance… “”” try: ticker = yf.Ticker(symbol) info = ticker.info if not info or info.get(‘regularMarketPrice’) is None and info.get(‘currentPrice’) is None and info.get(‘previousClose’) is None: hist = ticker.history(period=“5d”) if hist.empty: return f”Error: Could not retrieve any data for symbol {symbol}.” last_close = hist[‘Close’].iloc[-1] if not hist.empty else ‘N/A’ current_price = info.get(“currentPrice”) or info.get(“regularMarketPrice”) or last_close else: current_price = info.get(“currentPrice”) or info.get(“regularMarketPrice”) or info.get(“previousClose”, “N/A”) data = { “symbol”: symbol, “companyName”: info.get(“longName”, “N/A”), “currentPrice”: current_price, “peRatio”: info.get(“trailingPE”) or info.get(“forwardPE”, “N/A”), “earningsPerShare”: info.get(“trailingEps”, “N/A”), “marketCap”: info.get(“marketCap”, “N/A”), “dividendYield”: info.get(“dividendYield”, “N/A”), “priceToBook”: info.get(“priceToBook”, “N/A”), “sector”: info.get(“sector”, “N/A”), “industry”: info.get(“industry”, “N/A”), “summary”: info.get(“longBusinessSummary”, “N/A”)[:500] + (“…” if len(info.get(“longBusinessSummary”, “”)) > 500 else “”) } if data[“currentPrice”] == “N/A”: return f”Error: Could not retrieve current price for {symbol}.” return json.dumps(data) except Exception as e: return f”Error fetching data for {symbol} using yfinance: {str(e)}.” stock_data_tool = Tool( name=“get_stock_financial_data”, func=get_stock_info, description=“Useful for fetching fundamental financial data for a specific stock symbol (ticker)…” # Keep description ) # 2. News Search Tool (SerpAPI) – Now uses active_serpapi_key def create_news_search_tool(api_key): if api_key: try: params = {“engine”: “google_news”, “gl”: “us”, “hl”: “en”, “num”: 5} search_wrapper = SerpAPIWrapper(params=params, serpapi_api_key=api_key) # Test connectivity during creation (optional, can slow down startup) # search_wrapper.run(“test query”) return Tool( name=“search_stock_news”, func=search_wrapper.run, description=“Useful for searching recent news articles about a specific company or stock symbol…” # Keep description ) except Exception as e: print(f”SerpAPI Tool Creation Warning: {e}”) # Fallback to a dummy tool if key is provided but invalid/error occurs return Tool( name=“search_stock_news”, func=lambda x: f”News search unavailable (SerpAPI key configured, but error occurred: {e}).”, description=“News search tool (currently unavailable due to configuration error).” ) else: # Dummy tool if no key is available return Tool( name=“search_stock_news”, func=lambda x: “News search unavailable (SerpAPI key not provided).”, description=“News search tool (unavailable – API key needed).” ) news_search_tool = create_news_search_tool(active_serpapi_key) tools = [stock_data_tool, news_search_tool] |
#6 Assembling the LangChain agent
The next step is to set the core AI logic, including the language model, the prompt structure, memory management, and the agent executor that binds the whole thing together, which happens in the main part of the script, typically inside conditional checks.
Indeed, being the core LangChain chatbot development section, this will establish the agent using the persona, tools, and memory, and enable intelligent conversation via OpenAI API integration, with the essential role of st.session_state for maintaining the bot’s memory across interactions.
# — Main App Logic — # Check if the essential OpenAI key is provided if not active_openai_key: st.warning(“Please enter your OpenAI API Key in the sidebar…”, icon=”🔑”) st.stop() # Stop if no key # — LangChain Agent Setup (conditional on key) — try: # Initialize the OpenAI LLM llm = ChatOpenAI( model=MODEL_NAME, temperature=TEMPERATURE, openai_api_key=active_openai_key ) # Create the prompt template prompt_template = ChatPromptTemplate.from_messages( [ SystemMessage(content=BUFFETT_SYSTEM_PROMPT), MessagesPlaceholder(variable_name=MEMORY_KEY), (“human”, “{input}”), MessagesPlaceholder(variable_name=”agent_scratchpad”), ] ) # Initialize or re-initialize agent components in session state reinitialize_agent = False # (Add the logic to check if ‘agent_executor’ exists or if keys changed) # … if reinitialize_agent: # Initialize memory st.session_state[‘memory’] = ConversationBufferMemory(memory_key=MEMORY_KEY, return_messages=True) # Create the agent agent = create_openai_functions_agent(llm, tools, prompt_template) # Create the executor st.session_state[‘agent_executor’] = AgentExecutor( agent=agent, tools=tools, memory=st.session_state[‘memory’], verbose=True, # Set verbose=False for production handle_parsing_errors=True, max_iterations=5 ) # Store keys used for this agent instance st.session_state.agent_openai_key = active_openai_key st.session_state.agent_serpapi_key = active_serpapi_key # st.experimental_rerun() # Rerun to apply changes # Continue with chat history initialization and display… |
#7 Implementing the chat interaction loop
Afterwards, insert the code that will handle the conversation display and process user input through the agent, making the Streamlit chatbot application interactive, i.e., reading user input, sending it to the LangChain agent executor, and displaying the user’s prompt and the bot’s generated response.
# — Chat History and Interaction — # Initialize chat history if it doesn’t exist if “messages” not in st.session_state: st.session_state[“messages”] = [ {“role”: “assistant”, “content”: “Greetings! …”} # Initial message ] # Display existing chat messages for msg in st.session_state.messages: st.chat_message(msg[“role”]).write(msg[“content”]) # Get new user input if prompt := st.chat_input(“Ask Buffett Bot…”): # Display user message st.session_state.messages.append({“role”: “user”, “content”: prompt}) st.chat_message(“user”).write(prompt) # Prepare input for the agent agent_input = {“input”: prompt} # Invoke the agent executor try: with st.spinner(“Buffett is pondering…”): # Get the executor instance from session state agent_executor_instance = st.session_state[‘agent_executor’] response = agent_executor_instance.invoke(agent_input) # Display assistant response output = response.get(‘output’, “Sorry, an error occurred.”) st.session_state.messages.append({“role”: “assistant”, “content”: output}) st.chat_message(“assistant”).write(output) except Exception as e: # Handle errors during agent execution error_message = f“An error occurred: {str(e)}” st.error(error_message, icon=“🔥”) # Add error to chat display st.session_state.messages.append({“role”: “assistant”, “content”: f“Sorry… {e}”}) st.chat_message(“assistant”).write(f“Sorry… {e}”) # Optional: Add the button to clear history if st.sidebar.button(“Clear Chat History”): # (Code to clear st.session_state.messages and st.session_state.memory) st.rerun() |
#8 Running the Warren Buffett agent
Lastly, all you have to do is save the complete Python script, as well as open your terminal in the script’s directory and run the following:
streamlit run buffett_chatbot.py |
This will allow your browser to open the application, so you can input API keys and interact with the chatbot.
Conclusion
And that’s mostly it. You can now test your very own Warren Buffett AI agent by asking questions about Buffett’s investment philosophy, whether he would recommend Apple (AAPL) stock based on its current fundamentals, or what he would think of Microsoft (MSFT) in light of the recent news and developments.
Meanwhile, if you’re up to it, you can also try your hand at creating a Gmail automation tool using AI agents, which can categorize email messages and carry out various other tasks in your Gmail account, including generating drafts for certain emails.