news 2026/9/28 6:49:41

从零搭建金融服务底座:支付、账户、清结算与对账实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零搭建金融服务底座:支付、账户、清结算与对账实战

最近在折腾一版内部代号叫financial-services的服务,说是“折腾”,其实是从零搭一套面向中小团队、能跑通收单、记账、清结算、对账、基础风控的金融服务底座。市面上讲支付接入、讲账户系统的文章不少,但大多只讲了某一个点,真正把整套链路串起来、能把每个环节的“为什么”说清楚的很少。这篇文章就把我这几个月踩过的坑、拿掉的头发和最终沉淀下来的方案一次性写透,希望能给正准备上手或者正在重构金融服务模块的同学省点时间。

先说清楚这东西解决了什么问题。financial-services 不是一个单一应用,而是一组微服务,核心职责是:统一管钱、统一记账、统一对接外部支付渠道、统一做交易风控和资金核对。做完之后,业务方接入支付只需要调一个接口,不用关心背后接的是微信、支付宝还是某个银行通道;财务对账不再靠人工导表格,日终自动跑批;账户余额、交易流水、结算报表全部同源,不会再出现“业务库说已支付、资金库说没到账”的扯皮。适合谁来参考?后端开发、技术负责人、以及准备做产业数字化但还没想清楚支付和资金体系怎么搭的创业者。

1. 先看清全局:金融服务技术栈到底在解决什么问题

1.1 把金融服务拆成五张图

我习惯把金融服务的整体架构拆成五个核心域:账户域、交易域、支付域、清结算域、风控合规域。这五个域不是拍脑袋分的,而是在实际踩坑之后逐渐演化出来的边界。

  • 账户域负责管“谁有多少钱”。客户账户、内部户、手续费户、冻结户,每一分钱都有归属。
  • 交易域负责管“发生了什么”。收单、退款、转账、分账,每一次资金动作都产生不可篡改的流水。
  • 支付域负责对接外部渠道。统一封装支付、查询、撤销、回调,屏蔽底层渠道差异。
  • 清结算域负责算清楚钱怎么分、怎么给。手续费计算、分润、T+1结算、结算单生成。
  • 风控合规域负责阻止不该发生的交易。黑名单、限额、频控、反欺诈规则、审计留痕。

为什么要拆得这么细?直接原因有三个。第一是避免循环依赖,比如支付域如果不拆出来,交易域直接去调渠道 SDK,那渠道的参数配置散落在业务代码里,换一个渠道就得改一次全链路;第二是独立扩容,账户和交易是高频且强一致性的场景,清结算往往是凌晨跑批,两者混在一起互相拖累;第三是故障隔离,支付渠道偶尔会抖动甚至长时间不可用,如果渠道调用混在主交易链路里,一个渠道超时可能导致整个交易服务雪崩,拆出独立支付域可以加熔断降级。

这张架构图我建议你在动手写代码之前先画出来,不需要很精细,只要把每个域的数据归属和调用关系写清楚就行。我第一版就是没画清楚就匆忙开做,做到中间发现账户和交易之间的流水对不上,再回过来重构,代价很高。

1.2 一个生活类比:像一家实体商超同时管收银和财务

如果上面的划分还是有点抽象,不妨把它想象成一家实体商超。收银台是交易域,每一笔扫码付款都是一次收单交易;收银机背后是账户域,每个储值客户的卡里有多少余额、今天是否被冻结了一笔充值赠送金,都在这里记录;对接微信、支付宝的是支付域,相当于商超跟不同银行签的 POS 刷卡通道;每天打烊后会计做的事情是清结算域,算今天一共收了多少、手续费多少、该结给供应商多少;门口站着的保安和监控就是风控合规域,防止有人刷爆卡、防止内部舞弊、保留每一帧录像备查。

这套类比对小白特别友好,也方便你跟业务方对齐需求。很多业务同事一听“账户系统”就一脸懵,但你说“就是商超里记客户储值的本子”,他们立刻能说出需求来:要有余额、要有充值和消费记录、退卡要退钱、赠送金不能直接提现。你看,需求其实就是这些,只是我们用技术语言把它包装复杂了。

1.3 选型前必须想清楚的三件事

动手前还有三个事情必须想清楚,想清楚之前千万别选框架。

