法律 AI Agent:从架构到案例匹配的技术方案与工程实践

AI Agent的法律合规框架:数据保护、责任归属与监管要求完整指南 2024年5月,我接到了国内某知名智能房产经纪人Agent SaaS平台创始人的紧急咨询电话。那天下午,该平台接到了上海市消费者权益保护委员会的约谈函:上海一位市民王女士通过其平台的Agent“智能房管家小李”预约了一套位于浦东张江的房源,但小李擅自修改了经纪人报备的真实房源信息——把“靠近地铁站1.8公里”改成了“步行8分钟可达(约600米)”,还隐瞒了该房源属于回迁房土地性质剩余使用权仅32年的关键信息,导致王女士支付了2万元意向金后才发现被骗,要求平台和经纪人双倍返还并赔偿精神损失。 阅读详情

普通人遇到法律问题,第一反应往往不是"找律师",而是——“我这事算什么性质?该怎么办?”

劳动争议、民间借贷、婚姻纠纷、交通事故……这些高频法律场景,真正走到诉讼阶段的只是少数。大多数人卡在第一步:不知道自己的情况对应什么法律问题,也不知道该从哪开始。

这篇文章从整体架构讲到案例匹配模块的技术实现——LangGraph 工作流编排、ES + Qdrant 多路召回、LLM 精排、Guardrail 三层校验链。不做概念科普,只讲设计和代码。


一、整体定位:四级漏斗


用户描述问题
    ↓
第一层:案情导诊
判断属于什么法律问题,评估严重程度,给出行动方向
    ↓
第二层:案例匹配(核心能力)
检索相似案例,分析判决结果,提供辩护/应诉思路参考
    ↓
第三层:自助工具
生成法律文书,提供流程指引和证据清单
    ↓
第四层:律师匹配
按领域/地区推荐律师

用户从导诊进入,根据问题的复杂程度停在不同的层级。简单问题导诊 + 自助工具就够了,复杂问题走到底层找律师。


二、整体架构


用户界面(小程序 / Web / 公众号)
      │
┌─────▼────────────────────────────────────┐
│             Agent 核心层                  │
│                                          │
│  案情理解 → 导诊分类 → 行动建议          │
│  事实提取    风险评估    分步指南         │
│  要素识别    紧急度     材料清单          │
│                                          │
│  案例匹配 → 辩护思路                     │
│  语义检索    策略推荐                     │
│  判决分析    法条引用                     │
│                                          │
│  文书生成 → 律师匹配 → 流程跟踪          │
└────┬───────────┬───────────┬─────────────┘
     │           │           │
┌────▼───┐ ┌────▼────┐ ┌───▼───────────┐
│ 知识库  │ │ 案例库  │ │ 外部服务      │
│         │ │         │ │               │
│ 法律条文 │ │ 裁判文书 │ │ 律师信息     │
│ 司法解释 │ │ 按案由   │ │ 法院信息     │
│ 流程知识 │ │ 按语义   │ │ 工商信息     │
│ 文书模板 │ │ 判决结果 │ │               │
└─────────┘ └─────────┘ └───────────────┘

图片

三、案例匹配:完整技术实现


案例匹配是 Agent 最有价值也最难的模块。用户说"老板不给工资还把我辞了",Agent 能从裁判文书库中找到事实最接近的案例,告诉用户类似情况法院怎么判的、赔偿范围多少、怎么主张权利。

3.1 LangGraph 工作流编排

整个流程有 4 个 Stage,但不是简单的线性流水线。Stage 1 发现关键信息缺失要回退问用户,Stage 3 精排结果太差要放宽召回条件重试。用 LangGraph 的状态图来编排是最自然的选择。

from langgraph.graph import StateGraph, END
from typing import TypedDict, Optional, List

# === 全局状态定义 ===

class LegalCaseState(TypedDict):
    user_input: str
    structured: Optional[dict]           # Stage 1 结构化结果
    missing_info: List[str]              # 缺失的关键信息
    tag_filtered_ids: List[str]          # 标签过滤后的候选 ID
    recall_candidates: List[dict]        # 向量召回结果
    reranked_top5: List[dict]            # 精排结果
    output: Optional[dict]               # 最终产出
    retry_count: int                     # 重试次数
    max_retries: int                     # 最大重试

# === 构建状态图 ===

workflow = StateGraph(LegalCaseState)

workflow.add_node("extract_legal_elements", extract_legal_elements)
workflow.add_node("ask_missing_info", ask_missing_info)
workflow.add_node("tag_filter", tag_filter)
workflow.add_node("vector_recall", vector_recall)
workflow.add_node("llm_rerank", llm_rerank)
workflow.add_node("relax_recall", relax_recall)
workflow.add_node("generate_output", generate_output)

workflow.set_entry_point("extract_legal_elements")

# 有条件边:信息缺失 → 反问用户
workflow.add_conditional_edges(
    "extract_legal_elements",
    decide_missing_info,
    {"ask_user": "ask_missing_info", "proceed": "tag_filter"}
)
workflow.add_edge("ask_missing_info", "extract_legal_elements")

# 召回链路
workflow.add_edge("tag_filter", "vector_recall")
workflow.add_edge("vector_recall", "llm_rerank")

# 精排不达标 → 放宽条件重试
workflow.add_conditional_edges(
    "llm_rerank",
    decide_retry,
    {"acceptable": "generate_output", "retry": "relax_recall", "failed": END}
)
workflow.add_edge("relax_recall", "vector_recall")

app = workflow.compile()

为什么用 LangGraph 而不是 LangChain Chain? 因为流程中有多个条件分支和回退环路——信息缺失要回退到反问、精排不达标要放宽条件重试。Chain 是 DAG 结构,表达不了带环的流程;StateGraph 的循环边天然适合这种场景。

路由函数实现:

def decide_missing_info(state: LegalCaseState) -> str:
    """判断是否需要反问用户补充信息"""
    if state["missing_info"] and state["retry_count"] == 0:
        critical = ["amount_involved", "has_contract"]
        for info in state["missing_info"]:
            if info in critical:
                return "ask_user"
    return "proceed"

