跳到主要内容

Lawsight - FTO

VincentWei    2026年11月4日 13:41:29

1. 系统概览

项 内容
定位 FTO(Freedom to Operate)报告生成 Demo:七阶段多智能体工作流 + 对话式人机协同
后端 Python 3.12 · FastAPI · asyncio(每任务一协程) · Pydantic 数据契约
存储 SQL(WAL,5 张表:任务/事件/LLM流水/对话/轨迹)+ Redis Stream(wf:llm_tokens 令牌消息队列)
模型 GLM 文本(glm-5.3-flashx,含 glm.chat 调用面)+ GLM 视觉(glm-4.5v,调用面 glm.vision)
外部服务 智慧芽开放平台(P002 检索 / P011 著录 / P010 图传 / P060 以图搜图)+ Google Patents 权利要求与外观视图抓取
前端 Vue3 + Vite:任务列表/创建 · Chatbot 对话台 · 工作台(阶段/判定/报告/Token)· Redis Stream 实时视图
双模式 invention 发明专利 FTO(claim chart 全要素规则)/ design 外观设计 FTO(组件暴力拆解 × 视觉比对)
容错 MOCK_LLM / MOCK_SEARCH 离线开关;单语检索失败隔离;LLM 失败规则兜底;Redis 失联降级 SQLite

2. 总体架构图

graph TB
    subgraph FE["前端 web/ (Vue3 + Vite)"]
        APP["App.vue<br/>任务列表/创建表单<br/>多图上传·专利文件上传·中英切换"]
        CHAT["ChatPanel.vue<br/>对话控制台(关卡卡片)"]
        DETAIL["TaskDetail.vue + VisualPanel.vue<br/>阶段进度/漏斗/claim chart/风险矩阵/报告"]
        TS["TokenStream.vue<br/>Redis Stream 实时指标"]
    end

    subgraph API["API 层 server/app"]
        MAIN["main.py<br/>FastAPI 入口·CORS·静态文件"]
        APIR["api.py<br/>REST + SSE·全部需 user_id"]
    end

    subgraph CORE["编排与智能体核心"]
        WF["workflow.py ★<br/>WorkflowEngine(7阶段流水线)<br/>检查点暂停/恢复·3关卡·rerun"]
        DLG["dialog.py<br/>Dialog Orchestrator<br/>21个工具注册表·两段式执行"]
        HAR["harness.py<br/>Agent Harness<br/>输入/输出守卫·步数/token预算·轨迹"]
        SCH["schemas.py<br/>Pydantic 数据契约(FTOState...)"]
    end

    subgraph INFRA["基础设施"]
        LLM["llm.py<br/>GLM 客户端 chat/chat_json/vision<br/>JSON鲁棒解析·token计量挂点"]
        ZHY["zhihuiya.py<br/>智慧芽客户端 P002/P011/P010/P060<br/>Google Patents 抓取"]
        TM["token_metrics.py<br/>SQLite流水 + XADD wf:llm_tokens"]
        STORE["store.py<br/>SQLite 5表持久层"]
        IMG["images.py<br/>上传/降采样/base64/PIL标注图"]
        DOCS["docs.py<br/>PDF/DOCX/TXT/MD抽取·专利号解析"]
    end

    subgraph EXT["外部服务"]
        GLM[("智谱 GLM<br/>glm-5.3-flashx / glm-4.5v")]
        ZHYA[("智慧芽开放平台<br/>connect.zhihuiya.com")]
        GP[("Google Patents")]
        REDIS[("Redis<br/>Stream wf:llm_tokens")]
        SQLITE[("SQLite<br/>data/fto.db (WAL)")]
    end

    APP --> APIR
    CHAT -->|"POST /tasks/{id}/chat"| APIR
    DETAIL -->|"GET /workflow · SSE /events/stream"| APIR
    TS -->|"GET /tokens/stream"| APIR
    MAIN --- APIR

    APIR --> WF
    APIR --> DLG
    APIR --> STORE
    APIR --> IMG
    APIR --> DOCS

    WF --> SCH
    WF --> LLM
    WF --> ZHY
    WF --> STORE
    DLG --> HAR
    DLG --> LLM
    DLG --> STORE
    DLG --> ZHY

    LLM --> TM
    TM --> SQLITE
    TM -->|"XADD 9字段契约"| REDIS
    STORE --> SQLITE
    LLM --> GLM
    ZHY --> ZHYA
    ZHY --> GP

