Files
ailine/backend/app/agent_subgraphs
root 93b1f1b8ed docs: 恢复三大子图文档
- 恢复 contact/README.md
- 恢复 dictionary/README.md
- 恢复 research/README.md
- 恢复 agent_subgraphs/README.md
2026-04-25 13:47:15 +08:00
..
2026-04-25 13:47:15 +08:00
2026-04-25 13:47:15 +08:00
2026-04-25 13:47:15 +08:00
2026-04-25 13:47:15 +08:00

LangGraph Agent - 全能个人助手系统

该模块负责将个人助手从"查询型"升级为"全能执行型",通过 LangGraph 子图架构实现通讯录管理、智能词典、增强研究分析等核心功能。


🔧 公共工具与共享组件

三个子图共享一套统一的基础设施和通用工具,避免重复实现,确保架构一致。

公共工具架构

┌─────────────────────────────────────────────────────────────────┐
│                      公共工具层 (Shared Tools)                        │
├─────────────────────────────────────────────────────────────────┤
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│  │意图理解工具  │ │人工审核工具  │ │格式化输出  │ │状态管理│ │
│  └──────────────┘ └──────────────┘ └──────────────┘ └──────────┘ │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│  │检查点持久化  │ │条件路由      │ │LLM 调用      │ │数据库  │ │
│  └──────────────┘ └──────────────┘ └──────────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      子图层 (Subgraphs)                         │
├─────────────────────────────────────────────────────────────────┤
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐            │
│  │  通讯录子图  │ │  智能词典子图│ │ 研究分析子图│            │
│  └──────────────┘ └──────────────┘ └──────────────┘            │
└─────────────────────────────────────────────────────────────────┘

公共工具详解

1. 意图理解工具 (Intent Understanding Tool)

技术栈LangChain LLM + 少样本提示词 + 结构化输出

使用方法

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() + 状态持久化

使用方法

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 生成

使用方法

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

使用方法

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 条件边 + 路由函数

使用方法

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 + 重试 + 流式输出

使用方法

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

使用方法

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 + 类型注解

使用方法

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 中配置):

# 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. 继承状态基类
from agent_subgraphs.common.state import BaseSubgraphState

class MySubgraphState(BaseSubgraphState):
    my_field: str
  1. 使用公共意图理解
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
  1. 使用公共人工审核
from agent_subgraphs.common.human_loop import human_approval_node

def my_workflow(state: MySubgraphState) -> MySubgraphState:
    return human_approval_node(state)
  1. 使用公共格式化输出
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+ 子图执行、状态管理

主图架构流程图

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

子图架构总览

graph TB
    MainGraph[主图<br/>MainState]
    
    MainGraph --> ContactSub[通讯录子图<br/>ContactSubState]
    MainGraph --> DictSub[词典子图<br/>DictSubState]
    MainGraph --> ResearchSub[研究子图<br/>ResearchSubState]
    
    ContactSub --> ContactNodes[内部节点<br/>parse_intent<br/>add_contact<br/>list_contacts<br/>generate_draft<br/>human_approval<br/>send_email]
    DictSub --> DictNodes[内部节点<br/>translate<br/>lookup<br/>extract_terms<br/>daily_word]
    ResearchSub --> ResearchNodes[内部节点<br/>decompose<br/>web_search<br/>extract_info<br/>generate_report]
    
    ContactNodes --> PG[(PostgreSQL<br/>联系人)]
    DictNodes --> PG2[(PostgreSQL<br/>生词本)]
    ResearchNodes --> Qdrant[(Qdrant<br/>向量检索)]
    
    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)

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]

状态映射函数

# 通讯录子图输入映射
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,
    }

🎯 主图实现

主图构建器

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
恶意邮件发送 强制人工审核,单日发送数量限制 人工审核节点
联系人隐私 向量检索结果脱敏展示,仅交互时完整显示 通讯录子图节点
搜索内容安全 过滤成人内容,屏蔽高风险域名 研究子图搜索工具
敏感词输出 流式输出后处理过滤 最终响应节点

人工审核节点

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": ["确认", "修改", "取消"],
        }
    )

🚀 快速开始

环境配置

# 激活虚拟环境
source venv/bin/activate

# 安装依赖(新增)
pip install langgraph langchain-experimental

配置文件

.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

运行测试

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: 高级特性

  • 智能家居控制子图
  • 日程管理子图
  • 更多工具集成

📚 相关文档