Python异步客户端所有权:TaskGroup、借用模式与离线测试

企业微信AI Bot对接实战:Hermes Agent本地部署全指南 企业微信AI Bot本质是受限于消息通道的轻量级接口,缺乏语义理解与工具调用能力;Hermes Agent作为轻量级AI Agent运行时,填补了这一空白,通过WebSocket长连接、Python 3.11异步引擎与本地LLM协同,实现意图识别、多系统集成与业务自动化。其技术价值在于不依赖公网、数据不出内网、模型可插拔,适用于CRM查询、BI图表生成、Jenkins部署等典型企业场景。本文聚焦Linux环境下的Hermes Agent部署核心链路,涵盖Ubuntu系统选型、Python 3.11编译安装、 阅读详情

快速回答:共享异步客户端应该由谁关闭?

在本文约定的借用模式中,外层拥有者创建并关闭客户端;接受客户端参数的批量函数只负责等待自己创建的任务,不关闭传入的对象。TaskGroup 退出时会等待组内任务完成;这不等于证明真实网络连接已释放。

角色本例职责什么时候结束
资源拥有者创建假客户端并调用关闭任务组退出后
批量函数借用客户端并等待组内任务所有组内任务退出后返回
单个任务使用客户端,不关闭共享资源自己结束或退出时

适用环境:Python 3.11 及以上,标准库,无需密钥或网络。输入是两个合成名称;输出为转换后的字符串和用于测试的事件顺序。本例不适用于推断厂商 SDK 线程安全、远程取消、真实连接池或计费行为。

本文给出标准库可运行示例,覆盖资源拥有、借用与异常退出,并附完整测试和排错。

问题:谁创建,谁关闭?

多个协程共用客户端时,如果其中一个请求顺手关闭它,其余请求可能还在使用连接。相反,所有人都只借用而没有所有者,又可能一直不释放。先定义合同:创建资源的外层负责关闭;接收外部 client 的函数只借用,不负责关闭;批量任务全部退出后,才能退出拥有者作用域。

本例仅使用 Python 3.11+ 标准库和 FakeClient,不连接网络;它演示本地协程顺序,不是对任何 SDK、连接池、远程取消或计费的验证。上次资源文章侧重模拟传输和关闭顺序,本文专门讨论拥有者与借用者的 API 合同。

可复制的完整离线示例

保存为 ownership_demo.py,运行 python ownership_demo.py:

"""Offline ownership demonstration; no HTTP client or network requests."""
import asyncio
from contextlib import asynccontextmanager
import unittest

class FakeClient:
    def __init__(self, events):
        self.events = events
        self.closed = False

    async def request(self, name):
        if self.closed:
            raise RuntimeError('client already closed')
        self.events.append(f'{name}:start')
        try:
            await asyncio.sleep(0)
            return name.upper()
        finally:
            self.events.append(f'{name}:done')

    async def aclose(self):
        self.closed = True
        self.events.append('client:close')

@asynccontextmanager
async def owned_client(events):
    client = FakeClient(events)
    try:
        yield client
    finally:
        await client.aclose()

async def run_batch(client, names):
    """Borrowed client: tasks finish before return; caller owns close."""
    async with asyncio.TaskGroup() as group:
        tasks = [group.create_task(client.request(name)) for name in names]
    return [task.result() for task in tasks]

async def run_owned(names, events):
    async with owned_client(events) as client:
        return await run_batch(client, names)

class OwnershipTests(unittest.IsolatedAsyncioTestCase):
    async def test_owned_closes_after_tasks(self):
        events = []
        self.assertEqual(await run_owned(['a', 'b'], events), ['A', 'B'])
        self.assertEqual(events[-1], 'client:close')
        self.assertLess(events.index('a:done'), events.index('client:close'))
        self.assertLess(events.index('b:done'), events.index('client:close'))

    async def test_borrowed_is_not_closed(self):
        events = []
        client = FakeClient(events)
        self.assertEqual(await run_batch(client, ['a']), ['A'])
        self.assertFalse(client.closed)
        await client.aclose()

    async def test_close_when_body_raises(self):
        events = []
        with self.assertRaisesRegex(ValueError, 'failed'):
            async with owned_client(events):
                raise ValueError('failed')
        self.assertEqual(events, ['client:close'])

