# IPCA **Repository Path**: lwhay/IPCA ## Basic Information - **Project Name**: IPCA - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-05 - **Last Updated**: 2026-05-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # LangGraph Demo LangGraph 可视化框架。 这版的目标很明确: - `nodes/` 里写的就是标准 LangGraph 节点函数 - `edges/` 里写的就是标准路由函数 - 前端只负责拖拽、连线、选择“哪个节点函数 / 哪个路由函数” ## 核心思路 在 LangGraph 里,本来就是两类东西: 1. 节点函数 传给 `add_node("name", node_func)` 2. 路由函数 传给 `add_conditional_edges("name", route_func, path_map)` 所以这个 Demo 也按这个方式组织: - `nodes/*.py`:节点函数 - `edges/*.py`:路由函数 静态边不需要单独写文件,前端直接连线即可,对应 `add_edge(...)`。 ## 目录结构 ```txt LangGraphDemo/ ├── app.py ├── env.template ├── plugin_framework.py ├── nodes/ │ ├── llm_chat.py │ ├── tavily_search.py │ └── template_text.py ├── edges/ │ ├── text_contains.py │ ├── text_equals.py │ └── field_truthy.py ├── static/ │ └── index.html └── requirements.txt ``` ## 使用方式 1. 进入目录 ```bash cd "/Users/owen/AI_learning/LangGraph/LangGraphDemo" ``` 2. 安装依赖 ```bash pip install -r requirements.txt ``` 3. 启动服务 ```bash python app.py ``` 4. 浏览器打开 ```txt http://127.0.0.1:8899 ``` ## 环境变量 后端会读取当前项目目录下的 `.env`: ```txt /Users/owen/AI_learning/LangGraph/LangGraphDemo/.env ``` 第一次使用时,可以从模板复制: ```bash cp env.template .env ``` 可用配置: - LLM - `LLM_BASE_URL` - `LLM_API_KEY` - `LANGGRAPH_DEMO_MODEL`,默认 `openai:gpt-4o-mini` - Tavily - `TAVILY_API_KEY` 兼容说明: - 代码当前仍兼容旧变量名 `QIHANG_BASE_URL` / `QIHANG_API` - 但仓库内统一推荐使用 `LLM_*` 命名 ## 节点怎么写 每个节点文件只需要两样东西: 1. `NODE` 元信息字典 给前端展示名字和说明 2. `node(state)` 函数 这就是标准 LangGraph 节点函数 最小示例: ```python NODE = { "type": "my_node", "title": "My Node", "description": "一个自定义节点示例。", } def node(state): return { "last_output": f"hello {state['input']}", "logs": ["my_node: done"], } ``` 后端会等价于: ```python builder.add_node("some_name", node) ``` 这是最原生的: ```python def node(state): return {...} ``` ### 节点返回什么 和 LangGraph 原生一致: - 最常见:返回状态更新字典 - `return {"last_output": "xxx"}` - 也可以返回 `Command(...)` 注意: - 路由函数不是节点函数 - 节点函数本身不负责 `add_conditional_edges(...)` ## 路由函数怎么写 每个路由文件也只需要两样东西: 1. `EDGE` 元信息字典 给前端展示名字和说明 2. `route(state)` 函数 这就是标准 LangGraph 路由函数 最小示例: ```python EDGE = { "type": "needs_search", "title": "Needs Search Route", "description": "如果需要搜索,返回 search,否则返回 direct。", } def route(state): if "SEARCH" in state["last_output"]: return "search" return "direct" ``` 后端会等价于: ```python builder.add_conditional_edges( "some_node", route, { "search": "tool_node", "direct": "answer_node", }, ) ``` ### 重要说明 这也是为什么: - 路由函数是“挂在节点上的” - 不是“每一条边自己有一个条件函数” 也就是说,前端里你给某个节点选择一个路由函数后,这个节点的所有外连线都会被组织成一次 `add_conditional_edges(...)`。 每条外连线的 `label`,就是 `path_map` 的 key。 所以路由函数返回什么,边的 label 就要写什么。 ## 当前内置 state 这个 Demo 统一使用下面这个 state: ```python class DemoState(TypedDict): input: str last_output: str tool_result: str data: dict[str, Any] logs: Annotated[list[str], operator.add] ``` 推荐约定: - 普通文本输出写到 `last_output` - 工具结果写到 `tool_result` - 自定义结构化数据放到 `data` - 调试日志追加到 `logs` ## `plugin_framework.py` 还保留了什么 保留了少量通用 helper: - `DemoState` - `get_model()` - `get_tavily_tool()` - `read_state_value()` - `to_text()` - `to_jsonable()` 这些 helper 可以用,也可以不用。 学生完全可以在自己的 node / edge 文件里直接写原生 LangGraph 逻辑。 ## 当前内置示例 节点: - `llm_chat` - `tavily_search` - `template_text` 路由函数: - `text_contains` - `text_equals` - `field_truthy` ## 前端交互语义 - 拖一条普通线:表示 `add_edge(...)` - 给某个节点选择一个路由函数:表示这个节点改用 `add_conditional_edges(...)` - 此时该节点所有外连线的 label 都必须填写,并和路由函数返回值对应 ## 学习顺序 1. 先看 `nodes/template_text.py`,理解最简单节点 2. 再看 `nodes/llm_chat.py`,理解模型节点 3. 再看 `edges/text_contains.py`,理解路由函数 4. 最后回到前端,把一个节点挂上路由函数,看它如何变成 `add_conditional_edges(...)`