Files
group_fqcd_jr/开发文档/D7.4-开发引导.md
张胜宇 bc61d5c579 docs: 入库权威文档目录(客服agent/ 24 份 + 开发文档/ 50 份,替换旧命名的过期副本)
## 为什么做这一步

权威文档 74 份此前**只在本机**,评审者 clone 分支后看不到任何设计文档;而仓库里那两份同名目录
是 **2026-09-16 之前的过期副本,连文件名都是旧的**(无体系编号)。本次按「**权威覆盖过期**」入库。

## 入库内容

| 目录 | 文件数 | 体积 | 说明 |
|---|---|---|---|
| `客服agent/` | 24 | 0.77 MB | `D2.1`~`D2.6` 对外交付四件套 + 演示脚本/答辩报告 + `_build` 构建工具 |
| `开发文档/` | 50 | 2.16 MB | `D1.x` 索引与决策、`D3.x` 方案、`D4.x` 清除与重构留痕、`D5.x` 业务流程、`D6.x` 业务事实基座、`D7.x` 交付物、`D8.x` 规范 |

**旧的过期副本整体移除**(`客服Agent执行Todolist.md` → `D2.1-客服Agent执行Todolist.md` 之类
的改名 + 新增 `D2.5`/`D2.6`),入库后目录内容与权威副本**逐文件一致(零差异,已复核)**。

## 入库前的安全扫描(必须留痕)

- 扫描规则:`sk-` 类密钥 / `Bearer` 长串 / `password=`、`api_key=` 赋值 / 会话中出现过的两把明文 key 片段。
- 结论:**真实密钥只出现在 `.env`**(已被 `.gitignore` 命中,未入库);`.env.example` 与
  `config/risk.env.example` 只有**空占位**。
- 文档内唯一命中是 `D3.1` 里一处**截断的示例 JWT**(`Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`),
  末尾带省略号,是接口文档的示意值,**不是可用凭据**。
2026-09-20 15:03:15 +08:00

