# LangGraph Agent - 全能个人助手系统 该模块负责将个人助手从"查询型"升级为"全能执行型",通过 LangGraph 子图架构实现通讯录管理、智能词典、增强研究分析等核心功能。 --- ## 🔧 公共工具与共享组件 三个子图共享一套统一的基础设施和通用工具,避免重复实现,确保架构一致。 ### 公共工具架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 公共工具层 (Shared Tools) │ ├─────────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ │ │意图理解工具 │ │人工审核工具 │ │格式化输出 │ │状态管理│ │ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────┘ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ │ │检查点持久化 │ │条件路由 │ │LLM 调用 │ │数据库 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 子图层 (Subgraphs) │ ├─────────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 通讯录子图 │ │ 智能词典子图│ │ 研究分析子图│ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 公共工具详解 #### 1. 意图理解工具 (Intent Understanding Tool) **技术栈**:LangChain LLM + 少样本提示词 + 结构化输出 **使用方法**: ```python from agent_subgraphs.common.intent import parse_intent result = parse_intent( user_input="添加张三电话13800138000", intent_categories=["contact", "dictionary", "research", "chat"] ) # 返回: { # "intent_type": "contact", # "sub_intent": "add", # "extracted_info": {"name": "张三", "phone": "13800138000"} # } ``` **实现逻辑**: - 使用 LLM 进行意图分类,输出结构化 JSON - 关键词匹配兜底(如"保存"、"添加" → contact) - 自动提取关键信息(实体、参数) - 支持自定义意图分类器 **所有子图共用**:在 `agent_subgraphs/common/intent.py` --- #### 2. 人工审核工具 (Human-in-the-loop Tool) **技术栈**:LangGraph `interrupt()` + 状态持久化 **使用方法**: ```python from agent_subgraphs.common.human_loop import human_approval_node def email_send_workflow(state: dict) -> dict: # 生成邮件草稿... state["pending_action"] = {"type": "email_send", "draft": draft} return human_approval_node(state) # 挂起等待用户确认 ``` **实现逻辑**: - 使用 `interrupt()` 触发挂起 - 支持三种操作:确认、修改、取消 - 超时自动取消(可配置超时时间) - 用户反馈结构化存储 - 支持断点续作 **共享位置**:`agent_subgraphs/common/human_loop.py` **应用场景**: - 通讯录:邮件发送、联系人删除 - 研究分析:信息源确认、报告结构调整 - 智能词典:批量删除确认 --- #### 3. 格式化输出工具 (Formatting Tool) **技术栈**:Jinja2 模板 + Markdown 生成 **使用方法**: ```python from agent_subgraphs.common.format import format_output result = format_output( template="contact_result", data={"contact": contact_data, "action": "added"} ) ``` **实现逻辑**: - 预定义输出模板库 - 支持 Markdown、HTML、纯文本三种格式 - 自动处理列表、表格等复杂结构 - 支持用户自定义模板 **共享位置**:`agent_subgraphs/common/format.py` --- #### 4. 检查点持久化工具 (Checkpoint Tool) **技术栈**:LangGraph CheckpointSaver + SQLite / PostgreSQL **使用方法**: ```python from agent_subgraphs.common.checkpoint import get_checkpointer checkpointer = get_checkpointer(db_url="sqlite:///checkpoints.db") # 在图编译时传入 graph = workflow.compile(checkpointer=checkpointer) ``` **实现逻辑**: - 自动在每个节点执行后保存检查点 - 支持断点续作 - 状态版本管理 - 支持查询历史状态 **共享位置**:`agent_subgraphs/common/checkpoint.py` --- #### 5. 条件路由工具 (Conditional Routing Tool) **技术栈**:LangGraph 条件边 + 路由函数 **使用方法**: ```python from agent_subgraphs.common.routing import route_by_intent def my_router(state: dict) -> str: return route_by_intent( state, { "translate": "translate_node", "lookup": "lookup_node", } ) ``` **实现逻辑**: - 标准化的意图路由 - 支持复杂条件判断 - 路由函数可组合 - 自动处理默认分支 **共享位置**:`agent_subgraphs/common/routing.py` --- #### 6. LLM 调用工具 (LLM Invocation Tool) **技术栈**:LangChain ChatOpenAI + 重试 + 流式输出 **使用方法**: ```python from agent_subgraphs.common.llm import call_llm, call_llm_stream # 同步调用 result = call_llm(prompt="翻译这句话", system_prompt="你是翻译官") # 流式调用 async for chunk in call_llm_stream(prompt="写一篇文章"): print(chunk.content, end="") ``` **实现逻辑**: - 统一的 LLM 调用接口 - 自动重试(指数退避) - 支持流式和非流式 - Token 计数和监控 - 模型 fallback 机制 **共享位置**:`agent_subgraphs/common/llm.py` --- #### 7. 数据库工具 (Database Tool) **技术栈**:SQLAlchemy + PostgreSQL / SQLite **使用方法**: ```python from agent_subgraphs.common.db import get_db, add_record, query_records # 获取 session with get_db() as db: # 添加记录 add_record(db, Contact, {"name": "张三", "phone": "13800138000"}) # 查询记录 contacts = query_records(db, Contact, filters={"name": "张三"}) ``` **实现逻辑**: - 统一的 ORM 会话管理 - 标准 CRUD 操作封装 - 支持事务 - 自动错误处理 **共享位置**:`agent_subgraphs/common/db.py` --- #### 8. 状态基类工具 (State Base Classes) **技术栈**:TypedDict + 类型注解 **使用方法**: ```python from agent_subgraphs.common.state import BaseSubgraphState class ContactState(BaseSubgraphState): # 继承基础字段 contact_data: Optional[dict] # 自定义字段... ``` **实现逻辑**: - 预定义基础状态字段 - 类型安全 - 状态验证 - 状态合并辅助函数 **共享位置**:`agent_subgraphs/common/state.py` --- ### 公共工具目录结构 ``` agent_subgraphs/ ├── common/ # 公共工具层 │ ├── __init__.py │ ├── intent.py # 意图理解工具 │ ├── human_loop.py # 人工审核工具 │ ├── format.py # 格式化输出工具 │ ├── checkpoint.py # 检查点持久化工具 │ ├── routing.py # 条件路由工具 │ ├── llm.py # LLM 调用工具 │ ├── db.py # 数据库工具 │ ├── state.py # 状态基类 │ └── prompts/ # 公共提示词模板 │ ├── intent.j2 │ └── format.j2 ├── contact/ # 通讯录子图(简化版,使用公共工具) ├── dictionary/ # 智能词典子图(简化版,使用公共工具) └── research/ # 研究分析子图(简化版,使用公共工具) ``` --- ### 公共配置项 所有子图共享的配置项(在 `.env` 中配置): ```env # LLM 配置 LLM_PROVIDER=deepseek LLM_MODEL=deepseek-chat LLM_API_KEY=*** LLM_TEMPERATURE=0.7 LLM_MAX_TOKENS=2000 # 数据库配置 DB_URL=postgresql://user:pass@localhost/agent_db # 检查点配置 CHECKPOINT_DB_URL=sqlite:///checkpoints.db # 人工审核配置 HUMAN_LOOP_TIMEOUT=3600 # 格式化配置 DEFAULT_OUTPUT_FORMAT=markdown ``` --- ### 使用公共工具开发新子图 创建新子图的步骤: 1. **继承状态基类** ```python from agent_subgraphs.common.state import BaseSubgraphState class MySubgraphState(BaseSubgraphState): my_field: str ``` 2. **使用公共意图理解** ```python from agent_subgraphs.common.intent import parse_intent def intent_node(state: MySubgraphState) -> MySubgraphState: result = parse_intent(state["user_input"], ["my_intents]) state.update(result) return state ``` 3. **使用公共人工审核** ```python from agent_subgraphs.common.human_loop import human_approval_node def my_workflow(state: MySubgraphState) -> MySubgraphState: return human_approval_node(state) ``` 4. **使用公共格式化输出** ```python from agent_subgraphs.common.format import format_output def format_node(state: MySubgraphState) -> MySubgraphState: state["final_result"] = format_output("my_template", state) return state ``` --- ## 📑 目录导航 - [核心功能](#-核心功能) - 三大子图功能和技术特性 - [技术架构](#️-技术架构) - 技术栈、子图架构图、数据流 - [子图设计](#-子图设计) - 三个核心子图的详细说明 - [状态管理](#-状态管理) - 主状态和子状态定义 - [安全与边界](#️-安全与边界) - 安全机制和边界控制 - [快速开始](#-快速开始) - 开发环境搭建 - [实现指南](#-实现指南) - 子图开发、工具集成 - [未来规划](#-未来规划) - 多模态、流式输出等 --- ## 🎯 核心功能 ### 三大核心子图 | 子图模块 | 功能概述 | 关键特性 | |---------|---------|---------| | **通讯录子图** | 联系人 CRUD、邮件读取与审核、外发邮件、智能嗅探 | 人工审核强制、敏感信息加密、IMAP 邮箱绑定 | | **智能词典子图** | 翻译、查词、每日一词、专业名词提炼、生词本管理 | 联想记忆法、艾宾浩斯遗忘曲线、Anki 导出 | | **研究分析子图** | 联网搜索、报告生成、引用溯源、可视化图表 | 人工干预点、可定制报告结构、引用验证 | ### 通用机制 - ✅ **人工审核(Human-in-the-loop)**:通用节点,用于邮件发送、重要操作前的确认 - ✅ **自动联系人嗅探**:对话中出现"人名+联系方式"时,主动询问是否保存 - ✅ **流式输出**:所有 LLM 生成内容均采用流式传输,提升交互体验 - ✅ **长期记忆**:PostgreSQL + pgvector 实现持久化记忆和语义检索 --- ## 🏗️ 技术架构 ### 技术栈总览 | 层级 | 组件 | 技术选型 | 版本 | 说明 | |------|------|---------|------|------| | **Agent 框架** | 工作流编排 | LangGraph + LangChain | latest | 子图架构,状态机驱动 | | **LLM 服务** | 模型调用 | 智谱 AI / DeepSeek / 本地模型 | latest | 多模型路由 | | **向量数据库** | 语义检索 | Qdrant / pgvector | v1.12+ | 对话记忆、联系人语义索引 | | **关系数据库** | 结构化存储 | PostgreSQL | v16 | 联系人、生词本、邮件配置 | | **邮件协议** | IMAP/SMTP | `imaplib` / `smtplib` | 内置 | 邮件读取和发送 | | **后端框架** | API 服务 | FastAPI + Uvicorn | v0.115+ | 子图执行、状态管理 | ### 主图架构流程图 ```mermaid graph TB Start[START] --> Intent[意图分类节点] Intent -->|contact| ContactSubgraph[通讯录子图] Intent -->|dictionary| DictSubgraph[智能词典子图] Intent -->|research| ResearchSubgraph[研究分析子图] Intent -->|chat| ChatNode[普通对话节点] ContactSubgraph --> Final[最终响应] DictSubgraph --> Final ResearchSubgraph --> Final ChatNode --> Final Final --> End[END] style Start fill:#e1f5ff style Intent fill:#fff4e1 style ContactSubgraph fill:#e8f5e9 style DictSubgraph fill:#f3e5f5 style ResearchSubgraph fill:#ffebee style Final fill:#fff9c4 ``` ### 子图架构总览 ```mermaid graph TB MainGraph[主图
MainState] MainGraph --> ContactSub[通讯录子图
ContactSubState] MainGraph --> DictSub[词典子图
DictSubState] MainGraph --> ResearchSub[研究子图
ResearchSubState] ContactSub --> ContactNodes[内部节点
parse_intent
add_contact
list_contacts
generate_draft
human_approval
send_email] DictSub --> DictNodes[内部节点
translate
lookup
extract_terms
daily_word] ResearchSub --> ResearchNodes[内部节点
decompose
web_search
extract_info
generate_report] ContactNodes --> PG[(PostgreSQL
联系人)] DictNodes --> PG2[(PostgreSQL
生词本)] ResearchNodes --> Qdrant[(Qdrant
向量检索)] style MainGraph fill:#e1f5ff style ContactSub fill:#e8f5e9 style DictSub fill:#f3e5f5 style ResearchSub fill:#ffebee ``` ### 状态传递机制 ``` 主状态 (MainState) │ ├─→ input: {user_input: messages[-1].content} │ ▼ 子图状态 (SubState) │ ├─→ 内部处理... │ ▼ output: {messages: [AIMessage(final_result)], last_action: sub_state} │ ▼ 主状态更新 ``` --- ## 📂 项目结构 ``` Agent1/ ├── agent_subgraphs/ # LangGraph 子图模块 │ ├── __init__.py │ ├── contact/ # 通讯录子图 │ │ ├── README.md │ │ ├── __init__.py │ │ ├── state.py # 子图状态定义 │ │ ├── graph.py # 子图构建器 │ │ ├── nodes.py # 子图节点实现 │ │ ├── tools.py # 子图工具集 │ │ └── prompts.py # 提示词模板 │ ├── dictionary/ # 智能词典子图 │ │ ├── README.md │ │ ├── __init__.py │ │ ├── state.py │ │ ├── graph.py │ │ ├── nodes.py │ │ ├── tools.py │ │ └── prompts.py │ └── research/ # 研究分析子图 │ ├── README.md │ ├── __init__.py │ ├── state.py │ ├── graph.py │ ├── nodes.py │ ├── tools.py │ └── prompts.py ├── backend/ # 现有后端模块 │ └── app/ │ ├── graph/ # 主图构建 │ │ ├── graph_builder.py # 主图 + 子图集成 │ │ └── state.py # 主状态定义 │ └── ... └── ... ``` --- ## 🎯 状态管理 ### 主状态定义 (MainState) ```python from typing import TypedDict, List, Optional, Annotated from langchain_core.messages import BaseMessage from langgraph.graph import add_messages class MainState(TypedDict): messages: Annotated[List[BaseMessage], add_messages] intent: str # 顶层意图:contact / dictionary / research / chat sub_intent: str # 细分意图 # 工具通用 tool_call: Optional[dict] # 当前要执行的工具调用 tool_result: str # 控制流 next_node: str human_feedback: Optional[str] # 用于挂起重启 # 子图结果 last_contact_action: Optional[dict] last_dict_action: Optional[dict] last_research_action: Optional[dict] ``` ### 状态映射函数 ```python # 通讯录子图输入映射 def contact_input_mapper(state: MainState) -> dict: return { "user_input": state["messages"][-1].content, } # 通讯录子图输出映射 def contact_output_mapper(sub_state: dict, original: MainState) -> dict: return { "messages": [AIMessage(content=sub_state["final_result"])], "last_contact_action": sub_state, } ``` --- ## 🎯 主图实现 ### 主图构建器 ```python from langgraph.graph import StateGraph, START, END from agent_subgraphs.contact import build_contact_subgraph from agent_subgraphs.dictionary import build_dict_subgraph from agent_subgraphs.research import build_research_subgraph def build_main_graph() -> StateGraph: main_graph = StateGraph(MainState) # 添加子图节点 main_graph.add_node( "contact_module", build_contact_subgraph(), input=contact_input_mapper, output=contact_output_mapper, ) main_graph.add_node( "dict_module", build_dict_subgraph(), input=dict_input_mapper, output=dict_output_mapper, ) main_graph.add_node( "research_module", build_research_subgraph(), input=research_input_mapper, output=research_output_mapper, ) main_graph.add_node("chat_node", chat_node) main_graph.add_node("final_response", final_response_node) # 主图路由 main_graph.add_conditional_edges( START, route_main_intent, { "contact": "contact_module", "dictionary": "dict_module", "research": "research_module", "chat": "chat_node", } ) # 所有路径汇聚到最终响应 main_graph.add_edge("contact_module", "final_response") main_graph.add_edge("dict_module", "final_response") main_graph.add_edge("research_module", "final_response") main_graph.add_edge("chat_node", "final_response") main_graph.add_edge("final_response", END) return main_graph.compile() def route_main_intent(state: MainState) -> str: """顶层意图分类""" user_input = state["messages"][-1].content # 使用 LLM 分类 # 返回 contact / dictionary / research / chat ``` --- ## 🔒 安全与边界 ### 安全机制 | 风险点 | 对策 | 实现位置 | |--------|------|---------| | 邮箱密码泄露 | 使用环境变量存储,永不写入日志 | `agent_subgraphs/contact/tools.py` | | 恶意邮件发送 | 强制人工审核,单日发送数量限制 | 人工审核节点 | | 联系人隐私 | 向量检索结果脱敏展示,仅交互时完整显示 | 通讯录子图节点 | | 搜索内容安全 | 过滤成人内容,屏蔽高风险域名 | 研究子图搜索工具 | | 敏感词输出 | 流式输出后处理过滤 | 最终响应节点 | ### 人工审核节点 ```python from langgraph.graph import interrupt def human_approval_node(state: dict) -> dict: """人工审核节点:挂起图,等待外部输入""" pending_action = state["pending_action"] # 触发中断,等待外部通过 update_state 传入 human_feedback return interrupt( { "type": "human_approval", "message": f"请确认操作:{pending_action}", "options": ["确认", "修改", "取消"], } ) ``` --- ## 🚀 快速开始 ### 环境配置 ```bash # 激活虚拟环境 source venv/bin/activate # 安装依赖(新增) pip install langgraph langchain-experimental ``` ### 配置文件 在 `.env` 中新增: ```env # 通讯录模块 IMAP_SERVER=imap.qq.com IMAP_PORT=993 SMTP_SERVER=smtp.qq.com SMTP_PORT=587 EMAIL_USER=your_email@qq.com EMAIL_PASSWORD=your_auth_code # 词典模块 DEEPL_API_KEY=your_deepl_key YOUDAO_API_KEY=your_youdao_key # 研究模块 SEARCH_API_KEY=your_search_key ``` ### 运行测试 ```python from backend.app.graph.graph_builder import build_main_graph # 编译主图 graph = build_main_graph() # 调用子图 result = graph.invoke({ "messages": [HumanMessage(content="添加张三电话 13800138000")] }) print(result["messages"][-1].content) ``` --- ## 📖 实现指南 ### 添加新子图 1. 在 `agent_subgraphs/` 下创建新文件夹 2. 创建 `state.py` 定义子图状态 3. 创建 `nodes.py` 实现子图节点 4. 创建 `graph.py` 构建子图 5. 在主图 `graph_builder.py` 中注册新子图 ### 子图开发最佳实践 - ✅ 子图拥有独立的状态,避免与主状态命名冲突 - ✅ 使用 `input`/`output` 映射函数进行状态转换 - ✅ 子图内部节点之间直接连接,主图只负责路由到子图入口 - ✅ 将工具封装在子图内部,通过节点调用 - ✅ 提供子图级别的单元测试 --- ## 🎯 未来规划 ### Phase 1: 基础功能(当前) - [ ] 通讯录子图完整实现 - [ ] 智能词典子图完整实现 - [ ] 研究分析子图完整实现 - [ ] 主图集成和状态管理 ### Phase 2: 增强功能 - [ ] 流式输出改造(所有 LLM 调用) - [ ] 多模态语音输入(STT) - [ ] 可视化图表生成 - [ ] Anki 生词本导出 ### Phase 3: 高级特性 - [ ] 智能家居控制子图 - [ ] 日程管理子图 - [ ] 更多工具集成 --- ## 📚 相关文档 - [通讯录子图 README](./contact/README.md) - 详细了解通讯录模块 - [智能词典子图 README](./dictionary/README.md) - 详细了解词典模块 - [研究分析子图 README](./research/README.md) - 详细了解研究模块 - [主项目 README](../README.md) - 了解整体架构