def decide_retry(state: LegalCaseState) -> str:
    """判断精排结果是否可接受"""
    if not state["reranked_top5"]:
        return "retry" if state["retry_count"] < state["max_retries"] else "failed"

    top_score = state["reranked_top5"][0].get("overall_score", 0)
    if top_score < 6.0 and state["retry_count"] < state["max_retries"]:
        state["retry_count"] += 1
        return "retry"
    return "acceptable"

3.2 Stage 1:案情结构化

用户的口语化描述先转化为结构化法律要素。这一步做不好,后面全是错的。

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field

class LegalElements(BaseModel):
    case_type: str = Field(description="案件类型:民事/刑事/行政")
    case_category: str = Field(description="案由大类,如劳动争议")
    sub_category: str = Field(description="案由小类")
    employment_duration: Optional[str] = None
    has_contract: Optional[bool] = None
    unpaid_wages: Optional[dict] = None
    termination_type: Optional[str] = None
    amount_involved: Optional[str] = None
    keywords: List[str] = Field(default_factory=list)
    applicable_laws: List[str] = Field(default_factory=list)
    missing_info: List[str] = Field(default_factory=list)

parser = PydanticOutputParser(pydantic_object=LegalElements)

prompt = ChatPromptTemplate.from_messages([
    ("system", """你是一个法律案情分析专家。将用户的自然语言描述转化为结构化法律要素。
注意:
1. **只抽取明确提到的信息,不要猜测**

2. **如果关键信息缺失,在 missing_info 中标注**

3. **案由分类参考《民事案件案由规定》**

{format_instructions}"""),
    ("human", "{user_input}")
])

chain = prompt | llm | parser

输出结构化结果的同时,missing_info 字段驱动 LangGraph 的 ask_missing_info 节点反问用户补全信息:

def ask_missing_info(state: LegalCaseState):
    questions = []
    for k in state["missing_info"][:3]:
        if k == "amount_involved":
            questions.append("您的月工资是多少?这关系到赔偿金额的计算。")
        elif k == "has_social_security":
            questions.append("公司有没有给您缴纳社保?")
        elif k == "has_contract":
            questions.append("您和公司签过劳动合同吗?")
    return {"messages": [AIMessage(content="/n".join(questions))]}

3.3 Stage 2:多路召回

裁判文书网有上亿份判决书,不能全量做向量检索。分两级:ES 标签过滤 + Qdrant 向量语义检索。

第一级:ES 标签精确过滤

用 Stage 1 的结构化标签做过滤,快速缩小候选集。选用 ES 而不是关系数据库,因为裁判文书除了结构化字段还有全文内容,ES 的倒排索引可以同时在结构化字段和文本字段上做混合过滤。

from elasticsearch import Elasticsearch

es = Elasticsearch("http://localhost:9200")

def tag_filter(state: LegalCaseState) -> LegalCaseState:
    elements = state["structured"]

    must_clauses = [
        {"term": {"case_category": elements["case_category"]}},
        {"terms": {"sub_category": [elements["sub_category"]]}},
        {"range": {"year": {"gte": 2022, "lte": 2026}}},
    ]

    if elements.get("has_contract") is False:
        must_clauses.append({"term": {"has_contract": False}})

    if elements.get("amount_involved") and elements["amount_involved"] != "未知":
        amount = extract_number(elements["amount_involved"])
        must_clauses.append({"range": {"amount_involved": {"lte": amount * 2}}})

    body = {
        "query": {"bool": {"must": must_clauses}},
        "size": 5000,
        "_source": ["case_id", "case_category", "fact_summary", "judgment"]
    }

    resp = es.search(index="judgments", body=body)
    case_ids = [hit["_source"]["case_id"] for hit in resp["hits"]["hits"]]

    return {"tag_filtered_ids": case_ids}
第二级:Qdrant 向量语义检索

在标签过滤后的候选集上,用事实描述做语义检索。选 Qdrant 而不是 Milvus:这个场景只需要单机部署、百亿级以内的向量量,Qdrant 一个 Docker 容器搞定,部署成本比 Milvus 低得多。

Embedding 模型选 bge-m3(1024 维)。法律文书中法条编号(“第82条”)、案例编号(“(2023)京01民终1234号”)中英文混写,bge-m3 的多语言能力在 1024 维下检索精度比 text-embedding-3-small 高 3-5 个百分点(在我们的 2000 条标注测试集上)。

from qdrant_client import QdrantClient
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("BAAI/bge-m3")
client = QdrantClient(host="localhost", port=6333)

def vector_recall(state: LegalCaseState) -> LegalCaseState:
    case_ids = state["tag_filtered_ids"]
    query_text = state["structured"].get("fact_summary", state["user_input"])
    query_vector = model.encode(query_text).tolist()

    # Qdrant 支持用 payload filter 缩小搜索范围
    hits = client.search(
        collection_name="judgments_by_category",
        query_vector=query_vector,
        query_filter={"must": [{"has_id": case_ids}]},
        limit=50,
    )

    # 混合权重:0.6 × 向量相似度 + 0.4 × 标签匹配度
    candidates = []
    for hit in hits:
        vector_score = hit.score
        tag_score = compute_tag_match(state["structured"], hit.payload)
        combined = 0.6 * vector_score + 0.4 * tag_score

        candidates.append({
            "case_id": hit.payload["case_id"],
            "fact_summary": hit.payload["fact_summary"],
            "judgment": hit.payload["judgment"],
            "combined_score": combined,
        })

    candidates.sort(key=lambda x: x["combined_score"], reverse=True)
    return {"recall_candidates": candidates[:50]}

为什么先做标签过滤再做向量检索? 因为"法律关系相似"和"事实描述相似"是两回事。两个案例都提到"欠薪",但一个是劳动合同纠纷(适用劳动法),一个是劳务合同纠纷(适用民法典),法律关系不同,判决依据完全不同。标签过滤确保候选集在法律关系上是同类的。

混合权重
def compute_tag_match(structured: dict, payload: dict) -> float:
    score = 0.0
    # 子案由一致给 0.5
    if structured.get("sub_category") == payload.get("sub_category"):
        score += 0.5
    # 要素重叠比例
    elements = structured.get("legal_elements", {})
    payload_elems = payload.get("legal_elements", {})
    overlap = sum(1 for k, v in elements.items()
                  if v and v != "未知" and payload_elems.get(k) == v)
    total = sum(1 for v in elements.values() if v and v != "未知")
    if total > 0:
        score += 0.5 * (overlap / total)
    return score