if __name__ == '__main__':
    unittest.main(verbosity=2)

这次本地运行了三个 unittest 方法,输出 Ran 3 tests 和 OK。第一个测试检查两个任务各自的 done 出现在 client:close 之前;它不要求两个任务之间固定顺序。第二个检查借用者返回后客户端仍打开;第三个检查作用域内直接抛出异常时,演示客户端的关闭方法仍被调用。

关键边界

  1. run_owned 创建并拥有资源;run_batch 接受外部资源,只等待其 TaskGroup 中的任务,不关闭传入对象。调用者要为外部资源安排生命周期。
  2. asyncio.TaskGroup 在上下文退出时等待组内任务;遇到任务异常时会处理其余任务并传播异常。生产应用仍需按 Python 版本和实际客户端语义处理异常组和取消。
  3. 示例 aclose 是无阻塞的本地假实现。真实关闭可能抛错、阻塞或被再次取消;需要明确超时、异常保留、幂等和服务退出策略。不能由本例推断真实网络连接一定释放。
  4. 不要在单个子任务中关闭共享 client;也不要把仍在运行的后台任务留在资源作用域外。需要长生命周期客户端时,应由应用生命周期层创建与关闭,并按实际 SDK 文档评估并发安全。

常见问题与排查

提示 TaskGroup 不存在? 检查 python --version,该示例需要 Python 3.11 或更新版本。

运行顺序与例子不完全相同? 任务之间的执行顺序不固定;只断言每个任务完成早于关闭,不断言 a 与 b 的先后。

为何测试通过仍出现连接问题? 假客户端没有 socket、连接池或超时。对真实 SDK 应在授权环境以本地服务或 mock 传输补充集成验证,不能把本例当成线上证明。

小练习

增加空任务列表场景:在 owned 模式下仍应关闭一次,在 borrowed 模式下不能关闭。然后为真实接入写一张所有权表:资源在哪里创建、谁借用、在哪退出、异常如何记录。下一篇将讨论如何为多模型比较固定输入和评价标准。

参考:Python TaskGroup 官方文档;asynccontextmanager 官方文档。

本文由 AI 辅助整理;本地示例与测试结果已核对。

Claude Code 安装配置全指南:API 调用型本地 IDE 的信任链路构建 Claude Code 并非官方 AI 编程模型,而是一个依赖 Anthropic API 的第三方桌面封装工具,其本质是构建一条安全、稳定、可调试的本地 HTTP 请求通道。理解这一‘API 调用型本地 IDE’定位,是解决 macOS 权限报错、Windows Git 环境失效、Python 版本冲突等高频问题的前提。它不运行模型,但需打通操作系统信任链(如 Full Disk Access、辅助功能授权)、终端环境链(Git/Python/Node 版本协同)和网络链(代理配置与证书验证)。典型应用场 阅读详情

相关推荐

Desktop Agent:基于LangGraph的本地智能体运行时详解

智能体(Agent)是AI工程化落地的核心范式,其本质是具备状态管理、工具调用与任务编排能力的自主工作流。LangGraph作为面向有状态Agent的图编排框架,通过可序列化State和检查点机制,解决了传统无状态链式调用无法维持上下文的根本缺陷。结合FastAPI提供的标准化Agent Protocol接口与SQLite实现的零配置、可审计本地持久化,Desktop Agent构建出真正可嵌入开发者日常工作的轻量级本地运行时。它适用于本地知识库问答、自动化脚本集成、隐私敏感型AI应用等场景,是当前少有的开

mybwu_com的专栏 623

Python异步客户端资源关闭实验:MockTransport、TaskGroup与8项测试

完整模拟传输与可观测字节流,验证借用客户端、响应关闭、任务组失败和已等待取消;附执行输出及8项离线测试。

FlowBarAI的博客 192

3天干完6个月的活,Claude把模型搬上AMD

一条挺刺激的消息:Anthropic 给投资人的材料里有一张幻灯片,写着它的 Claude Mythos Preview 只花了大约​,就摸清了怎么让另一个 Claude 模型在 AMD 的 MI355X 上跑起来。同一处还写了个对照数字:过去给一块新芯片做推理适配,通常要几十名工程师、​。3 天对 6 个月,这个比值太扎眼,当天中文互联网上就冒出一堆「英伟达的护城河塌了」的说法。我把能翻到的材料都翻了一遍,越看越觉得,塌掉的那一小块是真的,可塌的位置和很多人想的不一样。

