Skip to content
LIVE
Loading prices...
How to build a Warren Buffett AI agent in minutes

How to build a Warren Buffett AI agent in minutes

How to build a Warren Buffett AI agent in minutes

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.

Ad

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.

Ad

#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.

Testing the Warren Buffett AI agent. Source: Analytics Vidhya
Testing the Warren Buffett AI agent. Source: Analytics Vidhya

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.

How do you rate this article?

Join our Socials

Briefly, clearly and without noise – get the most important crypto news and market insights first.