重试时的放宽策略
def relax_recall(state: LegalCaseState) -> LegalCaseState:
    retry = state["retry_count"]
    if retry == 1:
        state["tag_filtered_ids"] = expand_category(state)  # 案由扩大到父类
    elif retry == 2:
        state["tag_filtered_ids"] = remove_year_filter(state)  # 去掉年份限制
    elif retry >= 3:
        state["tag_filtered_ids"] = None  # 全库向量检索
    return state

3.4 Stage 3:LLM 精排

向量召回回来的 TOP 50,还需要做一次精细比对。向量相似度衡量的是"措辞相似",不是"法律关系相似"。

用 LangChain 的 with_structured_output 实现多维评分:

from langchain_core.pydantic_v1 import BaseModel, Field

class CaseScore(BaseModel):
    cause_match: int = Field(ge=1, le=10, description="案由匹配度")
    fact_similarity: int = Field(ge=1, le=10, description="事实相似度")
    dispute_focus: int = Field(ge=1, le=10, description="争议焦点")
    reference_value: int = Field(ge=1, le=10, description="参考价值")

class RerankResult(BaseModel):
    scores: List[CaseScore]

rerank_prompt = ChatPromptTemplate.from_messages([
    ("system", """你是一个法律案例比对专家。请从以下维度评分(1-10):
A. 案由匹配度 B. 事实相似度 C. 争议焦点 D. 参考价值
要严格评分,事实不相似就给低分。"""),
    ("human", "用户案情:{user_case}/n候选案例:{case_info}")
])

structured_llm = llm.with_structured_output(RerankResult)
rerank_chain = rerank_prompt | structured_llm

批量评分并加权聚合:

def llm_rerank(state: LegalCaseState) -> LegalCaseState:
    candidates = state["recall_candidates"][:50]
    scored = []

    for i in range(0, len(candidates), 5):
        batch = candidates[i:i+5]
        result = rerank_chain.invoke({
            "user_case": state["user_input"],
            "case_info": [
                {"case_fact": c["fact_summary"][:500],
                 "case_judgment": c["judgment"][:300]}
                for c in batch
            ]
        })
        for idx, score in enumerate(result.scores):
            scored.append({
                batch[idx],
                "overall_score": (
                    score.cause_match * 0.3 +
                    score.fact_similarity * 0.3 +
                    score.dispute_focus * 0.2 +
                    score.reference_value * 0.2
                )
            })

    scored.sort(key=lambda x: x["overall_score"], reverse=True)
    return {"reranked_top5": scored[:5]}

这份精排结果同时输入到判决统计(用 TOP 50 的判决结果做统计分析)和策略建议(用 TOP 5 的法院观点生成)。

3.5 Guardrail 实现

法律 Agent 的 Guardrail 和其他场景不同——它防护的不是"执行了危险操作",而是输出了误导性法律内容。

用 LangGraph 的 Condition 做第一道闸,自定义规则引擎做第二道,知识库检索做第三道:

def guardrail_check(state: LegalCaseState) -> str:
    output = state["output"]

    # 第一道:Agent 自检 — 绝对化表述拦截
    if any(p in str(output) for p in ["保证", "一定", "100%", "肯定赢"]):
        return "rewrite"

    # 第二道:规则拦截
    if state["structured"]["case_type"] in ("刑事", "行政"):
        if "律师" not in str(output):
            return "block"

    if "不构成法律意见" not in str(output):
        return "rewrite"

    # 第三道:法条引用校验
    cited_laws = extract_law_citations(str(output))
    for law in cited_laws:
        if not verify_citation(query_law_knowledge_base(law), str(output)):
            return "rewrite"

    return "pass"

# 注册为 LangGraph 条件边
workflow.add_conditional_edges(
    "generate_output",
    guardrail_check,
    {"pass": END, "rewrite": "generate_output", "block": "blocked_output"}
)

法条引用校验的实现——用精确查询,不用向量检索。法条原文一字不能差,向量检索的召回率做不到 100%:

def extract_law_citations(text: str) -> List[str]:
    import re
    pattern = r"[《]?([^》]+?法)[》]?第(/d+)条"
    matches = re.findall(pattern, text)
    return [f"{m[0]}第{m[1]}条" for m in matches]

def query_law_knowledge_base(law_citation: str) -> str:
    result = es.get(index="law_knowledge_base", id=law_citation)
    return result["_source"]["original_text"]

四、安全性设计


法律 Agent 和其他场景最大的不同是:给错了建议,用户可能真的会输掉官司。

三条红线

  • 不能给确定性结论。 不说"你一定能赢",说"类似案例胜诉率约 80%"
  • 不能替代律师。 刑事案件、重大商事纠纷必须建议咨询律师
  • 不能建议违法操作。 不指导毁灭证据、虚假陈述等

免责声明的分级

DISCLAIMERS = {
    "civil": (
        "⚠️ 以上分析基于公开数据和通用法律知识,不构成正式法律意见。"
        "每个案件情况不同,建议咨询执业律师。"
    ),
    "criminal": (
        "🚨 您描述的情况可能涉及刑事/重大民事纠纷。"
        "建议立即委托执业律师处理。本工具仅提供参考信息,"
        "不能替代专业法律服务。"
    ),
}

这些是 Guardrail 代码强制追加的,不是 LLM 自觉加上的。如果 Guardrail 检测到输出中缺少免责声明,会触发 rewrite 强制补上。


五、关键的工程决策


案由分库 vs 全库统一检索

每个高频案由(劳动争议、民间借贷、婚姻家事、交通事故、买卖合同纠纷)在 Qdrant 里各一个 collection。这五类占了民事诉讼的 70% 以上。

COLLECTION_MAP = {
    "劳动争议": "judgments_labor",
    "民间借贷": "judgments_loan",
    "婚姻家事": "judgments_family",
    "交通事故": "judgments_traffic",
    "买卖合同纠纷": "judgments_contract",
}

好处:检索范围小速度快、无跨案由语义噪音、不同案由可独立调优。代价:案由识别必须准确,新增案由需要建新库。

