[{"data":1,"prerenderedAt":1500},["ShallowReactive",2],{"lab-/labs/tianting":3},{"id":4,"title":5,"author":6,"body":7,"category":1483,"date":1484,"description":1485,"extension":1486,"featured":1487,"home_position":1139,"image":1488,"meta":1489,"navigation":1487,"order":1109,"path":1490,"seo":1491,"status":1492,"stem":1493,"tags":1494,"__hash__":1499},"content/labs/TianTing.md","TiTi","sibuchen",{"type":8,"value":9,"toc":1450},"minimark",[10,15,20,29,36,39,43,48,59,63,183,185,189,193,200,244,254,260,268,294,300,323,327,337,363,366,371,377,384,388,399,407,453,461,472,477,483,487,493,498,542,547,584,598,602,613,619,655,663,678,682,688,693,705,710,716,724,756,760,766,787,793,819,823,831,845,850,871,875,881,995,997,1001,1005,1011,1015,1021,1032,1039,1050,1058,1069,1071,1075,1082,1088,1091,1159,1161,1165,1168,1297,1308,1310,1314,1318,1321,1325,1328,1332,1335,1339,1348,1352,1355,1359,1362,1364,1368,1446],[11,12,14],"h1",{"id":13},"titi-智能客服系统","TiTi 智能客服系统",[16,17,19],"h2",{"id":18},"一项目概述","一、项目概述",[21,22,23,24,28],"p",{},"TiTi (TianTing) 是一个",[25,26,27],"strong",{},"企业级 AI 智能客服平台","，支持多渠道接入（Web 网页、飞书 IM），采用 Agent 编排架构实现意图识别与自动路由，结合 RAG 检索增强、知识图谱、MCP 工具调用和人工客服转接，为用户提供端到端的智能问答服务。",[21,30,31,32,35],{},"项目采用",[25,33,34],{},"前后端分离 + Docker 容器化","部署，后端基于 Python FastAPI，前端基于 Next.js (React)，通过 Nginx 网关统一入口。",[37,38],"hr",{},[16,40,42],{"id":41},"二技术架构","二、技术架构",[44,45,47],"h3",{"id":46},"_21-整体架构图","2.1 整体架构图",[49,50,55],"pre",{"className":51,"code":53,"language":54},[52],"language-text","用户端（Web / 飞书）\n       │\n       ▼\n   Nginx Gateway (:3534)\n       │\n   ┌───┴───┐\n   ▼       ▼\nNext.js   FastAPI (:2811)\n(frontend)    │\n              ├── Agent Runtime (LangChain + LangGraph)\n              │      ├── Orchestrator（编排器）\n              │      ├── FAQ Agent / After-sale Agent / Custom Agent\n              │      ├── Sub-Agent 调用链\n              │      └── MCP 工具执行\n              │\n              ├── RAG Pipeline\n              │      ├── Embedder (NVIDIA nv-embed-v1 / OpenAI Compatible)\n              │      ├── Retriever (pgvector cosine + Qdrant fallback)\n              │      └── QA Search (向量优先 + ILIKE 兜底)\n              │\n              ├── Knowledge Graph (Neo4j)\n              │      ├── Agent-Skill-Tool 关系图\n              │      └── User-Conversation-Agent 关系图\n              │\n              └── IM Channel Adapter\n                     ├── WebAdapter（WebSocket）\n                     └── FeishuAdapter（Lark SDK）\n\n数据层：\n  PostgreSQL (pgvector) — 主数据 + 向量存储\n  Redis — 缓存 / 限频 / ARQ 异步任务队列\n  Qdrant — 高性能向量检索\n  Neo4j — 知识图谱\n  MongoDB — 对话日志 / 非结构化数据\n","text",[56,57,53],"code",{"__ignoreMap":58},"",[44,60,62],{"id":61},"_22-技术栈","2.2 技术栈",[64,65,66,79],"table",{},[67,68,69],"thead",{},[70,71,72,76],"tr",{},[73,74,75],"th",{},"层级",[73,77,78],{},"技术选型",[80,81,82,93,103,113,123,133,143,153,163,173],"tbody",{},[70,83,84,90],{},[85,86,87],"td",{},[25,88,89],{},"前端",[85,91,92],{},"Next.js 14 (App Router)、React、TypeScript、Zustand 状态管理、next-intl 国际化、pnpm",[70,94,95,100],{},[85,96,97],{},[25,98,99],{},"后端",[85,101,102],{},"Python 3.12、FastAPI、SQLAlchemy 2.0 (async)、Pydantic v2",[70,104,105,110],{},[85,106,107],{},[25,108,109],{},"AI 框架",[85,111,112],{},"LangChain、LangGraph、OpenAI Compatible API",[70,114,115,120],{},[85,116,117],{},[25,118,119],{},"向量存储",[85,121,122],{},"pgvector (PostgreSQL) + Qdrant（双引擎，Qdrant 优先）",[70,124,125,130],{},[85,126,127],{},[25,128,129],{},"知识图谱",[85,131,132],{},"Neo4j 5 + APOC",[70,134,135,140],{},[85,136,137],{},[25,138,139],{},"消息队列",[85,141,142],{},"Redis (ARQ 异步任务)",[70,144,145,150],{},[85,146,147],{},[25,148,149],{},"日志存储",[85,151,152],{},"MongoDB 7",[70,154,155,160],{},[85,156,157],{},[25,158,159],{},"IM 集成",[85,161,162],{},"飞书 Lark SDK (lark-oapi)",[70,164,165,170],{},[85,166,167],{},[25,168,169],{},"安全",[85,171,172],{},"JWT (access + refresh token)、AES-256-GCM (API Key 加密)、bcrypt 密码哈希",[70,174,175,180],{},[85,176,177],{},[25,178,179],{},"部署",[85,181,182],{},"Docker Compose、Nginx 反向代理",[37,184],{},[16,186,188],{"id":187},"三核心模块详解","三、核心模块详解",[44,190,192],{"id":191},"_31-agent-编排系统","3.1 Agent 编排系统",[21,194,195,196,199],{},"这是天听的核心引擎。系统采用",[25,197,198],{},"编排器 + 子 Agent"," 的多智能体架构：",[201,202,203,210,216,226],"ul",{},[204,205,206,209],"li",{},[25,207,208],{},"Orchestrator（编排器）","：作为入口 Agent，负责意图识别和任务路由。编排器通过 LLM Tool Calling 机制，自主决定是直接回复用户，还是调用子 Agent 处理特定问题。",[204,211,212,215],{},[25,213,214],{},"专业 Agent","：包括 FAQ Agent（常见问题）、After-sale Agent（售后处理）、Custom Agent（自定义），每种 Agent 拥有独立的 System Prompt、模型配置、技能和工具。",[204,217,218,221,222,225],{},[25,219,220],{},"Sub-Agent 调用链","：编排器通过 ",[56,223,224],{},"call_subagent_*"," 工具动态调用子 Agent，子 Agent 的返回结果作为上下文回传给编排器，形成多轮推理循环（最多 8 轮）。",[204,227,228,231,232,235,236,239,240,243],{},[25,229,230],{},"人工转接","：双重触发机制 —— 关键词匹配（",[56,233,234],{},"transfer_keywords","）和 LLM 判断（",[56,237,238],{},"transfer_to_human"," 工具调用），转接时自动创建 ",[56,241,242],{},"HumanSession"," 进入等待队列。",[21,245,246,249,250,253],{},[25,247,248],{},"Agent Runtime 核心流程","（",[56,251,252],{},"agents/runtime/runtime.py","）：",[49,255,258],{"className":256,"code":257,"language":54},[52],"用户消息 → 查找 Orchestrator → 检查转接关键词\n                                      │\n                    ┌─────────────────┤\n                    ▼                 ▼\n              直接转人工        构建 System Prompt\n                                (技能元数据 + 工具描述)\n                                      │\n                                      ▼\n                              LLM 推理循环 (最多8轮)\n                              ┌──────────────┐\n                              │ Tool Calls?  │\n                              │  是 → 并行执行│→ 结果回注上下文 → 继续循环\n                              │  否 → 返回文本│→ 结束\n                              └──────────────┘\n",[56,259,257],{"__ignoreMap":58},[21,261,262,249,265,253],{},[25,263,264],{},"支持的 Agent 类型",[56,266,267],{},"models/agent.py",[201,269,270,276,282,288],{},[204,271,272,275],{},[56,273,274],{},"orchestrator"," — 编排器，全局唯一入口",[204,277,278,281],{},[56,279,280],{},"faq"," — FAQ 问答",[204,283,284,287],{},[56,285,286],{},"after-sale"," — 售后处理",[204,289,290,293],{},[56,291,292],{},"custom"," — 自定义场景",[21,295,296,299],{},[25,297,298],{},"Agent 可配置能力","：",[201,301,302,305,308,311,314,317,320],{},[204,303,304],{},"System Prompt（最大 5000 字符）",[204,306,307],{},"模型配置（关联 ModelConfig，支持多 LLM Provider）",[204,309,310],{},"Skills（技能，多对多关联）",[204,312,313],{},"MCP Servers（外部工具服务）",[204,315,316],{},"Tools（内置工具 + MCP 工具，可启用/禁用）",[204,318,319],{},"知识库（文档 + QA 对，向量化后用于 RAG 检索）",[204,321,322],{},"子 Agent 编排关系",[44,324,326],{"id":325},"_32-mcp-工具系统","3.2 MCP 工具系统",[21,328,329,330,249,333,336],{},"天听实现了完整的 ",[25,331,332],{},"Model Context Protocol (MCP) 客户端",[56,334,335],{},"agents/mcp_client.py","），支持两种传输模式：",[201,338,339,345],{},[204,340,341,344],{},[25,342,343],{},"SSE 模式","：通过 HTTP 连接远程 MCP Server，获取工具列表",[204,346,347,350,351,354,355,358,359,362],{},[25,348,349],{},"stdio 模式","：通过子进程启动本地 MCP Server，使用 JSON-RPC 2.0 协议通信（支持 ",[56,352,353],{},"initialize"," 握手、",[56,356,357],{},"tools/list"," 发现、",[56,360,361],{},"tools/call"," 执行）",[21,364,365],{},"每个 Agent 可关联多个 MCP Server，工具在运行时自动发现并注入到 LLM 的 Tool Calling 上下文中。",[21,367,368,299],{},[25,369,370],{},"工具执行流程",[49,372,375],{"className":373,"code":374,"language":54},[52],"LLM 返回 tool_calls\n       │\n       ▼\n解析工具名称\n       │\n       ├── call_subagent_* → 调用子 Agent Runtime\n       ├── transfer_to_human → 触发人工转接\n       └── MCP 工具 → MCPClient._execute_tool → 转发到对应 MCP Server\n",[56,376,374],{"__ignoreMap":58},[21,378,379,380,383],{},"工具支持并行执行（",[56,381,382],{},"_execute_tool_calls_parallel","），并标注只读/危险属性。",[44,385,387],{"id":386},"_33-rag-检索增强系统","3.3 RAG 检索增强系统",[21,389,390,391,394,395,398],{},"天听实现了完整的 RAG Pipeline，支持",[25,392,393],{},"文档检索","和 ",[25,396,397],{},"QA 检索","两条路径：",[21,400,401,249,404,253],{},[25,402,403],{},"文档检索链路",[56,405,406],{},"rag/",[408,409,410,419,436],"ol",{},[204,411,412,249,415,418],{},[25,413,414],{},"Embedder",[56,416,417],{},"embedder.py","）：调用 Embedding API（默认 NVIDIA nv-embed-v1，4096 维），支持单条/批量文本向量化，内置文本分块（chunk_size=500, overlap=50）",[204,420,421,249,424,427,428,431,432,435],{},[25,422,423],{},"Qdrant Client",[56,425,426],{},"qdrant_client.py","）：管理两个 Collection —— ",[56,429,430],{},"document_chunks","（文档块）和 ",[56,433,434],{},"knowledge_qa","（QA 对），提供 upsert/search/delete 操作",[204,437,438,249,441,444,445,448,449,452],{},[25,439,440],{},"Retriever",[56,442,443],{},"retriever.py","）：Qdrant 优先检索，pgvector cosine_distance 兜底；支持混合检索（",[56,446,447],{},"hybrid_search","）和重排序（",[56,450,451],{},"rerank","）",[21,454,455,249,458,253],{},[25,456,457],{},"QA 检索链路",[56,459,460],{},"rag/qa_search.py",[201,462,463,466,469],{},[204,464,465],{},"向量语义检索优先（Qdrant → pgvector）",[204,467,468],{},"Embedding 失败时自动降级为 ILIKE 关键词匹配",[204,470,471],{},"关键词匹配时计算相关性分数（子串匹配 + 词重叠率）",[21,473,474,299],{},[25,475,476],{},"降级策略设计",[49,478,481],{"className":479,"code":480,"language":54},[52],"Qdrant 可用? → 是 → Qdrant 语义检索\n    │ 否\n    ▼\npgvector 可用? → 是 → pgvector cosine 检索\n    │ 否\n    ▼\nILIKE 关键词匹配兜底\n",[56,482,480],{"__ignoreMap":58},[44,484,486],{"id":485},"_34-知识图谱系统","3.4 知识图谱系统",[21,488,489,490,253],{},"基于 Neo4j 构建 Agent 关系图谱（",[56,491,492],{},"graph/",[21,494,495,299],{},[25,496,497],{},"图谱节点类型",[201,499,500,506,512,518,524,530,536],{},[204,501,502,505],{},[56,503,504],{},"Agent"," — 智能体（属性：id, name, type, is_enabled）",[204,507,508,511],{},[56,509,510],{},"Skill"," — 技能",[204,513,514,517],{},[56,515,516],{},"Tool"," — 工具",[204,519,520,523],{},[56,521,522],{},"KnowledgeDocument"," — 知识文档",[204,525,526,529],{},[56,527,528],{},"KnowledgeQA"," — 问答对",[204,531,532,535],{},[56,533,534],{},"User"," — 用户",[204,537,538,541],{},[56,539,540],{},"Conversation"," — 对话",[21,543,544,299],{},[25,545,546],{},"关系类型",[201,548,549,554,559,564,569,574,579],{},[204,550,551],{},[56,552,553],{},"Agent -[:HAS_SUB_AGENT]-> Agent",[204,555,556],{},[56,557,558],{},"Agent -[:HAS_SKILL]-> Skill",[204,560,561],{},[56,562,563],{},"Agent -[:HAS_TOOL]-> Tool",[204,565,566],{},[56,567,568],{},"Agent -[:HAS_KNOWLEDGE_DOC]-> KnowledgeDocument",[204,570,571],{},[56,572,573],{},"Agent -[:HAS_QA]-> KnowledgeQA",[204,575,576],{},[56,577,578],{},"User -[:INITIATED]-> Conversation",[204,580,581],{},[56,582,583],{},"Conversation -[:HANDLED_BY]-> Agent",[21,585,586,589,590,593,594,597],{},[25,587,588],{},"同步策略","：应用启动时执行 ",[56,591,592],{},"full_sync","（清空 + 全量同步），运行时通过 ",[56,595,596],{},"sync_service"," 增量同步变更。",[44,599,601],{"id":600},"_35-多渠道-im-系统","3.5 多渠道 IM 系统",[21,603,604,605,608,609,612],{},"采用",[25,606,607],{},"适配器模式","设计（",[56,610,611],{},"im/","），支持渠道无缝扩展：",[49,614,617],{"className":615,"code":616,"language":54},[52],"IMAdapter (ABC)          IMClient (ABC)\n    │                        │\n    ├── WebAdapter           ├── FeishuClient\n    └── FeishuAdapter        └── ...\n",[56,618,616],{"__ignoreMap":58},[201,620,621,627,643,649],{},[204,622,623,626],{},[25,624,625],{},"IncomingMessage","：统一消息模型（channel, content, user_id, session_id, extra）",[204,628,629,632,633,636,637,636,640,452],{},[25,630,631],{},"IMAdapter","：抽象接口（",[56,634,635],{},"send_message",", ",[56,638,639],{},"send_streaming_message",[56,641,642],{},"channel_name",[204,644,645,648],{},[25,646,647],{},"IMClient","：底层客户端抽象",[204,650,651,654],{},[25,652,653],{},"Channel Registry","：渠道注册表，运行时动态创建适配器实例",[21,656,657,249,660,253],{},[25,658,659],{},"飞书集成",[56,661,662],{},"im/feishu/",[201,664,665,672,675],{},[204,666,667,668,671],{},"基于 ",[56,669,670],{},"lark-oapi"," SDK，支持 Webhook 和 WebSocket 两种事件接收模式",[204,673,674],{},"实现消息发送、回复、用户名查询",[204,676,677],{},"Webhook 模式：Token 验签 + 事件分发",[44,679,681],{"id":680},"_36-人工客服系统","3.6 人工客服系统",[21,683,684,685,299],{},"当 Agent 无法处理时，支持",[25,686,687],{},"无缝转接人工客服",[21,689,690,299],{},[25,691,692],{},"数据模型",[201,694,695,700],{},[204,696,697,699],{},[56,698,242],{},"：人工客服会话（状态流转：waiting → active → ended）",[204,701,702,704],{},[56,703,540],{},"：对话会话（状态：active / transferred / resolved / pending）",[21,706,707,299],{},[25,708,709],{},"核心流程",[49,711,714],{"className":712,"code":713,"language":54},[52],"Agent 判断需要转人工\n       │\n       ▼\n创建 HumanSession (status=waiting)\nConversation.status → \"transferred\"\n       │\n       ▼\nWebSocket 推送 admin 频道\n管理员看到等待队列\n       │\n       ▼\n客服点击「接手」\nHumanSession.status → \"active\"\n       │\n       ▼\n客服通过 WebSocket 与用户实时对话\n支持快捷回复\n       │\n       ▼\n结束会话\nHumanSession.status → \"ended\"\nConversation.status → \"resolved\"\n",[56,715,713],{"__ignoreMap":58},[21,717,718,249,721,253],{},[25,719,720],{},"API 接口",[56,722,723],{},"api/admin/human_service.py",[201,725,726,732,738,744,750],{},[204,727,728,731],{},[56,729,730],{},"GET /queue"," — 获取等待队列（含当前客服的活跃对话）",[204,733,734,737],{},[56,735,736],{},"POST /accept"," — 接手对话",[204,739,740,743],{},[56,741,742],{},"POST /messages"," — 客服发送消息",[204,745,746,749],{},[56,747,748],{},"POST /end"," — 结束会话",[204,751,752,755],{},[56,753,754],{},"GET /quick-replies"," — 快捷回复模板",[44,757,759],{"id":758},"_37-实时通信系统","3.7 实时通信系统",[21,761,762,763,253],{},"基于 WebSocket 实现双向实时通信（",[56,764,765],{},"ws/",[201,767,768,778],{},[204,769,770,773,774,777],{},[25,771,772],{},"Admin WebSocket"," (",[56,775,776],{},"/ws/admin",")：管理员后台实时推送 —— 新对话通知、对话状态变更、实时统计数据",[204,779,780,773,783,786],{},[25,781,782],{},"Chat WebSocket",[56,784,785],{},"/ws/chat/{session_id}",")：用户聊天实时消息推送",[21,788,789,792],{},[25,790,791],{},"ChannelManager"," 实现发布-订阅模式：",[201,794,795,801,807,813],{},[204,796,797,800],{},[56,798,799],{},"publish_realtime_status"," — 推送实时统计",[204,802,803,806],{},[56,804,805],{},"publish_new_conversation"," — 推送新对话",[204,808,809,812],{},[56,810,811],{},"publish_conversation_update"," — 推送对话更新",[204,814,815,818],{},[56,816,817],{},"publish_message"," — 推送聊天消息",[44,820,822],{"id":821},"_38-安全与认证系统","3.8 安全与认证系统",[21,824,825,249,828,253],{},[25,826,827],{},"认证体系",[56,829,830],{},"core/security.py",[201,832,833,836,839,842],{},[204,834,835],{},"JWT 双 Token 机制：Access Token（24h / 记住我 30d）+ Refresh Token（7d / 30d）",[204,837,838],{},"bcrypt 密码哈希（12 轮）",[204,840,841],{},"AES-256-GCM 加密存储 LLM API Key",[204,843,844],{},"Token 掩码显示",[21,846,847,299],{},[25,848,849],{},"API 安全",[201,851,852,855,858,864],{},[204,853,854],{},"CORS 跨域控制",[204,856,857],{},"请求限频（通用 60/min，聊天 30/min）",[204,859,860,861,452],{},"CAPTCHA 验证码（",[56,862,863],{},"core/captcha.py",[204,865,866,867,870],{},"自定义异常体系（",[56,868,869],{},"core/exceptions.py","，110 个符号定义）",[44,872,874],{"id":873},"_39-管理后台前端","3.9 管理后台（前端）",[21,876,877,878,253],{},"基于 Next.js App Router 的管理后台（",[56,879,880],{},"frontend/src/app/(admin)/",[64,882,883,893],{},[67,884,885],{},[70,886,887,890],{},[73,888,889],{},"页面",[73,891,892],{},"功能",[80,894,895,905,915,925,935,945,955,965,975,985],{},[70,896,897,902],{},[85,898,899],{},[56,900,901],{},"/dashboard",[85,903,904],{},"仪表盘 —— 实时统计、意图分布、渠道分布、最近对话",[70,906,907,912],{},[85,908,909],{},[56,910,911],{},"/agents",[85,913,914],{},"Agent 管理 —— 创建/编辑/删除 Agent，配置 Prompt、模型、技能、工具、知识库、子 Agent",[70,916,917,922],{},[85,918,919],{},[56,920,921],{},"/knowledge",[85,923,924],{},"知识库管理 —— 文档上传/向量化、QA 对管理",[70,926,927,932],{},[85,928,929],{},[56,930,931],{},"/tools",[85,933,934],{},"工具管理 —— 内置工具 + MCP 工具配置",[70,936,937,942],{},[85,938,939],{},[56,940,941],{},"/skills",[85,943,944],{},"技能管理 —— Agent 技能的创建与配置",[70,946,947,952],{},[85,948,949],{},[56,950,951],{},"/human-service",[85,953,954],{},"人工客服 —— 等待队列、实时对话、快捷回复",[70,956,957,962],{},[85,958,959],{},[56,960,961],{},"/history",[85,963,964],{},"历史记录 —— 对话历史浏览与搜索",[70,966,967,972],{},[85,968,969],{},[56,970,971],{},"/users",[85,973,974],{},"用户管理 —— 管理员账号管理",[70,976,977,982],{},[85,978,979],{},[56,980,981],{},"/api-keys",[85,983,984],{},"API 密钥管理 —— LLM Provider API Key 加密存储",[70,986,987,992],{},[85,988,989],{},[56,990,991],{},"/settings",[85,993,994],{},"系统设置",[37,996],{},[16,998,1000],{"id":999},"四数据模型设计","四、数据模型设计",[44,1002,1004],{"id":1003},"_41-核心实体关系","4.1 核心实体关系",[49,1006,1009],{"className":1007,"code":1008,"language":54},[52],"User ──────┐\n           │\nModelConfig ── Agent (orchestrator/faq/after-sale/custom)\n                │\n                ├── AgentSkill ─── Skill\n                ├── AgentTool ─── ToolConfig\n                ├── AgentMCPServer ─── MCPServerConfig\n                ├── AgentSubAgent ─── Agent (子Agent)\n                ├── AgentKnowledgeDocument ─── KnowledgeDocument\n                │                              └── DocumentChunk (向量化分块)\n                └── AgentKnowledgeQA ─── KnowledgeQA (向量化QA)\n\nConversation ─── Message\n    │\n    └── HumanSession ─── User (operator)\n",[56,1010,1008],{"__ignoreMap":58},[44,1012,1014],{"id":1013},"_42-关键模型","4.2 关键模型",[21,1016,1017,249,1019,253],{},[25,1018,504],{},[56,1020,267],{},[201,1022,1023,1026,1029],{},[204,1024,1025],{},"类型：orchestrator / faq / after-sale / custom",[204,1027,1028],{},"关联：模型配置、技能、工具、MCP 服务器、子 Agent、知识库文档、QA 对",[204,1030,1031],{},"配置：system_prompt、transfer_keywords（转人工关键词）、supported_channels（支持的渠道）",[21,1033,1034,249,1036,253],{},[25,1035,540],{},[56,1037,1038],{},"models/conversation.py",[201,1040,1041,1044,1047],{},[204,1042,1043],{},"状态：active → transferred → resolved / pending",[204,1045,1046],{},"渠道：web / feishu",[204,1048,1049],{},"处理者：agent / human",[21,1051,1052,249,1055,253],{},[25,1053,1054],{},"ModelConfig",[56,1056,1057],{},"models/model_config.py",[201,1059,1060,1063,1066],{},[204,1061,1062],{},"多 LLM Provider 支持（base_url + api_key + model_id）",[204,1064,1065],{},"API Key AES-GCM 加密存储",[204,1067,1068],{},"能力标记（capabilities JSONB）、上下文窗口大小",[37,1070],{},[16,1072,1074],{"id":1073},"五api-设计","五、API 设计",[21,1076,1077,1078,1081],{},"统一 RESTful API（",[56,1079,1080],{},"/api/v1/","），采用 camelCase 响应格式：",[49,1083,1086],{"className":1084,"code":1085,"language":54},[52],"认证模块    /api/v1/auth/*\n仪表盘    /api/v1/dashboard/*\nAgent管理  /api/v1/agents/*\n工具管理    /api/v1/tools/*\n技能管理    /api/v1/skills/*\n知识库管理  /api/v1/knowledge/*\n人工客服    /api/v1/human-service/*\n历史记录    /api/v1/history/*\n用户管理    /api/v1/users/*\n系统设置    /api/v1/settings/*\nAPI密钥    /api/v1/api-keys/*\n聊天会话    /api/v1/chat/sessions/*\n飞书Webhook /api/v1/feishu/*\nWebSocket  /ws/admin, /ws/chat/{session_id}\n",[56,1087,1085],{"__ignoreMap":58},[21,1089,1090],{},"统一响应格式：",[49,1092,1096],{"className":1093,"code":1094,"language":1095,"meta":58,"style":58},"language-json shiki shiki-themes github-light github-dark","{\n  \"code\": 0,\n  \"message\": \"success\",\n  \"data\": { ... }\n}\n","json",[56,1097,1098,1107,1123,1137,1153],{"__ignoreMap":58},[1099,1100,1103],"span",{"class":1101,"line":1102},"line",1,[1099,1104,1106],{"class":1105},"sVt8B","{\n",[1099,1108,1110,1114,1117,1120],{"class":1101,"line":1109},2,[1099,1111,1113],{"class":1112},"sj4cs","  \"code\"",[1099,1115,1116],{"class":1105},": ",[1099,1118,1119],{"class":1112},"0",[1099,1121,1122],{"class":1105},",\n",[1099,1124,1126,1129,1131,1135],{"class":1101,"line":1125},3,[1099,1127,1128],{"class":1112},"  \"message\"",[1099,1130,1116],{"class":1105},[1099,1132,1134],{"class":1133},"sZZnC","\"success\"",[1099,1136,1122],{"class":1105},[1099,1138,1140,1143,1146,1150],{"class":1101,"line":1139},4,[1099,1141,1142],{"class":1112},"  \"data\"",[1099,1144,1145],{"class":1105},": { ",[1099,1147,1149],{"class":1148},"s7hpK","...",[1099,1151,1152],{"class":1105}," }\n",[1099,1154,1156],{"class":1101,"line":1155},5,[1099,1157,1158],{"class":1105},"}\n",[37,1160],{},[16,1162,1164],{"id":1163},"六部署架构","六、部署架构",[21,1166,1167],{},"Docker Compose 编排 7 个服务：",[64,1169,1170,1186],{},[67,1171,1172],{},[70,1173,1174,1177,1180,1183],{},[73,1175,1176],{},"服务",[73,1178,1179],{},"镜像",[73,1181,1182],{},"端口",[73,1184,1185],{},"说明",[80,1187,1188,1202,1216,1230,1243,1256,1270,1283],{},[70,1189,1190,1193,1196,1199],{},[85,1191,1192],{},"postgres",[85,1194,1195],{},"pgvector/pgvector:pg16",[85,1197,1198],{},"5432",[85,1200,1201],{},"主数据库 + 向量存储",[70,1203,1204,1207,1210,1213],{},[85,1205,1206],{},"redis",[85,1208,1209],{},"redis:7-alpine",[85,1211,1212],{},"6379",[85,1214,1215],{},"缓存 + 任务队列",[70,1217,1218,1221,1224,1227],{},[85,1219,1220],{},"qdrant",[85,1222,1223],{},"qdrant/qdrant:latest",[85,1225,1226],{},"6333",[85,1228,1229],{},"向量检索引擎",[70,1231,1232,1235,1238,1241],{},[85,1233,1234],{},"neo4j",[85,1236,1237],{},"neo4j:5-community",[85,1239,1240],{},"7687",[85,1242,129],{},[70,1244,1245,1248,1251,1254],{},[85,1246,1247],{},"mongodb",[85,1249,1250],{},"mongo:7",[85,1252,1253],{},"27017",[85,1255,149],{},[70,1257,1258,1261,1264,1267],{},[85,1259,1260],{},"backend",[85,1262,1263],{},"自建镜像",[85,1265,1266],{},"2811",[85,1268,1269],{},"FastAPI 后端",[70,1271,1272,1275,1277,1280],{},[85,1273,1274],{},"frontend",[85,1276,1263],{},[85,1278,1279],{},"2424",[85,1281,1282],{},"Next.js 前端",[70,1284,1285,1288,1291,1294],{},[85,1286,1287],{},"gateway",[85,1289,1290],{},"nginx:alpine",[85,1292,1293],{},"3534",[85,1295,1296],{},"Nginx 反向代理",[21,1298,1299,1300,1303,1304,1307],{},"支持开发模式（",[56,1301,1302],{},"docker compose up","，自动加载 override.yml 挂载本地代码）和生产模式（",[56,1305,1306],{},"docker compose -f docker-compose.yml up","）。",[37,1309],{},[16,1311,1313],{"id":1312},"七项目亮点与技术难点","七、项目亮点与技术难点",[44,1315,1317],{"id":1316},"_71-多-agent-编排架构","7.1 多 Agent 编排架构",[21,1319,1320],{},"采用 Orchestrator + Sub-Agent 模式，编排器通过 LLM Tool Calling 自主决策路由，支持最多 8 轮推理循环，子 Agent 结果回注上下文形成闭环。相比固定流程的 LangGraph 图，新 Runtime 更灵活，支持动态工具发现和并行工具调用。",[44,1322,1324],{"id":1323},"_72-多级降级的-rag-系统","7.2 多级降级的 RAG 系统",[21,1326,1327],{},"Qdrant → pgvector → ILIKE 三级降级策略，确保在任一组件故障时系统仍可提供基本的检索能力。QA 检索融合了语义相似度和关键词匹配的混合评分。",[44,1329,1331],{"id":1330},"_73-mcp-协议集成","7.3 MCP 协议集成",[21,1333,1334],{},"完整实现 MCP (Model Context Protocol) 客户端，支持 SSE 和 stdio 两种传输模式，JSON-RPC 2.0 协议通信，实现外部工具的标准化接入。",[44,1336,1338],{"id":1337},"_74-多渠道统一接入","7.4 多渠道统一接入",[21,1340,1341,1342,1344,1345,1347],{},"通过适配器模式抽象 IM 渠道差异，",[56,1343,625],{}," 统一消息模型，新增渠道只需实现 ",[56,1346,631],{}," 接口。已实现 Web 和飞书两个渠道。",[44,1349,1351],{"id":1350},"_75-agent-知识库-图谱联动","7.5 Agent-知识库-图谱联动",[21,1353,1354],{},"Agent 配置自动同步到 Neo4j 知识图谱，可视化 Agent 之间的编排关系、知识依赖关系，支持基于图的查询分析。",[44,1356,1358],{"id":1357},"_76-安全设计","7.6 安全设计",[21,1360,1361],{},"API Key 使用 AES-256-GCM 加密存储，JWT 双 Token 机制支持续期，请求限频和验证码防护，密码 bcrypt 哈希存储。",[37,1363],{},[16,1365,1367],{"id":1366},"八代码规模","八、代码规模",[64,1369,1370,1380],{},[67,1371,1372],{},[70,1373,1374,1377],{},[73,1375,1376],{},"维度",[73,1378,1379],{},"数据",[80,1381,1382,1390,1398,1406,1414,1422,1430,1438],{},[70,1383,1384,1387],{},[85,1385,1386],{},"后端 Python 文件",[85,1388,1389],{},"135",[70,1391,1392,1395],{},[85,1393,1394],{},"前端 TSX/TS 文件",[85,1396,1397],{},"51",[70,1399,1400,1403],{},[85,1401,1402],{},"后端类定义",[85,1404,1405],{},"225",[70,1407,1408,1411],{},[85,1409,1410],{},"后端函数/方法",[85,1412,1413],{},"792",[70,1415,1416,1419],{},[85,1417,1418],{},"后端接口定义",[85,1420,1421],{},"54",[70,1423,1424,1427],{},[85,1425,1426],{},"Docker 服务数",[85,1428,1429],{},"7",[70,1431,1432,1435],{},[85,1433,1434],{},"API 端点模块",[85,1436,1437],{},"13",[70,1439,1440,1443],{},[85,1441,1442],{},"数据库表",[85,1444,1445],{},"~15",[1447,1448,1449],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":58,"searchDepth":1109,"depth":1109,"links":1451},[1452,1453,1457,1468,1472,1473,1474,1482],{"id":18,"depth":1109,"text":19},{"id":41,"depth":1109,"text":42,"children":1454},[1455,1456],{"id":46,"depth":1125,"text":47},{"id":61,"depth":1125,"text":62},{"id":187,"depth":1109,"text":188,"children":1458},[1459,1460,1461,1462,1463,1464,1465,1466,1467],{"id":191,"depth":1125,"text":192},{"id":325,"depth":1125,"text":326},{"id":386,"depth":1125,"text":387},{"id":485,"depth":1125,"text":486},{"id":600,"depth":1125,"text":601},{"id":680,"depth":1125,"text":681},{"id":758,"depth":1125,"text":759},{"id":821,"depth":1125,"text":822},{"id":873,"depth":1125,"text":874},{"id":999,"depth":1109,"text":1000,"children":1469},[1470,1471],{"id":1003,"depth":1125,"text":1004},{"id":1013,"depth":1125,"text":1014},{"id":1073,"depth":1109,"text":1074},{"id":1163,"depth":1109,"text":1164},{"id":1312,"depth":1109,"text":1313,"children":1475},[1476,1477,1478,1479,1480,1481],{"id":1316,"depth":1125,"text":1317},{"id":1323,"depth":1125,"text":1324},{"id":1330,"depth":1125,"text":1331},{"id":1337,"depth":1125,"text":1338},{"id":1350,"depth":1125,"text":1351},{"id":1357,"depth":1125,"text":1358},{"id":1366,"depth":1109,"text":1367},"agent","2026-03-16","TiTi (TianTing) 是一个企业级 AI 智能客服平台，支持多渠道接入（Web 网页、飞书 IM），采用 Agent 编排架构实现意图识别与自动路由，结合 RAG 检索增强、知识图谱、MCP 工具调用和人工客服转接，为用户提供端到端的智能问答服务。项目采用前后端分离 + Docker 容器化部署，后端基于 Python FastAPI，前端基于 Next.js (React)，通过 Nginx 网关统一入口。","md",true,null,{},"/labs/tianting",{"title":5,"description":1485},"ACTIVE","labs/TianTing",[1495,1496,1497,1498,6],"AIAgent","web","全栈","Docker","xC53UzsM15IsTwRcQPvR1JFFyIaEHXQOOLc-nvbH9N8",1781104361314]