货代领域模型
本文档定义货代业务的核心数据模型,基于 Chameleon 现有模型扩展。
模型关系图
erDiagram
FREIGHT_SHIPMENT ||--o{ FREIGHT_DOCUMENT : contains
FREIGHT_SHIPMENT ||--o{ TRACKING_EVENT : tracks
FREIGHT_SHIPMENT ||--o{ FREIGHT_PARTY : involves
FREIGHT_DOCUMENT ||--|| DOCUMENT : extends
FREIGHT_SHIPMENT }o--|| AGENT : belongs_to
FREIGHT_SHIPMENT }o--|| SESSION : linked_to
MEMORY_FACT }o--|| FREIGHT_SHIPMENT : references
核心实体
FreightShipment(货运主表)
记录端到端的货物流转信息。
class FreightShipment(Base):
"""货运主表:记录端到端货物流转.
Attributes:
id: 货运唯一标识.
shipment_no: 业务单号.
bl_no: 提单号 (Bill of Lading Number).
container_no: 集装箱号.
status: 当前货运状态 (booked/pickup/in_transit/arrived/customs/delivered).
origin_port: 起运港代码.
destination_port: 目的港代码.
carrier: 承运人代码.
etd/eta: 预计离港/到港时间.
atd/ata: 实际离港/到港时间.
extracted_data_json: AI 提取的结构化数据.
"""
关键字段说明:
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
shipment_no |
String(64) | 业务单号,唯一索引 | "SHA24020001" |
bl_no |
String(64) | 提单号 | "MAEU1234567890" |
container_no |
String(32) | 集装箱号,ISO 6346 格式 | "MSKU1234567" |
status |
Enum | 货运状态 | "in_transit" |
origin_port |
String(16) | 起运港 UN/LOCODE | "CNSHA" |
destination_port |
String(16) | 目的港 UN/LOCODE | "USLAX" |
carrier |
String(64) | 承运人代码 | "MAERSK" |
数据库索引:
CREATE INDEX ix_shipment_bl_no ON freight_shipment(bl_no);
CREATE INDEX ix_shipment_container ON freight_shipment(container_no);
CREATE INDEX ix_shipment_status_eta ON freight_shipment(status, eta);
FreightDocument(货代单证表)
记录单证元数据与解析结果,与现有 Document 模型一对一关联。
class FreightDocument(Base):
"""货代单证表.
Attributes:
document_id: 关联的 Document 记录.
doc_type: 单证类型 (HBL/MBL/AWB/Invoice/PackingList等).
shipment_id: 关联的货运记录.
extracted_fields_json: AI 提取的字段.
extraction_confidence: 提取置信度.
validation_status: 验证状态.
review_status: 人工复核状态.
"""
单证类型枚举:
class DocumentType(str, Enum):
HBL = "hbl" # 海运分提单
MBL = "mbl" # 海运主提单
AWB = "awb" # 空运提单
COMMERCIAL_INVOICE = "commercial_invoice"
PACKING_LIST = "packing_list"
CUSTOMS_DECLARATION = "customs_declaration"
CERTIFICATE_OF_ORIGIN = "certificate_of_origin"
INSURANCE_CERT = "insurance_cert"
处理状态流转:
上传 → 解析中 → 提取完成 → 验证中 → 验证通过
│ ↓ ↓
└→ 解析失败 待复核 → 复核通过
FreightParty(贸易参与方)
从单证提取的实体,用于客户画像与历史关联。
class FreightParty(Base):
"""贸易参与方.
Attributes:
party_type: 参与方类型 (shipper/consignee/notify/broker).
name: 名称.
normalized_name: 标准化名称(用于去重).
address: 地址.
country_code: 国家代码.
entity_key: 实体唯一标识(名称+国别哈希).
"""
TrackingEvent(物流跟踪事件)
聚合多源跟踪数据。
class TrackingEvent(Base):
"""物流跟踪事件.
Attributes:
shipment_id: 关联货运.
event_code: 标准化事件代码.
event_description: 事件描述.
event_datetime: 事件发生时间.
source_type: 数据来源 (carrier/port/gps/customs).
source_reference: 源系统参考号.
location_code/name: 地点信息.
"""
事件代码示例:
| 代码 | 描述 | 来源 |
|---|---|---|
GATE_IN |
进港 | 港口 |
LOADED |
已装船 | 船公司 |
DEPARTURE |
已离港 | 船公司/港口 |
ARRIVAL |
已到港 | 船公司/港口 |
CUSTOMS_HOLD |
海关扣留 | 海关 |
DELIVERED |
已交付 | GPS/承运人 |
业务记忆模型
货代场景的记忆系统复用核心平台的 MemoryFact 模型,但扩展了货代专用的事实类型。
记忆事实类型
class FreightFactType(str, Enum):
SHIPMENT_ROUTE = "shipment_route" # 货运路由偏好
PARTY_PREFERENCE = "party_pref" # 收发货人偏好
EXCEPTION_HISTORY = "exception_hist" # 历史异常
DOCUMENT_PATTERN = "doc_pattern" # 单证格式模式
COMMUNICATION_PREF = "comm_pref" # 沟通偏好
典型记忆内容
货运路由记忆:
{
"fact_type": "shipment_route",
"entity_type": "party",
"entity_id": "entity_key_hash",
"fact_summary": "该客户偏好从上海(CNSHA)出运,常用承运人MAERSK",
"fact_payload": {
"preferred_origin": "CNSHA",
"preferred_carriers": ["MAERSK", "MSC"],
"avg_monthly_volume": 15,
"common_destinations": ["USLAX", "USNYC"]
},
"confidence_score": 0.92
}
历史异常记忆:
{
"fact_type": "exception_hist",
"entity_type": "shipment",
"entity_id": "SHA24020001",
"fact_summary": "该票货物曾在目的港产生滞港费,原因:清关文件延迟",
"fact_payload": {
"exception_type": "demurrage",
"root_cause": "document_delay",
"cost_incurred": 450.00,
"resolution": " expedited customs clearance"
},
"confidence_score": 1.0
}
模型关联关系
# 关联查询示例
# 1. 查询某提单的所有单证
session.query(FreightDocument).join(
FreightShipment
).filter(
FreightShipment.bl_no == "MAEU1234567890"
).all()
# 2. 查询某客户的所有货运历史
session.query(FreightShipment).join(
FreightParty
).filter(
FreightParty.entity_key == customer_key
).order_by(
FreightShipment.created_at.desc()
).all()
# 3. 查询某货运的跟踪时间线
session.query(TrackingEvent).filter(
TrackingEvent.shipment_id == shipment_id
).order_by(
TrackingEvent.event_datetime
).all()
# 4. 查询相关记忆
session.query(MemoryFact).filter(
MemoryFact.entity_type.in_(["shipment", "party"]),
MemoryFact.entity_id.in_([shipment_id, party_key]),
MemoryFact.confidence_score > 0.7
).order_by(
MemoryFact.importance_score.desc()
).limit(5).all()
数据库迁移
# 生成迁移脚本
uv run alembic revision --autogenerate -m "add freight domain models"
# 执行迁移
uv run alembic upgrade head
相关文档
- Agent Runtime 架构实现 - 整体实现方案
- 单证处理 - 单证处理流程
- 货物跟踪 - 跟踪数据聚合
- MCP 工具 - 外部系统集成