第一,你的量级假设是什么。是日均几百笔还是日均百万笔?这决定了你要不要上分库分表、要不要上分布式事务、要不要引入消息队列。我见过一个项目日均交易几千笔,却上了全套分布式事务、消息中间件和两套数据库,运维成本比业务本身还高。金融系统复杂,但不是所有团队都需要银行级架构。

第二,资金准确性优先级永远高于可用性。电商系统可以接受短暂的时间延迟,但绝不能接受账目错乱。这意味着宁可交易响应慢 50ms,也要保证数据库落库成功、流水写入完整;宁可回调消息迟一点送达,也不能因为消息丢失导致订单状态跟资金状态不一致。这个认知决定了你在技术选型时会非常保守,不太会为了追求性能去引入没有强一致性保障的组件。

第三,合规是底线,不是可选项。金融相关业务需要持牌经营或者与持牌机构合作,这部分属于业务红线,技术系统要把资质校验、协议留痕、数据留档、权限审计做成硬编码规则,而不是靠运营自觉。技术上做不到位,业务做得再大也是悬在空中。

2. 核心系统设计与技术决策:这些坑我踩过

2.1 数据库与存储选型:别让 Redis 管钱

先说存储层。我最终的方案是:业务数据以关系型数据库为准,Redis 只做缓存和限流,绝不作为余额或交易流水的权威数据源。这是我在早期版本吃过大亏之后定下的铁律——当时为了提升余额查询性能,把部分客户的余额放在 Redis 里,结果一次 Redis 集群抖动导致多个客户余额读到旧值,差点引发资金纠纷。

主库我选了 MySQL 8.0 系列,按客户维度做分库分表,分片键是 customer_id,理由是最常见的查询都围绕单一客户展开:查余额、查流水、查订单。这样分片打散后,单客户的读写都会落在一个分片上,天然避免跨库事务。如果业务模型以多租户的聚合查询为主,那分片键设计就得另说,这在金融场景下要非常谨慎。

分库分表不建议一开始就上,我建议**“单库起步、预留分片键、半年后看数据量再决定”**。MySQL 在合理索引下支撑千万级流水并不难,很多系统死在了过度设计而不是数据量上。真到了需要分库分表的时候,优先选成熟的中间件方案,比如 ShardingSphere,自己造轮子处理分布式 ID、分布式事务、跨分片查询,代价远超想象。

还有一个容易忽略的点:余额字段一定要带版本号或者使用乐观锁更新。我用的是UPDATE account SET balance = balance - #{amount}, version = version + 1 WHERE account_id = #{id} AND balance >= #{amount}这种带条件的更新语句,用数据库行锁保证扣款安全,同时通过受影响行数判断余额是否充足。这比先查余额再更新要安全得多,也避免了不少并发超扣的问题。

2.2 账户与记账模型:复式记账法是压舱石

账户域最核心的设计是引入复式记账法。传统业务系统常见的做法是“余额加减法”:用户支付 100,就把用户余额减 100、商户余额加 100,一了百了。听起来简单,一旦出现手续费、退款、分账、冻结,账目就会逐渐对不上,最后只能靠人去查。

复式记账法来自会计学,规则就一条:每一笔资金变动至少涉及两个账户,有借必有贷,借贷必相等。我实际落地时会在流水表里记录这笔交易的借方向(如“客户应收-100”)和贷方向(如“商户应付+100”),每一笔都有唯一的流水号,并关联原始业务单号。

用复式记账的好处有三个。第一是自我校验,任何一笔交易如果借贷不平衡,日终汇总立刻会暴露,不需要出问题之后再翻日志。第二是天然支持冲正,退款或调账在复式记账下不会直接修改历史流水,而是新增一笔红字冲销流水,保证痕迹可追溯。第三是支持多维对账,流水表里的借贷方向可以推导出任意账户的余额变动,也就不需要业务系统在别处再维护一套余额账。

账户余额我建议拆成四个字段:总余额、可用余额、冻结余额、在途余额。四者的关系是:总余额 = 可用 + 冻结 + 在途。支付时从可用余额扣减、冻结时从可用转冻结、退款时先在在途记账、渠道确认到账后再结转可用。这套模型看起来多花了一些字段,但后期做结算、做退款、做风控冻结时就会非常顺手,不用再为“钱到底可不可以动”这个问题写一堆 if。

2.3 幂等与状态机:防重是金融系统的生命线