裁判文书预处理

原始裁判文书有几大问题:长(少则几千字多则几万字)、模板化(大量格式文本)、噪声多(OCR 错误)。预处理必须做 LLM 提取,只把 fact_summary(300 字以内)拿去 Embedding。

超过 512 token 长度的文本,bge-m3 的向量表示质量会明显下降。所以提取内容控制在 500 字以内做 Embedding。

冷启动策略

从最高人民法院发布的典型案例和指导案例开始——这些案例质量高、权威性强,数量不多(几千份)但覆盖主要案由。然后扩展到各省高院的裁判文书,最后再扩展到基层法院。

增量更新:每周跑一次增量 pipeline,新文书经过预处理 → Embedding → Qdrant upsert,不需要全量重建。

时效性

2020 年的案例和 2025 年的案例,法律可能有修改(如 2024 年民法典合同编司法解释)。默认只检索近 3 年,案例太少才放宽。


六、V2.0 升级:五个关键优化


上面这套方案上线跑通(以下简称 V1.0)之后,有几个问题会暴露出来。我们在迭代过程中识别了五个核心短板,对应做了 V2.0 的架构升级。

6.1 CrossEncoder 初排:解决 LLM 精排成本

V1.0 的问题: TOP 50 直接送 LLM 打分。如果用的 GPT-4.1 或 Claude,50 个 case 逐个看,单次查询仅精排就要几万 token,成本和延迟都扛不住。月活一万用户,光精排每个月烧掉几千美元。

V2.0 的改进: 在向量检索和 LLM 精排之间加一层 CrossEncoder 初排。

V1.0:  ES → Qdrant (50) → LLM 精排 → TOP 5
V2.0:  ES → Qdrant (50) → CrossEncoder (50→20) → LLM 精排 → TOP 5

CrossEncoder 比向量检索(Bi-Encoder)精度高,比 LLM 成本低一个数量级。

from sentence_transformers import CrossEncoder

# bge-reranker-v2 或 Qwen3-Reranker 均可
reranker = CrossEncoder("BAAI/bge-reranker-v2-m3")

def cross_encoder_rerank(state: LegalCaseState) -> LegalCaseState:
    candidates = state["recall_candidates"][:50]
    query = state["structured"].get("fact_summary", state["user_input"])

    pairs = [(query, c["fact_summary"][:512]) for c in candidates]
    scores = reranker.predict(pairs)

    for idx, score in enumerate(scores):
        candidates[idx]["crossencoder_score"] = float(score)
        # 融合向量得分和 CrossEncoder 得分
        candidates[idx]["combined_score"] = (
            0.3 * candidates[idx]["combined_score"] +
            0.7 * float(score)
        )

    candidates.sort(key=lambda x: x["combined_score"], reverse=True)
    return {"recall_candidates": candidates[:20]}  # 只保留 TOP 20 给 LLM
方案单次成本延迟精度
LLM 直接看 50 个$$$10-20s最高
CrossEncoder 50→20 + LLM 看 20 个$2-3s≈ 持平
纯 CrossEncoder$~1s略低但有瓶颈

CrossEncoder 的得分(01)和向量余弦相似度(01)做加权融合。线上实验下来,0.7 × CrossEncoder + 0.3 × 向量相似度 效果最好,既保留了语义信息,又大幅压低了 LLM 调用量。

选型上 bge-reranker-v2-m3 和 Qwen3-Reranker 都可用。前者对中英文混写文本(法律文书场景)表现更好,后者在纯中文场景略优。

6.2 法条优先 + 联合推理:纠正成文法系逻辑

V1.0 的问题: 案例匹配→策略推荐,这套逻辑是美国判例法思维。中国是成文法系,裁判逻辑是法条 → 司法解释 → 指导案例,案例只是参考,不能作为判决依据。

只给用户看"类似案例怎么判",不给"法律依据是什么",在中国法律场景下是半成品。

V2.0 的改进: 召回链路改成法条召回 → 案例召回 → 联合推理。

V1.0:  案情结构化 → 案例检索 → 策略推荐
V2.0:  案情结构化 → ┌── 法条检索 (Law RAG)
                    ├── 案例检索 (Case RAG)
                    └── 联合推理 (Legal Reasoner)

法条检索独立成一条召回链路:

def law_recall(state: LegalCaseState) -> LegalCaseState:
    """从法律知识库中检索相关法条"""
    elements = state["structured"]

    # 方法 1:基于案由的精确匹配
    law_ids = es.search(index="law_knowledge_base", body={
        "query": {"bool": {"must": [
            {"term": {"applicable_categories": elements["case_category"]}},
        ]}},
        "size": 10,
    })

    # 方法 2:基于关键要素的语义检索
    query_text = " ".join(elements.get("keywords", []))
    law_vectors = law_model.encode(query_text).tolist()
    law_hits = law_client.search(
        collection_name="laws",
        query_vector=law_vectors,
        limit=5,
    )

    return {"law_candidates": combine_law_results(law_ids, law_hits)}

联合推理阶段,LLM 同时看到法条原文和相似案例,生成的建议结构变为:

📋 分析结果

【法律依据】
劳动合同法第10条:建立劳动关系应当订立书面劳动合同
劳动合同法第82条:未签合同超过一个月,应支付双倍工资
劳动合同法第87条:违法解除劳动合同,应支付二倍经济补偿金

【相似案例参考】
案例1:张三诉XX公司……(以下为参考,不作为判决依据)

【策略建议】
基于上述法律依据和参考案例……

法条是依据,案例是参考。 用户先看到法律依据,再看案例,逻辑上更符合中国法律体系。

6.3 法律知识图谱:连接法条、概念与案例

V1.0 的问题: 法条库和案例库各自独立。当法条更新时(如 2024 年民法典合同编司法解释发布),旧案例引用的法条版本可能已经不适用。而且法条和场景之间的关联是隐式的,检索全靠语义相似度,精度不够。

V2.0 的改进: 建一个法律知识图谱(Neo4j),把法条、法律概念、适用场景、关联案例串起来。

from neo4j import GraphDatabase

