# Foreign Trade Assistant — 业务概览

> 最后更新：2026-05-12
> 本文档面向开发者，描述系统业务逻辑、模块职责和数据流向。
> 产品功能说明见「项目需求文档.md」。

---

## 一、系统定位

**一句话**：外贸公司的 AI 销售助手。覆盖「引流 → 转化」全链路。

```
引流（找客户）                 转化（拿订单）
─────────────────────         ─────────────────────
• B2B平台诊断优化               • 客户分析与开发信
• 社媒内容策略                  • AI高级销售员
• LinkedIn营销                  • 报价与谈判
• 海关数据挖掘
```

**运行依赖**：
- `hermes-agent`（AIAgent 引擎、工具系统、cron）
- LLM API Key（用户自备，配置在 `~/.hermes/.env`）

---

## 二、四大核心业务场景

### 场景 1：文档问答（文档库）

用户上传公司文档（PDF/Excel/Word/图片），Agent 自动理解并回答关于文档内容的问题。

```
用户：「这个供应商的MOQ是多少？」
  → Agent 读取文档
  → 找到：「MOQ: 500pcs/style」
  → 返回答案 + 来源标注
```

**支撑模块**：
- `library.py` — 管理文档库（关联本地目录路径）
- `b2b-document` skill — 16 种文件格式解析逻辑

### 场景 2：客户开发（引流 + 转化）

用户描述一个潜在客户，Agent 分析并生成定制化开发信。

```
用户：「帮我分析这个客户：https://linkedin.com/in/xxx」
  → Agent 提取公司/联系人信息
  → 判断客户类型（价格敏感/品质导向/关系型）
  → 生成定制化开发信 + 跟进序列
```

**支撑模块**：
- `customer.py` — 客户 CRUD + 关联文档库
- `b2b-lead-generation` skill — Account IQ 分析、冷邮件、GAP Selling
- `b2b-linkedin-marketing` skill — LinkedIn 内容策略

### 场景 3：营销内容生成

Agent 结合公司产品资料，生成可直接发布的社媒内容。

```
用户：「生成本周 Facebook 发布计划」
  → Agent 读取公司产品资料
  → 生成 5 条帖子（文案 + 图片建议 + 标签）
  → 用户复制粘贴发布
```

**支撑模块**：`b2b-social-media` skill（FB/Ins/TikTok/YouTube）

### 场景 4：每日自动化

定时任务自动执行，无需人工干预。

```
每天 09:30  → Agent 生成今日 LinkedIn Post 草稿
每天 17:30  → Agent 汇总今日工作 → 追加到工作日报
每周五     → Agent 汇总周报
```

**支撑模块**：`b2b-daily-automation` skill（7 个 cron 任务）

---

## 三、模块架构

```
server.py (FastAPI 入口, 146行)
  │
  ├── init_db()                    # 启动时建表/v0迁移
  ├── trade_router (挂载 /api/trade/*)
  │     │
  │     └── api.py (846行，超标待拆分)
  │           │
  │           ├── companies/          # 公司 CRUD
  │           │     └── company.py   # 公司 + trade_companies CRUD
  │           │
  │           ├── libraries/         # 文档库 CRUD
  │           │     └── library.py   # 文档库 + 关联客户
  │           │
  │           ├── customers/         # 客户 CRUD
  │           │     └── customer.py  # 客户 + 关联文档库
  │           │
  │           ├── conversations/     # 对话历史
  │           │     └── chat_memory.py  # 对话保存 + Hindsight 记忆
  │           │
  │           ├── onboarding/        # 首次引导
  │           │     └── onboarding.py # 引导状态 + 首次公司创建
  │           │
  │           ├── chat/              # AI Agent 对话
  │           │     ├── helpers.py   # check_provider / build_query
  │           │     └── prompt.py    # TRADE_SYSTEM_PROMPT
  │           │
  │           └── memory/             # 长期记忆
  │                 └── memory.py    # Hindsight 桥接
  │
  └── static/trade_chat.html (SPA 前端, 多公司 UI)
```

### 模块职责表

| 模块 | 文件 | 职责 | 行数 |
|------|------|------|------|
| 入口 | `server.py` | FastAPI 启动、版本检查、DB 初始化 | 146 ✅ |
| 路由 | `api.py` | HTTP 端点（companies/libraries/customers/chat/onboarding） | **846 ❌** |
| 公司 | `company.py` | 公司 CRUD + trade_companies 配置 + 数据目录创建 | ~333 |
| 文档库 | `library.py` | 文档库 CRUD + 关联客户 | ~200 |
| 客户 | `customer.py` | 客户 CRUD + 关联文档库 | ~260 |
| 对话 | `chat_memory.py` | 对话历史 + Hindsight 记忆 | ~200 |
| 引导 | `onboarding.py` | 首次引导状态检测 + 公司原子创建 | 190 |
| 帮助 | `helpers.py` | Provider 检查 + Prompt 构建 + Agent 参数 | 136 ✅ |
| 提示词 | `prompt.py` | 系统提示词（外贸销售员行为规范） | — |
| 记忆 | `memory.py` | Hindsight 客户端桥接（可选，无 API 时降级） | 220 ✅ |
| 安装 | `post_install.py` | skills 复制 + .trade-template 初始化 | ~180 |
| 前端 | `static/trade_chat.html` | 多公司侧边栏 + 聊天界面 + SSE 流式展示 | — |

