Skip to content

Commit 1cdd349

Browse files
authored
Merge pull request #10 from ks6088ts-labs/feature/issue-9_basic-workflow-agent
add basic workflow agent
2 parents 2a3ac57 + a677f40 commit 1cdd349

File tree

6 files changed

+140
-0
lines changed

6 files changed

+140
-0
lines changed

docs/index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ uv run python -m template_langgraph.tasks.search_documents_on_elasticsearch
2424
# Run Kabuto Helpdesk Agent
2525
uv run python -m template_langgraph.tasks.run_kabuto_helpdesk_agent "KABUTOの起動時に、画面全体が紫色に点滅し、システムがフリーズします。"
2626
uv run python -m template_langgraph.tasks.run_kabuto_helpdesk_agent "KABUTOのマニュアルから禅モードに関する情報を教えて下さい"
27+
28+
# BasicWorkflowAgent
29+
uv run python -m template_langgraph.tasks.draw_basic_workflow_agent_mermaid_png "data/basic_workflow_agent.png"
30+
uv run python -m template_langgraph.tasks.run_basic_workflow_agent "KABUTOの起動時に、画面全体が紫色に点滅し、システムがフリーズします。"
2731
```
2832

2933
## References

template_langgraph/agents/basic_workflow_agent/__init__.py

Whitespace-only changes.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
from langchain_core.messages import AIMessage
2+
from langgraph.graph import END, START, StateGraph
3+
4+
from template_langgraph.agents.basic_workflow_agent.models import AgentInput, AgentOutput, AgentState
5+
from template_langgraph.llms.azure_openais import AzureOpenAiWrapper
6+
from template_langgraph.loggers import get_logger
7+
8+
logger = get_logger(__name__)
9+
10+
11+
class BasicWorkflowAgent:
12+
def __init__(self):
13+
self.llm = AzureOpenAiWrapper().chat_model
14+
15+
def create_graph(self):
16+
"""Create the main graph for the agent."""
17+
# Create the workflow state graph
18+
workflow = StateGraph(AgentState)
19+
20+
# Create nodes
21+
workflow.add_node("initialize", self.initialize)
22+
workflow.add_node("do_something", self.do_something)
23+
workflow.add_node("finalize", self.finalize)
24+
25+
# Create edges
26+
workflow.add_edge(START, "initialize")
27+
workflow.add_edge("initialize", "do_something")
28+
workflow.add_edge("do_something", "finalize")
29+
workflow.add_edge("finalize", END)
30+
31+
# Compile the graph
32+
return workflow.compile()
33+
34+
def initialize(self, state: AgentState) -> AgentState:
35+
"""Initialize the agent with the given state."""
36+
logger.info(f"Initializing BasicWorkflowAgent with state: {state}")
37+
# Here you can add any initialization logic if needed
38+
return state
39+
40+
def do_something(self, state: AgentState) -> AgentState:
41+
"""Perform some action with the given state."""
42+
logger.info(f"Doing something with state: {state}")
43+
44+
# Here you can add the logic for the action
45+
response: AIMessage = self.llm.invoke(
46+
input=state["messages"],
47+
)
48+
logger.info(f"Response after doing something: {response}")
49+
state["messages"].append(
50+
{
51+
"role": "assistant",
52+
"content": response.content,
53+
}
54+
)
55+
56+
return state
57+
58+
def finalize(self, state: AgentState) -> AgentState:
59+
"""Finalize the agent's work and prepare the output."""
60+
logger.info(f"Finalizing BasicWorkflowAgent with state: {state}")
61+
# Here you can add any finalization logic if needed
62+
return state
63+
64+
def run_agent(self, input: AgentInput) -> AgentOutput:
65+
"""Run the agent with the given input."""
66+
logger.info(f"Running BasicWorkflowAgent with question: {input.model_dump_json(indent=2)}")
67+
app = self.create_graph()
68+
initial_state: AgentState = {
69+
"messages": [
70+
{
71+
"role": "user",
72+
"content": input.request,
73+
}
74+
],
75+
}
76+
final_state = app.invoke(initial_state)
77+
logger.info(f"Final state after running agent: {final_state}")
78+
return AgentOutput(response=final_state["messages"][-1].content)
79+
80+
def draw_mermaid_png(self) -> bytes:
81+
"""Draw the graph in Mermaid format."""
82+
return self.create_graph().get_graph().draw_mermaid_png()
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from typing import Annotated, TypedDict
2+
3+
from langgraph.graph.message import add_messages
4+
from pydantic import BaseModel, Field
5+
6+
7+
class AgentInput(BaseModel):
8+
request: str = Field(..., description="ユーザーからのリクエスト")
9+
10+
11+
class AgentOutput(BaseModel):
12+
response: str = Field(..., description="エージェントの応答")
13+
14+
15+
class AgentState(TypedDict):
16+
messages: Annotated[list, add_messages]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import sys
2+
3+
from template_langgraph.agents.basic_workflow_agent.agent import BasicWorkflowAgent
4+
5+
if __name__ == "__main__":
6+
png_path = "data/basic_workflow_agent.png"
7+
if len(sys.argv) > 1:
8+
png_path = sys.argv[1]
9+
10+
with open(png_path, "wb") as f:
11+
f.write(BasicWorkflowAgent().draw_mermaid_png())
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import logging
2+
import sys
3+
4+
from template_langgraph.agents.basic_workflow_agent.agent import AgentInput, BasicWorkflowAgent
5+
from template_langgraph.loggers import get_logger
6+
7+
logger = get_logger(__name__)
8+
logger.setLevel(logging.INFO)
9+
10+
if __name__ == "__main__":
11+
question = "「鬼灯」を実行すると、KABUTOが急に停止します。原因と対策を教えてください。"
12+
if len(sys.argv) > 1:
13+
# sys.argv[1] が最初の引数
14+
question = sys.argv[1]
15+
16+
# Agentのインスタンス化
17+
agent = BasicWorkflowAgent()
18+
19+
# AgentInputの作成
20+
agent_input = AgentInput(
21+
request=question,
22+
)
23+
24+
# エージェントの実行
25+
logger.info(f"Running BasicWorkflowAgent with input: {agent_input.model_dump_json(indent=2)}")
26+
agent_output = agent.run_agent(input=agent_input)
27+
logger.info(f"Agent output: {agent_output.model_dump_json(indent=2)}")

0 commit comments

Comments
 (0)