Skip to content

Commit 59b6185

Browse files
committed
add simple multi agent for explaining Command function
1 parent d1a1e66 commit 59b6185

File tree

5 files changed

+170
-0
lines changed

5 files changed

+170
-0
lines changed

docs/references.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
- [Streamlit](https://python.langchain.com/docs/integrations/callbacks/streamlit/)
1010
- [LangChain MCP Adapters](https://github.com/langchain-ai/langchain-mcp-adapters)
1111
- [Research Agent with MCP Integration.](https://github.com/langchain-ai/deep_research_from_scratch/blob/main/src/deep_research_from_scratch/research_agent_mcp.py)
12+
- [Command: A new tool for building multi-agent architectures in LangGraph](https://blog.langchain.com/command-a-new-tool-for-multi-agent-architectures-in-langgraph/)
13+
- [Combine control flow and state updates with Command](https://langchain-ai.github.io/langgraph/how-tos/graph-api/#combine-control-flow-and-state-updates-with-command)
14+
- [Command: a new tool for building multi-agent architectures in LangGraph](https://www.youtube.com/watch?v=6BJDKf90L9A)
1215

1316
### Sample Codes
1417

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import logging
2+
3+
import typer
4+
from dotenv import load_dotenv
5+
6+
from template_langgraph.agents.simple_multi_agent.multi_agent import app as multi_agent_app
7+
from template_langgraph.agents.simple_multi_agent.weather_agent import app as weather_agent_app
8+
from template_langgraph.loggers import get_logger
9+
10+
app = typer.Typer(
11+
add_completion=False,
12+
help="SimpleMultiAgent CLI",
13+
)
14+
logger = get_logger(__name__)
15+
16+
17+
@app.command()
18+
def weather_agent(
19+
query: str = typer.Option(
20+
"What's the weather in Japan?",
21+
"--query",
22+
"-q",
23+
help="The query to ask the model",
24+
),
25+
verbose: bool = typer.Option(
26+
False,
27+
"--verbose",
28+
"-v",
29+
help="Enable verbose output",
30+
),
31+
):
32+
if verbose:
33+
logger.setLevel(logging.DEBUG)
34+
35+
response = weather_agent_app.invoke(
36+
{
37+
"messages": [
38+
{"role": "user", "content": query},
39+
],
40+
},
41+
debug=True,
42+
)
43+
logger.info(response["messages"][-1].content)
44+
45+
46+
@app.command()
47+
def multi_agent(
48+
query: str = typer.Option(
49+
"What's the weather in Japan?",
50+
"--query",
51+
"-q",
52+
help="The query to ask the model",
53+
),
54+
verbose: bool = typer.Option(
55+
False,
56+
"--verbose",
57+
"-v",
58+
help="Enable verbose output",
59+
),
60+
):
61+
if verbose:
62+
logger.setLevel(logging.DEBUG)
63+
64+
response = multi_agent_app.invoke(
65+
{
66+
"messages": [
67+
{"role": "user", "content": query},
68+
],
69+
},
70+
debug=True,
71+
)
72+
logger.info(response["messages"][-1].content)
73+
74+
75+
if __name__ == "__main__":
76+
load_dotenv(
77+
override=True,
78+
verbose=True,
79+
)
80+
app()

template_langgraph/agents/simple_multi_agent/__init__.py

Whitespace-only changes.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from typing import Literal
2+
3+
from langgraph.graph import END, START, MessagesState, StateGraph
4+
from langgraph.types import Command
5+
6+
from template_langgraph.agents.simple_multi_agent.weather_agent import app
7+
from template_langgraph.llms.azure_openais import AzureOpenAiWrapper
8+
from template_langgraph.loggers import get_logger
9+
10+
logger = get_logger(__name__)
11+
12+
13+
def transfer_to_weather_agent():
14+
"""Call this to transfer to the weather agent"""
15+
16+
17+
tools = [transfer_to_weather_agent]
18+
llm = AzureOpenAiWrapper().chat_model.bind_tools(tools=tools)
19+
20+
21+
def call_model(state: MessagesState) -> Command[Literal["weather_agent", END]]:
22+
messages = state["messages"]
23+
response = llm.invoke(messages)
24+
if len(response.tool_calls) > 0:
25+
return Command(
26+
goto="weather_agent",
27+
)
28+
else:
29+
return Command(
30+
goto=END,
31+
update={
32+
"messages": [response],
33+
},
34+
)
35+
36+
37+
workflow = StateGraph(MessagesState)
38+
39+
workflow.add_node("agent", call_model)
40+
workflow.add_node("weather_agent", app)
41+
workflow.add_edge(START, "agent")
42+
app = workflow.compile()
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from typing import Literal
2+
3+
from langchain_core.tools import tool
4+
from langgraph.graph import END, START, MessagesState, StateGraph
5+
from langgraph.prebuilt import ToolNode
6+
from langgraph.types import Command
7+
8+
from template_langgraph.llms.azure_openais import AzureOpenAiWrapper
9+
10+
11+
@tool
12+
def search(query: str) -> str:
13+
"""Call to surf the web"""
14+
if "japan" in query.lower():
15+
return "It's 60 degrees and cloudy in Japan"
16+
return "It's 90 degrees and sunny in Japan"
17+
18+
19+
tools = [search]
20+
tool_node = ToolNode(tools=tools)
21+
llm = AzureOpenAiWrapper().chat_model.bind_tools(tools=tools)
22+
23+
24+
def call_model(state: MessagesState) -> Command[Literal["tools", END]]:
25+
messages = state["messages"]
26+
response = llm.invoke(messages)
27+
if len(response.tool_calls) > 0:
28+
next_node = "tools"
29+
else:
30+
next_node = END
31+
return Command(
32+
goto=next_node,
33+
update={
34+
"messages": [response],
35+
},
36+
)
37+
38+
39+
workflow = StateGraph(MessagesState)
40+
41+
workflow.add_node("agent", call_model)
42+
workflow.add_node("tools", tool_node)
43+
workflow.add_edge(START, "agent")
44+
workflow.add_edge("tools", "agent")
45+
app = workflow.compile()

0 commit comments

Comments
 (0)