金融服务里最经典的故障就是重复扣款。客户端超时重试、支付渠道回调重复通知、运营在同一条订单上多点了两次退款,任何一个环节防不住,都会造成资金差错。我在所有写接口上统一实现了三层防重:

第一层是客户端传入的幂等键。每次支付请求必须携带一个全局唯一的请求号(如商户系统生成的merchant_order_no),服务端在入口处校验该请求号是否已处理过,已处理过直接返回原结果。第二层是数据库唯一索引。在交易表中对(merchant_order_no, channel_code)建立唯一索引,即使并发请求同时穿过第一层校验,数据库层面也会挡住重复插入。第三层是状态机约束。每个订单只能按“待支付 → 支付中 → 已支付 → 已结算/已退款”的状态顺序流转,非法状态变更直接抛出异常。

状态机是这个方案里最体现工程价值的地方。不要用if (order.status == 1) { ... }这种散落的判断逻辑,而是显式定义一张状态流转表,比如定义允许的流转路径:待支付可以取消、可以发起支付;支付中可以收到回调转为已支付;已支付可以退款但不能再次支付。代码层面可以用枚举加 Map 管理合法流转,也可以用状态机框架,但最简单的其实就是一张二维表(当前状态+事件 = 目标状态)。这张表要写进代码评审的必查项目里,状态机一旦有漏洞,资金就是白花花的损失。

2.4 资金安全核对机制:对账不是可选项

我见过太多系统上线了收单功能却把对账模块拖到“以后再做”。这绝对是个错误,对账应该跟主交易链路同时上线,哪怕第一版只做最简单的日终对账。资金安全不能靠事后人肉翻数据,而要靠系统自动核对。

我设计的是三级核对机制。第一级是实时核对,支付回调成功后,交易域立即异步发送一份明细到对账中心,同时更新账户流水,保证订单状态、账户流水、商户通知三方一致。第二级是日终核对,每日凌晨定时拉取各支付渠道的对账单,与本地交易流水逐笔比对,分类出“本地已支付、渠道未出账”“渠道已出账、本地未支付”“金额不一致”等差异类型。第三级是差错处理,差异记录自动生成差错工单,人工介入处理后留痕归档。

为什么对账必须做?因为支付渠道也是人写的系统,也会丢数据、重复通知、金额解析错误。回到商超的例子,每天晚上收银机的小票和当天实际收到的钱必须要对一遍,对不上就要查为什么,这是店主的本能。线上金融系统也一样,而且系统越自动化,越需要一个每天自动“数钱包”的脚本替你盯住每一分钱。

3. 实操流程:从商户进件到日终对账的完整链路

3.1 商户进件与渠道接入:一切从合规起步

金融服务不只是写代码,首先是一个准入过程。拿收单业务来说,每一家接入的业务方都要走“商户进件”流程:提交主体资质、结算账户信息、经营类目,系统侧则需要做实名认证、黑名单筛查和风险评级。我所在的项目里,这部分我封装成一个进件服务,调用第三方实名认证接口,校验统一社会信用代码、法人身份证、银行账户三要素是否一致。

进件通过后,系统会在内部给商户生成一个merchant_id,并为其开立两个内部账户:一个做交易资金记账的结算户,一个做手续费归集的手续费户。这一步很关键——商户的钱和自己的手续费必须分账,否则清结算时会乱成一锅粥。渠道接入时,支付域保存渠道的 app_id、商户号、证书/密钥,并为每个商户配置渠道参数路由。

给一个参考的核心字段表:

模块关键字段说明
商户merchant_id, merchant_no, status, risk_level内部唯一ID与外部商户号分离
账户account_id, customer_id, account_type, balance账户类型区分子商户户/手续费户
渠道channel_code, app_id, mch_id, cert_info一个商户可配多个渠道
流水flow_no, order_no, account_id, direction, amountdirection 区分借/贷记方

3.2 收单交易主链路:从上送渠道到回调通知

一次标准收单的完整链路是这样的:用户在前端发起支付,业务系统调用收单接口,收单服务先生成一个内部订单号,锁定请求参数并记录初始状态,然后根据商户配置找到对应的支付渠道,组装渠道参数请求下单,渠道返回支付凭据(如支付链接或二维码),业务系统把凭据返回给前端。用户完成支付后,渠道异步回调,支付域验签、验金额,确认无误后更新订单状态、通知交易域记账,交易域生成账户流水并更新余额。