340 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 智能财富管家系统 — 开发实施引导
> **体系编号**:`D7.4` · 域:七、早期系统文档 · 编号体系见 `D1.1` §4.0
> ### ⚠️ 文档状态标注(2026-09-17 文档整理 · CS-DOC-2026-017)
>
> **状态:已被现行开发计划覆盖 —— 开工请勿依据本文档。**
>
> - **覆盖关系**:本文档(07-17,技术实施参考)的职责已由 `客服agent/D2.3-客服Agent开发计划.html` **v1.0**(批次划分、会签门、门禁、交付物)与 `客服agent/D2.1-客服Agent执行Todolist.md` **v5.2**(52 项逐项 DoD)承接。
> - **口径差异**:本文 Phase 划分基于**早期系统模型**(含投顾类 Agent、以 `XX科技` 为品牌),与本项目现行口径「**南方基金**(南方基金管理股份有限公司)· 热线 `400-889-8899` · 官网 `nffund.com`」及「投顾模块已整体清除(CS-PURGE-2026-012/013)」不一致。
> - **处置方式**:按《文档规整方案》(CS-DOC-2026-014)D-2 —— **保留原文 + 加本标注**,不做「只改品牌」(那会造出「品牌已对、业务仍旧」的更危险状态)。
> - **权威入口**:`开发文档/D1.1-文档索引与权威声明.md` 的「开工只读 5 份」。
> **本文档配套于**:《XX科技·智能财富管家系统 — 项目开发需求文档》v1.0
> **文档性质**:技术实施参考,非需求规格。提供代码示例、工具推荐、实现思路等开发辅助信息
> **适用对象**:参与本项目开发的工程师(学生团队)
---
## 目录
- [Phase 1:基础设施 + 智能客服Agent](#phase-1基础设施--智能客服agent)
- [Phase 2:客户画像 + 数据分析Agent](#phase-2客户画像--数据分析agent)
- [Phase 3:知识图谱 + 投顾/业务操作Agent](#phase-3知识图谱--投顾业务操作agent)
- [Phase 4:风控预警 + 记忆体系](#phase-4风控预警--记忆体系)
- [Phase 5:系统集成 + 联调优化](#phase-5系统集成--联调优化)
---
## Phase 1:基础设施 + 智能客服Agent
### 1.1 项目结构
严格按分层架构组织代码:
```
app/
├── api/ # API路由层
│ ├── chat.py # 对话接口
│ ├── knowledge.py # 知识库管理
│ └── admin.py # 管理接口
├── service/ # 业务逻辑层
│ ├── rag_service.py
│ ├── agent_service.py
│ └── memory_service.py
├── tool/ # 工具层
│ ├── document_parser.py
│ ├── embedding_tool.py
│ └── milvus_tool.py
├── model/ # 数据模型
│ ├── schemas.py # Pydantic模型
│ └── entities.py # 数据库ORM模型
├── config/ # 配置
│ ├── settings.py # 环境配置
│ └── database.py # 数据库连接
├── utils/ # 工具类
│ ├── response.py # 统一响应格式
│ ├── exceptions.py # 异常处理
│ └── logger.py # 日志模块
└── main.py # 入口文件
```
### 1.2 RAG 实现方案参考
| 方案 | 适用场景 | 核心代码 |
|------|---------|---------|
| **A — LangChain RetrievalQA**(推荐) | 快速上手,链式编排 | `retriever = Milvus.as_retriever()` → `qa = RetrievalQA.from_chain_type(llm, retriever=retriever)` |
| **B — LlamaIndex VectorStoreIndex** | 已有 LlamaIndex 经验 | `index = VectorStoreIndex.from_vector_store(milvus_collection)` → `query_engine = index.as_query_engine()` |
| **C — 自建 Pipeline** | 需要完全自定义控制流 | Embedding → Milvus Search → Prompt拼装 → LLM调用 |
### 1.3 Embedding 模型选型
| 模型 | 维度 | 特点 |
|------|------|------|
| `text-embedding-ada-002`(OpenAI) | 1536 | 语义理解效果好,需 API Key |
| `bge-large-zh`(本地部署) | 1024 | 中文效果优秀,无 API 费用,需 GPU |
> 注意:选定后全局统一,所有 Milvus 集合使用相同维度。
### 1.4 分块策略
- **FAQ 问答对**:每个问答对作为一个独立 chunk,**不分块**
- **长文档**:`RecursiveCharacterTextSplitter`(`separator=\n\n`,`chunk_size=512`,`chunk_overlap=64`)
- **元数据**:保留标题层级信息
### 1.5 Redis 会话管理
```python
import redis
import tiktoken
r = redis.Redis(host="localhost", port=6379, db=0)
# 写入消息
r.lpush(f"session:{session_id}:messages", json.dumps({"role": "user", "content": message}))
# 读取并截断
messages = r.lrange(f"session:{session_id}:messages}", 0, -1)
enc = tiktoken.get_encoding("cl100k_base")
total_tokens = 0
truncated = []
for msg in reversed(messages):
total_tokens += len(enc.encode(msg))
if total_tokens > 4096:
break
truncated.append(msg)
# truncated 为逆序,需反转回正序
```
---
## Phase 2:客户画像 + 数据分析Agent
### 2.1 NL2SQL 实现参考
**System Prompt 模板**(动态 Schema 筛选):
```
你是金融数据分析专家。根据以下数据库Schema生成SQL查询。
仅允许SELECT语句,禁止任何修改操作。
结果最多返回100行。
数据库Schema(仅包含与问题相关的表):
CREATE TABLE sys_user (...);
CREATE TABLE fin_product (...);
...
```
**Few-shot 示例**:
| 自然语言 | SQL |
|---------|-----|
| "AUM超过100万的客户数" | `SELECT COUNT(*) FROM fin_customer_profile WHERE total_assets > 1000000` |
| "客户张三的持仓" | `SELECT p.product_name, h.shares, h.current_value FROM fin_holdings h JOIN fin_product p ON h.product_id = p.id WHERE h.customer_id = (SELECT id FROM sys_user WHERE real_name = '张三')` |
### 2.2 置信度计算(Phase 2 基础版)
Phase 2 阶段仅实现基础版本:来源初始值 + 简单时间衰减。完整实现见 Phase 4 F4.3。
```python
SOURCE_INITIAL = {"风评问卷": 0.9, "AI对话提取": 0.6, "用户自述": 0.4, "默认值": 0.2}
def calc_base_confidence(source: str, age_days: int) -> float:
base = SOURCE_INITIAL.get(source, 0.2)
decay = max(0, 1 - age_days / 365 * 0.2)
return max(0.0, min(1.0, base * decay))
```
### 2.3 画像研判规则
直接参考项目目录中的 `D6.4.1-投资者风险画像研判规则.md`,实现四维度加权打分逻辑。
---
## Phase 3:知识图谱 + 投顾/业务操作Agent
### 3.1 Neo4j Python Driver
```python
from neo4j import GraphDatabase
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password"))
with driver.session() as session:
result = session.run(
"MATCH (c:Customer)-[:INVESTS_IN]->(p:Product) RETURN c.name, p.product_name"
)
for record in result:
print(record["c.name"], record["p.product_name"])
```
### 3.2 GraphRAG 实现思路
1. **实体识别**:LLM 或正则提取产品名、客户名、行业等实体
2. **图谱查询**:构造 Cypher 语句获取关联实体和关系路径
3. **格式化为文本**:将图谱查询结果格式化为自然语言描述
4. **上下文拼接**:将图谱文本拼接到 RAG 检索结果中
5. **融合排序**:向量 Score × 0.6 + 图谱 Score × 0.4,注入 LLM Prompt
### 3.3 NL2API Function Calling 示例
```python
tools = [
{
"type": "function",
"function": {
"name": "purchase_product",
"description": "为客户申购理财产品",
"parameters": {
"type": "object",
"properties": {
"customer_id": {"type": "integer", "description": "客户ID"},
"product_code": {"type": "string", "description": "产品代码"},
"amount": {"type": "number", "description": "申购金额(元)"}
},
"required": ["customer_id", "product_code", "amount"]
}
}
}
]
```
> 8 个业务 API 建议用 FastAPI 的 `APIRouter` 组织,每个 API 独立 endpoint,放在 `app/api/operations/` 目录下。
---
## Phase 4:风控预警 + 记忆体系
### 4.1 风控规则引擎(策略模式)
```python
from abc import ABC, abstractmethod
class BaseRiskRule(ABC):
rule_id: str
rule_name: str
risk_level: str
@abstractmethod
def evaluate(self, transaction: dict) -> bool: ...
class LargeTransactionRule(BaseRiskRule):
rule_id = "R001"
rule_name = "大额现金交易"
risk_level = "低"
threshold = 50000 # 5万元
def evaluate(self, transaction: dict) -> bool:
return transaction["amount"] >= self.threshold
class FrequentTransactionRule(BaseRiskRule):
rule_id = "R003"
rule_name = "频繁交易"
risk_level = "中"
def evaluate(self, transaction: dict) -> bool:
# 7天内交易次数 >= 10
return transaction["weekly_count"] >= 10
```
### 4.2 置信度计算完整实现
见需求文档 Phase 4 F4.3 中的 `BaseConfidenceCalcTool`、`FinalConfidenceRankTool`、`MemoryUnitValidator` 伪代码。
### 4.3 Redis Pub/Sub 示例
```python
import json
import redis
# 发布(风控Agent)
redis_client.publish("event:risk_alert", json.dumps({
"alert_id": 1001,
"customer_id": 10001,
"alert_level": "中",
"trigger_rules": ["R003", "R007"]
}))
# 订阅(投顾Agent / 客服Agent)
pubsub = redis_client.pubsub()
pubsub.subscribe("event:risk_alert")
for message in pubsub.listen():
if message["type"] == "message":
data = json.loads(message["data"])
handle_alert(data)
```
### 4.4 周期校准任务(APScheduler)
```python
from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()
# 每周日凌晨3点执行全量置信度重算
scheduler.add_job(recalculate_confidence, 'cron', day_of_week='sun', hour=3)
scheduler.start()
# 手动触发接口
# POST /api/admin/recalculate-confidence
```
---
## Phase 5:系统集成 + 联调优化
### 5.1 流式输出(SSE)
```python
from fastapi.responses import StreamingResponse
@router.post("/chat/stream")
async def chat_stream(request: ChatRequest):
async def event_generator():
async for chunk in llm.astream(prompt):
yield f"data: {chunk.content}\n\n"
yield "data: [DONE]\n\n"
return StreamingResponse(event_generator(), media_type="text/event-stream")
```
### 5.2 Agent 路由(工厂模式)
```python
AGENT_REGISTRY = {
"customer": CustomerAgent,
"advisor": AdvisorAgent,
"risk": RiskAgent,
"analyst": AnalystAgent,
"operator": OperatorAgent,
}
def get_agent(agent_type: str):
agent_class = AGENT_REGISTRY.get(agent_type)
if not agent_class:
raise ValueError(f"Unknown agent type: {agent_type}")
return agent_class()
```
### 5.3 降级方案
| 组件 | 降级策略 |
|------|---------|
| LLM | OpenAI 不可用时切换到本地模型(如 Qwen) |
| Milvus | 向量检索超时时用 MySQL LIKE 关键词查询 |
| Neo4j | 图谱查询超时时跳过图谱增强,仅使用 RAG 结果 |
| Redis | 连接失败时直连 MySQL,恢复后自动回填缓存 |
### 5.4 演示脚本建议
| 序号 | 场景 | 覆盖模块 |
|------|------|---------|
| 1 | 客户A(高净值)完整旅程 | 开户→风评→咨询→申购→持仓 |
| 2 | 客户B(普通投资者)风控触发 | 大额交易→预警→工单处置 |
| 3 | 多Agent协作联动 | 客服→业务操作→风控联动 |
| 4 | NL2SQL 数据查询 | 自然语言→SQL→结果解读 |
| 5 | GraphRAG vs 纯RAG 对比 | 同一问题两种检索方式的效果差异 |
---
> **文档结束** — 开发实施引导完。本文档内容仅为技术参考,具体实现以《项目开发需求文档》中的功能需求和验收标准为准。