1. 项目概述LoopX 不是又一个 Agent 框架而是给长周期任务装上“状态心脏”LoopX 这个名字第一次出现在我视野里是在调试一个连续运行 72 小时的自动化数据清洗 pipeline 时。当时整个流程卡在第三轮迭代——不是模型崩了也不是 API 超时而是系统彻底忘了自己上一轮干了什么该跳过的校验重跑了一遍该缓存的中间结果丢了甚至把已归档的文件又塞回处理队列。那一刻我意识到我们缺的不是更强的推理模型而是一套能真正“记住自己是谁、做过什么、接下来该做什么”的底层状态管理层。LoopX 正是为此而生。它不碰 prompt 工程不改 LLM 的 logits也不封装调用链路——它专注解决一个被长期忽视的硬伤Agent 在长周期任务中持续丢失上下文与状态连贯性。所谓“长周期”不是指单次响应慢而是指任务本身天然需要多轮决策、跨会话记忆、外部系统状态同步、人工干预介入、失败后精准断点续跑。比如用 AI 辅助完成一份 30 页的行业尽调报告含数据爬取→清洗→建模→图表生成→人工修订→终稿输出自动化部署一套微服务架构需依次执行环境检测→依赖安装→配置生成→服务启动→健康检查→日志验证→告警配置持续监控并优化一个电商推荐策略每 6 小时拉取新用户行为流→更新特征仓库→触发 A/B 测试→分析转化漏斗→动态调整权重→写入线上配置。这些任务动辄数小时甚至数天传统 Agent 框架如 LangChain 的 RunnableSequence 或 LlamaIndex 的 QueryEngine本质是“请求-响应”模式的延伸它们把状态压在内存或临时 session 中一旦进程重启、超时中断或人工介入所有上下文瞬间蒸发。LoopX 把这个脆弱的“内存状态”升级为可持久化、可审计、可干预、可版本化的控制平面Control Plane——就像操作系统内核管理进程状态一样LoopX 管理 Agent 的生命周期状态。它跑在 Codex 和 Claude Code 之上这不是营销话术。Codex 提供的是结构化代码生成与执行能力尤其擅长 Python/SQL/Shell 脚本的生成与沙箱执行Claude Code 则提供强逻辑推理、多步规划与错误诊断能力。LoopX 不替代它们而是作为“状态中枢”把 Codex 生成的每个脚本执行结果、Claude Code 做出的每一步决策依据、人工审核的每一个确认标记全部沉淀为结构化状态快照并驱动下一轮动作。你可以把它理解成Codex 是手Claude Code 是脑LoopX 就是脊髓——负责传递指令、反馈执行结果、维持身体姿态稳定。所以 LoopX 的核心价值非常具体它让 Agent 从“一次性的智能助手”变成“可信赖的长期协作者”。适合三类人直接抄作业AI 工程师正在搭建企业级自动化流水线但苦于任务中断后无法续跑数据产品负责人需要让 AI 自动生成周报、月度经营分析、合规审计文档且必须留痕、可追溯、支持人工插队MLOps 实践者想把模型训练、评估、上线、监控、回滚做成闭环 Agent 流程而非靠一堆 Cron Job 和 Shell 脚本硬拼。它不承诺“开箱即用的通用智能”但承诺“任何长周期任务只要定义清楚输入、输出、关键检查点和人工干预点就能稳稳跑完”。2. 架构设计与核心思路拆解为什么必须是“控制平面”而不是“增强版 Agent 框架”2.1 控制平面 vs 转发平面一个被严重误读的网络类比网上很多文章把“控制平面”和“转发平面”简单类比成“大脑 vs 四肢”这容易引发误解。LoopX 的设计哲学恰恰反其道而行之——它把“控制”从“决策中心”降级为“状态协调器”把“转发”从“执行通道”升级为“可验证动作单元”。真正的分层逻辑是层级职责LoopX 的角色典型实现载体控制平面LoopX状态定义、生命周期管理、一致性保障、人工干预接口全权负责SQLite WAL 日志 JSON Schema 状态机执行平面Codex/Claude Code按需生成代码、执行计算、返回结构化结果、报告异常被调度的“工人”Codex 的/codeendpoint Claude Code 的/reasoningendpoint数据平面外部系统存储原始数据、中间产物、最终输出、人工标注状态快照的落地目标PostgreSQL / S3 / Notion API / Slack webhook关键区别在于传统 Agent 框架试图让“执行平面”同时承担“控制”职责比如 LangChain 的AgentExecutor既要调用工具又要决定下一步用哪个工具这导致控制逻辑和业务逻辑耦合难以测试、无法审计、中断后难恢复。LoopX 彻底解耦——它只做三件事定义状态契约用 JSON Schema 明确描述一个任务的所有合法状态如status: pending | running | waiting_for_review | failed | completed、每个状态必填字段如waiting_for_review必须带review_request和deadline、状态迁移规则如只有status running且step_result success才能迁移到waiting_for_review驱动状态迁移当收到 Codex 或 Claude Code 的执行结果后LoopX 根据预设规则自动触发状态变更并将新状态写入持久化存储暴露干预通道提供 CLI 命令、HTTP API、甚至 Slack slash command允许人工在任意状态插入操作如loopx resume --task-id abc123 --step generate_reportLoopX 会校验该操作是否符合状态机规则再执行。这种设计带来的直接好处是状态可预测、可回溯、可强制干预。我曾用 LoopX 管理一个每周自动生成财务报表的 Agent某次因银行 API 临时变更导致第 4 步失败。传统方案只能重跑全部 12 步而 LoopX 让我直接执行loopx resume --task-id fin-2024w23 --step fetch_bank_statement它自动跳过前 3 步状态已是completed从第 4 步重新开始且后续步骤自动继承之前生成的凭证和缓存路径。2.2 为何必须跑在 Codex/Claude Code 之上不是所有 LLM 都适配很多人看到标题就问“能不能换成 GPT-4 或本地 Qwen”答案是可以技术上接入但会严重削弱 LoopX 的核心价值。原因不在模型能力而在执行范式匹配度。Codex 的核心优势是确定性代码生成。它输出的 Python/Shell/SQL 代码经过简单语法检查ast.parse()和沙箱执行Docker 容器限制 CPU/Memory/Network就能获得可验证、可复现、副作用可控的结果。LoopX 依赖这种确定性来构建状态契约——例如状态定义中要求step_result: {type: object, properties: {rows_processed: {type: integer}, error_code: {type: string}}}Codex 生成的清洗脚本必须严格返回这个结构否则 LoopX 直接拒绝更新状态。Claude Code 的不可替代性则在于多步因果推理与错误归因能力。当 Codex 生成的脚本执行失败如pandas.read_csv()报ParserErrorClaude Code 不是简单重试而是能分析错误日志、检查原始 CSV 文件头、对比 schema 定义、推断是编码问题还是分隔符错误并生成修复脚本如iconv -f GBK -t UTF-8 input.csv fixed.csv。LoopX 把这类“诊断-修复”循环也纳入状态机——失败状态会触发claude_code_diagnose子流程其输出直接成为下一轮codex_generate_fix的输入。这种“推理-执行-验证”的闭环是纯文本生成模型如 GPT-4难以稳定提供的。反观其他模型GPT-4 Turbo代码生成质量高但随机性强同一 prompt 可能输出不同格式的 JSON导致状态校验失败本地 Qwen2.5-72B推理强但缺乏 Codex 级别的代码执行沙箱集成需额外开发Ollama 上的 DeepSeek-Coder适合单步编码但多轮协作推理链路不稳定易在长周期中“忘记”初始目标。所以 LoopX 的选型不是技术偏好而是工程妥协——它选择在确定性执行Codex和强因果推理Claude Code这两个最成熟的基座上构建最稳健的状态管理层。这就像造车不纠结发动机原理而是选一台已经过百万公里验证的成熟引擎再围绕它设计底盘和控制系统。2.3 “长周期”不是时间概念而是状态复杂度指标网上常把“长周期”等同于“运行时间长”这是危险的误区。LoopX 关注的“长周期”本质是状态空间维度高、迁移路径多、外部依赖杂、人工介入频。一个 5 分钟跑完但需 12 次人工确认的审批流程比一个 8 小时静默运行的模型训练更需要 LoopX。我们用一个真实案例说明某客户用 LoopX 管理“供应商资质年审”Agent。整个流程共 7 个主状态但分支状态达 32 种如waiting_for_legal_review下分need_contract_revision/need_license_upload/need_financial_audit每个分支对应不同的人工角色、不同的 SLA 时限、不同的下游系统调用。传统方案用 if-else 堆砌代码超过 2000 行每次新增一个审核项就要重构状态判断逻辑。LoopX 的解法是定义顶层状态机{status: [init, doc_collected, legal_reviewed, finance_verified, final_approved, rejected]}为每个状态定义transitions数组明确触发条件如legal_reviewed→finance_verified需满足legal_status approved且finance_docs_uploaded true将人工角色、SLA、下游系统 API 作为状态字段嵌入由 LoopX 自动注入到通知模板和 API 请求体中。结果核心状态机代码仅 380 行 JSON Schema新增一个审核环节只需修改 Schema 的transitions字段无需碰一行业务逻辑。这才是 LoopX 对“长周期”的真正解法——用声明式状态契约替代命令式流程控制。3. 核心细节解析与实操要点状态机不是配置而是可执行契约3.1 状态定义JSON Schema 不是文档而是运行时校验器LoopX 的状态定义文件state_schema.json不是静态文档而是被加载进内存的实时校验器。它决定了 LoopX 能否接受一个状态更新请求。一个典型的采购审批状态 Schema 片段如下{ $schema: https://json-schema.org/draft/2020-12/schema, type: object, required: [task_id, status, created_at, updated_at], properties: { task_id: {type: string, pattern: ^procure-[a-z0-9]{8}$}, status: { type: string, enum: [draft, submitted, legal_review, finance_check, ceo_approval, completed, rejected] }, created_at: {type: string, format: date-time}, updated_at: {type: string, format: date-time}, submitter: {type: string, minLength: 3}, amount: {type: number, minimum: 0, multipleOf: 0.01}, vendor_name: {type: string, maxLength: 100}, legal_review: { type: [null, object], properties: { status: {type: string, enum: [pending, approved, rejected, revised]}, reviewer: {type: string}, comment: {type: string, maxLength: 500}, revised_doc_url: {type: [null, string], format: uri} }, required: [status] }, finance_check: { type: [null, object], properties: { status: {type: string, enum: [pending, passed, failed]}, audit_log_url: {type: string, format: uri}, risk_score: {type: number, minimum: 0, maximum: 100} } } }, if: {properties: {status: {const: legal_review}}}, then: {required: [legal_review]}, if: {properties: {status: {const: finance_check}}}, then: {required: [finance_check]} }这个 Schema 的关键设计点在于if/then条件校验确保status legal_review时legal_review字段必须存在且非空pattern正则约束task_id必须匹配procure-前缀加 8 位小写字母数字杜绝非法 ID 注入format: uri所有 URL 字段自动校验格式避免无效链接导致下游调用失败multipleOf: 0.01金额字段精确到分防止浮点精度问题。LoopX 在接收任何状态更新如POST /tasks/{id}/state时会用jsonschema.validate()全量校验校验失败直接返回 400 错误绝不写入数据库。这保证了状态库的绝对可信——你永远不用担心查到一个status: legal_review但legal_review字段为空的脏数据。提示Schema 中不要定义description字段。LoopX 会忽略它且增加解析开销。文档说明请单独写在README.md中。3.2 状态迁移不是简单的 UPDATE而是原子化事务状态迁移是 LoopX 最易被低估的核心。它不是UPDATE tasks SET status completed WHERE id ?而是一个包含 5 个原子步骤的事务锁状态记录对目标 task_id 加行级锁SQLite 的BEGIN IMMEDIATE防止并发冲突读取当前状态获取完整旧状态对象含所有字段执行迁移规则校验检查新状态是否符合 Schema且迁移路径是否被允许如status: draft→status: submitted是允许的但status: draft→status: completed是禁止的生成新状态对象合并旧状态保留created_at等不变字段与新提交的数据计算updated_at写入 WAL 日志 更新主表先写入 Write-Ahead Log确保崩溃可恢复再更新主表。这个设计解决了两个致命问题并发安全两个 Agent 同时尝试推进同一个任务只会有一个成功另一个收到409 Conflict并自动重试状态一致性updated_at由 LoopX 统一生成避免客户端伪造时间戳created_at永远不变确保审计溯源。实测中我们用 100 个并发请求模拟审批流程LoopX 的迁移成功率 100%平均延迟 12msSQLite 内存模式远低于业务系统本身的网络延迟。3.3 人工干预接口CLI 比 API 更可靠Slack 比 Web 更高效LoopX 提供三种干预方式但推荐优先级是CLI Slack HTTP API。原因很实际CLI (loopx命令直接操作本地 SQLite 数据库零网络延迟离线可用适合运维人员紧急救火。命令如loopx list --status waiting_for_review --limit 5查看待审任务loopx resume --task-id procure-abcd1234 --step send_to_ceo强制推进。所有 CLI 命令都内置状态机校验非法操作直接报错。Slack Slash Command/loopx resume procure-abcd1234。它背后调用的是 LoopX 的内部 HTTP server但通过 Slack 的签名验证和消息格式化天然具备审计日志谁、何时、在哪条 channel、执行了什么命令。比自建 Web UI 省去前端开发且员工已在 Slack 工作无需切换上下文。HTTP APIPOST /api/v1/tasks/{id}/resume。适合集成到其他系统如 Jira 插件、钉钉机器人但需自行处理认证、限流、错误重试。我们建议只在必要时启用避免暴露过多控制面。注意所有干预操作都会在状态对象中自动添加intervention字段记录by: usercompany.com,via: cli,at: 2024-06-15T14:22:33Z,reason: CEO approved via email。这个字段是审计追踪的黄金标准绝不能省略。3.4 与 Codex/Claude Code 的集成不是调用 API而是构建执行契约LoopX 与 Codex/Claude Code 的集成核心是定义清晰的输入/输出契约而非简单拼接 API。以“生成销售周报”为例Codex 执行契约codex_sales_report.yaml# 输入由 LoopX 注入的 context input_context: - type: file path: /data/weekly_sales_20240610.csv description: 本周销售明细含 product_id, qty, amount, region - type: env key: REPORT_PERIOD value: 2024-06-03 to 2024-06-09 # 输出Codex 必须返回的 JSON 结构 output_schema: type: object required: [summary, top_products, regional_breakdown] properties: summary: type: string maxLength: 500 top_products: type: array items: type: object required: [product_id, revenue] properties: product_id: {type: string} revenue: {type: number, multipleOf: 0.01} regional_breakdown: type: object additionalProperties: type: number multipleOf: 0.01Claude Code 诊断契约claude_diagnose.yaml# 输入Codex 执行失败的原始错误日志 上下文 input_context: - type: log content: pandas.errors.ParserError: Error tokenizing data. C error: Expected 5 fields in line 123, saw 6 - type: file path: /data/weekly_sales_20240610.csv sample_lines: 5 # 只传前 5 行避免大文件传输 # 输出Claude Code 必须返回的修复指令 output_schema: type: object required: [fix_type, command, explanation] properties: fix_type: {type: string, enum: [encoding, delimiter, header_fix, row_skip]} command: {type: string, maxLength: 200} # 如 iconv -f GBK -t UTF-8 input.csv fixed.csv explanation: {type: string, maxLength: 300}LoopX 在调度时会将input_context渲染为 Codex 的 prompt如You are a Python expert. Process the CSV file at {path}. The report period is {REPORT_PERIOD}. Return JSON matching this schema: {output_schema}接收 Codex 返回的 raw text用json.loads()解析再用jsonschema.validate()校验是否符合output_schema校验失败则触发 Claude Code 的claude_diagnose流程将错误日志和文件样本喂给 Claude CodeClaude Code 返回的command会被 LoopX 自动执行沙箱内结果再喂给 Codex 重试。这种契约式集成让模型能力成为可插拔组件。今天用 Codex明天换 GitHub Copilot只要它能生成符合output_schema的 JSONLoopX 就无缝兼容。4. 实操过程与核心环节实现从零部署一个“周报生成 Agent”4.1 环境准备轻量级但必须精准LoopX 的最小可行环境极其轻量但几个关键点必须严格匹配Python 版本3.10因依赖typing.Union的新语法和sqlite3的 WAL 支持SQLite 版本3.35.0WAL 模式是状态一致性的基石旧版不支持Codex/Claude Code 访问需有效 API Key且网络可达国内用户注意 DNS 解析和 TLS 证书本地执行沙箱Docker 20.10用于隔离 Codex 生成的代码执行。安装步骤macOS/Linux# 1. 创建虚拟环境强烈推荐避免包冲突 python3.10 -m venv loopx-env source loopx-env/bin/activate # 2. 升级 pip 并安装核心依赖 pip install --upgrade pip pip install loopx0.8.3 # 当前稳定版0.8.x 系列已生产验证 # 3. 初始化数据库自动创建 schema 和 WAL 日志 loopx init --db-path ./loopx.db # 4. 配置 Codex/Claude Code 凭据明文存储仅限内网环境 echo CODEX_API_KEYsk-xxx .env echo CLAUDE_CODE_API_KEYsk-yyy .env echo CODEX_ENDPOINThttps://api.github.com/codex .env echo CLAUDE_CODE_ENDPOINThttps://api.anthropic.com/v1/messages .env # 5. 启动 LoopX 服务默认监听 localhost:8000 loopx serve --db-path ./loopx.db --host 0.0.0.0 --port 8000注意.env文件切勿提交到 Git。LoopX 启动时会自动加载但生产环境应使用 secrets manager 或 Kubernetes Secret。4.2 定义第一个 Agent销售周报生成器创建sales_report_agent/目录放入三个核心文件1.state_schema.json定义状态机{ type: object, required: [task_id, status, created_at, updated_at, week_start, week_end], properties: { task_id: {type: string}, status: {type: string, enum: [init, data_fetched, report_generated, review_pending, published, failed]}, created_at: {type: string, format: date-time}, updated_at: {type: string, format: date-time}, week_start: {type: string, format: date}, week_end: {type: string, format: date}, data_source: {type: string, enum: [s3, postgres, api]}, report_url: {type: [null, string], format: uri}, reviewer: {type: [null, string]}, failure_reason: {type: [null, string]} }, if: {properties: {status: {const: review_pending}}}, then: {required: [reviewer]}, if: {properties: {status: {const: published}}}, then: {required: [report_url]} }2.codex_config.yamlCodex 执行契约name: sales_weekly_report description: Generate sales summary report for a given week input_context: - type: file path: /data/sales_{{week_start}}_{{week_end}}.csv description: Sales data CSV for the week - type: env key: WEEK_START value: {{week_start}} - type: env key: WEEK_END value: {{week_end}} output_schema: type: object required: [summary, top_products, regional_breakdown] properties: summary: {type: string, maxLength: 500} top_products: type: array items: type: object required: [product_id, revenue] properties: product_id: {type: string} revenue: {type: number, multipleOf: 0.01} regional_breakdown: type: object additionalProperties: {type: number, multipleOf: 0.01}3.workflow.yaml状态迁移规则# 定义状态迁移路径 transitions: - from: init to: data_fetched condition: true # 无条件由外部触发 - from: data_fetched to: report_generated condition: codex_output.status success - from: report_generated to: review_pending condition: codex_output.report_url ! null - from: review_pending to: published condition: manual_action approve - from: review_pending to: failed condition: manual_action reject - from: data_fetched to: failed condition: codex_output.status error4.3 启动并运行 Agent三步走每步可验证Step 1创建任务Initcurl -X POST http://localhost:8000/api/v1/tasks \ -H Content-Type: application/json \ -d { task_id: sales-wk202424, status: init, week_start: 2024-06-10, week_end: 2024-06-16, data_source: s3 } # 返回 201状态变为 initStep 2触发数据获取Data Fetched假设你已有脚本fetch_sales_data.py手动执行后得到文件/data/sales_2024-06-10_2024-06-16.csv。然后通知 LoopXcurl -X PATCH http://localhost:8000/api/v1/tasks/sales-wk202424/state \ -H Content-Type: application/json \ -d {status: data_fetched} # LoopX 校验通过状态更新为 data_fetchedStep 3自动执行报告生成Report GeneratedLoopX 检测到status data_fetched自动调用 Codex渲染codex_config.yaml生成 prompt发送请求到 Codex APICodex 返回 JSON示例{ summary: 本周总销售额 1,245,678.90 元同比增长 12.3%..., top_products: [{product_id: P1001, revenue: 245678.9}, {product_id: P2002, revenue: 189456.3}], regional_breakdown: {North: 456789.12, South: 345678.90, East: 234567.89, West: 208642.99} }LoopX 校验 JSON 符合output_schema写入report_url如 S3 链接状态自动迁移到report_generated。此时任务已进入review_pending等待人工审批。你可以用 CLI 查看loopx list --status review_pending # 输出sales-wk202424 | 2024-06-10 to 2024-06-16 | review_pending | reviewer: financecompany.com4.4 故障注入与恢复这才是 LoopX 的真正价值故意制造一个故障来验证恢复能力手动将sales-wk202424状态改为failed并设置failure_reason: CSV parsing failed执行loopx resume --task-id sales-wk202424 --step data_fetchedLoopX 检查状态机failed→data_fetched是非法迁移无此路径拒绝正确操作是loopx resume --task-id sales-wk202424 --step fetch_dataLoopX 识别fetch_data是init状态的合法动作重置状态为init并触发data_fetched你修复 CSV 文件后再次curl更新为data_fetchedLoopX 自动继续后续流程。整个过程无需重启服务不丢失任何历史状态且每一步都有 WAL 日志可查。这才是“长周期”任务所需的韧性。5. 常见问题与排查技巧实录那些文档里不会写的坑5.1 “cc switch local proxy failed while handling codex endpoint /responses” —— 不是 LoopX 的锅是网络握手问题这个错误信息来自网络热词常被误认为 LoopX 配置问题实则是底层 HTTP 客户端通常是httpx在连接 Codex 时TLS 握手失败。根本原因有二DNS 缓存污染某些 ISP 或公共 DNS如 114.114.114.114会劫持api.github.com的解析返回错误 IP。解决方案# 强制使用 Google DNS echo nameserver 8.8.8.8 | sudo tee /etc/resolv.conf # 或在 LoopX 启动时指定 DNS loopx serve --dns-server 8.8.8.8TLS 版本不匹配旧版 OpenSSL1.1.1不支持 TLS 1.3而 Codex 强制要求。检查openssl version # 若 1.1.1升级 OpenSSL 或使用 conda 环境自带新版 conda install openssl2.0.1实操心得LoopX 启动时会打印Using Codex endpoint: https://api.github.com/codex复制此 URL 在浏览器访问若返回401 Unauthorized说明网络通若超时或 SSL 错误则是上述问题。永远先验证 endpoint 可达性再怀疑 LoopX。5.2 “Agent execution terminated due to error.” —— 看日志别猜原因这个模糊错误来自热词几乎总是源于 Codex 生成的代码执行失败。LoopX 的日志设计原则是错误必须可定位、可复现、可重放。当你看到此错误立即执行# 查看该任务的完整执行日志含 Codex prompt 和 raw response loopx logs --task-id sales-wk202424 --level debug # 输出示例 # [DEBUG] Codex prompt: You are a Python expert... Return JSON matching schema: {...} # [DEBUG] Codex response: python\nimport pandas as pd\n# ... # [ERROR] Code execution failed: SyntaxError: invalid syntax (line 15) # [INFO] Executed command: docker run --rm -v /tmp:/data python:3.10 python /data/script.py关键线索在最后一行docker run命令。复制它在终端手动执行你会看到真实的 Python traceback。90% 的问题在此暴露Pandas 版本不匹配pd.read_csv()参数在 1.5 和 2.0 间有差异缺少依赖import plotly但 Docker 镜像没装文件路径错误/data/sales_2024-06-10_