这里值得展开的是验签和金额校验。渠道回调报文里都会带签名,你下单时的金额和回调里的金额必须完全一致,不一致哪怕差一分钱也要按异常处理。我处理过一起回调金额比下单金额多一分钱的案例,排查后是某个渠道在浮点转换时存在精度问题。所以你们所有的金额字段全部使用分为单位的整数存储,杜绝浮点数参与资金计算。这一点怎么强调都不过分——金额计算只用整数,只做加减乘除,不做任何浮点运算。

回调处理的伪代码大致是这样:

// 1. 验签失败直接拒绝 if (!channelSdk.verifySign(callbackParams)) { throw new InvalidSignException("签名校验失败"); } // 2. 幂等检查:请求号已处理过直接返回成功 Order order = orderMapper.selectByOrderNo(callbackParams.getOrderNo()); if (order != null && order.getPaid()) { return Response.success("duplicate callback"); } // 3. 金额一致性校验 if (order.getAmount() != callbackParams.getAmount()) { throw new AmountMismatchException("回调金额与订单金额不一致"); } // 4. 状态机流转与记账(同一事务) transactionTemplate.execute(status -> { orderMapper.updateStatus(order.getId(), OrderStatus.PAID); accountService.credit(merchantSettleAccount, order.getAmount(), order.getOrderNo()); accountService.debit(feeAccount, feeAmount, order.getOrderNo()); });

这里第 2 步和第 4 步之间如果服务重启,重复回调会被唯一索引拦下,所以幂等是多重保障的,不是靠单一个判断。

3.3 清结算与分账:钱怎么算清楚

收单完成只是资金流转的开始,紧跟着还有清分和结算。清分指的是把一笔交易金额拆解:一部分是商户的结算款,一部分是平台手续费,可能还有分账方(如渠道服务商、推荐人)的分润。结算则是把商户应收的结算款真正打到商户的银行账户。

手续费怎么算?我实现的方案是把费率配置做成多维度规则:按类目(如餐饮 0.6%、零售 0.38%)、按交易金额阶梯、按商户等级配置不同的费率。计算时优先匹配最细粒度规则,其次匹配类目规则,最后走默认费率。费率规则在清结算模块里是一张独立的配置表,由运营维护,不散落在代码里。

结算的节奏一般是 T+1,也就是交易次日将已出账的结算款汇总成结算单,提交给代付机构打款。这里有个细节:不是每一笔交易单独打款,而是把商户在结算周期内的所有净额汇总成一笔打款,减少代付手续费、降低银行批次处理压力。结算单生成后要进入待确认状态,与渠道清算流水核对无误后,再执行打款。打款结果通过异步回执更新,成功则标记已结算,失败则进入人工处理队列。

3.4 日终对账脚本怎么落地

日终对账我建议直接用定时任务跑,不推荐搞太复杂的实时流计算。对绝大多数交易量在百万笔以下的业务,一个可靠的 Daily Job 比流式计算更简单、更可维护、更容易回放。

对账脚本的核心流程是:第一步,从渠道下载当日对账单文件,解析成统一的渠道流水模型;第二步,跟本地交易流水按订单号做全量比对;第三步,分类输出差异记录。比对规则可以归纳为三类:本地的已支付订单在渠道账单里找不到(可能本地多记或渠道延迟)、渠道账单里有但本地没有(可能渠道异常导致本地丢失回调)、两边都有但金额不一致(优先怀疑浮点或解析错误)。

伪代码思路:

def reconcile(local_orders, channel_bills): local_map = {o.order_no: o for o in local_orders} channel_map = {b.order_no: b for b in channel_bills} diff = [] for order_no, local in local_map.items(): if order_no not in channel_map: diff.append(("local_not_in_channel", local)) elif local.amount != channel_map[order_no].amount: diff.append(("amount_mismatch", local, channel_map[order_no])) for order_no, bill in channel_map.items(): if order_no not in local_map: diff.append(("channel_not_in_local", bill)) return diff

如果对账单文件很大,我建议加一个“分片+多线程”解析,但不要在主事务里做,避免阻塞日间交易。跑批时最好给订单表加一个reconciled标记位,下次跑批只处理未标记的数据,幂等重跑也方便。对账跑批时间建议选在凌晨渠道出完清分文件之后,并把失败告警接到值班群,确保第二天早上发现、当天处理,不要拖到第三天。