class LawGraph:
    def __init__(self, uri, user, password):
        self.driver = GraphDatabase.driver(uri, auth=(user, password))

    def query_related(self, law_article: str) -> List[dict]:
        """查询某法条关联的场景、概念和案例"""
        with self.driver.session() as session:
            result = session.run("""
                MATCH (l:LawArticle {article: $article})
                OPTIONAL MATCH (l)-[:APPLIES_TO]->(s:LegalScenario)
                OPTIONAL MATCH (l)<-[:BASED_ON]-(c:Case)
                OPTIONAL MATCH (l)-[:RELATES_TO]->(concept:LegalConcept)
                RETURN l.article AS article, l.content AS content,
                       collect(DISTINCT s.name) AS scenarios,
                       collect(DISTINCT c.case_id) AS cases,
                       collect(DISTINCT concept.name) AS concepts
            """, article=law_article)
            return result.single().data()

图谱结构(三元组示例):

劳动合同法第82条 — [适用于] → 未签劳动合同
劳动合同法第82条 — [适用于] → 双倍工资请求
劳动合同法第82条 — [关联] → 经济补偿金
张三诉XX公司案 — [依据] → 劳动合同法第82条
张三诉XX公司案 — [关键词] → 未签劳动合同

这种关联比向量检索精确得多。问"未签合同能拿多少钱",图谱直接找到第82条和关联案例,不需要语义匹配。

更关键的是法条变更追踪:

def check_law_update(law_article: str) -> Optional[str]:
    """检查法条是否有新版本"""
    with graph.session() as session:
        result = session.run("""
            MATCH (l:LawArticle {article: $article})
            WHERE l.effective_date < date() AND l.superseded_by IS NOT NULL
            RETURN l.superseded_by AS new_article
        """, article=law_article)
        record = result.single()
        return record["new_article"] if record else None

当法条被新法替代时,图谱能直接溯源到最新版本,避免引用已失效法条。

6.4 Case Memory:跨会话的案件上下文

V1.0 的问题: 用户的咨询不是一次性完成的。

第一天:"公司拖欠工资" → 系统抽取结构化信息
第二天:"公司让我签离职协议" → 系统重新抽取,不知道是同一个人同一个案件
第三天:"仲裁申请怎么写" → 再次重新抽取

每次都要 LLM 重新做法案要素抽取,浪费 token 不说,还丢失了上下文连贯性。

V2.0 的改进: 引入 Case Memory 层,用独立的持久化存储保存用户的案件上下文。

class CaseMemory:
    """跨会话的案件记忆"""

    def __init__(self):
        self.db = DuckDB("case_memory.db")  # 轻量本地存储
        self.db.execute("""
            CREATE TABLE IF NOT EXISTS case_memory (
                session_id VARCHAR,
                case_id VARCHAR,
                structured_data JSON,
                created_at TIMESTAMP,
                updated_at TIMESTAMP,
                is_active BOOLEAN DEFAULT TRUE
            )
        """)

    def get_active_case(self, session_id: str) -> Optional[dict]:
        row = self.db.execute(
            "SELECT structured_data FROM case_memory "
            "WHERE session_id = ? AND is_active = TRUE "
            "ORDER BY updated_at DESC LIMIT 1",
            [session_id]
        ).fetchone()
        return json.loads(row[0]) if row else None

    def save_case(self, session_id: str, structured: dict):
        """持久化结构化结果"""
        case_id = structured.get("case_id", str(uuid4()))
        self.db.execute("""
            INSERT INTO case_memory (session_id, case_id, structured_data,
                                     created_at, updated_at)
            VALUES (?, ?, ?, NOW(), NOW())
            ON CONFLICT (case_id) DO UPDATE SET
                structured_data = EXCLUDED.structured_data,
                updated_at = NOW()
        """, [session_id, case_id, json.dumps(structured)])

在 LangGraph 的入口处先查 Memory,有活跃案件则跳过 Stage 1 的结构化抽取:

def route_with_memory(state: LegalCaseState) -> str:
    """如果有活跃的案件记忆,跳过结构化抽取直接进入召回"""
    memory = CaseMemory()
    active = memory.get_active_case(state["session_id"])
    if active and is_same_case(active, state["user_input"]):
        state["structured"] = active
        return "skip_extraction"  # 直接跳到召回
    return "extract"

这一层用 DuckDB 就够了——数据量小(用户维度的案件记录),不需要独立部署数据库服务。每个用户一个 session,每个 session 保留最近一个活跃案件的上下文。

6.5 MCP Tool Layer:接入外部数据源

V1.0 的问题: 所有知识都来自自有知识库。但法律场景中很多信息需要实时查询外部数据源——公司工商信息、法院公告、律师执业信息、裁判文书网最新判例。

V2.0 的改进: 通过 MCP(Model Context Protocol)标准协议接入外部工具。

Agent 推理层
    ↓
MCP Tool Layer
    ├── 企业信息查询(天眼查 / 企查查 API)
    ├── 法院公告查询
    ├── 律师执业信息查询
    ├── 裁判文书网检索
    └── 工商注册信息查询

在 LangGraph 中,这些工具注册为可被 Agent 调用的节点:

from langchain_core.tools import tool

@tool
def query_company_info(company_name: str) -> dict:
    """查询企业的工商注册信息"""
    # 通过 MCP 协议调用天眼查 API
    return mcp_call("tianyancha", {"keyword": company_name})

@tool
def query_lawyer_info(name: str, region: str) -> List[dict]:
    """查询某地区的律师执业信息"""
    return mcp_call("lawyer_db", {"name": name, "region": region})

@tool
def check_court_announcement(case_id: str) -> Optional[dict]:
    """查询法院公告信息"""
    return mcp_call("court_api", {"case_id": case_id})

# 在 Legal Reasoner 节点中,Agent 根据场景自动调用工具
def legal_reasoner(state: LegalCaseState) -> LegalCaseState:
    """联合推理:综合法条、案例、外部数据生成建议"""
    # Agent 根据推理需要自动调用工具
    # 比如用户提到某公司 → Agent 自动调用 query_company_info
    # 比如需要推荐律师 → Agent 自动调用 query_lawyer_info
    result = reasoning_chain.invoke({
        "user_case": state["user_input"],
        "laws": state["law_candidates"],
        "cases": state["reranked_top5"],
        "tools": [query_company_info, query_lawyer_info, check_court_announcement],
    })
    return {"output": result}

