diff --git a/README.md b/README.md index eecb3b0..4d8872f 100644 --- a/README.md +++ b/README.md @@ -1,34 +1 @@ -# LangGraph Streaming Agent - -This project demonstrates how to use LangGraph's streaming capabilities to display LLM responses token by token in real time. - -## Prerequisites - -- Python 3.10+ -- An OpenAI API key. Set it in a `.env` file or export `OPENAI_API_KEY`. - -## Installation - -bash -git clone -cd -python -m venv .venv -source .venv/bin/activate # On Windows use `.venv\Scripts\activate` -pip install -r requirements.txt - - -## Usage - -bash -python src/main.py - - -You will be prompted to enter a question. The answer will stream to the console as it is generated. - -## How it works - -The script builds a simple LangGraph agent that uses the OpenAI LLM. It calls `agent.stream()` with `stream_mode=['messages', 'updates']` and iterates over the returned chunks, printing each token as it arrives. - -## License - -MIT \ No newline at end of file +# LangGraph Streaming Agent\n\nThis project demonstrates how to use LangGraph to stream responses from an AI agent in real-time. Instead of waiting for the entire answer, the agent outputs tokens as they are generated, providing a more interactive experience.\n\n## Prerequisites\n\n- Python 3.10 or higher\n- An OpenAI API key (set as `OPENAI_API_KEY` in your environment)\n\n## Installation\n\nbash\npip install -r requirements.txt\n\n\n## Running the Agent\n\nbash\npython src/main.py\n\n\nThe agent will ask a simple math question and stream the answer token by token. You will see a separator when the agent moves to a new step.\n\n## Customization\n\n- Modify the `messages` in `src/main.py` to ask different questions.\n- Add or replace tools in the `tools` list to extend the agent's capabilities.\n \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 842d5d9..b7dd493 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1 @@ -langgraph -langchain -langchain-openai -python-dotenv \ No newline at end of file +langgraph\nlangchain\nopenai\npython-dotenv\n \ No newline at end of file diff --git a/src/main.py b/src/main.py index 74c2423..1ac63af 100644 --- a/src/main.py +++ b/src/main.py @@ -1,52 +1 @@ -import os -from dotenv import load_dotenv -from langgraph import AgentBuilder -from langchain_openai import ChatOpenAI - -load_dotenv() - -OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") -if not OPENAI_API_KEY: - raise ValueError("OPENAI_API_KEY not set in environment") - -llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo") - -builder = AgentBuilder(llm=llm) -agent = builder.build() - -def format_message(message) -> str: - if message.content: - return message.content - if message.tool_calls: - tool = message.tool_calls[0] - return f"{tool['name']}({tool['args']})" - return "" - -step = 1 - -def format_chunk_message(chunk): - global step - message, meta = chunk - if meta.get("langgraph_step") != step: - step = meta.get("langgraph_step") - print("\n --- --- --- \n") - if message.content: - print(message.content, end="", flush=True) - -def main(): - user_input = input("Enter your question: ") - stream = agent.stream( - {"messages": [{"role": "human", "content": user_input}]}, - stream_mode=["messages", "updates"] - ) - for chunk_type, chunk_data in stream: - if chunk_type == "messages": - format_chunk_message(chunk_data) - elif chunk_type == "updates": - if chunk_data.get("model"): - last_message = chunk_data["model"]["messages"][-1] - print(format_message(last_message)) - print("\n\nDone.") - -if __name__ == "__main__": - main() \ No newline at end of file +import os\nfrom dotenv import load_dotenv\nfrom langgraph import create_agent\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.tools import CalculatorTool\n\nload_dotenv()\n\ndef format_message(message) -> str:\n if message.content:\n return message.content\n return f\"{message.tool_calls[0]['name']}({message.tool_calls[0]['args']})\"\n\n\ndef main():\n llm = ChatOpenAI(temperature=0)\n tools = [CalculatorTool()]\n agent = create_agent(llm=llm, tools=tools)\n\n stream = agent.stream(\n {\n \"messages\": [{\"role\": \"human\", \"content\": \"What is 12 * 34?\"}]\n },\n stream_mode=['messages', 'updates']\n )\n\n step = 1\n for chunk in stream:\n chunk_type, chunk_data = chunk\n if chunk_type == \"messages\":\n message, meta = chunk_data\n if meta.get('langgraph_step') != step:\n step = meta.get('langgraph_step')\n print('\\n --- --- --- \\n')\n if message.content:\n print(message.content, end='', flush=True)\n elif chunk_type == \"updates\":\n if chunk_data.get('model'):\n last_message = chunk_data['model']['messages'][-1]\n print(format_message(last_message))\n\n print() # Final newline\n\n\nif __name__ == \"__main__\":\n main()\n \ No newline at end of file