调用关系要点

  • 每次任务 = WorkflowEngine 中的一个 asyncio.Task 协程(engine.launch() 幂等启动);
  • 每次对话 = 一个 Harness Run(H-xxxx),完整轨迹落库可回放;
  • 每次 LLM 调用(含对话与视觉)都经 token_metrics.record() 双写 SQLite + Redis Stream。

3. 七阶段工作流流程图(含关卡与检查点)

flowchart TD
    START(["POST /tasks 创建<br/>auto_start=true"]) --> S1

    S1["S1 FeatureParser 特征解析<br/>──────────<br/>invention: 技术特征清单 F-xx·must/should/optional<br/>design: 设计要点 D-xx·形状/图案/色彩<br/>中英双语检索关键词"]
    S1 --> CK1{{"检查点落盘<br/>FTOState 快照"}}

    CK1 --> G1{"关卡①特征确认<br/>gates_enabled?"}
    G1 -->|"awaiting_review<br/>对话卡片推送"| H1["人工: 批准/改特征/退回"]
    H1 -->|approve| S2
    G1 -->|"关闭或已确认"| S2

    S2["S2 PatentRetriever 专利检索<br/>──────────<br/>①中文TACD + 英文TACD 分路检索(单语失败不隔离影响)<br/>②零命中→LLM泛化产品类别词重试<br/>③design模式: P010上传主视图→P060以图搜图(DESIGN优先)<br/>④P011批量著录补全·同PN去重"]
    S2 --> CK2{{"检查点 s2_search"}} --> S3

    S3["S3 LegalFilter 法律状态过滤<br/>──────────<br/>①地域过滤(目标法域+WO,全滤则回退)<br/>②patent_type 法律状态代理<br/>③LLM相关性分档 high/med/low(失败回退全medium)<br/>④design: DESIGN类优先 ⑤上传专利文件直入比对"]
    S3 --> CK3{{"检查点 s3_filter"}} --> S4

    S4["S4 ClaimAnalyzer 权利要求比对<br/>──────────<br/>逐专利扇出·每篇完成即子检查点<br/>━━ invention ━━<br/>权利要求→MRE最小要素·逐要素映射<br/>verdict: literal/equivalent/not_covered/uncertain<br/>全要素规则→claim chart<br/>━━ design ━━<br/>A: 视觉暴力拆解(6-12组件,bbox/九宫格)<br/>B: 逐组件对比→整体视觉效果综合判断"]
    S4 -->|每篇专利| SUBCK{{"子检查点<br/>checkpoint=s3_filter<br/>篇间可暂停"}}
    SUBCK --> S4
    S4 --> CK4{{"检查点 s4_mapping"}} --> S5

    S5["S5 RiskAssessor 风险评估<br/>──────────<br/>三维评级: 侵权可能性/专利有效性/执法倾向<br/>→综合 High/Medium/Low<br/>LLM失败→规则引擎兜底(claim chart统计)"]
    S5 --> CK5{{"检查点 s5_risk"}}
    CK5 --> G2{"存在 High<br/>且未复核?"}
    G2 -->|"是"| H2["关卡②律师复核<br/>claim chart+评分依据卡片<br/>确认/改判(override_risk)/定向重跑"]
    H2 -->|approve| S6
    G2 -->|"否"| S6

    S6["S6 ReportWriter 报告撰写<br/>──────────<br/>总体判定=规则计算(杜绝数字幻觉)<br/>LLM生成中英双语执行摘要<br/>模板渲染 Markdown(双模板:发明/外观)"]
    S6 --> CK6{{"检查点 s6_report"}} --> S7

    S7["S7 QAReviewer 质量审核<br/>──────────<br/>①规则校验(专利遗漏/空报告/评级孤儿)<br/>②LLM交叉一致性(数字/结论/术语)<br/>③发现issue→修订循环(≤qa_max_retry)"]
    S7 --> CK7{{"检查点 s7_qa"}}
    CK7 --> G3{"关卡③终审签发"}
    G3 -->|approve| DONE(["completed<br/>报告附签发人+时间戳"])
    G3 -->|"reject 批注"| BACK["checkpoint=s5_risk<br/>批注入 report_edit_notes"]
    BACK --> S6

    PAUSE(["POST /pause"]) -.->|"pause_requested=1<br/>下一检查点生效"| S4