MCP 的核心价值不是"能调外部 API"——这并不新鲜——而是标准化的工具定义和发现协议。未来法律科技生态中,法院、律所、数据服务商都暴露 MCP Server,Agent 可以即插即用,不用为每个数据源写定制集成代码。

V2.0 架构全景

                        用户
                          │
                          ▼
                    ┌──────────┐
                    │ Case     │ ← 跨会话记忆
                    │ Memory   │
                    └────┬─────┘
                          │
                          ▼
                   LangGraph Orchestrator
                    │    │        │
                    ▼    ▼        ▼
              案件理解  法条检索   案例检索
               (图谱)   (Law RAG) (Case RAG)
                          │
                          ▼
                    知识图谱 (Neo4j)
                    法条 ↔ 场景 ↔ 案例
                          │
                          ▼
                   CrossEncoder (50→20)
                          │
                          ▼
                    LLM 精排 (20→5)
                          │
                          ▼
                   Legal Reasoner
                   (联合推理 + MCP Tool)
                          │
                          ▼
                      Guardrail
                          │
                          ▼
                       输出

V1.0 到 V2.0 的五个升级,本质上是同一个认知转变:

图片

法律 AI Agent 不是搜索引擎。它不是在找"最像"的东西,而是在做"法律推理"。

这个转变体现在每一个改动里——法条优先于案例、知识图谱替代纯语义检索、CrossEncoder 加上 LLM 做两级精排而非让 LLM 独自扛、Memory 让 Agent 记住案情而非每次都重新理解、工具调用让 Agent 能核实信息而非全靠知识库。

如果说法学是一个"法条 × 事实 × 经验"的三元推理,V1.0 只解决了"事实 → 经验"这一条路径,V2.0 才补齐了另外两条。

层级V1.0 选型V2.0 升级作用
工作流编排LangGraph StateGraphLangGraph + Memory 路由多阶段流转 + 条件回退 + 重试控制
结构化抽取LLM + Pydantic Output Parser同上 + Case Memory 跳过口语化→结构化法律要素
法条检索ES 精确查询Law RAG + 知识图谱 (Neo4j)法条依据优先召回
标签过滤Elasticsearch同上案由/要素筛选,千万级→万级
向量检索Qdrant + bge-m3同上语义相似度召回
初排无CrossEncoder (bge-reranker-v2)低成本 50→20 过滤
精排LLM 看 50 个 → TOP 5LLM 看 20 个 → TOP 5多维评分
联合推理案例→策略建议法条 + 案例 + MCP 工具联合推理符合成文法体系
法条校验ES 精确查询+ 图谱变更追踪确保法条版本准确
跨会话记忆无DuckDB Case Memory同案件多轮对话不重复抽取
外部工具无MCP Tool Layer企业查询/法院公告/律师库
GuardrailLangGraph Condition + 规则同上 + 法条版本校验三层校验链

几个关键决策:

  1. 1. 用 LangGraph 而不是 Chain,因为流程带环(反问回退、重试放宽)

  2. 2. 先 ES 标签过滤再 Qdrant 向量检索,而不是全库向量搜索

  3. 3. 裁判文书必须预处理提取,不能用原文 Embedding(超过 512 token 质量下降)

  4. 4. 精排加一层 CrossEncoder 做初排,LLM 只看 20 个,成本降低 60%

  5. 5. 法条召回优先于案例召回——中国是成文法系,不是判例法

  6. 6. 法条引用用精确查询校验,不用向量检索;图谱追踪法条版本变更

  7. 7. Guardrail 是代码逻辑,不是说一句"仅供参考"

这里给大家精心整理了一份全面的AI大模型学习资源,包括:AI大模型全套学习路线图(从入门到实战)、精品AI大模型学习书籍手册、视频教程、实战学习、面试题等,资料免费分享!

👇👇扫码免费领取全部内容👇👇
在这里插入图片描述

1. 成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。

这里,我们为新手和想要进一步提升的专业人士准备了一份详细的学习成长路线图和规划。可以说是最科学最系统的学习成长路线。
在这里插入图片描述

2. 大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。(书籍含电子版PDF)

在这里插入图片描述

3. 大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识。

在这里插入图片描述

4. 2026行业报告

行业分析主要包括对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。

5. 大模型项目实战

学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

在这里插入图片描述

6. 大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

在这里插入图片描述

7. 资料领取:全套内容免费抱走,学 AI 不用再找第二份

不管你是 0 基础想入门 AI 大模型,还是有基础想冲刺大厂、了解行业趋势,这份资料都能满足你!
现在只需按照提示操作,就能免费领取:

👇👇扫码免费领取全部内容👇👇
在这里插入图片描述

法律领域Agentic AI开发训练营:提示工程架构师带你完成从理论到项目 当AI从“执行指令的计算器”进化为“能自主思考的法律助理”,法律行业的效率边界正在被重新定义——但如何让AI真正“懂法律”?本文将以法律领域Agentic AI开发用“法律助理”的比喻讲清Agentic AI的本质;用“写菜谱”的逻辑教你设计严谨的法律提示;用智能劳动合同审查Agent的实战项目,演示RAG、工具调用、合规校验的落地技巧;解答法律AI最棘手的问题:如何保证输出准确?如何符合合规要求? 阅读详情

相关推荐

基于多Agent架构的AI代码审查系统:从原理到工程实践

代码审查是保障软件质量、统一编码规范的关键环节,其核心原理在于通过系统化的检查机制发现潜在缺陷。传统人工审查受限于经验、精力与一致性,而自动化代码分析技术则通过静态分析、规则引擎等手段,实现了对编码规范、安全漏洞等问题的规模化检测。随着大语言模型(LLM)等AI技术的发展,代码审查正从基于固定规则的自动化,向具备语义理解与逻辑推理能力的智能化演进。这种智能化的核心价值在于,它能将开发者从重复性劳动中解放,使其更专注于架构与核心逻辑,同时通过多维度、并行的深度分析,显著提升缺陷发现的覆盖率和效率。在实际应用场

weixin_30268921的博客 706

Agentic AI在罕见病诊断中的突破:提示工程架构师的技术方案与案例分析

