法律即代码:开源项目vericlaw如何用规则引擎实现合同自动化

news2026/5/11 3:40:03
1. 项目概述与核心价值最近在折腾一些自动化流程特别是涉及到合同、协议这类法律文书的生成与审核时发现了一个挺有意思的开源项目Sheygoodbai/vericlaw。乍一看这个名字结合其仓库描述就能猜到它大概和法律Law以及验证Verification有关。深入把玩之后我发现它远不止一个简单的工具更像是一个为开发者、法务科技LegalTech从业者甚至是中小型企业主设计的“法律逻辑自动化引擎”。简单来说vericlaw的核心目标是将法律条文、合同条款中的逻辑规则转化为机器可读、可执行的代码。它试图解决一个经典痛点我们有一份几十页的PDF合同里面规定了各种条件、义务、违约责任比如“若甲方在收到货物后30日内未提出书面异议则视为验收合格”但每次都要人工去翻阅、判断是否触发某个条款效率低下且容易出错。vericlaw提供了一套框架让你可以像写业务规则一样把这些法律逻辑“编译”成程序实现自动化的合规检查、合同状态追踪和事件响应。这玩意儿适合谁呢如果你是开发者正在构建涉及电子签约、供应链管理、金融服务或任何需要强规则引擎的应用它可以帮你把复杂的业务合规逻辑从硬编码中解放出来变得更清晰、更易维护。如果你是法务或合规人员懂一点技术它能让你用一种更结构化的方式去理解和“测试”合同条款甚至模拟不同履约路径下的结果。当然对于技术爱好者来说这也是一个窥探“法律即代码”Law as Code这一前沿领域的绝佳实践入口。2. 核心架构与设计哲学拆解2.1 从自然语言到可执行逻辑的桥梁vericlaw的设计哲学根植于“形式化方法”和“领域特定语言”DSL。它不试图理解自然语言的全部含义那是NLP的难题而是聚焦于提取法律文本中的结构性逻辑和关键实体。其架构通常包含几个核心层解析与抽象层这一层负责处理输入。输入可能是一段结构化的文本描述使用vericlaw定义的某种语法也可能是通过其他工具从PDF中提取并初步标注的文本。它的任务是将这些文本解析成内部的抽象语法树AST识别出“参与者”Parties、“义务”Obligations、“条件”Conditions、“事件”Events等基本法律概念单元。逻辑建模层这是核心。在这一层上述概念单元被转化为形式化的逻辑表达式。例如一个付款条款可能被建模为Obligation(Payer, Payee, amount, deadline)并附带一个条件Condition(Invoice_Received AND Within_Terms)。vericlaw可能会提供一套内置的“法律逻辑原语”比如before(),after(),upon(),if(),unless()等用于构建这些表达式。规则引擎/执行层建模好的逻辑需要在一个“世界”里运行。这一层包含一个规则引擎可能基于Rete算法或其他它负责评估事实Facts——即真实发生的事件或数据如“发票已发送”、“当前日期是2023-10-27”——是否触发了某条规则即法律条款并推导出相应的法律效果Legal Effects如“付款义务生效”、“违约金计算启动”。查询与验证接口最后它需要提供API或DSL让用户能够进行查询“根据当前事实甲方有哪些待履行义务”和验证“如果乙方延迟交货10天根据合同第5.2条我方最高可索赔多少”。vericlaw的优势在于它提供了一整套“从文本到逻辑再到验证”的端到端框架思路而不是一个孤立的点工具。它鼓励开发者将法律逻辑视为应用程序中一等公民的、可版本控制、可测试的代码资产。2.2 为什么选择规则引擎而非硬编码这是理解vericlaw价值的关键。面对合同逻辑新手可能会想“我写一堆if-else不就行了” 对于极其简单的场景或许可以。但法律逻辑的复杂性很快会让if-else陷入泥潭网状依赖条款A的生效以条款B的履行为条件而条款B又依赖于事件C的发生……这种网状关系用if-else难以清晰表达和维护。动态性合同在执行过程中事实状态是动态变化的。规则引擎可以持续监听事实库的变化自动重新评估所有相关规则而if-else需要显式地在每个可能改变状态的地方调用判断逻辑。可解释性当系统做出一个决定如“判定违约”你需要知道是依据哪条些规则推导出来的。好的规则引擎天然具备推理链追溯能力而if-else堆砌出的逻辑路径很难回溯。业务人员可参与理想情况下法务人员应该能以接近自然语言的方式通过DSL参与规则的定义和修改而不是直接修改代码。vericlaw的DSL设计正是为了降低这道鸿沟。因此vericlaw采用规则引擎作为底层核心是将法律逻辑的复杂性管理起来的理性选择。它把“法律推理”这个非确定性较强的过程尽可能地框定在一个确定性计算模型中。3. 核心概念与DSL初探要上手vericlaw首先得理解它定义的核心领域概念。虽然不同版本实现可能有差异但以下概念基本是通用的。3.1 核心领域实体参与者Party合同或法律关系的参与方如Buyer,Seller,Lender,Borrower。每个参与者有属性名称、ID等。资产Asset或标的Subject Matter合同涉及的对象如货物、服务、金钱、知识产权。可以定义其属性数量、规格、价值。义务Obligation一方对另一方负有的作为或不作为的责任。这是核心单元。一个义务通常包含debtor债务人履行义务方。creditor债权人享有权利方。action行为需要做什么支付X元、交付Y货物。trigger触发条件何时/何条件下该义务生效。deadline期限何时必须完成。权利Right或权力Power与义务相对应一方可以要求另一方履行义务或采取某种行动的能力。条件Condition一个布尔表达式其真值决定某个法律效果如义务生效、权利终止是否发生。可以是先决条件Condition Precedent或后续条件Condition Subsequent。事件Event在合同生命周期中发生的、可能改变各方权利义务状态的事实。如Signing签署、Delivery交付、Payment付款、Breach违约。条款Clause一个或多个义务、权利、条件的逻辑组合对应合同中的一个自然段或章节。3.2 一个简化的DSL示例vericlaw可能会定义一种类似下面的DSL具体语法需查看项目文档让用户以结构化的方式描述条款# 这不是vericlaw的真实语法仅为示意其思想 clause: payment_terms parties: - id: buyer role: Payer - id: seller role: Payee obligations: - id: pay_invoice debtor: buyer creditor: seller action: type: payment amount: {{invoice.amount}} currency: USD trigger: type: event event: invoice_issued condition: invoice.status valid deadline: type: relative after_trigger: 30 days effects: on_fulfilled: - set: contract.stage payment_completed on_breached: - create_obligation: pay_late_fee # 触发另一项义务支付滞纳金这段“代码”清晰地定义了一个付款条款卖方开具有效发票后买方有义务在30天内支付发票金额并规定了履行和违约后的不同效果。注意DSL的设计需要在“表达能力”和“易用性”之间做权衡。过于复杂像编程语言会吓跑领域专家过于简单又无法覆盖真实合同的复杂性。vericlaw的挑战之一就是设计一套恰到好处的DSL。3.3 事实与规则的分离这是规则引擎的经典模式也是vericlaw必须遵循的。事实Facts是动态输入的系统状态如{ event: ‘delivery’, party: ‘courier’, timestamp: ‘2023-10-27T10:00:00Z’, asset_id: ‘item_123’ }。规则Rules是静态定义的法律逻辑如上文的DSL。引擎的工作就是将不断流入的事实与已有的规则进行匹配从而推导出新的衍生事实如obligation_activated或触发动作。这种分离使得系统非常灵活你可以修改规则合同条款而不影响事实处理流程你也可以用不同的历史事实集来“重放”或模拟合同执行情况用于争议分析或合规审计。4. 实战构建一个简单的合同自动检查器假设我们有一个简单的软件许可协议场景我们用vericlaw的思路来构建一个原型。请注意以下代码是概念性示例基于对vericlaw理念的理解并非直接复制其源码。4.1 定义领域模型首先我们需要定义数据模型。这里我们用Python类来示意。# models.py from datetime import datetime, timedelta from enum import Enum from typing import Optional, List from pydantic import BaseModel # 用于数据验证是个好选择 class Party(BaseModel): id: str name: str role: str # e.g., Licensor, Licensee class EventType(Enum): CONTRACT_SIGNED contract_signed PAYMENT_RECEIVED payment_received SOFTWARE_DELIVERED software_delivered SUPPORT_REQUESTED support_requested BREACH_REPORTED breach_reported class Fact(BaseModel): 系统中发生的一个事实 event_type: EventType party_id: str timestamp: datetime payload: dict {} # 携带额外信息如金额、描述 class ObligationStatus(Enum): PENDING pending # 条件未满足未激活 ACTIVE active # 条件已满足待履行 FULFILLED fulfilled BREACHED breached TERMINATED terminated class Obligation(BaseModel): 一个义务实例 id: str debtor_id: str creditor_id: str description: str trigger_condition: str # 一个可评估的表达式字符串如 facts:payment_received deadline: Optional[datetime] status: ObligationStatus ObligationStatus.PENDING created_at: datetime fulfilled_at: Optional[datetime]4.2 实现一个简易规则引擎接下来我们实现一个非常简单的规则引擎核心。它负责匹配事实和规则并更新义务状态。# engine.py import re from typing import Dict, List from models import Fact, Obligation, ObligationStatus, EventType class SimpleLegalRuleEngine: def __init__(self): self.obligations: Dict[str, Obligation] {} self.facts: List[Fact] [] # 定义一些简单的规则映射什么事件会触发哪个义务 self._rule_mappings { EventType.CONTRACT_SIGNED: [obligation_pay_license_fee], EventType.PAYMENT_RECEIVED: [obligation_deliver_software], EventType.SOFTWARE_DELIVERED: [obligation_provide_support], } def add_obligation(self, obligation: Obligation): 向引擎添加一个义务定义 self.obligations[obligation.id] obligation def assert_fact(self, fact: Fact): 断言一个新的事实并触发规则评估 self.facts.append(fact) print(f[Engine] 新事实: {fact.event_type} by {fact.party_id}) self._evaluate_rules(fact) def _evaluate_rules(self, triggering_fact: Fact): 评估规则看新事实是否触发了任何义务 # 1. 查找可能被此事实触发的义务ID triggered_obligation_ids self._rule_mappings.get(triggering_fact.event_type, []) for obl_id in triggered_obligation_ids: if obl_id in self.obligations: obl self.obligations[obl_id] # 2. 检查该义务当前状态是否为PENDING if obl.status ObligationStatus.PENDING: # 3. 这里简化处理直接激活。真实场景需要解析trigger_condition并评估。 # 例如检查是否所有先决条件事实都已存在。 print(f[Engine] 事实 {triggering_fact.event_type.value} 激活了义务 {obl.id}) obl.status ObligationStatus.ACTIVE # 可以在这里生成新的衍生事实如 obligation_activated # 4. 检查所有ACTIVE的义务看其deadline是否已过模拟违约检查 current_time datetime.now() for obl in self.obligations.values(): if obl.status ObligationStatus.ACTIVE and obl.deadline and current_time obl.deadline: print(f[Engine] 警告义务 {obl.id} 已逾期状态置为BREACHED) obl.status ObligationStatus.BREACHED # 可以触发违约金计算等后续规则 def get_party_obligations(self, party_id: str, status: Optional[ObligationStatus] None) - List[Obligation]: 查询某个参与方的义务 result [o for o in self.obligations.values() if o.debtor_id party_id] if status: result [o for o in result if o.status status] return result4.3 定义合同规则并运行模拟现在我们用一个脚本来模拟一个简单的软件许可合同执行流程。# main.py from datetime import datetime, timedelta from engine import SimpleLegalRuleEngine from models import Party, Obligation, ObligationStatus, Fact, EventType def main(): # 1. 初始化引擎 engine SimpleLegalRuleEngine() # 2. 定义参与方 licensor Party(idp1, nameAwesomeSoft Inc., roleLicensor) licensee Party(idp2, nameStartupXYZ Ltd., roleLicensee) # 3. 定义合同中的义务这些通常由DSL解析生成 # 义务1: 被许可方支付许可费在合同签署后激活30天内支付 obligation_pay Obligation( idobligation_pay_license_fee, debtor_idlicensee.id, creditor_idlicensor.id, description支付年度软件许可费金额10,000 USD, trigger_conditionfacts:contract_signed, # 简化条件 deadlinedatetime.now() timedelta(days30), statusObligationStatus.PENDING, created_atdatetime.now() ) # 义务2: 许可方交付软件在收到付款后激活7天内交付 obligation_deliver Obligation( idobligation_deliver_software, debtor_idlicensor.id, creditor_idlicensee.id, description交付v1.0软件安装包及许可证密钥, trigger_conditionfacts:payment_received, deadlinedatetime.now() timedelta(days37), # 假设付款后7天 statusObligationStatus.PENDING, created_atdatetime.now() ) # 义务3: 许可方提供一年技术支持在软件交付后激活 obligation_support Obligation( idobligation_provide_support, debtor_idlicensor.id, creditor_idlicensee.id, description提供为期12个月的线上技术支持, trigger_conditionfacts:software_delivered, deadlinedatetime.now() timedelta(days36537), # 交付后一年 statusObligationStatus.PENDING, created_atdatetime.now() ) # 4. 将义务添加到引擎 engine.add_obligation(obligation_pay) engine.add_obligation(obligation_deliver) engine.add_obligation(obligation_support) print( 合同模拟开始 ) print(f许可方: {licensor.name}) print(f被许可方: {licensee.name}) print(初始状态所有义务待定(PENDING)) print(- * 40) # 5. 模拟事件流 # 事件1: 合同签署 print(\n[事件1] 双方签署合同。) engine.assert_fact(Fact( event_typeEventType.CONTRACT_SIGNED, party_idlicensee.id, # 假设由被许可方发起签署动作 timestampdatetime.now() )) # 查询被许可方当前义务 pending_obls engine.get_party_obligations(licensee.id, ObligationStatus.ACTIVE) print(f 被许可方激活的义务: {[o.id for o in pending_obls]}) # 事件2: 被许可方支付费用 (假设在第15天支付) print(f\n[事件2] 被许可方在第15天支付许可费。) engine.assert_fact(Fact( event_typeEventType.PAYMENT_RECEIVED, party_idlicensee.id, timestampdatetime.now() timedelta(days15), payload{amount: 10000, currency: USD} )) pending_obls engine.get_party_obligations(licensor.id, ObligationStatus.ACTIVE) print(f 许可方激活的义务: {[o.id for o in pending_obls]}) # 事件3: 许可方交付软件 (假设在付款后第5天即总第20天交付) print(f\n[事件3] 许可方在第20天交付软件。) engine.assert_fact(Fact( event_typeEventType.SOFTWARE_DELIVERED, party_idlicensor.id, timestampdatetime.now() timedelta(days20), payload{version: 1.0, delivery_method: download_link} )) pending_obls engine.get_party_obligations(licensor.id, ObligationStatus.ACTIVE) print(f 许可方激活的义务应包含支持义务: {[o.id for o in pending_obls]}) # 6. 模拟一个逾期场景假设我们快进到第40天检查义务1是否逾期 print(f\n[状态检查] 模拟时间快进到第40天。) # 我们手动触发引擎的逾期检查逻辑在实际引擎中这会由定时任务或每次事实断言后触发 # 这里为了演示我们直接修改一个义务的deadline为过去然后模拟一个无关事实来触发检查 obligation_pay.deadline datetime.now() timedelta(days5) # 设为5天后但我们现在在第40天所以已过35天 # 断言一个无关事实触发引擎内部的 _evaluate_rules 方法它会检查deadline engine.assert_fact(Fact( event_typeEventType.SUPPORT_REQUESTED, party_idlicensee.id, timestampdatetime.now() timedelta(days40) )) # 检查义务1的状态 breached_obls engine.get_party_obligations(licensee.id, ObligationStatus.BREACHED) print(f 被许可方违约的义务: {[o.id for o in breached_obls]}) print(\n 模拟结束 ) if __name__ __main__: main()运行这个脚本你会看到一个简单的合同生命周期模拟展示了义务如何被事件链式触发以及逾期如何被自动检测。这只是一个极度简化的原型真实的vericlaw项目会更复杂包含更强大的DSL解析器、更完善的规则引擎如Drools集成、持久化存储以及API层。5. 深入核心条件表达式的解析与求值上面的简易引擎中我们用trigger_condition字符串和硬编码的规则映射来模拟触发逻辑。在实际的vericlaw或类似系统中条件表达式的解析与求值是核心技术难点之一。一个条件可能非常复杂fact:payment_received AND fact:delivery_verified AND (party.role Buyer OR contract.agreement_type Standard)5.1 设计一个灵活的表达式语言我们需要一个小型的表达式求值器。有几种方案使用现有表达式库如Python的eval()极度危险切勿在生产环境使用因为允许任意代码执行或更安全的库如asteval、simpleeval或者jmespath用于JSON查询。自定义语法树AST解析为法律逻辑设计一套有限的语法自己写解析器或使用Lark、PLY等工具。这是最灵活但最复杂的方式。使用规则引擎内置DSL如果vericlaw底层集成Drools可以直接用Drools的DRL语言。一个折中的方案是使用simpleeval这样的安全求值器并为其提供丰富的上下文。# condition_evaluator.py import simpleeval from models import Fact from typing import List class ConditionEvaluator: def __init__(self): self._evaler simpleeval.SimpleEval() # 注册自定义函数 self._evaler.functions[has_fact] self._has_fact self._evaler.functions[before] self._before self._evaler.functions[after] self._after def evaluate(self, condition_expr: str, context: dict) - bool: 评估条件表达式。 :param condition_expr: 表达式字符串如 has_fact(payment_received) and amount 1000 :param context: 求值上下文包含 facts, parties, contract_vars 等 :return: 布尔值结果 # 将上下文注入求值器 self._evaler.names context try: result self._evaler.eval(condition_expr) return bool(result) except Exception as e: print(f条件求值错误 {condition_expr}: {e}) return False def _has_fact(self, event_type_str: str) - bool: 自定义函数检查是否存在特定类型的事实 # 这个函数需要在evaluate时能访问到context中的facts列表 # 这里只是示意实际实现需要更精巧的上下文传递 facts_in_context self._evaler.names.get(facts, []) return any(f.event_type.value event_type_str for f in facts_in_context) def _before(self, date_str1: str, date_str2: str) - bool: 自定义函数比较日期 # 实现日期解析和比较 pass def _after(self, date_str1: str, date_str2: str) - bool: pass # 使用示例 evaluator ConditionEvaluator() context { facts: [Fact(event_typeEventType.PAYMENT_RECEIVED, ...)], # 事实列表 amount: 1500, party_role: Buyer } condition has_fact(payment_received) and amount 1000 and party_role Buyer is_triggered evaluator.evaluate(condition, context) print(f条件 {condition} 评估为: {is_triggered})这样我们就可以在DSL中编写更丰富的条件如trigger_condition: has_fact(contract_signed) and contract.value 50000。5.2 将DSL编译为内部表示真正的vericlaw项目不会让用户直接写simpleeval表达式。它会定义一套更友好、更贴近法律的DSL然后有一个“编译器”将其转换为这种可求值的表达式或直接转换成引擎的内部规则表示。例如DSL可能是这样的CLAUSE PaymentClause { TRIGGER ON InvoiceIssued(seller, buyer, invoice) CONDITION invoice.amount 0 AND invoice.valid true CREATES Obligation { debtor: buyer, creditor: seller, action: Pay(amount: invoice.amount, currency: invoice.currency), deadline: TRIGGER.timestamp 30 days } }编译器的工作就是解析这段文本生成对应的Obligation对象并将其trigger_condition属性设置为一个由底层求值器能理解的表达式如has_fact(InvoiceIssued) and fact.payload.amount 0 ...同时注册事件类型InvoiceIssued到规则映射中。6. 高级话题与挑战6.1 不确定性处理与默认规则法律条文并非总是非黑即白存在解释空间和默认规则Default Rules。例如“合理时间”、“商业上合理的努力”如何量化vericlaw这类系统通常采取以下策略参数化将模糊概念定义为可配置的参数由合同双方在签署时约定具体值如“合理时间”定义为“不超过15个工作日”。提供解释注释在DSL中允许附加注释或链接到解释性文档提醒用户此处存在解释空间。模拟与情景分析系统可以运行多种可能的情景给“合理时间”赋予不同的值展示不同解释下的结果范围辅助决策而非给出单一确定答案。6.2 合规性与证据链在法律科技应用中审计追踪Audit Trail至关重要。系统必须完整记录原始合同文本不可篡改的存证。使用的DSL规则版本。所有输入的事实事件及其来源、时间戳。每一次规则触发的推理过程为什么这个义务被激活依据了哪些事实和条款。所有系统输出的结论如生成的义务、违约通知。这些日志需要采用防篡改技术如哈希链、区块链存证进行保存以备争议时作为证据。6.3 集成与扩展性vericlaw作为一个引擎需要与现有系统集成输入集成如何从DocuSign、Adobe Sign等电子签约平台获取“合同签署”事件如何从ERP或财务系统获取“付款完成”事件这需要定义标准的事件格式如CloudEvents和提供适配器。输出集成当检测到违约时是自动发送邮件通知法务部门还是在CRM中创建一条工单或是触发一个工作流引擎需要提供灵活的动作Action钩子。扩展性不同的法律领域劳动法、知识产权法、金融监管有特殊概念。系统需要支持通过插件或扩展DSL来定义新的领域特定类型和函数。7. 常见问题与实战避坑指南在实际尝试应用vericlaw或自建类似系统时你会遇到不少坑。以下是一些常见问题和我总结的经验Q1法律条文翻译成规则时总感觉不完整或有歧义怎么办A这是“法律即代码”的根本挑战。不要追求100%的自动化。明确系统的定位是辅助和增强而非替代律师。优先处理那些高频、重复、逻辑清晰的条款如付款期限、滞纳金计算、自动续约。对于模糊条款系统可以标记出来提示需要人工复核。与法务专家紧密合作进行多次迭代评审是保证规则质量的关键。Q2规则越来越多维护起来会不会很乱A会。必须建立良好的规则治理体系版本控制像管理代码一样用Git管理DSL规则文件。每次合同变更对应一次规则提交便于追溯。分类与标签按合同类型、条款类别、参与方等对规则进行分类。测试用例为每套规则编写测试用例模拟各种正常和边缘情况确保规则修改不会引入意外后果。这实际上是“法律逻辑的单元测试”。文档化为每个复杂的规则编写注释说明其对应的原始合同条款位置和商业意图。Q3性能问题当事实和规则数量很大时引擎会不会变慢A对于非常复杂的合同网络或高频事件流性能是需要考虑的。优化策略包括规则索引像数据库一样为规则建立索引只评估可能被当前事实触发的那部分规则Rete算法核心思想。增量计算只重新计算受新事实影响的那部分状态而不是全量重算。异步处理对于非实时要求的合规检查可以将事实放入队列异步处理。规则简化在保证逻辑正确的前提下合并或简化规则表达式。Q4如何说服业务方或法务同事接受这种“代码化”的方式A用实例说话。找一个他们痛点最深的、手工处理繁琐且易错的流程比如每月几百份采购合同的付款条件审核用vericlaw的思路做一个最小可行产品MVP。演示如何将一份合同条款快速转化为规则并模拟几种业务场景展示自动判断的准确性和效率提升。重点突出一致性机器不会疲劳和疏忽、可追溯性每个决定都有据可查和模拟能力“如果……会怎样”分析。Q5开源项目Sheygoodbai/vericlaw成熟度如何可以直接用于生产吗A这需要仔细评估。查看其GitHub仓库的活跃度最近提交、Issue和PR数量、文档完整性、测试覆盖率以及许可证。通常这类前沿开源项目更偏向于概念验证PoC或研究原型。你可以将其作为学习框架和设计灵感的来源理解其核心模型和API设计。但在投入生产前很可能需要基于其思想结合自身业务需求进行大量的加固、扩展和集成开发或者考虑更成熟的企业级规则引擎产品如IBM ODM、Camunda并与法律领域模型相结合。最后法律科技的自动化是一条漫长但充满价值的路。vericlaw这样的项目为我们提供了宝贵的思维工具和实践起点。它提醒我们即使是最依赖人类专业知识的法律领域其底层逻辑也有被结构化、数字化乃至自动化的空间。关键在于找到技术与专业的恰当结合点用技术赋能专业人士而不是试图取代他们。从一个小而具体的场景开始解决一个真实的问题积累经验再逐步扩展这才是稳妥的落地之道。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2602353.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…