Skip to content

Commit

Permalink
Merge pull request #66 from ks6088ts-labs/feature/issue-64_add-tools
Browse files Browse the repository at this point in the history
add an agent app with LangGraph
  • Loading branch information
ks6088ts authored Jun 1, 2024
2 parents a6ecb08 + 321f89c commit 35b2174
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 10 deletions.
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
- [Add message history (memory) > In-memory](https://python.langchain.com/v0.1/docs/expression_language/how_to/message_history/#in-memory)
- [Tool calling agent](https://python.langchain.com/v0.1/docs/modules/agents/agent_types/tool_calling/)
- [LangChain > Tools > Bing Search](https://python.langchain.com/v0.1/docs/integrations/tools/bing_search/)
- [Tool Calling with LangChain](https://blog.langchain.dev/tool-calling-with-langchain/)
- [langchain/cookbook/tool_call_messages.ipynb](https://github.com/langchain-ai/langchain/blob/master/cookbook/tool_call_messages.ipynb?ref=blog.langchain.dev)

## Backend

Expand Down
2 changes: 2 additions & 0 deletions frontend/entrypoint.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from frontend.solutions import (
agent_langgraph,
azure_ai_vision,
azure_storage,
chat,
Expand Down Expand Up @@ -28,6 +29,7 @@ def start(
SolutionType.DOCUMENT_INTELLIGENCE.value: document_intelligence.start,
SolutionType.AZURE_STORAGE.value: azure_storage.start,
SolutionType.AZURE_AI_VISION.value: azure_ai_vision.start,
SolutionType.AGENT_LANGGRAPH.value: agent_langgraph.start,
}
return solutions[solution_name.upper()](
backend_url=backend_url,
Expand Down
100 changes: 100 additions & 0 deletions frontend/solutions/agent_langgraph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import logging
import operator
from collections.abc import Sequence
from os import getenv
from typing import Annotated, TypedDict

import streamlit as st
from dotenv import load_dotenv
from langchain_core.messages import BaseMessage, HumanMessage, ToolMessage
from langchain_core.runnables import ConfigurableField, RunnableLambda
from langchain_openai import AzureChatOpenAI
from langgraph.graph import END, StateGraph

from frontend.solutions.internals.tools.examples import add, exponentiate, get_current_weather, multiply

logger = logging.getLogger(__name__)
load_dotenv("frontend.env")

tools = [
multiply,
exponentiate,
add,
get_current_weather,
]
llm = AzureChatOpenAI(
api_key=getenv("AZURE_OPENAI_API_KEY"),
api_version=getenv("AZURE_OPENAI_API_VERSION"),
azure_endpoint=getenv("AZURE_OPENAI_ENDPOINT"),
azure_deployment=getenv("AZURE_OPENAI_GPT_MODEL"),
).bind_tools(tools)

llm_with_tools = llm.configurable_alternatives(
ConfigurableField(id="llm"),
)


class AgentState(TypedDict):
messages: Annotated[Sequence[BaseMessage], operator.add]


def should_continue(state):
return "continue" if state["messages"][-1].tool_calls else "end"


def call_model(state, config):
return {"messages": [llm_with_tools.invoke(state["messages"], config=config)]}


def call_tools(state):
def _invoke_tool(tool_call):
tool = {tool.name: tool for tool in tools}[tool_call["name"]]
return ToolMessage(tool.invoke(tool_call["args"]), tool_call_id=tool_call["id"])

tool_executor = RunnableLambda(_invoke_tool)
last_message = state["messages"][-1]
return {"messages": tool_executor.batch(last_message.tool_calls)}


def create_graph():
workflow = StateGraph(AgentState)
workflow.add_node("agent", call_model)
workflow.add_node("action", call_tools)
workflow.set_entry_point("agent")
workflow.add_conditional_edges(
"agent",
should_continue,
{
"continue": "action",
"end": END,
},
)
workflow.add_edge("action", "agent")
return workflow.compile()


def start(
backend_url: str,
log_level: int,
):
logger.setLevel(log_level)
logger.debug(f"set log level to {log_level}")

st.title("ChatGPT-like clone")

graph = create_graph()

if prompt := st.chat_input("What is up?"):
with st.chat_message("user"):
st.markdown(prompt)

with st.spinner("Analyzing..."):
with st.chat_message("assistant"):
response = graph.invoke(
{
"messages": [
HumanMessage(prompt),
]
}
)
st.json(response)
9 changes: 0 additions & 9 deletions frontend/solutions/chat_langchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,6 @@ def get_session_history(session_id: str) -> BaseChatMessageHistory:
return store[session_id]


def run_bing_search(
query: str,
k=1,
) -> str:
from langchain_community.utilities import BingSearchAPIWrapper

return BingSearchAPIWrapper(k=k).run(query=query)


def start(
backend_url: str,
log_level: int,
Expand Down
Empty file.
Empty file.
25 changes: 25 additions & 0 deletions frontend/solutions/internals/tools/examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from langchain_core.tools import tool


@tool
def multiply(x: float, y: float) -> float:
"""Multiply 'x' times 'y'."""
return x * y


@tool
def exponentiate(x: float, y: float) -> float:
"""Raise 'x' to the 'y'."""
return x**y


@tool
def add(x: float, y: float) -> float:
"""Add 'x' and 'y'."""
return x + y


@tool
def get_current_weather(city: str) -> str:
"""Get the current weather in 'city'."""
return f"The weather in {city} is sunny."
1 change: 1 addition & 0 deletions frontend/solutions/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ class SolutionType(Enum):
DOCUMENT_INTELLIGENCE = "DOCUMENT_INTELLIGENCE"
AZURE_STORAGE = "AZURE_STORAGE"
AZURE_AI_VISION = "AZURE_AI_VISION"
AGENT_LANGGRAPH = "AGENT_LANGGRAPH"
16 changes: 15 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ langchain = "^0.2.1"
langchain-openai = "^0.1.8"
langchain-community = "^0.2.1"
langsmith = "^0.1.67"
langgraph = "^0.0.60"


[tool.poetry.group.azure-functions.dependencies]
Expand Down

0 comments on commit 35b2174

Please sign in to comment.