**拆分触发**：`api.py`（846 行）超过 500 行上限，需要按业务域拆分为多个 Router 子模块。

---

## 四、数据模型

```
companies ── 1:N ──► trade_companies  (1:1, is_active 等配置)
    │
    └── 1:N ──► libraries      ── N:M ──► customers
                   │                    │
                   └── 1:N ──► conversations
```

**6 张数据表**：

| 表 | 主键 | 核心字段 | 用途 |
|----|------|---------|------|
| `companies` | id | name, slug, contact, is_active | 公司基本信息 |
| `trade_companies` | company_id | data_dir, agent_identity_md, is_active | Trade 专属配置 |
| `libraries` | id | name, root_path, description, company_id | 文档库目录 |
| `customers` | id | name, contact, note, company_id | 客户记录 |
| `customer_libraries` | (library_id, customer_id) | — | 多对多关联表 |
| `conversations` | id | query, response, files_read, company_id | 对话历史 |

每表均有 3 个备用 JSON 字段（`extra1/2/3`），避免未来 ALTER TABLE。

---

## 五、首次运行流程（Onboarding）

```
用户首次打开 http://127.0.0.1:9119/trade
        │
        ▼
┌─────────────────────────────────┐
│  前端 GET /api/trade/companies  │
│  → 返回 []（空）                 │
│  → 显示「请先创建公司」引导页    │
└─────────────────────────────────┘
        │
        ▼
┌─────────────────────────────────────────────┐
│  POST /api/trade/onboarding/first-company   │
│  Body: {                                    │
│    company_name: "深圳市星火电子有限公司",   │
│    contact_name: "李经理",                  │
│    contact_email: "li@xinghuo.com",         │
│    identity_data: {                         │
│      products: "智能家居产品",               │
│      differentiation: "源头工厂",            │
│      target_region: "欧洲、北美"             │
│    }                                        │
│  }                                          │
└─────────────────────────────────────────────┘
        │
        ▼
┌─────────────────────────────────────────────┐
│  onboarding.create_first_company()           │
│                                           │
│  Step 1: company.create()                  │
│    → 写入 companies 表                     │
│    → 写入 trade_companies 表              │
│    → 创建 ~/.trade/深圳市星火电子/ 目录骨架  │
│                                           │
│  Step 2: 写入 agent_identity_md           │
│    → DB: trade_companies.agent_identity_md │
│    → 文件: ~/.trade/深圳市星火电子/         │
│             agent-identity.md               │
└─────────────────────────────────────────────┘
        │
        ▼
  前端跳转到聊天界面，开始使用
```

---

## 六、对话流程（Chat）

```
用户提问：「帮我分析这个德国客户并写开发信」
        │
        ▼
┌─────────────────────────────────────────────┐
│  POST /api/trade/chat                       │
│  Header: X-Company-ID: 1                    │
│  Body: {query: "...", library_id?: 3}       │
└─────────────────────────────────────────────┘
        │
        ▼
┌─────────────────────────────────────────────┐
│  helpers.build_query(company_id, library_id,│
│                      query)                 │
│                                           │
│  1. 注入公司身份                           │
│     → trade_companies.agent_identity_md    │
│     → 或 ~/.trade/{slug}/agent-identity.md │
│                                           │
│  2. 注入文档库上下文（若有 library_id）    │
│     → 「用户正在文档库 X 中提问...」        │
│                                           │
│  3. 拼接 TRADE_SYSTEM_PROMPT               │
│     → 外贸高级销售员行为规范                │
│     → 销售话术、客户类型判断、谈判技巧      │
└─────────────────────────────────────────────┘
        │
        ▼
┌─────────────────────────────────────────────┐
│  AIAgent.chat(full_query)                  │
│                                           │
│  • quiet_mode=True, max_iterations=90      │
│  • 公司数据目录 → ~/.trade/{slug}/         │
│  • Agent Loop：读文件 → 分析 → 决策 → 行动  │
│  • 工具：read_file, terminal, web_search... │
└─────────────────────────────────────────────┘
        │
        ▼
┌─────────────────────────────────────────────┐
│  chat_memory.save_with_context()           │
│  → 写入 conversations 表                   │
│  → Hindsight.retain()（若已配置）          │
└─────────────────────────────────────────────┘
        │
        ▼
  返回 {"response": "...", "conversation": {...}}
```

---

## 七、API 端点总表