罕见病诊断的核心需求是**“在信息不完整、知识分散的情况下,快速缩小诊断范围,提供高置信度的建议”**。缺乏“自主决策”能力:无法根据患者的动态症状调整诊断策略(如患者补充“家族中有类似病例”后,AI需要主动启动基因检测建议);无法整合多源工具:罕见病诊断需要调用电子病历(EHR)、医学知识库(OMIM/Orphanet)、实验室系统(基因检测)等多个工具,传统AI难以实现“按需调用”;缺乏解释性:医生需要知道AI“为什么建议这个诊断”,而传统AI的“黑箱”输出无法满足这一需求。

专注搜索引擎技术 916

法律AI Agent实战:Qdrant+LlamaIndex构建可落地的法律知识引擎

向量数据库与AI Agent是当前法律科技的核心基础设施,其本质是将非结构化法律文本(如判决书、法条、合同)转化为可检索、可推理、可验证的语义知识。原理上需突破传统关键词匹配局限,依托嵌入模型实现语义理解,并通过混合过滤、重排序与逻辑校验保障专业准确性。技术价值在于显著压缩法律研究耗时,提升类案匹配精度与结论可信度。典型应用场景包括诉讼策略支持、合规审查辅助、合同风险识别等。本文聚焦法律领域特有的‘非对称复杂性’与‘强逻辑依赖’挑战,详解如何基于Qdrant实现多字段约束的精准向量检索,并将LlamaInd

weixin_29056781的博客 314

【人工智能学习笔记 一】 AI分层架构、基本概念分类与产品技术架构

总的来说AI主要由算法、算力、数据组成,算法是核心。LLM是基于Transformer架构的算法成果,属于NLP领域关键技术,赋予AI理解和生成语言的能力。如果把AI AGENT看作人工助手,LLM就是其大脑,提供智能核心。AIGC则基于LLM等技术,生成语言、图像、音频等内容,就像人基于大脑的一些语言和视觉的表达。举个例子:云雀模型是LLM,豆包的问答查询基于此,是AIGC在语言领域的应用;图片生成借助专门模型,也是AIGC。豆包APP里的智能体是AI AGENT,集成云雀能力为用户服务。

MaoLin Tian's Blog 7484

AI人工智能 Agent:对法律和规则的挑战

AI人工智能 Agent:对法律和规则的挑战 1.背景介绍 1.1 人工智能的兴起 近年来,人工智能(AI)技术的快速发展,使得智能系统在各个领域得到了广泛的应用。智能代理(AI Agent)作为人工智能系统的核心组成部分,正在逐

AI天才研究院 1025

提示工程架构师案例:用Agentic AI+提示工程实现法律条款智能提取系统

本文将以“法律条款智能提取系统”为案例,带你从零开始设计一个能自主分析法律文档、精准提取关键条款的AI系统。我们会拆解“提示工程架构师”的核心工作:如何通过系统化提示设计赋予AI法律专业能力,如何用Agentic框架让AI具备“规划-执行-反思”的自主决策能力,最终实现从“被动响应”到“主动完成复杂任务”的跨越。系统设计阶段:将“条款提取”拆解为文档解析、提取、校验、风险评估4个子任务,设计多Agent协作架构;提示工程核心:通过“角色定义+上下文知识+输出格式”三层结构,让大模型具备法律专业能力;

移动开发前沿的博客 1121

AI Agent 架构设计:ReAct 与 Self-Ask 模式对比与分析

在现代 Agent 设计中,任务型 Agent 和 认知型 Agent 的界限愈发清晰。前者专注于高效执行封闭领域的具体流程(如处理退款申请),而后者则致力于解决开放域的复杂问题(如“分析市场趋势并撰写报告”)。架构设计是决定 Agent 智能上限的关键。ReAct 和 Self-Ask 正是当前 LLM-based Agent 架构中,分别代表“行动派”和“思考派”的两种主流范式。

zhangzhentiyes的博客 1839

智能合同分析AI Agent:LLM在法律文本理解中的应用

随着区块链技术的迅速发展和普及,智能合同作为一种自主执行合同条款的计算机程序,逐渐成为人们关注的焦点。智能合同不仅能够提高合同执行效率,降低成本,还能够确保合同条款的透明性和不可篡改性。然而,智能合同的开发和应用面临着法律文本理解这一重大挑战。法律文本往往复杂且冗长,涉及众多专业术语和法律法规,如何有效地理解法律文本,使其与智能合同执行相匹配,成为了一个亟待解决的问题。本书籍的核心目标是探讨如何利用人工智能技术,特别是大语言模型(LLM),来解决智能合同分析中的法律文本理解问题。

欢迎来到我的优快云空间!这里聚焦AI大模型应用实战,分享前沿技术、实战案例与开发经验。 1244

AI Agent 工程实践(08):Workflow——什么时候应该拆成 Multi-Agent?

摘要: 本文探讨了AIAgent架构设计中常见的“过早采用多智能体(Multi-Agent)”误区。作者通过自身实践案例指出,80%的项目实际仅需单智能体(SingleAgent)或结合工作流(Workflow)即可满足需求,而无需复杂多智能体协作。文章提出三档渐进式架构选择标准:默认单智能体→多步线性任务升级为工作流→仅当需要并行、异构或上下文隔离时才拆解为多智能体。关键结论包括:Planner/Executor/Reviewer角色通常可作为单智能体的不同阶段;Reviewer因需独立上下文最有拆分价值

2401_85223846的博客 787

AI Agent在智能法律咨询中的角色

随着人工智能技术的飞速发展,AI Agent在各个领域的应用越来越广泛。在法律领域,智能法律咨询服务的需求日益增长。本文章的目的在于全面探讨AI Agent在智能法律咨询中的具体角色,分析其如何利用先进的技术手段为用户提供高效、准确的法律咨询服务。研究范围涵盖了AI Agent的核心概念、相关算法原理、数学模型,以及在实际项目中的应用和未来发展趋势等方面。本文首先介绍研究的背景信息,为读者奠定基础。接着阐述AI Agent和智能法律咨询的核心概念及其联系,通过直观的示意图和流程图展示其架构。

2502_91592937的博客 542

AI人工智能 Agent:在无人驾驶中的应用