检查点语义(workflow.py:115-123,261-263)

  • 阶段完成 → _save(state, checkpoint=stage) 持久化 FTOState JSON 快照;
  • S4 内每篇专利完成即子检查点(checkpoint 保持 s3_filter,恢复后跳过 pn in analyses 的专利);
  • 暂停 = 置 pause_requested 标志,在阶段边界或 S4 篇间生效(_PausedMidway 异常自然终止协程);
  • 恢复 = STAGES[idx(checkpoint)+1:] 续跑,不重放已完成工作;
  • 重跑 = POST /rerun:full 清空全部从 S1 / search 保留特征从 S2,run_count 轮次留痕。

4. 任务生命周期状态机

stateDiagram-v2
    [*] --> created: POST /tasks
    created --> running: start / auto_start
    running --> running: 各阶段执行(S1→S7)
    running --> paused: 暂停请求@检查点
    running --> awaiting_review: 阶段后开关卡(S1后/S5后High/S7后)
    running --> failed: 阶段异常(error留痕)
    paused --> running: resume(从检查点)
    failed --> running: start(从检查点)
    awaiting_review --> paused: 关卡①②approve→engine.launch
    paused --> running: 隐式
    awaiting_review --> completed: 关卡③approve(签发)
    awaiting_review --> paused: 关卡③reject→checkpoint=s5_risk重跑S6/S7
    paused --> cancelled: cancel
    running --> cancelled: cancel
    completed --> [*]
    cancelled --> [*]

    note right of awaiting_review
        gate ∈ {gate_feature, gate_legal, gate_final}
        超时: review_timeout_hours=72h(提醒)
        对话 approve_gate 与 REST /review 共用 resolve_gate()
    end note

5. 对话式人机协同与 Agent Harness(时序图)

sequenceDiagram
    autonumber
    participant U as 用户(ChatPanel)
    participant A as api.py POST /chat
    participant D as dialog.py 协调者
    participant H as harness.py 运行框架
    participant L as llm.py GLM
    participant T as 工具(21个)
    participant S as store.py SQLite

    U->>A: {user_id, message, lang}
    A->>D: handle_message()
    D->>S: 落库用户消息
    D->>H: 创建 HarnessRun(H-xxxx)

    H->>H: 输入守卫: 提示注入模式拦截→guarded终止

    loop ≤3步 & ≤60000 token
        D->>L: chat_json(上下文+21工具清单+历史)
        L-->>H: llm_decision 步骤(延迟/token留痕)
        alt tool=null
            L-->>D: 直接回复(闲聊/领域知识)
        else 选择工具
            D->>T: execute(查询/修改/干预/裁决)
            T->>S: 状态修改落盘+事件审计
            T-->>H: tool 步骤(结果摘要留痕)
            Note over T: 终止工具: approve_gate/<br/>reject_gate/cancel_task
        end
    end

    D->>L: 基于工具链结果生成自然语言回复
    H->>H: 输出守卫: 回复中专利号∉任务范围→疑似幻觉标注
    D->>S: 回复落库(含工具结果载荷)
    D->>S: harness_runs 轨迹落库(可回放)
    D-->>U: {reply, tool_chain, harness, task状态}

工具注册表(21 个,dialog.py:62-104)

类别 工具
查询(多源) get_task_overview get_features get_patents get_claim_chart get_risk get_report get_token_stats get_search_strategies live_search(智慧芽实时)
修改(干预) update_feature add_feature delete_feature record_clarification
流程干预 rerun_patent(定向单篇) rerun_task override_risk(律师改判回流) request_report_edit pause_task resume_task cancel_task
关卡裁决 approve_gate reject_gate

治理机制:事实必须经工具获取(系统提示硬约束);守卫拦截状态 guarded;预算耗尽优雅收敛 capped;每步 llm_decision/tool 含参数、结果摘要、延迟、token 全留痕。


6. S4 双模式比对设计图(核心判定引擎)

