Skip to content

Commit b58b898

Browse files
authored
Merge pull request #13 from ks6088ts-labs/feature/issue-12_structured-output
add structured output node demo
2 parents 1cdd349 + 7668576 commit b58b898

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

docs/index.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,15 @@ uv run python -m template_langgraph.tasks.run_kabuto_helpdesk_agent "KABUTOの
2828
# BasicWorkflowAgent
2929
uv run python -m template_langgraph.tasks.draw_basic_workflow_agent_mermaid_png "data/basic_workflow_agent.png"
3030
uv run python -m template_langgraph.tasks.run_basic_workflow_agent "KABUTOの起動時に、画面全体が紫色に点滅し、システムがフリーズします。"
31+
uv run python -m template_langgraph.tasks.run_basic_workflow_agent "私の名前はフグ田 サザエ。東京都世田谷区桜新町あさひが丘3丁目に住んでいる 24 歳の主婦です。夫のノリスケと子供のタラちゃんがいます。"
3132
```
3233

3334
## References
3435

36+
### Sample Codes
37+
38+
- [「現場で活用するためのAIエージェント実践入門」リポジトリ](https://github.com/masamasa59/genai-agent-advanced-book)
39+
3540
### Models
3641

3742
- [AzureOpenAIEmbeddings](https://python.langchain.com/docs/integrations/text_embedding/azureopenai/)

template_langgraph/agents/basic_workflow_agent/agent.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from langchain_core.messages import AIMessage
22
from langgraph.graph import END, START, StateGraph
33

4-
from template_langgraph.agents.basic_workflow_agent.models import AgentInput, AgentOutput, AgentState
4+
from template_langgraph.agents.basic_workflow_agent.models import AgentInput, AgentOutput, AgentState, Profile
55
from template_langgraph.llms.azure_openais import AzureOpenAiWrapper
66
from template_langgraph.loggers import get_logger
77

@@ -20,12 +20,14 @@ def create_graph(self):
2020
# Create nodes
2121
workflow.add_node("initialize", self.initialize)
2222
workflow.add_node("do_something", self.do_something)
23+
workflow.add_node("extract_profile", self.extract_profile)
2324
workflow.add_node("finalize", self.finalize)
2425

2526
# Create edges
2627
workflow.add_edge(START, "initialize")
2728
workflow.add_edge("initialize", "do_something")
28-
workflow.add_edge("do_something", "finalize")
29+
workflow.add_edge("do_something", "extract_profile")
30+
workflow.add_edge("extract_profile", "finalize")
2931
workflow.add_edge("finalize", END)
3032

3133
# Compile the graph
@@ -55,6 +57,15 @@ def do_something(self, state: AgentState) -> AgentState:
5557

5658
return state
5759

60+
def extract_profile(self, state: AgentState) -> AgentState:
61+
"""Extract profile information from the state."""
62+
logger.info(f"Extracting profile from state: {state}")
63+
profile = self.llm.with_structured_output(Profile).invoke(
64+
input=state["messages"],
65+
)
66+
state["profile"] = profile
67+
return state
68+
5869
def finalize(self, state: AgentState) -> AgentState:
5970
"""Finalize the agent's work and prepare the output."""
6071
logger.info(f"Finalizing BasicWorkflowAgent with state: {state}")
@@ -75,7 +86,10 @@ def run_agent(self, input: AgentInput) -> AgentOutput:
7586
}
7687
final_state = app.invoke(initial_state)
7788
logger.info(f"Final state after running agent: {final_state}")
78-
return AgentOutput(response=final_state["messages"][-1].content)
89+
return AgentOutput(
90+
response=final_state["messages"][-1].content,
91+
profile=final_state["profile"],
92+
)
7993

8094
def draw_mermaid_png(self) -> bytes:
8195
"""Draw the graph in Mermaid format."""

template_langgraph/agents/basic_workflow_agent/models.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,22 @@
44
from pydantic import BaseModel, Field
55

66

7+
class Profile(BaseModel):
8+
first_name: str = Field(..., description="名")
9+
last_name: str = Field(..., description="姓")
10+
age: int | None = Field(None, description="年齢")
11+
address: str | None = Field(None, description="住所")
12+
13+
714
class AgentInput(BaseModel):
815
request: str = Field(..., description="ユーザーからのリクエスト")
916

1017

1118
class AgentOutput(BaseModel):
1219
response: str = Field(..., description="エージェントの応答")
20+
profile: Profile | None = Field(None, description="抽出されたプロファイル情報")
1321

1422

1523
class AgentState(TypedDict):
1624
messages: Annotated[list, add_messages]
25+
profile: Profile | None = Field(None, description="抽出されたプロファイル情報")

0 commit comments

Comments
 (0)