AI人工智能 Agent:在无人驾驶中的应用 作者:禅与计算机程序设计艺术 1. 背景介绍 1.1 无人驾驶技术的发展历程 无人驾驶技术作为人工智能和机器人技术的集大成者,经历了漫长的发展历程。从上世纪70

AI天才研究院 1632

【干货收藏】AI Agent深度解析:架构、技术与应用实战指南

【干货收藏】AI Agent深度解析:架构、技术与应用实战指南

AI大模型的博客 2135

法律领域Agentic AI系统的用户体验设计:提示工程架构师的人机交互思考

法律领域的Agentic AI(智能体AI)区别于传统单轮问答系统,其核心是主动规划、交互推理、结果可追溯的智能伙伴。本文从提示工程架构师的视角,结合法律领域“高专业性、强合规性、结果影响大”的独特约束,系统分析法律Agentic AI的用户体验(UX)设计逻辑:从概念层的“法律用户核心需求”到理论层的“第一性原理推导”,再到架构层的“组件交互模型”,最终落地到“提示工程如何连接AI能力与人类需求”。文章通过案例、代码、可视化工具,揭示法律Agentic AI的UX设计本质——

操作系统内核探秘的博客 1015

AI Agent 工程实践(35):我的 AI Engineering OS 最终架构

本篇是第四阶段系列收官之作,复盘 00‑35 篇全部内容,提出 **AI Engineering OS**:由 Knowledge、Rules、Runtime、Memory、Review、Provider、Tools 七大支柱,搭配 Review 驱动自进化反馈闭环构成的完整系统框架。区分普通 Agent 框架与 OS 的核心差异:OS 可以把运行产生的错误与经验自动沉淀回知识与规则,实现系统越用越聪明。给出目录骨架、配置样例、复盘闭环核心代码。

2401_85223846的博客 644

用Arduino Uno和纸板做个扫地机器人?手把手教你复刻一个低成本DIY方案(附完整代码)

本文详细介绍了如何用Arduino Uno和纸板制作一款低成本DIY扫地机器人,涵盖材料准备、机械结构设计、电路系统搭建和智能清扫算法实现。通过开源硬件和日常废弃物,打造极致性价比的创客项目,适合初学者学习电子和编程。

weixin_42531588的博客 285

使用Python进行核磁数据预处理

随着医学与人工智能技术的快速崛起,伴随算法算力、数据等关键要素的积累和突破,人工智能技术在精准医学领域的科研应用也随之飞快增长,相关科研成果和学术论文数量逐年激增,医学影像人工智能涉及的技术如图像分割、病灶识别、病灶自动勾画、影像组学、深度学习模型构建和临床信息解析越来越趋于分析流程化,模块化,帮助越来越多的医生在临床科研实践中获得突破性的进展。根据具体的应用和数据类型,你可能需要调整或添加额外的步骤。对于更高级的处理,如图像分割或NMR数据的复杂处理,你可能需要查阅更专业的文献或使用更专业的软件工具。

xhlo521的博客 3132

深入解析AI Agent:构建AI Agent系统的难点、框架选型与6种架构设计模式

文章全面解析了AI Agent系统,包括其基本概念(大语言模型与工具的循环系统)、构建难点(确保LLM有合适上下文)、框架选型维度(工作流与代理、可预测性、门槛上限等)以及6种架构设计模式(路由分发、代理、微调缓存、目标导向、智能体组合和双重安全)。文章强调,构建可靠AI Agent的关键是控制LLM的上下文,并推荐使用LangGraph等框架同时支持工作流和AI Agent,以实现最佳可靠性和灵活性。

Androiddddd的博客 1380

Vivado ChipScope Debugging: Overcoming Common DRC Errors in FPGA Design

本文深入解析Vivado ChipScope调试中常见的DRC错误,特别是AVAL-244和AVAL-245等时钟相关问题,提供实用的Tcl命令解决方案和最佳实践。通过将DRC错误降级为警告的技巧,帮助FPGA设计者高效完成调试流程,同时强调何时应保留DRC检查以确保设计可靠性。

weixin_30335575的博客 418

7天上线法律AI助手:ChatLaw SaaS平台零代码部署指南

你是否还在为法律AI产品开发周期长、技术门槛高而烦恼?本文将带你基于中文法律大模型ChatLaw,从零构建一个可商用的SaaS平台,全程无需复杂编码,7天即可完成从架构设计到用户交互的全流程落地。读完本文你将获得: - 3套开箱即用的法律AI模型部署方案 - 5个核心功能模块的配置技巧 - 10分钟完成的Web界面搭建方法 - 完整的多Agent协作流程图解 ## 架构设计:ChatLaw的技术

gitblog_00318的博客 1175

ArcGIS Pro2.5深度学习使用注意事项

ArcGIS Pro2.5深度学习使用中的注意事项1、ArcGIS Pro2.5深度学习使用中的注意事项1.1、Label深度学习样本工具参数介绍1.2、准备数据参数介绍1.3、训练模型介绍1.4、ArcGIS Pro2.5深度学习推理工具和模型对应关系介绍1.4.1、Classify Objects Using Deep Learning1.4.2、Classify Pixels Using D...

GIS哼哈哈的博客 7202

IgH EtherCAT 从入门到精通:第 29 章 实战:EoE 远程维护通道搭建

摘要:本章详细介绍了基于EoE(Ethernet over EtherCAT)协议的远程维护通道搭建方案。主要内容包括:1)网络架构设计,采用管理网络与EoE子网隔离的方案;2)从站EoE支持确认与IP地址配置,提供API和命令行两种方式;3)路由/交换两种部署模式,重点推荐路由模式并给出自动化配置脚本;4)SSH远程访问配置,包括直接连接和跳板访问两种方式;5)安全加固措施,如防火墙规则、SSH密钥认证等;6)故障恢复机制与性能注意事项。该方案实现了通过EtherCAT网络对从站设备的远程SSH访问、文件

从事嵌入式linux android驱动开发,拥有全栈能力 365
上一篇: 重磅 |完备的 AI Agent 学习路线,最详细的资源整理
下一篇: 用户增长这件事,AI比我懂?
AI_小站
博客等级 码龄3年 6255粉丝 1154原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值