flowchart TB
    subgraph INV["invention 发明专利 FTO"]
        I1["权利要求文本<br/>Google Patents抓取(claims_source=google)<br/>失败回退摘要(abstract)·上传文件(upload)"] --> I2
        I2["LLM拆解3-6个MRE最小要素"] --> I3["逐要素映射产品特征<br/>literal字面/equivalent等同/<br/>not_covered未覆盖/uncertain"]
        I3 --> I4{"全要素规则<br/>(chart回推兜底)"}
        I4 -->|全部literal或equivalent| I5["infringement"]
        I4 -->|存在not_covered| I6["non_infringement"]
        I4 -->|其余| I7["uncertain"]
        I5 & I6 & I7 --> I8["claim chart + 规避设计建议"]
    end

    subgraph DES["design 外观设计 FTO"]
        D1["产品多图(≤10,本地base64降采样)<br/>+ 专利视图(Google抓取→本地化)"] --> D2
        D2["阶段A 组件暴力拆解(glm.vision)<br/>产品侧×专利侧各6-12组件<br/>整体轮廓/部件/装饰/图案/色彩<br/>bbox 0-1000归一化 + 九宫格region"] --> D3
        D3["组件分割标注图(PIL)<br/>bbox精确框 > region九宫格 > 自动网格兜底"] --> D4
        D4["阶段B 逐组件对比(chat_json)<br/>形状/图案/色彩逐一比对<br/>相同/近似/不相同/不确定"] --> D5{"整体观察·综合判断<br/>overall_visual"}
        D5 -->|identical/similar| D6["infringement"]
        D5 -->|different| D7["non_infringement"]
        D5 -->|由组件verdict回推| D8["uncertain"]
        D6 & D7 & D8 --> D9["组件对比表+标注图+设计规避提示"]
    end

    IN["screened_patents<br/>(S3输出)"] --> INV
    IN --> DES
    I8 --> R["ClaimAnalysis → state.analyses[pn]"]
    D9 --> R

7. 数据设计

7.1 FTOState —— 单体状态快照(Pydantic,schemas.py:99-137)

全部工作流状态序列化为一个 JSON 存入 tasks.state,即检查点快照本体:

输入(product_name/tech_description/jurisdictions/report_type/lang/图片/专利文件)
 ├─ S1: features[F-xx/D-xx{tier,search_hints双语}] + open_questions
 ├─ S2: search_strategies[{strategy_type,query_expr,hit_count}审计] + candidate_patents[Patent]
 ├─ S3: screened_patents + screen_matrix[{relevance,action}]
 ├─ S4: analyses{pn → ClaimAnalysis{claim_chart|components,components_visual,determination}}
 ├─ S5: risks[RiskItem{三维评级,overall,reviewer_override}]
 ├─ S6/S7: report_md + summary(zh/en) + qa_status/qa_issues
 ├─ 关卡: feature_confirmed / risk_confirmed / clarifications / report_edit_notes
 └─ stage_runs[StageRun{agent,status,items_done/total}] 阶段台账

7.2 SQLite 表(store.py:14-84)

