
agent-review
Review aviation agent code changes for architecture compliance. Use when reviewing changes to shared
作者 roznet|オープンソース
Aviation Agent Architecture Review
Review code changes in shared/aviation_agent/ and web/server/api/aviation_agent_chat.py for compliance with the LangGraph agent architecture.
Agent Flow
Planner -> [Predict Next Queries] -> Tool -> Formatter -> END
The planner selects the appropriate tool based on user query. No routing layer.
Available Tools (from shared/airport_tools.py)
Airport Tools:
search_airports- Text/name/code search, country queriesfind_airports_near_location- Proximity search near a placefind_airports_near_route- Airports along a routeget_airport_details- Details for a specific ICAO codeget_notification_for_airport- Notification requirements
Rules Tools:
answer_rules_question- RAG-based semantic search (single country)browse_rules- Tag-based listing with paginationcompare_rules_between_countries- Semantic comparison (2+ countries)
Architecture Rules
-
UI Payload Stability - Flattened approach:
- Stable top-level keys (
kind,tool,departure,icao, etc.) toolfield for frontend context (e.g., legend mode switching)- Flattened common fields (
filters,visualization,airports) suggested_queriesfor follow-up suggestionsshow_rulesfor rules tools
- Stable top-level keys (
-
Tool Name Consistency:
- Tool names must match
shared/airport_tools.get_shared_tool_specs() - Planner uses literal tool names from manifest
- Tool names must match
-
State Management:
- Use
AgentStateTypedDict, no direct mutations - Errors stored in state, not raised as exceptions
- Use LangGraph reducers (
operator.addfor messages)
- Use
-
UI Payload Building:
- Only
build_ui_payload()createsui_payload - Centralized in
formatting.py - Tool-to-kind mapping must be correct
- Only
-
Visualization Types (from tool results):
route_with_markers- Route with airport markersmarkers- General airport markerspoint_with_markers- Location point with airportsmarker_with_details- Single airport focus
-
Filter Extraction:
- Filters in
plan.arguments.filters - Extracted by planner, not formatter
- Tools return
filter_profile
- Filters in
-
Error Handling:
- Store errors in
state["error"] - Formatter handles errors gracefully
- Errors emitted as SSE events
- Store errors in
-
Separation of Concerns:
planning.py- Planner logic onlyexecution.py- Tool execution onlyformatting.py- Formatting and UI payloadgraph.py- LangGraph nodes only
-
Configuration Management:
- LLM settings from
behavior_config.llms.* - Feature flags from
behavior_config.*.enabled - Prompts via
behavior_config.load_prompt(key) - No hardcoded config values
- LLM settings from
-
Tools Return DATA, Formatters Do SYNTHESIS:
- Tools NEVER call LLMs or do synthesis
- Tools return
_tool_typemarker for formatter routing - Formatter selects prompt based on
_tool_type - Example:
_tool_type: "comparison"→ usecomparison_synthesis_v1.md
-
Streaming Requirements:
- Use
astream_events(version="v2")for streaming - SSE events:
plan,thinking,tool_call_start,tool_call_end,message,ui_payload,done,error - Track token usage across all LLM calls
- Use
-
Structured Output:
- Prefer
with_structured_output(method="function_calling")for OpenAI - Validate planner output against tool manifest
- Fallback to
PydanticOutputParserfor non-OpenAI models
- Prefer
Review Checklist
UI Payload Structure
ui_payloadhaskindfield?ui_payloadhastoolfield for frontend context?- Common fields flattened at top level?
build_ui_payload()is the only place creatingui_payload?
Tool Name Consistency
- Tool names match
shared/airport_tools.py? - No hardcoded tool names that don't exist?
State Management
- Uses
AgentStateTypedDict? - Errors stored in state, not raised?
- Messages use
operator.addreducer?
Configuration
- No hardcoded LLM models/temperatures?
- Prompts loaded from config?
Formatter Strategy
- Comparison tool returns
_tool_type: "comparison"? - Formatter checks
_tool_typeand uses correct prompt? - No LLM synthesis happening in tools?
Streaming
- Uses
astream_events(version="v2")? - Token usage tracked across all LLM calls?
Red Flags
- Breaking UI payload structure: Changing stable top-level fields
- Missing tool field: UI payload without
toolfield - Invented tool names: Using names not in
shared/airport_tools.py - Direct state mutations:
state["key"] = valueinstead of returning dict - UI payload outside
build_ui_payload(): Creating manually - Raised exceptions:
raise Exception()instead ofreturn {"error": "..."} - Hardcoded config: LLM models, temperatures in code
- LLM synthesis in tools: Tools calling LLM directly (should return data only)
- Missing
_tool_typemarker: Comparison tool not setting_tool_type: "comparison" - Wrong streaming API: Using deprecated
astream()instead ofastream_events(version="v2")
Output Format
APPROVED:
file:line- Explanation of why it's correct
VIOLATION:
file:line- Description- Problem: Why it violates architecture
- Fix: Suggested corrected implementation
- Impact: What breaks
Key Files
Core Agent
shared/aviation_agent/state.py- AgentState TypedDictshared/aviation_agent/planning.py- Planner and AviationPlanshared/aviation_agent/execution.py- Tool executionshared/aviation_agent/formatting.py- Formatter and UI payloadshared/aviation_agent/graph.py- LangGraph assembly
RAG & Comparison
shared/aviation_agent/rules_rag.py- RAG system for rules retrievalshared/aviation_agent/answer_comparer.py- Embedding-based comparisonshared/aviation_agent/comparison_service.py- High-level comparison API
Adapters
shared/aviation_agent/adapters/streaming.py- SSE streaming adaptershared/aviation_agent/next_query_predictor.py- Follow-up suggestions
External
shared/airport_tools.py- Tool manifestconfigs/aviation_agent/default.json- Config schemaweb/server/api/aviation_agent_chat.py- FastAPI endpoint
Design Documents
designs/LLM_AGENT_DESIGN.md- Full architecture referencedesigns/CHATBOT_WEBUI_DESIGN.md- WebUI integrationdesigns/UI_FILTER_STATE_DESIGN.md- Filter and visualization mapping