despite some issues described below, your graph decomposition (separate model/tool/route nodes) is a strong start, and your questions show you’re debugging at the right level.
The issues I found are very common in early agent workflows - you’re on a solid track bro ![]()
Really nice work sharing your repo openly and iterating in public, I truly appreciate! ![]()
some quick findings:
High: blank_node returns full state, which can duplicate message history
- File:
agent/nodes/tools_nodes.py(blank_node) - Problem:
blank_nodereturns the entirestateinstead of a partial update
With currentmessagesreducer set tooperator.add, this can append full history back into itself - Impact: Message list can grow incorrectly (duplicate history), increase token costs, and break logic relying on “last message”
- Fix: Return
{}from pass-through nodes (or explicit minimal updates only).
Also switch message reducer toadd_messages(see finding #2), which is designed for message lists
High: Message state uses operator.add instead of add_messages
- File:
agent/messages_state/messages_state.py - Problem:
messagesusesAnnotated[list[AnyMessage], operator.add]. - Impact: Raw list concatenation does not provide message-aware merge semantics (id-aware updates, safe merge behavior for chat state). This is fragile for tool-calling loops and especially unsafe when branches are parallelized
- Fix: Use LangGraph’s built-in message reducer:
from langgraph.graph.message import add_messagesmessages: Annotated[list[AnyMessage], add_messages]
High: Tool dispatch is manual and unvalidated; vulnerable to call/result mismatch in parallel scenarios
- Files:
agent/nodes/tools_nodes.py,agent/nodes/choose.py,agent/main.py - Problem: Custom tool nodes always read from
state["messages"][-1].tool_callsand do not validate tool name dispatch against a tool registry - Impact: If multiple AI messages/tool-call batches appear in close sequence (or if you enable parallel branches), tool-call/result pairing can drift, producing invalid chat history and hard-to-debug behavior
- Fix: Use
ToolNode/agent runtime defaults (prefercreate_agentfor standard agent loops), or at minimum:- route a specific tool call payload to each tool executor
- validate tool name before invocation
- guarantee 1
ToolMessagepertool_call_id
High: Repository is not runnable out of the box (missing dependency manifest and missing config module)
- Files: project root,
utils/model_builder.py - Problem: No
requirements.txt/pyproject.tomlin repo; runtime immediately fails on missinglangchain_core
utils/model_builder.pyimportsutils.key.deepseek, bututils/key.pyis not committed - Impact: Reproducibility is broken; reviewers cannot run or verify behavior
- Fix: Add packaging and setup docs:
- committed dependency manifest
.env.example- load API key from environment via
os.getenv, not a local ignored module
Medium: Control-flow logic is brittle ("True"/"False" exact string matching)
- File:
agent/nodes/choose.py - Problem:
search_or_notchecks exact text equality on model output (== "False"). - Impact: Small output variation (
"false","False.", localized text) changes graph routing unexpectedly. - Fix: Use structured outputs / tool-call / strict schema for decision nodes, or normalize/parse robustly.
Medium: Entry script executes immediately on import
- File:
agent/main.py - Problem: Graph streaming runs at module import time.
- Impact: Importing for tests or reuse triggers real execution side effects.
- Fix: Wrap execution in
if __name__ == "__main__":.
Medium: Incorrect boolean expression in stream filtering
- File:
agent/main.py - Problem:
("False" or "True")always evaluates to"False". - Impact: Intended filtering logic is incorrect.
- Fix: Replace with explicit set check, e.g.:
chunk[-1][0].content not in {"False", "True"}.
Medium: Relative output path in PNG helper is unstable
- File:
utils/png_print.py - Problem: Writes to
../agent/graph_show/graph.pngrelative to CWD, not module path. - Impact: Output can go to wrong location depending on execution directory.
- Fix: Use
pathlib.Path(__file__)-based absolute path resolution.
Medium: Tool API shape inconsistency
- File:
agent/tools/base_tools.py - Problem:
search_local_position(city: str)requires acityargument even though description says it should fetch current user location. - Impact: Model may fail to provide required args; unnecessary invocation errors.
- Fix: Align signature with intended behavior (
search_local_position()) or rename and update prompt/docs.
Low: Dead/placeholder modules and weak tests
- Files:
agent/tools/all_tools.py,agent/tools/mcp_tools.py,test/test_01.py - Problem: Empty modules and a non-test script in
test/. - Impact: Noise and no confidence from automated tests.
- Fix: Remove placeholders or implement them; add real tests for:
- graph routing,
- tool-call/tool-result pairing,
- reducer behavior under repeated/branch execution.