GitHub 可用性危机分析：三个九都难以维持
GitHub 可用性危机分析：三个九都难以维持一、新闻概述1. 标题GitHub 在勉强维持三个九的可用性方面举步维艰2. 发布时间2026 年 2 月 10 日 12:39 UTC3. 来源The Register（技术媒体）二、核心内容1. 事件摘要A. 主要内容GitHub 近期频繁出现服务中断和性能问题，其可用性甚至难以维持三个九（99.9%）的标准。B. 核心亮点2026 年 2 月 9 日发生多起服务故障Actions、Pull Requests、通知和 Copilot 全部受影响通知延迟长达 50 分钟Copilot 策略传播问题持续 17 小时2025 年某个时段正常运行时间曾降至 90% 以下2. 关键信息A. 故障时间2026 年 2 月 9 日 15:54 UTC 开始确认问题B. 受影响服务GitHub ActionsPull Requests通知服务GitHub CopilotC. 恢复时间2026 年 2 月 9 日 19:29 UTC 确认恢复正常3. 背景介绍A. 服务等级协议GitHub Enterprise Cloud 的 SLA 规定 99.9% 的正常运行时间，但不对所有用户做出保证。B. 行业标准五个九（99.999% 的正常运行时间）是云计算行业的金标准，但许多供应商连 90% 都难以维持。三、详细报道1. 主要故障事件A. 2026 年 2 月 9 日服务中断graph LR T1[15:54 UTC] --> A[确认部分 GitHub 服务出现问题] T2[16:29 UTC] --> B[Copilot 策略传播问题开始] T3[17:57 UTC] --> C[通知延迟降至约 30 分钟] T4[19:29 UTC] --> D[确认服务恢复正常] T5[次日 09:57 UTC] --> E[Copilot 问题完全解决] style T1 fill:#e1f5ff style T2 fill:#ffe1e1 style T3 fill:#fff4e1 style T4 fill:#e1ffe1 style T5 fill:#e1e1ff问题详情：通知延迟：最高达 50 分钟Copilot 策略传播：新启用的模型无法在用户访问时显示故障持续时间：约 3.5 小时（主要服务）Copilot 故障：持续约 17 小时B. 历史可用性问题根据非官方重建的状态页面数据，GitHub 在 2025 年某个时段的正常运行时间曾降至 90% 以下。2. 技术细节A. 可用性标准对比可用性等级正常运行时间年度停机时间适用场景一个九90%36.5 天消费级服务两个九99%3.65 天一般业务三个九99.9%8.76 小时企业服务（GitHub SLA）四个九99.99%52.56 分钟高可用服务五个九99.999%5.26 分钟关键基础设施B. 状态页面变更GitHub 更新了其状态页面的设计，使得以下操作变得更加困难：查看过去 90 天的整体运行情况可视化服务的整体可用性快速评估系统稳定性3. 相关事件graph LR A[GitHub 服务问题] --> B[Actions 故障] A --> C[Pull Requests 故障] A --> D[通知延迟] A --> E[Copilot 故障] B --> F[CI/CD 中断] C --> G[代码协作受阻] D --> H[团队沟通延迟] E --> I[AI 编程助手失效]四、影响分析1. 对开发者的影响A. 开发工作流中断CI/CD 管道因 Actions 故障而停止代码审查和合并流程受阻团队协作效率下降B. AI 编程辅助失效Copilot 服务中断影响开发者生产力策略传播问题导致新模型无法访问2. 对企业客户的影响A. SLA 争议Enterprise Cloud SLA 规定 99.9% 正常运行时间实际可用性可能难以达到承诺标准B. 业务连续性风险频繁的服务中断影响关键开发项目需要制定故障应急预案3. 行业影响A. 云服务可靠性信任危机云服务难以维持基本的可用性标准五个九的承诺在现实中难以实现B. 微软旗下服务稳定性质疑GitHub 作为微软子公司，其服务质量引发关注与其他微软服务的稳定性问题相呼应五、各方反应1. 用户反馈社区对 GitHub 频繁故障表示不满开发者担心依赖单一平台的风险2. 行业观察云服务可靠性普遍下降企业应规划故障应对策略3. 相关报道Zig 编程语言因微软 AI 痴迷而退出 GitHubGitHub 计划对自托管运行器收费后撤回决定六、经验教训1. 服务设计启示A. 透明度问题状态页面设计变更降低了透明度用户难以评估服务的整体可用性B. 监控与告警需要独立的第三方监控用户应自行监控关键服务2. 客户应对策略A. 多平台部署避免过度依赖单一代码托管平台考虑自托管或混合部署方案B. 故障预案制定服务中断时的应急预案建立离线工作能力3. 行业思考A. SLA 现实性供应商需要更现实的可用性承诺客户应理性评估 SLA 条款B. 可靠性投资云服务商需要投资基础设施可靠性简化架构以提高稳定性参考资料GitHub appears to be struggling with measly three nines availability - The Register
Manyana：基于 CRDT 的版本控制系统展望一、新闻概述1. 标题Manyana：Bram Cohen 发布基于 CRDT 的版本控制系统，合并永不失败2. 发布时间2026 年 3 月3. 来源Bram Cohen 官方博客二、核心内容1. 事件摘要A. 主要内容BitTorrent 创始人 Bram Cohen 发布 Manyana 项目，这是一个基于 CRDT（Conflict-Free Replicated Data Types，无冲突复制数据类型）的版本控制系统演示，提出了版本控制的未来愿景。B. 核心亮点合并永不失败，CRDT 保证最终一致性更智能的冲突标记，显示"发生了什么"和"谁做的"行顺序永久化，避免多分支合并问题历史记录存储在数据结构中，而非依赖 DAGRebase 不需要销毁历史约 470 行 Python 代码实现2. 关键信息A. 涉及技术CRDT（Conflict-Free Replicated Data Types）版本控制数据结构：WeaveB. 项目状态概念验证级别演示公有领域代码单文件操作未实现：Cherry-picking、本地撤销C. 核心特性无阻塞合并信息性冲突标记永久行排序历史感知3. 背景介绍A. 作者背景Bram Cohen 是 BitTorrent 的创始人，在分布式系统和版本控制领域有深厚经验。B. 技术背景传统版本控制系统（如 Git）使用 3-way merge，存在冲突处理困难、合并顺序敏感等问题。CRDT 是分布式系统中常用的数据结构，能保证最终一致性。三、详细报道1. 主要内容A. CRDT 基础原理CRDT（无冲突复制数据类型）的核心特性：合并永不失败最终一致性保证合并结果与顺序无关适用于多分支并行开发graph TD A[分支 A 修改] --> M[CRDT 合并] B[分支 B 修改] --> M C[分支 C 修改] --> M M --> R[一致的结果状态] M -.从不失败.-> RB. 冲突标记改进传统 VCS 的冲突标记：<<<<<<< left ======= def calculate(x): a = x * 2 logger.debug(f"a={a}") b = a + 1 return b >>>>>>> rightManyana 的智能冲突标记：<<<<<<< begin deleted left def calculate(x): a = x * 2 ======= begin added right logger.debug(f"a={a}") ======= begin deleted left b = a + 1 return b >>>>>>> end conflict改进点：标记显示操作类型（删除/添加）标记显示操作来源（left/right）清晰展示冲突的结构无需脑力重构发生了什么C. 核心设计特性特性 1：行顺序永久化当两个分支在同一点插入代码时，CRDT 选择一个顺序并保持永久。这解决了以下问题：冲突部分在不同分支上以不同顺序解决多人独立工作时合并结果不一致传统 VCS 在没有共同祖先时的合并困难特性 2：冲突不阻塞合并合并总是产生结果并发编辑"距离太近"时才会标记冲突冲突仅用于审查，不阻止工作继续算法追踪"每边做了什么"，而非仅显示两个结果特性 3：历史存储在结构中状态是一个 Weave（编织结构）：包含文件中曾经存在的每一行每行带有添加和删除的时间元数据合并不需要查找共同祖先不需要遍历 DAGgraph LR A[状态 A] --> M[CRDT 合并] B[状态 B] --> M M --> R[结果状态] R --> W[Weave 结构 包含完整历史] W -.无需.-> DAG[传统 DAG]D. Rebase 的改进传统 Rebase 的问题：创建虚构历史销毁原始提交的真实上下文激进 rebase 产生无共同祖先的拓扑CRDT 系统的 Rebase：可以逐个重放提交到新基线同时保留完整历史仅需在 DAG 中添加"主要祖先"注解优势：激进 rebase 不再破坏可追溯性传统 3-way merge 在无共同祖先时失效CRDT 不在乎，历史在 Weave 中2. 技术细节A. 架构设计graph TB subgraph Manyana File[文件] --> CRDT[CRDT 引擎] CRDT --> Weave[Weave 结构] Weave --> History[历史记录] Weave --> State[当前状态] end CRDT -.合并永不失败.-> Weave Weave -.包含.-> History Weave -.派生.-> StateC. Weave 数据结构Weave 是 Manyana 的核心数据结构：特点：单一结构包含所有历史行每行带有完整生命周期元数据支持高效的合并操作无需重构历史优势：合并复杂度与历史深度无关支持任意分支拓扑天然支持多路合并3. 数据与事实A. 项目规模代码量：约 470 行 Python许可证：公有领域（Public Domain）功能范围：单文件操作演示B. 已实现功能CRDT 合并引擎智能冲突标记Weave 数据结构基本版本控制操作C. 未实现功能Cherry-picking（拣选提交）本地撤销多文件支持完整 VCS 功能D. 设计文档完整设计文档包含在 README 中，涵盖了：Cherry-picking 的设计思路本地撤销的实现方案完整 VCS 的构建路径四、影响分析1. 行业影响A. 技术趋势CRDT 在版本控制领域的应用探索从"冲突解决"到"冲突避免"的范式转变分布式版本控制的新方向B. 竞争格局Git 统治地位面临新思路挑战其他 CRDT VCS 项目：Dolt、Yjs 等传统 VCS 可能借鉴部分概念C. 生态影响可能催生下一代版本控制工具对协作工具有启发意义推动 CRDT 技术更广泛应用2. 用户影响A. 潜在收益减少合并冲突处理时间更清晰的冲突上下文更自信的分支和合并操作更好的多团队协作体验B. 学习成本新的冲突标记语法不同的工作流程概念需要理解 CRDT 基本原理C. 迁移挑战从 Git 迁移的成本工具链生态成熟度团队采用阻力3. 技术趋势A. 技术方向从 DAG-first 到 Structure-first从冲突解决到冲突避免历史可追溯性优先分布式协作优化B. 未来发展完整 VCS 实现的可能性与现有工具的集成性能优化和扩展性企业级功能需求五、各方反应1. 官方立场Bram Cohen 强调 Manyana 是一个"演示"而非完整的版本控制系统，主要证明两点：CRDT 版本控制可以处理困难的 UX 问题提供了比现有工具更好的解决方案2. 技术意义A. 突破点解决了传统 VCS 的根本性问题提供了清晰的冲突展示保留了完整的历史记录B. 局限性当前仅为概念验证缺少完整 VCS 的功能需要更多工程实践3. 社区关注点A. 积极评价CRDT 应用方向的创新冲突标记的实际改进开源和公有领域贡献B. 技术讨论CRDT 在大规模代码库的性能与 Git 生态的兼容性实际生产环境的适用性C. 未来展望期待完整的 VCS 实现希望更多工具集成关注项目发展动态六、相关链接1. 项目资源Manyana 代码仓库README 设计文档2. 技术背景CRDT 论文和研究Bram Cohen 的技术博客3. 相关项目Dolt（SQL 版本控制）Yjs（CRDT 框架）Automerge（CRDF 实现）参考资料Manyana - Bram Cohen's Blog
rip 终端进程管理工具入门指南一、概述1. 简介A. 是什么rip 是一个用 Rust 语言编写的终端工具，提供交互式的进程查找和终止功能。通过模糊搜索界面，用户可以快速定位并杀死占用系统资源的进程。B. 为什么学比传统 ps 和 kill 命令更直观支持按 CPU、内存、端口等多维度排序实时监控模式可动态刷新进程列表跨平台支持 Linux、macOS 和 WindowsC. 学完能做什么快速定位高 CPU 或高内存消耗的进程精准终止指定端口占用的进程使用信号优雅地关闭应用程序实时监控系统进程状态2. 前置知识A. 必备技能基本终端命令操作了解进程和端口概念B. 推荐知识了解 Unix 信号机制了解系统资源监控基础二、环境准备1. 系统要求Linux：x86_64、aarch64 架构macOS：x86_64、arm64 架构Windows：x86_64 架构2. 安装步骤Homebrew（macOS/Linux）：brew install cesarferreira/tap/ripCargo：cargo install rip-cli从源码编译：cargo install --path .Nix：nix run github:cesarferreira/rip --no-write-lock-file3. 验证安装rip --version三、核心概念1. 基本术语模糊搜索（Fuzzy Search）：支持部分匹配的搜索方式信号（Signal）：发送给进程的指令，如 KILL、TERM实时模式（Live Mode）：自动刷新进程列表的模式端口模式（Ports Mode）：显示监听网络端口的进程2. 工作原理graph LR A[用户执行 rip] --> B[获取进程列表] B --> C[显示 TUI 界面] C --> D{用户操作} D -->|搜索| E[过滤进程] D -->|选择| F[标记进程] D -->|确认| G[发送信号] G --> H[终止进程] D -->|取消| I[退出界面]四、快速上手1. Hello World 示例# 启动 rip（默认按 CPU 排序） rip运行后会显示所有运行中的进程，可通过键盘进行交互操作。2. 核心功能演示# 预过滤特定名称的进程 rip -f chrome # 使用 SIGTERM 信号优雅终止 rip -s SIGTERM # 按内存使用排序 rip --sort mem # 按名称排序 rip --sort name3. 代码讲解基本使用流程执行 rip 命令进入交互界面直接输入进程名进行模糊搜索使用空格键选中/取消选中进程按回车键发送终止信号按 Esc 或 Ctrl+C 取消操作端口模式# 显示所有占用端口的进程 rip --ports # 终止占用特定端口的进程 rip --port 3000 # 端口模式配合实时刷新 rip --ports --live五、进阶内容1. 常用功能实时监控模式# 启动自动刷新模式 rip --live此模式下进程列表会定期更新，适合监控动态变化的系统状态。信号选择rip 支持多种 Unix 信号：信号编号描述KILL9强制杀死（默认）TERM15优雅终止INT2中断HUP1挂起QUIT3退出排序选项--sort cpu # 按 CPU 使用率（默认） --sort mem # 按内存占用 --sort pid # 按进程 ID --sort name # 按进程名称 --sort port # 按端口号2. 最佳实践优先使用 SIGTERM 信号，给予进程清理资源的机会对于无响应进程再使用 SIGKILL使用预过滤功能缩小搜索范围端口模式用于快速定位端口冲突问题3. 性能优化rip 使用 Rust 编写，资源占用极低模糊搜索算法高效，支持大量进程快速筛选实时模式采用智能刷新策略，避免过度消耗资源六、实战案例1. 场景描述开发环境中某个 Node.js 进程占用端口 3000，导致新服务无法启动。2. 实现步骤# 方法 1：直接使用端口模式 rip --port 3000 # 方法 2：先查找再终止 rip -f node # 方法 3：按 CPU 排序找到高消耗进程 rip --sort cpu在交互界面中：使用空格选中目标进程按回车确认终止3. 完整代码# 组合使用示例：实时监控端口 8080 rip --ports --live --sort port # 优雅终止所有 Chrome 进程 rip -f chrome -s TERM # 查看并终止高内存进程 rip --sort mem --live七、常见问题1. 安装问题Q: Homebrew 安装失败A: 确保已更新 Homebrew：brew updateQ: Cargo 安装缓慢A: 可使用国内镜像源加速2. 使用问题Q: 为什么进程终止后仍显示A: 实时模式会自动刷新，非实时模式可手动重启 ripQ: 无法终止系统进程A: 需要使用 sudo 权限运行 rip3. 运行问题Q: 界面显示异常A: 确保终端支持 TUI，尝试调整终端窗口大小Q: 找不到预编译二进制A: 可从源码编译，确保安装了 Rust 工具链参考资料rip GitHub 仓库rip-cli on crates.io
GitHub Actions 新增定时任务时区支持一、新闻概述1. 标题GitHub Actions 新增定时任务时区支持2. 发布时间2026 年 3 月 19 日3. 来源GitHub 官方博客二、核心内容1. 事件摘要A. 主要内容GitHub 官方在 2026 年 3 月 19 日的 changelog 中宣布，GitHub Actions 现已支持为定时任务（scheduled workflows）指定时区。用户不再局限于使用 UTC 时间，可以直接使用 IANA 时区标识符来配置本地时间执行。B. 核心亮点可在 cron 表达式中添加 timezone 字段支持 IANA 标准时区标识符（如 America/New_York、Asia/Shanghai）解决了困扰开发者近 4 年的需求同时发布了无需自动部署的环境配置功能2. 关键信息A. 版本说明功能类型：Improvement（功能改进）发布日期：2026 年 3 月 19 日相关讨论：GitHub Community Discussion #13454B. 涉及产品GitHub ActionsCI/CD 定时任务调度3. 背景介绍A. 历史背景该功能需求最早于 2022 年在 GitHub Community Discussion #13454 中提出。在功能发布之前，GitHub Actions 的定时任务仅支持 UTC 时间，导致非 UTC 时区的开发者需要手动计算时差，特别是在涉及夏令时（DST）的情况下更加复杂。B. 用户痛点亚洲时区用户（如 GMT+8 的新加坡）难以准确设置每月第一天的午夜任务需要手动调整夏令时和冬令时的时间差跨时区团队的协作调度困难三、详细报道1. 主要内容A. 功能更新新增 timezone 字段，开发者可以在 workflow 的 cron schedule 配置中直接指定时区：on: schedule: - cron: '0 8 * * *' timezone: 'America/New_York'B. 技术细节支持所有 IANA 时区数据库中的时区标识符timezone 字段与 cron 表达式配合使用系统会自动处理该时区的夏令时转换C. 已知问题发布初期存在一个小 bug：当 workflow 同时包含 schedule（带 timezone）和 workflow_dispatch 时，手动触发会报错。错误信息为「timezone in scheduled workflows is not yet supported」。但定时调度本身正常工作。2. 技术原理graph LR A[用户配置 Cron + Timezone] --> B[GitHub Actions 调度器] B --> C{解析时区} C --> D[转换为 UTC 执行时间] D --> E[在指定本地时间触发 Workflow]A. 配置示例示例 1：北京时间每天上午 8 点执行on: schedule: - cron: '0 8 * * *' timezone: 'Asia/Shanghai'示例 2：纽约时间每周一上午 9 点执行on: schedule: - cron: '0 9 * * 1' timezone: 'America/New_York'示例 3：柏林时间每月 1 日午夜执行on: schedule: - cron: '0 0 1 * *' timezone: 'Europe/Berlin'B. 旧版变通方案对比在时区支持发布之前，开发者使用的变通方案：# 旧方案：手动计算 UTC 时间 on: schedule: # 北京时间 8:00 = UTC 0:00 - cron: '0 0 * * *' # 或者在 workflow 中检查时间 jobs: check_time: runs-on: ubuntu-latest steps: - name: Check if it's 8 AM run: | current_hour=$(TZ='Asia/Shanghai' date +'%H') if [ "$current_hour" == "08" ]; then echo "run_tasks=true" >> $GITHUB_ENV fi四、影响分析1. 用户影响A. 现有用户无需修改现有配置，向后兼容可逐步将 UTC 配置迁移为本地时区需要注意已知的 workflow_dispatch bugB. 新用户可以直接使用本地时区配置，降低使用门槛无需手动计算时差，减少配置错误2. 技术趋势A. 标准化采用 IANA 时区数据库标准，与主流编程语言和系统保持一致时区自动处理夏令时，符合国际化最佳实践B. 用户体验GitHub 持续关注社区反馈，解决长期存在的用户体验问题本次更新同时包含「无需自动部署的环境配置」功能，体现了对开发者需求的重视五、各方反应1. 官方回应GitHub 工程师 nebuk89 于 2025 年 11 月在社区讨论中透露团队正在评估该功能，并承诺在 2026 年第一季度内发布。2. 社区反馈A. 期待已久的发布社区用户 mcassaniti 在功能发布后表示：「社区知道这个功能已经等待了很长时间，终于来了。感谢让我们的生活变得更容易。」B. 早期问题反馈部分用户发现了 timezone 字段与 workflow_dispatch 冲突的 bug，但多数用户对功能整体表示欢迎。C. 历史讨论热度该功能讨论帖自 2022 年创建以来，获得了超过 1700 个点赞和大量评论，是 GitHub Community 中最热门的功能请求之一。六、相关链接1. 官方公告GitHub Actions: Late March 2026 updatesGitHub Community Discussion #134542. 相关文档GitHub Actions 文档：事件触发 - scheduleIANA 时区数据库参考资料GitHub Actions: Late March 2026 updatesGitHub Community Discussion #13454
贝叶斯统计入门指南一、概述1. 简介A. 是什么贝叶斯统计是一种统计推断方法，它将概率视为对不确定性的度量，而非事件发生的长期频率。与频率学派统计不同，贝叶斯统计将模型参数视为随机变量，通过数据不断更新对参数的认知。B. 为什么学提供更直观的不确定性量化方式先验知识可以自然地融入模型特别适合小数据场景和复杂模型可信区间比置信区间更易理解C. 学完能做什么理解贝叶斯与频率学派的核心区别使用贝叶斯方法进行参数估计应用 PyMC 等 MCMC 工具解决实际问题构建包含先验知识的稳健模型2. 前置知识A. 必备技能基础概率论概念条件概率和贝叶斯定理Python 编程基础B. 推荐知识频率学派统计基础最大似然估计线性回归二、核心概念1. 哲学差异贝叶斯统计与频率学派统计的根本区别在于对概率的理解：维度频率学派贝叶斯学派参数固定但未知随机变量，服从分布数据随机抽样固定观测值概率长期频率不确定性的度量区间估计置信区间可信区间A. 置信区间 vs 可信区间置信区间：如果重复抽样多次，95% 的区间会包含真实参数可信区间：参数有 95% 的概率落在该区间内graph LR A[问题] --> B{统计框架} B --> C[频率学派] B --> D[贝叶斯学派] C --> E[参数固定] C --> F[数据随机] C --> G[置信区间] D --> H[参数分布] D --> I[数据固定] D --> J[可信区间]2. 贝叶斯定理贝叶斯推断的核心是贝叶斯定理：P(θ|X) = P(X|θ) × P(θ) / P(X)其中：P(θ|X)：后验分布，是我们想求解的P(X|θ)：似然函数，表示给定参数下观测数据的概率P(θ)：先验分布，表示对参数的初始认知P(X)：标准化常数，通常不需要显式计算graph TD A[先验分布] --> B[观测数据] B --> C[似然函数] A --> D[贝叶斯定理] C --> D D --> E[后验分布] E --> F[后验预测分布]3. 核心术语先验分布：对参数的初始假设似然函数：数据对参数的支持程度后验分布：结合先验和数据后的参数认知MAP 估计：最大后验概率估计后验预测分布：对新数据的预测分布三、快速上手1. 骰子问题示例假设你观察到一个骰子投掷 8 次，结果为 [1, 1, 2, 3, 3, 4, 4, 4]，但不知道骰子有多少面。A. 频率学派方法使用最大似然估计：P(X|n) = (1/n)^8当 n = 4 时似然最大，因为投掷结果的最大值为 4。95% 置信区间为 [4, 6]。B. 贝叶斯学派方法选择先验分布 P(n)，计算后验分布：P(n|X) ∝ (1/n)^k × P(n)使用均匀先验时，后验均值约为 4.26，95% 可信区间为 [4, 5]。2. 先验的影响先验分布的作用：数据少时，先验影响大数据多时，似然函数主导后验好的先验可以补偿数据不足import pymc as pm import numpy as np # 观测数据 observations = np.array([1, 1, 2, 3, 3, 4, 4, 4]) k = len(observations) x_max = int(observations.max()) with pm.Model() as model: # 几何先验 excess = pm.Geometric("excess", p=0.5) - 1 n = pm.Deterministic("n", excess + x_max) # 似然函数 pm.Potential("likelihood", -k * pm.math.log(n)) # MCMC 采样 trace = pm.sample(10000, tune=2000, chains=4) # 获取后验分布 posterior_n = trace.posterior["n"].values.flatten() print(f"后验均值: {posterior_n.mean():.2f}")3. 环境准备安装必要的 Python 库：pip install pymc arviz numpy matplotlib四、进阶内容1. 实际应用案例A. 地理分布建模问题：根据历史订单数据生成合成数据，需要按地理位置分配订单。频率学派问题：对新类别或新邮编不鲁棒数据稀疏时估计分布噪声大贝叶斯解决方案：使用 Dirichlet-Multinomial 分布建模似然使用人口分布作为先验（非稀疏）先验作为数据不足时的后备2. 数值方法：MCMC当后验分布无法解析求解时，使用马尔可夫链蒙特卡洛方法。A. Metropolis 算法从当前点 θ_t 提议新点 θ_{t+1}，以以下概率接受：min(1, P(θ_{t+1}|X) / P(θ_t|X))关键优势：不需要计算标准化常数 P(X)。B. NUTS 算法PyMC 默认使用的 No-U-Turn Sampler，是 Hamiltonian Monte Carlo 的改进版本，效率更高。graph LR A[定义先验] --> B[定义似然] B --> C[MCMC 采样] C --> D[后验分布] D --> E[统计分析]3. 线性回归的贝叶斯方法A. 基础实现import pymc as pm import arviz as az with pm.Model() as model: # 先验 a = pm.Normal("a", mu=0, sigma=10) b = pm.Normal("b", mu=0, sigma=10) sigma = pm.HalfNormal("sigma", sigma=10) # 似然 y_obs = pm.Normal("y_obs", mu=a * x + b, sigma=sigma, observed=y) # 采样 trace = pm.sample(1000, tune=1000, chains=4) # 提取结果 a_mean = trace.posterior["a"].values.mean() b_mean = trace.posterior["b"].values.mean()B. 处理异常值使用混合模型处理异常数据：with pm.Model() as model: # 先验 a = pm.Normal("a", mu=0, sigma=10) b = pm.Normal("b", mu=0, sigma=10) sigma = pm.HalfNormal("sigma", sigma=10) delta = pm.HalfNormal("delta", sigma=5) sigma_bgd = pm.Deterministic("sigma_bgd", sigma + delta) # 混合权重 gs = pm.Beta("gs", alpha=2, beta=2, shape=len(x)) # 混合似然 mu = a * x + b w = pm.math.stack([gs, 1 - gs], axis=1) pm.Mixture( "likelihood", w=w, comp_dists=[ pm.Normal.dist(mu=mu, sigma=sigma), pm.Normal.dist(mu=mu, sigma=sigma_bgd), ], observed=y, ) trace = pm.sample(1000, tune=1000, chains=4)4. 与正则化的关系频率学派的正则化方法本质上是贝叶斯先验：Ridge 回归（L2）= 高斯先验Lasso 回归（L1）= 拉普拉斯先验目标函数：θ_MAP = min_θ Σ(y_i - θ_0 - θ_1×x_i)^2/σ^2 + F(θ)五、最佳实践1. 先验选择使用无信息先验（均匀分布、宽高斯分布）当缺乏领域知识使用有信息先验（领域知识）当数据稀疏确保先验覆盖所有合理的参数值2. 收敛诊断检查多条链的混合情况查看 R-hat 统计量（应接近 1）检查轨迹图的自相关性3. 模型验证使用后验预测检验交叉验证与频率学派方法对比六、常见问题1. 先验是否敏感数据少时敏感，数据多时影响小。Bernstein-von Mises 定理保证在大数据极限下，贝叶斯与频率学派方法收敛到同一结果。2. 计算成本MCMC 方法计算成本较高，但对于复杂问题比解析求解可行得多。使用 NUTS 算法可以提高效率。3. 何时使用贝叶斯方法小数据场景需要融入先验知识需要直观的不确定性量化复杂层次模型参考资料Bayesian statistics for confused data scientistsFrequentism and Bayesianism: A Practical IntroductionA Modern Introduction to Probabilistic Programming with PyMCPyMC library homepage
微信 iLink Bot SDK 技术文档一、概述1. 项目简介A. 是什么weixin-bot 是一个微信 iLink Bot SDK，支持 Node.js 和 Python 两种语言实现。它为开发者提供了一套简洁的 API，让任何 Agent 可以在 5 分钟内接入微信消息收发功能。B. 为什么需要它传统的微信机器人接入面临以下痛点：协议复杂，需要深入理解微信 iLink Bot APIcontext_token 管理繁琐，处理不当会导致消息投递失败Session 过期需要手动重新登录需要配置 Webhook 接收消息，部署复杂weixin-bot SDK 通过封装底层协议细节，解决了这些问题：零配置，开箱即用凭证自动保存和续期context_token 自动管理长轮询收消息，无需 WebhookC. 应用场景AI Agent 接入微信作为交互渠道客服机器人自动回复群聊助手和消息监听微信消息自动化处理2. 技术背景A. iLink Bot APIiLink Bot API 是微信提供的机器人接口协议，采用 HTTP 长轮询方式接收消息，通过 HTTP POST 发送消息。关键特性包括：扫码登录认证长轮询获取更新context_token 上下文传递机制Typing 状态支持B. 协议关键发现SDK 开发过程中发现的关键协议细节：context_token：回复消息时必须原样传回 APIsendtyping：唯一能触发"对方正在输入中"的方式message_state：GENERATING 状态在 API 层面可用，但微信客户端不渲染Session 过期：errcode 为 -14 时需要重新登录二、系统架构1. 整体架构graph TB Agent[Agent 应用] -->|调用| SDK[weixin-bot SDK] SDK -->|HTTP 长轮询| API[iLink Bot API] SDK -->|HTTP POST| API API -->|推送消息| User[微信用户] User -->|扫码/发消息| API SDK -->|保存凭证| Local[本地存储]2. 组件说明Agent 应用：使用 SDK 的上层应用，如 AI Agent、客服机器人weixin-bot SDK：封装 iLink Bot API 协议的 SDK 库iLink Bot API：微信提供的机器人接口服务本地存储：保存登录凭证，避免重复扫码3. 交互流程sequenceDiagram participant Agent as Agent 应用 participant SDK as weixin-bot SDK participant API as iLink Bot API participant User as 微信用户 Note over Agent,User: 1. 登录阶段 Agent->>SDK: bot.login() SDK->>API: GET /get_bot_qrcode?bot_type=3 API-->>SDK: 返回二维码 URL SDK-->>Agent: 终端显示二维码 User->>API: 微信扫码确认 API-->>SDK: 返回 bot_token + baseurl SDK-->>Agent: 登录成功，凭证已保存 Note over Agent,User: 2. 消息收发循环 Agent->>SDK: bot.run() loop 长轮询循环 SDK->>API: POST /getupdates (最多保持 35 秒) User->>API: 发送消息 "你好" API-->>SDK: 返回消息 + context_token SDK-->>Agent: 触发 onMessage(msg) Agent->>SDK: bot.sendTyping(userId) SDK->>API: POST /sendtyping Note over User: 显示 "对方正在输入中" Agent->>SDK: bot.reply(msg, "Echo: 你好") SDK->>API: POST /sendmessage (带 context_token) API-->>User: 推送回复消息 SDK->>API: POST /sendtyping (取消 typing) end Note over Agent,User: 3. 异常处理 API-->>SDK: 返回 errcode: -14 (Session 过期) SDK->>SDK: 自动触发重新登录 SDK->>API: 重新获取二维码和 token SDK-->>Agent: 自动恢复运行三、安装指南1. 系统要求Node.js：14+ 版本Python：3.7+ 版本网络环境：可访问微信 iLink Bot API2. Node.js 安装npm install @pinixai/weixin-bot3. Python 安装pip install weixin-bot-sdk四、快速入门1. Node.js 示例import { WeixinBot } from '@pinixai/weixin-bot' const bot = new WeixinBot() await bot.login() bot.onMessage(async (msg) => { await bot.sendTyping(msg.userId) await bot.reply(msg, `Echo: ${msg.text}`) }) await bot.run()2. Python 示例from weixin_bot import WeixinBot bot = WeixinBot() bot.login() @bot.on_message async def handle(msg): await bot.send_typing(msg.user_id) await bot.reply(msg, f"Echo: {msg.text}") bot.run()3. 运行流程创建 WeixinBot 实例调用 login() 方法，终端显示二维码使用微信扫码确认登录注册消息处理回调调用 run() 启动长轮询循环五、API 参考1. 核心方法方法参数说明login()force?: boolean扫码登录，已有凭证则自动跳过onMessage()handler: Function注册消息处理回调reply()msg, text回复消息，自动取消 typing 状态send()userId, text主动发消息，需已有 context_tokensendTyping()userId显示"对方正在输入中"stopTyping()userId取消输入状态run()无启动长轮询循环stop()无停止运行2. 消息对象interface Message { userId: string // 用户 ID text: string // 消息文本 contextToken: string // 上下文 token，SDK 自动管理 }3. 使用示例// 回复消息 await bot.reply(msg, "收到你的消息") // 主动发消息 await bot.send(userId, "你好") // 显示 typing 状态 await bot.sendTyping(userId) // 取消 typing 状态 await bot.stopTyping(userId)六、高级特性1. context_token 自动管理context_token 是 iLink Bot API 的关键机制：API 返回消息时携带 context_token回复消息时必须原样传回，否则消息无法投递SDK 内部自动管理，开发者无需关心2. Typing 状态sendtyping 是唯一能触发"对方正在输入中"的方式：await bot.sendTyping(userId) // 开始输入状态 // ... 处理消息 ... await bot.reply(msg, text) // reply 会自动取消 typing3. Session 过期自动处理当 Session 过期（errcode: -14）时：SDK 自动检测到错误自动触发重新登录流程恢复后继续运行4. 凭证持久化登录成功后，SDK 自动保存凭证：bot_tokenbaseurl后续启动自动加载凭证，无需重复扫码七、技术细节1. 长轮询机制SDK 使用长轮询获取消息更新：请求 /getupdates 接口最多保持 35 秒有消息立即返回无消息超时返回空数组循环往复持续监听2. 消息投递保证为保证消息成功投递：使用收到的 context_token 原样传回SDK 内部维护 userId 到 context_token 的映射避免跨会话复用 token3. 协议限制以下是协议分析和使用中发现的限制：message_state: GENERATING 在 API 层面可用，但微信客户端不渲染气泡更新，不建议使用sendtyping 是唯一可靠的 typing 触发方式Session 会定期过期，需要处理 -14 错误码八、最佳实践1. 消息处理建议bot.onMessage(async (msg) => { try { // 1. 先显示 typing，提升用户体验 await bot.sendTyping(msg.userId) // 2. 处理业务逻辑 const response = await processMessage(msg.text) // 3. 回复消息（自动取消 typing） await bot.reply(msg, response) } catch (error) { console.error('处理消息失败:', error) } })2. 错误处理bot.onMessage(async (msg) => { try { await bot.reply(msg, "处理中...") } catch (error) { if (error.code === -14) { console.log('Session 过期，SDK 会自动重连') } else { console.error('发送消息失败:', error) } } })3. 资源清理// 优雅退出 process.on('SIGINT', async () => { console.log('正在停止 bot...') bot.stop() process.exit(0) })九、故障排查1. 常见问题问题：登录后收不到消息检查网络连接确认 run() 方法已调用查看控制台是否有错误日志问题：消息发送失败确认 context_token 有效检查是否使用 reply() 方法而非 send()查看错误码和错误信息问题：频繁要求重新登录检查 IP 是否被限制确认账号状态正常Session 有效期可能较短，属于正常现象2. 日志调试SDK 输出详细日志，方便调试：登录状态消息收发错误信息十、生态资源1. 官方资源GitHub 仓库：https://github.com/epiral/weixin-bot协议文档：docs/protocol-spec.md（1200+ 行详细分析）2. 示例项目Node.js Echo Bot：完整示例，含日志和 typingNode.js 流式测试：GENERATING vs FINISH 测试Node.js Typing 测试：sendtyping vs GENERATING 对比3. 相关包@pinixai/weixin-bot：Node.js SDKweixin-bot-sdk：Python SDK参考资料epiral/weixin-bot - GitHub
使用 AI Agent 将 MiniJinja 移植到 Go 语言一、新闻概述1. 标题使用 AI Agent 将 MiniJinja 移植到 Go 语言2. 发布时间2026 年 1 月 14 日3. 来源Armin Ronacher 个人博客（lucumr.pocoo.org）二、核心内容1. 事件摘要A. 主要内容Armin Ronacher 使用 AI Agent 成功将 MiniJinja（Rust 编写的 Jinja2 模板引擎）移植到 Go 语言。整个移植过程耗时约 10 小时，但人工参与时间仅 45 分钟，主要用于高层指导。B. 核心亮点AI Agent 独立完成绝大部分移植工作采用测试驱动开发方式，逐步实现词法分析、语法分析和运行时Agent 从字面移植转向行为移植，更符合 Go 语言习惯API 成本约 60 美元，使用 220 万 tokens2. 关键信息A. 涉及项目MiniJinja：Rust 版本的 Jinja2 模板引擎移植目标：原生 Go 语言实现B. 重要数据Agent 运行时长：10 小时（3 小时人工监督 + 7 小时独立运行）人工参与时间：约 45 分钟消息总数：2698 条用户提示：34 条工具调用：1386 次API 成本：60 美元Token 总量：220 万C. 使用的模型Claude Opus 4.5（主要开发阶段）GPT-5.2 Codex（测试修复阶段）3. 背景介绍A. MiniJinja 简介MiniJinja 是 Jinja2 模板引擎的 Rust 重新实现版本。Armin Ronacher 最初编写它是为了在 Rust 中进行基础设施自动化项目，虽然原项目没有继续，但 MiniJinja 本身对作者和其他用户都很有用。B. 测试机制MiniJinja 使用快照测试进行验证，通过 insta 工具比较输入和预期输出。这些快照测试成为验证 Go 移植版本的重要依据。三、详细报道1. 移植策略A. 测试驱动方法初始提示要求 Agent 确定如何验证移植。通过对话，作者与 Agent 达成一致路径：复用现有的 Rust 快照测试，逐步移植（词法分析器 → 语法分析器 → 运行时）。Agent 构建了 Go 端工具链：解析 Rust 测试输入文件（嵌入 JSON 配置头）解析参考 insta 快照文件并比较输出维护跳过列表以暂时排除失败的测试这形成了一个紧凑的反馈循环：Agent 有明确目标（让所有测试通过）和清晰的进度路径。graph LR A[Rust 快照测试] --> B[Go 测试工具] B --> C[词法分析器] C --> D[语法分析器] D --> E[运行时] E --> F[所有测试通过]B. Pi 的分支功能作者使用 Pi 的分支功能将会话结构化为不同阶段。通过回滚到较早部分并使用分支切换功能，自动告知 Agent 已完成的工作。分支切换时做两件事：保持在同一会话中，但从较早消息创建新分支切换时，将已完成的工作摘要作为引导消息添加到分支点这避免了 Agent 重新从头开始探索进度。C. 从字面移植到行为移植有趣的是，Agent 很快从字面移植转向行为移植。作者没有阻止这种转变，只要行为保持一致。原因有两个：代码库不大，必要时可以在最后调整这样更符合 Go 语言习惯例如，在运行时方面：实现了树遍历解释器（而非 Rust 的字节码解释器）决定使用 Go 的反射来实现值类型这些是 Agent 自主决定的，但比复制 Rust 解释器设计更合理（Rust 设计部分原因是缺乏垃圾回收器和运行时类型信息）。2. 需要人工干预的情况A. 错误消息处理Agent 完全放弃了所有必须失败的测试，因为运行时差异导致无法完美复制错误消息。作者引导它改用模糊匹配。B. 行为回归Agent 想要回退作者想保留的行为（如精确的 HTML 转义语义，或 range 必须返回迭代器）。如果没有引导，Agent 可能无法完成，或者作者会对结果失去信心。3. 完整覆盖的攻坚阶段修复主要语义不匹配后，剩余工作是填补所有缺失部分：缺失的过滤器、测试函数、循环扩展、宏、调用块等。作者切换到 Codex 5.2，排队提交几个继续让测试通过的提示，然后让它通过压缩独立工作。一旦基础覆盖完成，作者确信 Agent 可以在没有指导的情况下让剩余测试通过。这个阶段在无人监督的情况下通宵运行。4. 最终清理功能收敛后，作者要求 Agent：记录内部函数重新组织（如将过滤器移到单独文件）记录所有函数和过滤器（类似 Rust 代码库）此时设置了 CI、发布流程，并讨论创建的内容以进行最后的完善，然后合并。sequenceDiagram participant H as 人工 participant A as AI Agent participant R as Rust 代码 participant G as Go 代码 participant T as 测试 H->>A: 提供高层指导 A->>R: 分析现有代码 A->>G: 编写 Go 实现 A->>T: 运行快照测试 T-->>A: 测试结果 A->>G: 修复失败 H->>A: 纠正行为偏差 G-->>H: 最终代码四、影响分析1. 行业影响A. 技术选择不再受限这类移植现在已经可行。虽然几个月前移植已经可能，但需要更多关注。这种情况改变了某些动态。作者感觉技术选择不再受生态系统锁定约束。B. 代码价值转移价值正从代码本身转向测试和文档。一个好的测试套件可能比代码本身更有价值。不过，这不是保守测试秘密的理由——生成良好覆盖的测试也变得越来越容易。2. 移植可能性评估简单库：完全可行中等复杂度：如 MiniJinja，可行高度优化库：如 NumPy 移植到 Go 会更复杂，使其具有竞争力甚至更困难（多年优化积累）但总的来说，感觉现在可以使用更多库了。3. 社会动态变化过去有人将你的代码移植到其他语言是值得骄傲的事情。这是成就的标志——项目足够酷，有人花时间让它在其他地方可用。有了 Agent，它不再引起同样的感觉。Will McGugan 也指出了这种变化。五、各方反应1. 相关资源PR #854：MiniJinja Go 移植的 Pull RequestPi 会话记录：完整的 Agent 交互记录视频演示：移植过程的旁白视频2. 技术社区反馈Will McGugan 在 Bluesky 上指出，Agent 改变了代码移植带来的社会意义——从致敬行为变成了技术可行性的展示。六、关键经验总结1. 成功因素完善的测试套件是移植成功的基础测试驱动方法提供了清晰的进度指标适度的人工引导确保了方向正确从字面移植到行为移植的灵活性提高了代码质量2. 成本效益60 美元 API 成本45 分钟人工时间相比手动移植数小时到数天的工作量，效率提升显著3. 未来展望跨语言库的同步需要共享测试，否则不可避免地会出现分歧AI Agent 使得技术选型不再受限于语言生态代码的价值正在向测试和文档转移参考资料Porting MiniJinja to Go With an Agent
Astral 加入 OpenAI一、新闻概述1. 标题Astral 宣布加入 OpenAI，Ruff 和 uv 等工具将继续开源2. 发布时间2025 年（具体日期未在原文中注明）3. 来源Astral 官方博客二、核心内容1. 事件摘要A. 主要内容Astral 公司宣布已达成协议加入 OpenAI，成为 Codex 团队的一部分。B. 核心亮点Astral 被 OpenAI 收购，加入 Codex 团队开源工具 Ruff、uv、ty 将继续维护每月下载量达数亿次承诺继续保持开源2. 关键信息A. 涉及产品Ruff：Python 代码检查工具uv：Python 包管理工具ty：类型检查工具B. 重要数据月下载量：数亿次公司成立时间：约 3 年投资方：Accel（种子轮和 A 轮）、a16z（B 轮）C. 收购方OpenAI Codex 团队3. 背景介绍A. 公司历史Astral 由 Charlie Marsh 创立，致力于改变 Python 开发体验。三年前的发布文章中提到："如果能让 Python 生态系统生产力提高 1%，想象一下这种影响会如何复合增长。"B. 相关上下文Astral 开发的工具链已成为现代 Python 开发的基础设施。Ruff 作为快速的 Python linter，uv 作为极速的 Python 包管理器，在开发者社区中广受欢迎。三、详细报道1. 主要内容A. 收购详情Astral 团队将加入 OpenAI 的 Codex 团队收购完成后将继续支持开源工具保持与社区共同构建的开发模式B. 开源承诺所有工具将继续开源继续为 Python 生态系统构建工具与 OpenAI 的开源理念一致C. 未来规划继续维护现有开源工具探索与 Codex 的集成方式更广泛地思考软件开发未来2. 技术细节A. Astral 工具链架构graph LR Dev[开发者] --> Ruff[Ruff 代码检查] Dev --> uv[uv 包管理] Dev --> ty[ty 类型检查] Ruff --> Code[高质量代码] uv --> Env[快速环境] ty --> Type[类型安全]B. 工具特点Ruff：用 Rust 编写的极速 Python linteruv：用 Rust 编写的极速 Python 包管理器ty：类型检查工具C. OpenAI Codex 集成展望Astral 工具与 Codex 的无缝集成AI 辅助编程工具链增强提升软件开发生产力3. 数据与事实A. 用户规模月下载量达数亿次工具已成为 Python 开发基础设施B. 投资情况Accel 领投种子轮和 A 轮a16z 领投 B 轮C. 社区影响拥有全球用户基础被称为"最受喜爱的软件之一"四、影响分析1. 行业影响A. 技术趋势AI 与开发工具的深度融合开源工具在 AI 时代的重要性Rust 编写的工具在开发者工具领域的崛起B. 竞争格局OpenAI 加强开发工具领域布局Python 开发工具进入 AI 辅助新阶段可能推动其他厂商类似投资2. 用户影响A. 现有用户工具将继续免费开源功能持续改进可能获得 AI 增强功能B. 潜在用户更易接触 AI 辅助开发工具Python 开发体验提升C. 迁移成本无需迁移，工具保持不变可选的新 AI 功能3. 技术趋势A. 技术方向AI 与传统开发工具的边界模糊开源与商业模式的结合探索开发者工具进入新纪元B. 生态影响Python 生态系统持续繁荣开发工具标准化加速AI 辅助编程成为标配五、各方反应1. 官方回应Astral 创始人 Charlie Marsh 表示："AI 正在快速改变我们构建软件的方式，这种变化的步伐只会加速。如果我们的目标是让编程更高效，那么在 AI 和软件的前沿领域构建就感觉是最有杠杆作用的事情。"2. OpenAI 官方声明OpenAI 在其公告中确认将继续支持 Astral 的开源工具。3. 社区反馈A. 正面期待开源承诺获得社区认可期待与 AI 的结合创新B. 关注点收购后产品独立性未来商业化策略六、相关链接1. 官方公告Astral 官方博客公告OpenAI 收购公告2. 项目链接Ruff GitHub 仓库uv GitHub 仓库ty GitHub 仓库参考资料Astral to join OpenAI
Folio-OCR 三栏文档 OCR 工作台一、概述1. 简介A. 是什么Folio-OCR 是一款基于 GLM-OCR 和 Ollama 的三栏文档 OCR 工作台，专为书籍和文档的日常批量识别设计。它提供了一个现代化的 Web 界面，支持图片和 PDF 文件的批量光学字符识别，并具备智能版面分析、实时编辑和多种格式导出功能。B. 为什么学解决文档数字化过程中的人工识别效率问题利用本地化 OCR 方案保护数据隐私学习 FastAPI 前后端分离架构和版面分析技术了解如何将大型语言模型集成到实际应用中C. 学完能做什么搭建本地化的 OCR 识别服务批量处理 PDF 和图片文档使用版面分析技术提高识别准确率将识别结果导出为 Markdown、TXT 或 Word 文档2. 前置知识A. 必备技能基础的 Linux 命令行操作了解 Docker 基础概念B. 推荐知识Python 基础编程知识Web 开发基础概念OCR 和版面分析基础二、环境准备1. 系统要求操作系统：Linux、macOS、Windows 10/11Docker：20.10+（推荐使用 Docker 部署）Python：3.10+（本地部署）Ollama：已安装（本地部署）硬件：建议 8GB+ 内存，有 NVIDIA 显卡可获得更好性能2. 安装步骤Docker 部署（推荐）# 1. 克隆项目 git clone https://github.com/vorojar/Folio-OCR.git cd Folio-OCR # 2. 启动服务 docker compose up -d # 3. 下载 OCR 模型（约 2GB，只需执行一次） docker compose exec ollama ollama pull glm-ocr本地部署# 安装依赖 pip install -r requirements.txt # 拉取模型 ollama pull glm-ocr # 启动服务 python server.py # Windows 一键启动 start.bat3. 验证安装打开浏览器访问 http://localhost:3000，若能看到界面则表示安装成功。# 检查 Ollama 状态 curl http://localhost:11434/api/tags # 检查服务状态 curl http://localhost:3000/api/status三、核心概念1. 基本术语GLM-OCR：智谱 AI 开发的 OCR 模型，用于图像文字识别Ollama：本地化大模型运行平台，提供 GLM-OCR 的推理服务FastAPI：Python Web 框架，用于构建后端 APIPP-DocLayoutV3：PaddlePaddle 的文档版面分析模型SQLite：轻量级数据库，用于持久化存储文档和 OCR 结果版面分析：自动检测文档中的标题、正文、表格、图片等区域2. 工作原理graph LR User[用户] --> FE[前端界面] FE --> API[FastAPI 后端] API --> DB[(SQLite 数据库)] API --> Layout[版面分析模型] API --> Ollama[Ollama OCR 服务] Layout --> API Ollama --> API API --> FE API --> Storage[文件存储]系统采用三层架构设计：前端层：提供三栏式用户界面，负责文件上传、结果显示和用户交互后端层：FastAPI 提供 RESTful API，处理版面分析、OCR 调用和数据持久化服务层：Ollama 提供 OCR 推理服务，PP-DocLayoutV3 提供版面分析能力四、快速上手1. 基本使用流程graph TD A[启动服务] --> B[上传文档] B --> C[自动拆页处理] C --> D[版面分析] D --> E[OCR 识别] E --> F[编辑校对] F --> G[导出文档]2. 上传文档支持以下文件格式：图片：PNG、JPG、GIF、BMP文档：PDF支持多文件混合上传，系统会自动将所有文件合并为一个文档，并按页码顺序排列。3. OCR 识别系统提供两种 OCR 模式：单页识别：对选中的页面进行 OCR批量识别：点击 OCR All Pages 一键处理全部页面识别过程中会显示实时进度条和 ETA 时间估算，用户可以随时点击 Stop 按钮中断处理。4. 编辑与导出识别结果支持：Edit 模式：纯文本编辑，便于手动修正Preview 模式：实时渲染 HTML 表格和 Markdown 格式段落重排：自动合并因换行断开的段落导出格式：Markdown（.md）纯文本（.txt）Word 文档（.docx）五、核心功能1. OCR 引擎A. 版面分析使用 PP-DocLayoutV3 模型进行智能版面分析，自动识别以下区域：标题（title）正文（text）表格（table）图片（figure）页眉页脚、脚注、页码（自动跳过）B. 智能合并相邻文本区域会自动合并，减少 OCR 调用次数。例如 11 个文本区域可合并为 3 组，实现约 2.5 倍加速。C. LaTeX 处理自动将模型输出的 LaTeX 符号转换为 Unicode 字符：$\textcircled{1}$ → ①$\frac{1}{2}$ → ½其他常见数学符号D. 清理处理自动清理模型输出的 Markdown 围栏标记。2. 数据持久化使用 SQLite 数据库存储以下信息：文档元数据（ID、文件名、创建时间）页面信息（页码、文件名、OCR 结果、版面区域、处理时间）自动保存编辑内容（800ms 防抖）3. 界面交互A. 三栏布局左栏：页面缩略图，支持快速切换页面中栏：图片预览，显示版面分析区域框右栏：OCR 结果，支持编辑和预览B. 双向高亮点击图片中的区域框会高亮对应的文本块，点击文本块会高亮对应的图片区域。C. 全文搜索支持 Ctrl+F 全文搜索，跨页高亮显示匹配内容并统计命中次数。D. 键盘导航使用 ↑↓ 方向键快速切换页面。4. 网络容错所有网络请求都带有超时保护：状态检查：5 秒OCR 调用：180 秒其他请求：30 秒Ollama 断开后 UI 不会冻结，超时后会自动恢复可操作状态并通过 Toast 弹窗通知用户。六、技术架构1. 后端架构graph TB subgraph 后端服务 API[FastAPI Server] DB[(SQLite)] Layout[PP-DocLayoutV3] Uploads[uploads/ 目录] end subgraph 外部服务 Ollama[Ollama GLM-OCR] end API --> DB API --> Layout API --> Uploads API --> Ollama2. 版面分析流程sequenceDiagram participant U as 用户 participant API as FastAPI participant L as Layout 模型 participant O as Ollama U->>API: 上传图片 API->>L: 版面分析 L-->>API: 返回区域列表 API->>API: 合并相邻区域 loop 对每个合并区域 API->>O: OCR 调用 O-->>API: 返回识别文本 end API->>U: 返回完整结果3. 数据库设计erDiagram documents ||--o{ pages : 包含 documents { string doc_id PK string filename string created_at } pages { string doc_id FK integer num string filename text ocr_text text ocr_regions real ocr_time }4. 主要依赖依赖版本用途fastapi>=0.100.0Web 框架uvicorn>=0.23.0ASGI 服务器httpx>=0.25.0异步 HTTP 客户端pymupdf>=1.23.0PDF 处理Pillow>=10.0.0图像处理transformers>=4.40.0版面分析模型torch>=2.0.0深度学习框架python-docx>=1.1.0Word 文档生成七、部署架构1. Docker Compose 配置graph LR Host[宿主机] --> LB[Nginx/Proxy] LB --> App[App 容器] LB --> Ollama[Ollama 容器] App --> DB[(SQLite 数据卷)] App --> Files[uploads 数据卷]2. GPU 加速若有 NVIDIA 显卡，可编辑 docker-compose.yml 取消 deploy 段落的注释以启用 GPU 加速。services: ollama: deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu]3. 常用 Docker 命令docker compose down # 停止服务 docker compose up -d # 重新启动（数据不会丢失） docker compose logs -f app # 查看应用日志 docker compose logs -f ollama # 查看 Ollama 日志八、性能参考操作时间说明模型冷启动首次请求~50 秒需加载模型到内存后续单页识别~0.5 秒版面分析 + OCRPDF 渲染取决于页数2x 缩放矩阵渲染整体加速比2.5x相比逐区域 OCR九、常见问题1. 安装问题Ollama 未找到错误信息：Ollama not found解决方法：先安装 Ollama 并确保其在 PATH 中# macOS/Linux curl -fsSL https://ollama.com/install.sh | sh # Windows # 从 https://ollama.com/download 下载安装包模型下载失败解决方法：检查网络连接，手动执行模型拉取ollama pull glm-ocr2. 运行问题OCR 超时可能原因：图片过大或网络问题解决方法：系统已设置 180 秒超时，等待即可检查 Ollama 服务是否正常运行尝试重启服务版面分析失败可能原因：模型未正确加载解决方法：确保已安装 torch 和 transformers检查服务器日志查看具体错误3. 使用问题PDF 拆页不清晰说明：系统使用 2x 缩放矩阵渲染 PDF 以保证 OCR 质量解决方法：如需更高分辨率，可修改 server.py 中的 mat 参数导出的 Word 文档格式问题说明：DOCX 导出基于 python-docx，解析 OCR 结果中的表格和标题解决方法：识别时确保版面分析正确检测到表格区域十、项目结构Folio-OCR/ ├── server.py # FastAPI 后端（单文件） ├── index.html # HTML 页面 ├── script.js # 前端逻辑 ├── style.css # 样式 ├── latex_unicode.json # LaTeX → Unicode 映射表 ├── requirements.txt # Python 依赖 ├── Dockerfile # Docker 镜像构建 ├── docker-compose.yml # Docker Compose 编排 ├── start.bat # Windows 启动脚本 ├── folio_ocr.db # SQLite 数据库（运行时生成） └── uploads/ # 上传文件目录（运行时生成）十一、API 端点方法路径说明GET/前端页面GET/api/status服务状态、Ollama 连通性POST/api/load-model启动 Ollama 并预热模型POST/api/upload上传文件，返回 SSE 页面流GET/api/images/{doc_id}/{filename}获取页面图片POST/api/ocr/{doc_id}/{page_num}单页 OCRPOST/api/ocr/{doc_id}/all批量 OCR 全部页面GET/api/documents列出所有文档GET/api/documents/{doc_id}获取文档详情DELETE/api/documents/{doc_id}删除文档PUT/api/pages/{doc_id}/{page_num}/text保存编辑后的文本POST/api/export/{doc_id}导出 DOCX参考资料Folio-OCR GitHub 仓库GLM-OCR 模型Ollama 官方文档FastAPI 官方文档PP-DocLayoutV3 模型
Axe CLI 工具指南一、概述1. 简介A. 是什么Axe 是一个轻量级的命令行工具，用于运行单用途的 AI 代理。它使用 TOML 配置文件定义代理行为，支持多个 AI 提供商，包括 Anthropic、OpenAI 和 Ollama（本地模型）。B. 为什么学简化 AI 代理的创建和部署流程支持代码版本控制和团队协作提供持久化内存和技能系统支持 MCP（Model Context Protocol）工具扩展C. 学完能做什么使用 TOML 文件定义和管理 AI 代理配置多提供商支持实现代理间的委托调用使用 Docker 容器化部署集成外部 MCP 工具2. 前置知识A. 必备技能基本 Linux 命令行操作了解 TOML 配置文件格式熟悉 Git 版本控制B. 推荐知识Docker 容器基础概念AI API 使用经验MCP 协议基础二、环境准备1. 系统要求Linux、macOS 或 WindowsGo 1.21+（源码编译）Docker（可选，用于容器化部署）2. 安装步骤使用 Homebrew 安装（推荐）：brew install jrswab/tap/axe使用 Go 安装：go install github.com/jrswab/axe@latestDocker 方式：docker pull ghcr.io/jrswab/axe:latest3. 验证安装axe --version axe --help三、核心概念1. 基本术语Agent（代理）：AI 实体，执行特定任务Skill（技能）：可复用的指令集Memory（内存）：持久化的对话历史MCP：Model Context Protocol，工具扩展协议Provider（提供商）：AI 模型服务提供商2. 工作原理graph TB subgraph "配置层" A[agents/*.toml 代理定义] B[skills/SKILL.md 技能指令] C[config.toml 凭证配置] end subgraph "执行层 - Axe CLI" D[运行命令解析] E[上下文构建] F[工具调用] end subgraph "提供商层" G[Anthropic API] H[OpenAI API] I[Ollama 本地模型] end subgraph "存储层" J[持久化内存 timestamped logs] K[工作目录 sandboxed] end A --> D B --> E C --> D D --> E E --> F F --> G F --> H F --> I F --> K J --> E L[stdin 管道输入] --> D M[cron/git hooks] --> D3. 配置目录结构默认配置目录为 $XDG_CONFIG_HOME/axe/，通常为：Linux：~/.config/axe/macOS：~/Library/Application Support/axe/目录结构：~/.config/axe/ ├── agents/ │ └── *.toml # 代理定义文件 ├── skills/ │ └── SKILL.md # 技能指令文件 ├── config.toml # 凭证配置 └── memory/ # 持久化内存日志四、快速上手1. Hello World 示例首先创建配置文件 ~/.config/axe/config.toml：[anthropic] api_key = "your_anthropic_api_key"创建代理定义 ~/.config/axe/agents/greeting.toml：name = "greeting" model = "claude-3-haiku-20240307" provider = "anthropic" [system] prompt = "你是一个友好的助手，用中文回答问题。" [max_tokens] input = 10000 output = 4096运行代理：axe run greeting "你好，请介绍一下自己"2. 核心功能演示管道输入支持：echo "解释这个代码的作用" | axe run coder < main.pyGit hook 集成：axe hook install pre-commit axe hook list axe hook remove pre-commit列出可用代理：axe list3. 代码讲解代理定义说明：name：代理标识符，用于 axe run 命令model：使用的基础模型名称provider：AI 提供商（anthropic、openai、ollama）system.prompt：系统提示词max_tokens：输入输出 token 限制五、进阶内容1. 常用功能子代理委托代理可以调用其他代理，通过深度限制防止无限循环：name = "analyst" model = "claude-3-haiku-20240307" provider = "anthropic" [delegates] max_depth = 3 allow = ["coder", "researcher"]技能系统创建可复用的技能指令 ~/.config/axe/skills/coder/SKILL.md：# 代码审查技能 你是一位资深代码审查专家。审查时请： 1. 检查代码风格一致性 2. 识别潜在 bug 3. 建议性能优化 4. 评估安全性 输出格式： - 问题清单 - 改进建议 - 优先级标注在代理中使用技能：[skills] include = ["coder", "researcher"]持久化内存Axe 自动维护时间戳标记的内存日志，支持垃圾回收：[memory] enabled = true max_age = "30d" # 30 天后自动清理 max_size = "1GB" # 最大存储限制MCP 工具集成配置 MCP 服务器连接：[mcp] mcp.servers name = "filesystem" command = "npx" args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"] mcp.servers name = "github" command = "npx" args = ["-y", "@modelcontextprotocol/server-github"] env = { GITHUB_TOKEN = "your_github_token" }2. 最佳实践使用版本控制管理代理配置为不同环境创建不同的代理限制代理调用深度避免无限循环定期清理内存日志使用环境变量存储敏感信息3. 性能优化选择合适的模型平衡速度和质量使用本地 Ollama 模型减少延迟限制输入 token 大小缓存常用查询结果六、Docker 部署1. 场景描述将 Axe 容器化部署，确保环境隔离和可移植性。2. 实现步骤拉取镜像：docker pull ghcr.io/jrswab/axe:latest创建 Dockerfile 自定义构建：FROM ghcr.io/jrswab/axe:latest # 添加自定义配置 COPY config.toml /app/config.toml COPY agents/ /app/agents/ COPY skills/ /app/skills/ # 运行 ENTRYPOINT ["/app/axe"]运行容器：docker run -it \ -v ~/.config/axe:/app/config \ ghcr.io/jrswab/axe:latest \ run greeting "你好"使用 Docker Compose 编排：version: '3.8' services: axe: image: ghcr.io/jrswab/axe:latest volumes: - ./config:/app/config - ./agents:/app/agents - ./skills:/app/skills environment: - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} command: ["run", "coder", "review my code"]3. 安全加固使用只读挂载限制容器资源使用非 root 用户运行定期更新镜像七、常见问题1. 安装问题问题：Homebrew 无法安装解决：使用 Go 安装或 Docker 方式go install github.com/jrswab/axe@latest export PATH=$PATH:$(go env GOPATH)/bin2. 配置问题问题：API 密钥验证失败解决：检查 config.toml 格式和密钥有效性[anthropic] api_key = "sk-ant-xxx" [openai] api_key = "sk-xxx" [ollama] base_url = "http://localhost:11434"3. 运行问题问题：代理响应超时解决：调整超时设置或使用更快的模型[timeout] request = "60s" connect = "10s"八、参考资料参考资料Axe CLI GitHub RepositoryAxe Documentation