erDiagram
    tasks ||--o{ events : "任务事件时间线"
    tasks ||--o{ llm_calls : "LLM调用流水"
    tasks ||--o{ chat_messages : "对话历史(含关卡卡片)"
    tasks ||--o{ harness_runs : "对话运行轨迹"

    tasks {
        text id PK "T-XXXXXXXX"
        text user_id "全链路关联"
        text status "created/running/paused/awaiting_review/completed/failed/cancelled"
        text stage "当前阶段"
        text checkpoint "已完成检查点"
        int pause_requested "暂停标志位"
        text state "FTOState JSON快照"
        text gate "当前待审关卡"
        text signed_by "关卡③签发人"
        real review_deadline "审批超时"
        int run_count "重跑轮次"
    }
    events {
        int id PK
        text task_id FK
        text type "stage_start/stage_done/stage_item/paused/gate_open/..."
        text stage
        text data "JSON载荷"
    }
    llm_calls {
        int id PK
        text stage "s1..s7/chat"
        text name "glm.chat/glm.vision"
        text model
        int tokens_in
        int tokens_out
    }
    chat_messages {
        int id PK
        text role "user/assistant"
        text data "关卡卡片/工具结果载荷"
    }
    harness_runs {
        text run_uid UK "H-xxxxxxxxxx"
        text steps "轨迹JSON(llm_decision/tool步)"
        text status "done/capped/guarded"
    }

7.3 Redis Stream 令牌契约(token_metrics.py)

KEY: wf:llm_tokens (MAXLEN ~100000)  XADD 9字段:
ts | user_id | matter_id | stage | name | model | tokens_in | tokens_out | total
  • 双写策略:SQL 永远写(聚合查询事实源);Redis XADD 失联静默降级、30s 周期重连;
  • 消费方式:XREVRANGE(API GET /tokens/stream)、前端 TokenStream 实时视图、XREAD BLOCK 实时消费。

8. 模块职责与关键文件索引

文件 行数 职责
server/app/workflow.py 1234 ★ 引擎:7 阶段 handler、检查点、关卡开关、rerun、双模式比对、双报告模板
server/app/api.py 506 REST/SSE 全接口(任务/对话/审批/重跑/工作流全景/令牌/事件)
server/app/dialog.py 500 对话协调者:21 工具注册表 + 两段式执行
server/app/store.py 304 SQL 持久层(同步 + 全局锁,WAL)
server/app/zhihuiya.py 233 智慧芽 P002/P011/P010/P060 + Google Patents 抓取
server/app/images.py 216 图片上传/降采样/base64 转换/PIL 组件标注图
server/app/llm.py 179 GLM 客户端(chat/chat_json/vision、截断重试、限流退避、mock)
server/app/harness.py 166 运行框架(守卫/预算/轨迹/回放)
server/app/token_metrics.py 147 SQL + Redis Stream 生产者
server/app/schemas.py 137 Pydantic 数据契约
server/app/docs.py 87 专利文件抽取(PDF/DOCX/TXT/MD)+ 专利号/权利要求段解析
server/app/config.py 63 .env 配置(26 项设置)
web/src/components/* ~1400 前端视图层(薄客户端,轮询 + SSE)

9. API 分层设计

graph LR
    subgraph 任务生命周期
        A1["POST /tasks"] --- A2["GET /tasks?user_id="] --- A3["POST /{id}/start|pause|resume|cancel"]
    end
    subgraph 对话与审批
        B1["POST /{id}/chat"] --- B2["GET /{id}/chat"] --- B3["POST /{id}/review"] --- B4["GET /{id}/harness[/{run_uid}]"]
    end
    subgraph 分析产出
        C1["GET /{id}/workflow 全景"] --- C2["GET /{id}/report?lang="] --- C3["POST /{id}/rerun"]
    end
    subgraph 可观测
        D1["GET /{id}/tokens"] --- D2["GET /tokens/stats"] --- D3["GET /tokens/stream"] --- D4["GET /{id}/events[/stream SSE]"]
    end
    subgraph 上传
        E1["POST /uploads 图片≤10×8MB"] --- E2["POST /uploads/docs 专利文件≤6×20MB"] --- E3["/files/* 静态服务"]
    end

10. 关键设计决策与亮点

  1. 快照式检查点:以 FTOState 单体 JSON 为快照单位,检查点 = 阶段(S4 = 单专利)粒度,恢复天然幂等(pn in analyses 跳过),实现极简且可靠;
  2. 关卡即对话卡片:三个人工强制门与 chatbot 统一通道——同一 resolve_gate() 同时服务自然语言裁决与 REST 审批,人机协同只有一个交互面;
  3. 规则 × LLM 双层兜底:S3 分档失败回退 medium、S5 风险 LLM 失败走规则引擎(claim chart 统计评级)、S4 判定缺失由 chart 回推、S6 总体判定数字一律规则计算——LLM 只做叙述层,杜绝数字幻觉;
  4. 可观测性内建:每次 LLM 调用(chat/vision/对话)经 token_metrics.record() 双写 SQLite + Redis Stream(9 字段契约),Harness 每步轨迹可回放;
  5. 安全治理:输入守卫(提示注入启发式)+ 输出守卫(幻觉专利号检测)+ 步数/token 预算优雅收敛;
  6. 检索自愈:中英分路互不阻塞 → 零命中 LLM 泛化重试 → 以图搜图(design)多策略并行、各自审计留痕;
  7. 外观设计视觉管线:多图上传 → 降采样 base64 → glm.vision 暴力拆解(bbox/九宫格)→ PIL 标注图(三级兜底)→ 逐组件对比 + 整体观察综合判断,符合外观侵权判定司法框架;
  8. 演示友好:MOCK_LLM/MOCK_SEARCH 全离线可跑;search_limit=4 / max_analyze=3 控制规模成本。
最近更新: 2026年11月4日 13:41:29
浏览: 11

[[total]] 条评论

添加评论
  1. [[item.time]]
    [[item.user.username]] [[item.floor]]楼
  2. 点击加载更多……
  3. 添加评论