4. 风控与合规:金融服务的隐形天花板

4.1 规则引擎与风控策略配置

很多人觉得风控是大厂才需要的东西,这是误解。就算是日均百笔的交易系统,只要涉及资金,就必须有最基础的风控规则,否则一笔恶意退款就能让平台亏损。

我落地风控的方式是配置化规则引擎,不写死在业务代码里。规则分几层:

  • 名单层:黑名单商户/用户/银行卡,命中直接拦截。
  • 限额层:单笔限额、单日累计限额、单月累计限额,可以按商户/用户维度配置。
  • 频控层:同一用户在短时间内支付次数异常、同一商户短时间内大量交易等,触发条件后进入人工审核。
  • 行为层:设备指纹异常、IP 归属地异常、支付金额与实际商品价格偏离过大,标记后人工复核。

规则引擎不建议一开始就引入 Drools 这类重型框架,配置表加一个规则解释器在初期完全够用。我给每条规则配置优先级和动作(通过/拒绝/人工审核),规则命中后产生风控事件,写入独立的审计表。风控事件不阻塞交易,只做标记,当标记达到阈值时再升级为阻断。这样既能控制风险,又不会因为误杀导致大量正常交易被拒。

4.2 敏感数据与权限管控:金融数据不是普通业务数据

金融服务里最值钱的资产不是代码,是数据。我做的数据安全方案包括:落库加密、访问脱敏、权限分层、操作审计。手机号、身份证号、银行卡号这些字段在数据库中一律使用 AES-256-GCM 加密存储,密钥存放在独立的密钥管理服务中,应用不直接持密钥文件。日志打印时统一脱敏,只保留前缀后缀。查询接口按角色控制字段可见性,运营能看到交易金额但不能看到完整卡号。

操作审计这个点,不少团队会忽略。我要求所有涉及资金变动的写操作(退款、调账、冻结、解冻、修改费率)都记录操作人、操作时间、操作前快照、操作后快照和操作原因。这不是为了追责,而是排障的必要工具。有一次线上发现某商户的冻结余额异常减少,从审计日志里很快定位到是一位运营在测试环境误操作导致,十分钟内完成了数据修复和责任确认。如果没有审计日志,这种问题可能要查一整天。

4.3 合规红线:资质、协议、留痕

合规这块我只讲技术层面能做什么,业务资质问题必须咨询法律专业人士。技术侧该做的有三件事:第一是进件合规,每一家商户必须完成实名认证和协议签署才能开立账户;第二是数据合规,个人金融信息的采集、存储、使用都要有授权记录,不能默认勾选;第三是交易留痕,所有订单、流水、回调报文、对账结果都要持久化,并设置合理的保留周期。

这里有个容易被忽略的点:渠道侧的商户资料必须与本地进件资料定期同步校验。我碰到过一次渠道侧商户信息被渠道风控冻结,但我们系统本地显示正常,结果用户支付直接失败的情况。后来我加了定时任务,定期调用渠道查询接口同步商户状态和服务可用性,发现异常立即告警并暂停该商户的交易,避免用户端体验炸了之后才发现。

5. 生产环境常见问题与排查速查表

5.1 用户支付成功但订单状态没变

这是最典型的“掉单”问题。排查顺序:先看渠道回调日志有没有进来,没进来大概率是渠道异步通知失败,可以调用渠道订单查询接口主动确认;回调进来了就看验签是否通过,常见原因是回调时间误差过大导致签名校验用的时间戳不一致;再查订单状态机,看是否被早期的取消操作把状态锁定成了终态,导致无法流转到已支付。

这里我强烈建议实现一个主动查单补偿任务:定时扫描“支付中”状态的订单,超过一定时间主动调用渠道查单接口,以查询结果为准修正订单状态。这个补偿任务能兜住大部分回调丢失问题,而且实现简单,价值极高。

5.2 对账不平:本地有流水但渠道对账单没有

按我的经验,这类差异 80% 是“本地提前记账、渠道清算文件还没出”导致的时间差,尤其是深夜接近日切时段的交易,会归属到第二个工作日。处理方式不是直接改账,而是先把差异记录挂起,等待下一个工作日的对账单再比对一次,如果连续两个工作日仍不一致,再走差错工单人工处理。