### 公司

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/companies` | 列出所有公司 |
| POST | `/companies` | 创建公司 |
| GET | `/companies/{id}` | 获取公司详情 |
| PUT | `/companies/{id}` | 更新公司 |
| DELETE | `/companies/{id}` | 删除公司 |
| GET | `/companies/{id}/agent-identity` | 获取 Agent 身份 |
| PUT | `/companies/{id}/agent-identity` | 更新 Agent 身份 |

### 文档库

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/libraries` | 列出当前公司文档库（需 X-Company-ID） |
| POST | `/libraries` | 创建文档库 |
| GET | `/libraries/{id}` | 获取文档库详情 |
| PUT | `/libraries/{id}` | 更新文档库 |
| DELETE | `/libraries/{id}` | 删除文档库 |

### 客户

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/customers` | 列出当前公司客户（需 X-Company-ID） |
| POST | `/customers` | 创建客户 |
| GET | `/customers/{id}` | 获取客户详情 |
| PUT | `/customers/{id}` | 更新客户 |
| DELETE | `/customers/{id}` | 删除客户 |
| POST | `/customers/{id}/libraries/{lib_id}` | 关联文档库 |
| DELETE | `/customers/{id}/libraries/{lib_id}` | 取消关联 |
| GET | `/customers/{id}/libraries` | 列出客户关联的文档库 |

### 对话

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/conversations` | 列出当前公司对话历史 |
| POST | `/conversations` | 保存对话 |
| GET | `/conversations/{id}` | 获取单条对话 |

### Chat

| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/chat` | 普通对话（返回完整响应） |
| POST | `/chat/stream` | 流式对话（SSE，实时展示工具调用） |

### Onboarding

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/onboarding/status` | 引导是否完成 |
| POST | `/onboarding/first-company` | 原子创建公司 + Agent 身份 |

### 其他

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/memory/status` | Hindsight 记忆状态 |
| GET | `/memory/recall?q=` | 搜索长期记忆 |
| GET | `/models/providers` | 可用 LLM 提供商列表 |

---

## 八、数据隔离策略

```
每个请求必须携带 X-Company-ID Header

X-Company-ID: 1
    → 查询 companies WHERE id=1
    → 验证 is_active=True
    → 所有 DB 操作自动带上 company_id=1 过滤
    → Agent 数据目录 → ~/.trade/{slug}/

切换公司：
    → 前端切换下拉框 → 更新 sessionStorage['trade_company_id']
    → 后续所有请求自动携带新的 X-Company-ID
    → 清空当前对话，加载新公司数据
```

---

## 九、Skills 系统

11 个 B2B 行业 skills 安装到 `~/.hermes/skills/`，由 Hermes Agent 自动发现：

| Skill | 触发关键词 | 功能 |
|-------|-----------|------|
| `b2b-document` | 分析文档、提取内容、PDF | 16种文件格式解析 |
| `b2b-platform` | 阿里国际站、平台诊断 | 店铺优化方案 |
| `b2b-social-media` | Facebook、Instagram、发帖 | 内容日历生成 |
| `b2b-linkedin-marketing` | LinkedIn、开发信 | Profile优化+内容策略 |
| `b2b-lead-generation` | 客户分析、冷邮件、开发信 | Account IQ + 跟进序列 |
| `b2b-customs-data` | 海关数据、进口商 | 采购商筛选分析 |
| `b2b-onboarding` | 新公司部署、启动 | 全套营销方案 |
| `b2b-customer-mgmt` | 客户管理、报价单 | 生命周期管理 |
| `b2b-daily-automation` | 每日任务、定时 | 7个cron任务 |
| `b2b-data-directory` | 数据目录、~/.trade/ | 目录结构初始化 |
| `b2b-doc-generation` | 生成文档、PPTX、合同 | 专业文档生成 |
| `b2b-email-intel` | 邮箱背景调查、120+平台 | 客户真实性验证 |

---

## 十、已知缺口与待办

| 优先级 | 问题 | 说明 |
|--------|------|------|
| 🔴 高 | `api.py` 846 行超标 | 需拆分为 companies/libraries/customers/chat 四个 Router 子文件 |
| 🔴 高 | 前端无客户管理 UI | docs 说有「B2B 前端客户管理 UI」，实际未实现 |
| 🟡 中 | Windows 兼容性未测试 | docs 明确标注「待测试」 |
| 🟡 中 | macOS 兼容性未测试 | docs 明确标注「待测试」 |
| 🟡 中 | 无消息平台接入 | Telegram/微信/飞书接入规划中 |
| 🟢 低 | `api.py` 仍有 `import os` 未使用 | lint 未检查出来 |

---

## 十一、启动依赖链

```
python server.py
    │
    ├─ Hermes 版本检查 (_check_hermes_version)
    │     └─ 失败 → exit 1
    │
    ├─ load_hermes_dotenv() 加载 ~/.hermes/.env
    │
    ├─ init_db() 建表/迁移
    │     └─ 创建 data/trade.db
    │
    ├─ 挂载 /api/trade/* 路由
    │
    └─ uvicorn.run(port=9119)
          │
          └─ http://127.0.0.1:9119/trade  (前端)
              http://127.0.0.1:9119/api/trade/* (API)
```