DeepPing,日更,陪你聪明看世界。 409

MoviePilot 的 AI 协作总纲:解读 AGENTS.md 架构治理、包所有权与提交流程

MoviePilot 是一个 NAS 媒体库自动化管理工具,其仓库根目录的 [AGENTS.md](https://link.gitcode.com/i/0a65af73bdfeee9ddb7565e569f1b413) 是面向所有 AI Agent 与 LLM 的最高优先级指令集:它定义了一套「以文档为准、以源码为证」的工程契约——从包所有权(谁拥有哪一层代码)、架构依赖方向、到提交前的验证命令

gitblog_00676的博客 18

如何处理动态语言(Python / JS)的“隐形”调用链?

本文揭示动态语言(Python/JS)中静态AST解析导致调用链“断链”的核心问题,提出通过运行时追踪补全图谱的解决方案。基于Code-Graph-RAG的cgr trace机制,分别利用pytest插件与V8 Profiler捕获真实调用路径,将动态边合并至静态图谱,并在权重体系中提升动态边优先级。实践表明,该方法可显著提升图谱覆盖率,实现“结构+行为”双视角理解代码,为MCP与Rerank系统提供可靠支持。

xianyinsuifeng的博客 419

excel 利用SUBTOTAL函数计算筛选后数列总和、均值、最大、最小值

表里有三个人,咱们需要筛选出三个人,并分别计算他们的总和值。 先看一下数据范围(A1:B27) 通过筛选找张三。 按照上图所示输入函数,选择9,求和。 然后按照函数输入即可。 就能计算出结果。 筛选项选择王五,就会自动计算王五的总和。 筛选到李四就会自动计算李四的总和。 如果把9改成1,就是自动计算筛选出来的均值结果,如下图所示。 如果改成4就是取筛选项的最大值,选择5就是取最小值。 ...

yuanYW7556的博客 3万+

Pathway xpack Embedders 实战:为 RAG 与视频检索流水线接入 OpenAI、Gemini、LiteLLM 与本地向量模型

本篇围绕 Pathway Live Data Framework xpack 中的五类文本嵌入器(Embedder)展开:`OpenAIEmbedder`、`LiteLLMEmbedder`、`SentenceTransformerEmbedder`、`GeminiEmbedder` 和 `MarengoEmbedder`。读完后你将掌握每类嵌入器的默认模型、构造参数、截断与批处理机制、重试与缓存

gitblog_00178的博客 265

海康工业相机触发模式详解:软触发 vs 外触发,在C#里如何选与用?

本文深入解析海康工业相机的软触发与外触发模式,详细比较两者的特性差异、适用场景及C#实现方法。通过海康SDK配置指南和实战代码示例,帮助开发者掌握工业相机触发模式的选择与优化技巧,提升自动化检测系统的精确性和可靠性。

weixin_42635064的博客 556

NoneBot2 None 驱动(`nonebot.drivers.none`)源码级解析:无网络驱动的启动、生命周期与退出机制

NoneBot2 中的 **None 驱动**(`nonebot.drivers.none`)是一个不承载任何服务器或客户端连接的"空驱动",它既不开设 HTTP/WebSocket 服务,也不发起任何网络请求,只负责驱动框架的启动、停止、信号处理与生命周期管理。本文以 NoneBot2 仓库中的 [API 文档](https://link.gitcode.com/i/95b2be39f4b8bf

gitblog_00118的博客 387

保姆级教程:用QSTEM和DrProbe搞定你的第一张STEM模拟图(附Fe3O4实例文件)

本文提供了一份详细的STEM模拟图像生成教程,涵盖从晶体结构获取到最终图像模拟的全过程。通过QSTEM和DrProbe软件的操作指南,帮助材料科学研究者快速掌握STEM模拟技术,特别适合初学者。教程包含Fe3O4实例文件,详细解析参数设置、计算优化和结果分析等关键步骤。

weixin_33730836的博客 524

右腿驱动电路设计:从共模干扰原理到生物电采集实战

在生物电信号采集领域,共模干扰是影响测量精度的核心挑战之一,其本质源于环境电磁场通过容性耦合在人体表面产生的感应电流。根据欧姆定律,由于人体组织阻抗的不均衡性,共模电流会在不同测量点产生差异化的压降,从而转化为难以滤除的差分噪声。为解决这一问题,右腿驱动技术应运而生,它通过负反馈原理主动抵消干扰,显著提升系统的共模抑制比。该技术广泛应用于心电图、脑电图等医疗电子设备中,是确保微弱生理信号质量的关键环节。本文结合工程实践,深入剖析了右腿驱动电路中的仪表放大器选型、反馈环路稳定性设计以及PCB布局布线要点,为高

weixin_31476015的博客 445

Pathway LLM xpack Embedders 实战指南:五种内置嵌入 UDF 的原理、参数与源码级解析

本文基于 Pathway 仓库中 [70.embedders.md](https://link.gitcode.com/i/ac9b6094755232fd8ff9f62a76ae70f2) 用户指南,系统讲解 `pathway.xpacks.llm.embedders` 模块提供的五类文本嵌入包装器(OpenAI、LiteLLM、Sentence-Transformer、Gemini、Maren

gitblog_00381的博客 218

OpenAI Realtime API实时语音交互实战指南

实时语音交互是人机自然对话的核心能力,其本质在于构建低延迟、双向、流式协同的音频-语义闭环。它突破传统REST API的请求-响应范式,依托WebSocket实现毫秒级音频输入流(audio.delta)、模型生成流(text/audio.delta)与动态控制流(session.update)三重并行。该技术显著降低端到端延迟至300ms以内,支撑语音助手、智能客服、对话式教育等强实时场景。本文聚焦OpenAI Realtime API的工程落地,详解PCM音频流处理、VAD语音活动检测、AudioCon

weixin_32285357的博客 393

Pathway xpack Embedders 权威指南:五类向量化模型接入、参数解析与视频/多模态 RAG 实践

**导读**:本文聚焦 Pathway Live Data Framework 的 `pathway.xpacks.llm.embedders` 模块,系统讲解在向量存储(Vector Store)构建与 RAG 检索中如何把文本/视频内容转成向量。文中将逐一对齐 [Embedders 文档](https://link.gitcode.com/i/82a9f8668fdc525c5f03cf437

gitblog_00078的博客 445

直流电动机的建模仿真(1)他励,串励和并励电动机建模仿真

本文根据不同励磁方式的直流电动机的接线原理图,建立了相应的数学模型,然后根据与数学模型对应的等效电路以及模拟机械运动方程的等效电路,用Matlab/simulink中的SpecializedPower system库中的电路元件,建立了他励,并励和串励直流电动机的全等效电路仿真模型,经过与Matlab自带的直流电动机仿真模型比较以及仿真实例验证,所建立的仿真模型时完全正确的。

weixin_45670943的博客 7521

立创开源桌面激光雕刻机DIY全解析:从悬臂结构、Arduino主控到Marlin固件

本文详细解析了基于立创开源平台的桌面激光雕刻机DIY全过程。重点介绍了悬臂式机械结构的设计与优化,阐述了采用Arduino Mega 2560主控与RAMPS 1.4扩展板的经典控制方案,并深入讲解了Marlin固件的关键配置步骤,包括电机步数计算与激光功能启用,为创客和电子爱好者提供了一套完整的从硬件搭建到软件调试的实战指南。

weixin_42510201的博客 387

MoviePilot 分层架构与模块治理指南:基于 `docs/rules/05-architecture.md` 的迁移后代码结构详解

本文是 MoviePilot(NAS 媒体库自动化管理工具)在 legacy-module 重构完成后的分层架构与模块治理权威指南。它以仓库规则文档 [docs/rules/05-architecture.md](https://link.gitcode.com/i/60f28dde992945105ee093469e3918db) 为骨架,结合真实源码目录与治理脚本展开,帮助开发者理解:历史 `

gitblog_00387的博客 227

OpenClaw与传统AI助手区别,为什么要本地部署

OpenClaw是一款本地部署的开源AI助手框架,与ChatGPT等云端服务相比具有显著优势。它支持完全离线运行,数据隐私性高,所有信息都存储在本地设备上,避免了云端服务的隐私风险。OpenClaw采用模块化设计,可自由定制功能,且无需支付订阅费用,只需一次性硬件投入。推荐在树莓派、迷你主机等设备上部署,最低配置仅需1核CPU和1GB内存。安装过程包含系统初始化、依赖安装、配置设置等步骤,支持通过systemd服务实现开机自启和后台运行。特别适合注重数据安全、需要离线使用或预算有限的用户群体。

一键难忘的博客 1692

BrewUI:基于SwiftUI的Homebrew图形化界面实现

Homebrew 是 macOS 上最主流的包管理工具,其命令行交互虽高效却存在不可见、不可逆、难溯源等固有局限。SwiftUI 作为苹果原生声明式 UI 框架,凭借对 Swift Concurrency 的深度支持、Metal 渲染性能及与 macOS 安全模型(如 SIP、Gatekeeper)的天然兼容性,成为构建可靠 GUI 封装器的理想选择。BrewUI 并非替代终端,而是将 brew install、search 等操作转化为可观察、可中断、带进度反馈的可视化流程,显著降低轻量级技术用户(如设计

weixin_33824363的博客 423

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

多LLM抽象层:一套代码接入五家大模型的工程实践

大型语言模型(LLM)作为AI基础设施,正面临接口协议碎片化、参数语义不一致、错误码体系割裂等核心挑战。其本质是缺乏统一的调用契约,导致业务代码与具体模型深度耦合。多LLM抽象层通过定义标准化请求/响应结构、协议翻译机制与分层能力矩阵,在保留各家模型原生特性的同时,实现输入输出契约稳定。该技术显著降低模型切换成本,支撑金融、政务、法律等高合规场景下的动态路由、流式响应归一与token精准预估,是构建企业级AI中台的关键中间件。

weixin_33894640的博客 307

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

本地化部署 DeepSeek,构建单细胞与空间转录组 AI 分析平台

本地化部署 DeepSeek,构建单细胞与空间转录组 AI 分析平台

weixin_53637133的博客 177

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

AI全栈实战 | 3.9-01 爬虫入门:requests 加 BeautifulSoup 三分钟跑通,但 90% 的人栽在这 4 个“礼貌“问题上

⚠️:本文内容仅用于。请遵守目标站点的服务条款与相关法律法规,不得对目标服务造成负担,不得采集、传播个人隐私数据。技术是中性的,边界在你手里。爬虫的入门技术(requests 发请求 + BeautifulSoup 解析)三分钟就能学会。真正区分"会用爬虫"和"会做爬虫的人"的,是这篇我们跑通"请求→解析→存储"的最小闭环,然后重点把"合规与礼貌"这根弦给你绷上。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 425

从一段视频到可漫游的 4D 有声场景:思路拆解与最小复现手记

只需一段手机视频,你就能生成可"走进去"的 4D 有声场景:转头时狗叫声方向随之变化,走近时声音更清晰。本文拆解 Video-to-4DAVScene 的核心思路,手把手带你用几十行 Python 搭出最小管线,把视频中的运动物体变成带空间位置的声源,并附上三个真实踩坑的排障经验,代码可直接跑。🎧

helloagent的博客 241

【每天一个 Python 小案例30】Python 基础知识综合小项目:我的工具盒

作为系列收官,本篇把前 29 篇的知识点合成一个能直接用的命令行工具"我的工具盒":计算器(用 ast 解析表达式,不碰 eval)、单位换算与温度转换(一张换算表 + 特例分支)、记账与分类统计(Decimal + JSON 持久化)、以及用"字典当命令表"把菜单和业务逻辑解耦的主循环。文中对比了 eval 的安全隐患与 ast 白名单的做法,解释了 lambda 闭包在字典里的写法与晚绑定陷阱,并在最后给出整个系列的知识地图,把变量、数据结构、控制流、函数、类、异常、文件、标准库八块内容对应到具体篇目。

xinjiyaya的博客 427

yolo 和 deft 算法的区别

你应该是打错了:是,不是 defrat;

曾大强博客 256

二进制木马免杀-Python 分离免杀与 Web 挂马

二进制木马免杀-Python 分离免杀与 Web 挂马

2503_94637398的博客 269
上一篇: AI从零开始(第13课):学一个新概念,先解释再做两道题
下一篇: AI从零开始(第14课):七张日常提示词卡与核查清单
FlowBarAI
博客等级 码龄169天 0粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值