如果是“渠道对账单有、本地没有”,优先查回调网关日志,看是不是消息被消费了但本地事务回滚了。我经常发现的问题出在消费逻辑“先改库后发消息”,改成“先记录事件再异步处理”之后,这类问题的数量直线下降。

5.3 账户余额不等于交易流水的汇总

这是一个每过几个月就会冒出来的历史遗留问题,根因多数是早期版本里有过直接修改余额的记录,或者某次补偿任务重复执行导致余额多扣/少扣。排查思路是:写一个 SQL,按账户分组汇总所有流水金额,与账户余额表做差值,列出所有不平的账户。这个脚本建议直接加进日终巡检,每天自动跑,不再依赖人工发现问题。

修复方案不要直接改余额,要用“调账流水”来冲销,调账流水必须有业务单号、原因说明和审批人,这样才能保证任何时候余额变动都有据可查。

5.4 数据库死锁与热点账户

热点账户问题在金融服务里很常见,比如一个头部商户的所有交易都打到同一个结算账户,高并发时这一行的行锁竞争会非常激烈,严重时导致超时失败。三个解决思路:一是账户拆分,把热点账户拆成多个子账户,按主键取模分散压力;二是合并入账,将同一个商户的多笔交易在内存中先合并,定时批量入账;三是独立账户服务,将账户从主交易链中拆开,通过异步队列记账。

请注意,异步记账引入了资金延迟,必须在业务层面提示用户和商户“交易成功不代表已到账”,并且对账逻辑要兼容在途资金。不要为了解决性能引入新的不一致风险,资金场景宁可慢一点,也要稳一点。

5.5 排查顺序与工具建议

金融服务排障最忌讳一上来就翻业务代码。我的标准顺序是:先查账单(渠道对账单、本地流水表)、再查日志(回调、报文、调用链)、然后查状态(订单状态机、缓存)、最后才查代码和 SQL。任何资金差异问题,先把数据列出来对照,再想逻辑,大多数问题在看到数据的那一刻就已经有答案了。

日志一定要在关键节点打全,这是我在复盘时最深的体会。如果一段代码不打印入参出参和耗时,它就不该出现在资金链路上。我把日志规范成了硬性要求:外部接口必须有调用方报文、我方回包、耗时;内部服务之间必须有关键链路 traceId;对账和补偿任务必须打印扫描范围和差异数量,否则视为无效日志。

6. 写在最后:一点个人体会

整个 financial-services 做下来,我最大的体会是:金融系统的复杂度不在技术,而在对一致性和可追溯性的要求。写一个支付接口不难,难的是把每一笔钱的前因后果都记录下来,让它随时可以被验证、被追溯、被审计。这也是为什么我在整个项目里最重视的模块不是支付,而是账户流水和对账脚本,它们是整个系统的账本和镜子。

如果让我重来一次,我第一件事不是选框架、不是设计库表,而是先把幂等键、状态机、审计日志这三个基础规范定成团队铁律,让所有人在第一天写代码时就遵守。另外,建议你对账模块一定要跟主交易同步开发,不要有任何“以后补”的幻想,它上线得越晚,历史数据修复成本就越高。

最后再分享一个小技巧:给所有资金接口的返回结构里统一加上trace_id,内部服务调用时透传。排查线上资金问题的时候,一个 trace_id 就能把一次交易的完整生命周期串起来,省掉的不只是翻日志的时间,更是一整晚的焦虑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 6:49:34

计网实验源码解析:从传输层协议栈到HTTP服务器

简介:中南大学计算机网络实验源代码是一份面向计算机网络课程学习者的实践资源,涵盖A1与A3两个实验的2022年最新代码。A1侧重Socket编程中的TCP/UDP通信,演示连接建立、数据收发与异常处理;A3深入协议实现,涉及HTTP、D…

作者头像 李华
网站建设 2026/9/28 6:47:48

PI-Desktop + Ollama:本地开源AI编程智能体搭建指南

这段时间我一直在折腾一件事:把市面上那些收费的 AI 编程助手,全部换成跑在本地电脑上的开源方案。折腾到最后,真正留下来天天用的组合,就是题目标题里这套PI-Desktop Ollama。它不花钱、断网也能用,而且模型怎么换、…

作者头像 李华
网站建设 2026/9/28 6:45:14

Windows本地安装OpenClaw教程:TaoToken统一Key接入飞书机器人配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华