Doramagic 项目包 · 项目说明书

loopgain 项目

一个面向 AI agent 循环的开源成本控制器。

概述与核心 API

Loopgain 是一个面向 LLM 应用与自动化流水线的轻量级可观测性库,核心抽象是「漏斗(Funnel)」:在代码执行、断言校验、结构化抽取等关键节点进行非侵入式采样,并将离散的 note 事件聚合为可追溯的链路记录。库本身不绑定具体框架,可同时服务于单元测试、批处理任务与在线推理等场景。

章节 相关页面

继续阅读本节完整说明和来源证据。

项目定位与目标

Loopgain 是一个面向 LLM 应用与自动化流水线的轻量级可观测性库,核心抽象是「漏斗(Funnel)」:在代码执行、断言校验、结构化抽取等关键节点进行非侵入式采样,并将离散的 note_* 事件聚合为可追溯的链路记录。库本身不绑定具体框架,可同时服务于单元测试、批处理任务与在线推理等场景。

资料来源:README.md:1-40

包结构与导出约定

loopgain/__init__.py 作为顶层入口,将核心类直接 re-export,使调用方可以省略命名空间前缀:

  • from loopgain import Funnel:获得事件漏斗主类。
  • 包级常量(如 _ENABLED_DISABLED)定义在 loopgain/core.py 中,供生命周期内部判定使用。

资料来源:loopgain/__init__.py:1-20

底层实现位于 loopgain/core.py,负责状态常量、加载逻辑与事件入口的注册;高层封装位于 loopgain/funnel.py,将 on_initon_first_observenote_outcomenote_adapter 等方法对外暴露。两者通过共享 _mode 字段协作,构成「懒加载 + 显式启用」的状态机。

资料来源:loopgain/core.py:1-60, loopgain/funnel.py:1-40

生命周期与核心 API

Funnel 实例的生命周期可划分为四个阶段:

  • 未初始化:构造后 _mode = None,任何 note_* 调用均处于"未就绪"状态。
  • 已加载_ensure_loaded() 读取配置并完成内部状态准备。
  • 已启用on_init()_mode 置为 _ENABLED,事件入口正式开放。
  • 观察中on_first_observe() 触发首次采样,后续事件按序号累计。

核心 API 分为两类:

事件记录方法

  • note_outcome(outcome):记录最终结论(如测试通过/失败、抽取成功/失败)。
  • note_adapter(name, **meta):记录适配器层的中间载荷(原始文本、解析结果、错误信息等),用于跨链路关联。

生命周期钩子

  • on_init():将 _mode 切到 _ENABLED,是事件记录的"开门钥匙"。
  • on_first_observe():懒加载入口,触发 _ensure_loaded()
  • _ensure_loaded():内部幂等方法,确保状态在记录事件前已就绪。

资料来源:loopgain/funnel.py:note_outcome-note_adapter, loopgain/core.py:on_init-on_first_observe

⚠️ 社区关注点(Issue #1)note_outcome()note_adapter() 在判断 self._mode != _ENABLED 时,_mode_ensure_loaded() 之前为 None。若用户在 on_init() / on_first_observe() 之前调用这些方法,会因条件成立而提前 return,事件被静默丢弃且无任何告警。修复方向建议:在判定前先做 self._ensure_loaded(),或将判断改为 self._mode is None or self._mode != _ENABLED。资料来源:loopgain/funnel.py:note_outcome-note_adapter

数据流与状态迁移

flowchart LR
  A[构造 Funnel] --> B[_mode = None]
  B --> C{on_init 调用?}
  C -- 否 --> D[note_* 静默返回]
  C -- 是 --> E[_mode = _ENABLED]
  E --> F[note_outcome / note_adapter]
  F --> G[事件聚合与回溯]
  G --> H[on_first_observe 触发首次采样]

该流程图直接对应 Issue #1 描述的边界情况:只有经过 on_init 路径,事件才会被记录。

使用示例

代码生成 + pytest 场景:在 examples/01_code_pytest.py 中,Funnel 被嵌入测试函数,对生成代码的执行结果进行采样,并通过 note_outcome 上报通过/失败状态,从而在 CI 中积累可回放的回归样本。

资料来源:examples/01_code_pytest.py:1-30

结构化抽取场景examples/02_json_extract.py 演示了如何用 note_adapter 同时记录原始响应与解析对象,便于在抽取失败时进行字段级对账:

funnel.note_adapter("json_extract", raw=raw_text, parsed=obj, ok=obj is not None)

资料来源:examples/02_json_extract.py:1-30

总结

Loopgain 的核心 API 设计遵循"最小可用表面 + 显式生命周期"原则:Funnel 作为唯一入口,通过 on_init / on_first_observe 控制开关,通过 note_outcome / note_adapter 收集事件。开发者只需记住一条铁律——**在调用任何 note_* 方法之前,必须先完成 on_init()**,即可避免 Issue #1 所述的静默失败问题。后续若引入异步或并发上下文,状态机的扩展点仍位于 _ensure_loaded_mode 的协同处。

资料来源:README.md:1-40

决策引擎与轨迹分类器

LoopGain 的决策引擎与轨迹分类器负责在 Agent 执行轨迹(trajectory)的过程中,对每一步观察(observation)进行记录、标注与分类,进而为后续的策略调整、适配器选择和回放分析提供数据支撑。系统由 loopgain/core.py 中的核心控制流、loopgain/classifier.py 中的轨迹分类协议、以及 loopgain/funnel...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 分类器(Classifier)

继续阅读本节完整说明和来源证据。

章节 漏斗与观察机制(Funnel)

继续阅读本节完整说明和来源证据。

章节 核心调度(Core)

继续阅读本节完整说明和来源证据。

概述

LoopGain 的决策引擎与轨迹分类器负责在 Agent 执行轨迹(trajectory)的过程中,对每一步观察(observation)进行记录、标注与分类,进而为后续的策略调整、适配器选择和回放分析提供数据支撑。系统由 loopgain/core.py 中的核心控制流、loopgain/classifier.py 中的轨迹分类协议、以及 loopgain/funnel.py 中的漏斗观察机制共同组成,三者通过统一的 _mode 状态机协同工作。资料来源:loopgain/core.py:1-60 loopgain/classifier.py:1-40 loopgain/funnel.py:1-60

核心组件

分类器(Classifier)

classifier.py 实现了对 Agent 轨迹片段的分类协议 v2(参见 PROTOCOL_v2_classifier.md)。分类器接收单步 observation 或一段轨迹,输出该片段的元类别标签(如成功、失败、重试、超时、回退等),并将结果写入受控的回放缓冲区,供决策引擎在后续调度中复用。RESULTS_v2_classifier.md 给出了该协议在标准基准上的复现指标,是评估新分类器实现是否合规的依据。资料来源:loopgain/classifier.py:40-120 PROTOCOL_v2_classifier.md:1-60 RESULTS_v2_classifier.md:1-80

漏斗与观察机制(Funnel)

funnel.py 提供了 note_outcome()note_adapter() 两个标注入口,分别用于记录某次执行的最终结果与当时所选用的适配器(adapter)。漏斗内部以 _mode 字段控制自身行为,取值包括 _ENABLED_DISABLED 等;_mode 的赋值发生在 _ensure_loaded() 之中,而 _ensure_loaded() 仅在 on_init() 或首次 on_first_observe() 被触发时才会执行。资料来源:loopgain/funnel.py:1-80

社区已知问题(#1 最高互动量):在 on_init() 之前调用 note_outcome()note_adapter() 时,由于 _mode 仍为 None,方法内部的 self._mode != _ENABLED 判断会提前返回,导致标注结果被静默丢弃而调用方无感知。资料来源:loopgain/funnel.py:note_outcome/note_adapter 处

核心调度(Core)

core.py 是决策引擎的入口,负责串联分类器与漏斗:在 on_first_observe() 中调用 _ensure_loaded() 完成 _mode 初始化与缓冲区预热,在每次 observe 后调度分类器进行标注,并把分类结果反馈给策略层进行下一步动作选择。loopgain/__init__.py 负责将 Classifier 等核心类对外导出。资料来源:loopgain/core.py:60-200 loopgain/__init__.py:1-40

工作流程

下面给出从观察到分类的典型数据流:

flowchart LR
    A[Agent 执行轨迹] --> B[core.on_first_observe]
    B --> C[funnel._ensure_loaded]
    C --> D[_mode 初始化为 _ENABLED]
    D --> E[note_outcome / note_adapter]
    E --> F[classifier.classify]
    F --> G[回放缓冲区]
    G --> H[策略决策]

资料来源:loopgain/core.py:60-200 loopgain/funnel.py:80-160 loopgain/classifier.py:40-120

关键约束与最佳实践

  1. 初始化顺序:必须先触发 on_init()on_first_observe(),使 _ensure_loaded()_modeNone 切换到 _ENABLED,否则 note_outcome()note_adapter() 会因状态未初始化而静默返回。资料来源:loopgain/funnel.py:1-80
  2. 协议一致性:新增或修改分类逻辑时需遵循 PROTOCOL_v2_classifier.md 中描述的字段定义与判定顺序,以保证 RESULTS_v2_classifier.md 记录的可复现性指标不退化。资料来源:PROTOCOL_v2_classifier.md:1-120 RESULTS_v2_classifier.md:1-80
  3. 测试覆盖tests/test_classifier.py 提供了分类器的单元测试,覆盖正常轨迹、边界轨迹与异常轨迹三类输入,建议在修改 classifier.py 后同步扩展该文件。资料来源:tests/test_classifier.py:1-60

相关参考

资料来源:loopgain/core.py:60-200 loopgain/funnel.py:80-160 loopgain/classifier.py:40-120

框架集成适配器

loopgain/integrations/ 目录为多种主流智能体(Agent)编排框架提供轻量级适配器,使 LoopGain 的反馈循环(Feedback Loop)能够与外部框架的事件流无缝对接。适配器遵循统一的接入约定:将外部框架回调或运行时的输入输出,转换为 LoopGain 内部的 noteoutcome()、noteadapter() 与 oninit() 等观...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 LangGraph 适配器

继续阅读本节完整说明和来源证据。

章节 CrewAI 适配器

继续阅读本节完整说明和来源证据。

章节 AutoGen 适配器

继续阅读本节完整说明和来源证据。

loopgain/integrations/ 目录为多种主流智能体(Agent)编排框架提供轻量级适配器,使 LoopGain 的反馈循环(Feedback Loop)能够与外部框架的事件流无缝对接。适配器遵循统一的接入约定:将外部框架回调或运行时的输入输出,转换为 LoopGain 内部的 note_outcome()note_adapter()on_init() 等观测点,从而在不修改框架自身行为的前提下完成学习数据的采集。

设计目标与统一约定

所有适配器模块位于同一命名空间下,并暴露一致的 API 表面。__init__.py 负责聚合这些适配器,让上层用户能够一次性引入多个框架的支持 资料来源:loopgain/integrations/__init__.py:1-40

各适配器的共同特征包括:

  • 被动式挂载:不主动控制外部框架的执行流,仅在回调或上下文管理器出口处注入观测。
  • 状态对齐:依赖 LoopGain 的 Funnel 模块进行 _mode 初始化,适配器在调用前会触发 _ensure_loaded(),从而保证 _mode 已被正确设置。
  • 事件抽象:将外部框架的"任务启动""代理执行""工具调用""最终输出"等概念统一映射为 LoopGain 的 outcome 与 adapter 信号。

各框架适配器要点

LangGraph 适配器

loopgain/integrations/langgraph.py 针对 LangGraph 的图执行模型提供接入。该模块主要拦截节点(Node)执行前后的输入与输出,并将图的状态推进(state transition)作为 outcome 上报 资料来源:loopgain/integrations/langgraph.py:1-60。适配器在节点回调中调用 note_outcome(),使得图执行过程中的中间结果可被 LoopGain 收集。

CrewAI 适配器

loopgain/integrations/crewai.py 面向 CrewAI 的多代理协作场景。该适配器将每个 Agent 的"思考(thinking)"与"行动(action)"阶段分别映射为 outcome 事件,并将工具调用视作 adapter 信号,从而为后续的多代理协同学习提供基础 资料来源:loopgain/integrations/crewai.py:1-60

AutoGen 适配器

loopgain/integrations/autogen.py 适配 AutoGen 的对话型代理运行时。适配器将 UserProxyAgentAssistantAgent 之间的消息轮次视作 outcome 事件,把函数调用(function call)映射为 adapter 信号 资料来源:loopgain/integrations/autogen.py:1-60

LangChain 适配器

loopgain/integrations/langchain.py 主要覆盖 LangChain 的 ChainCallbackHandler 接口。适配器通过自定义 CallbackHandler 监听 on_chain_starton_chain_end 等钩子,将链式调用的输入与最终输出送入 LoopGain 资料来源:loopgain/integrations/langchain.py:1-60

OpenAI Agents 适配器

loopgain/integrations/openai_agents.py 针对 OpenAI 官方 Agents SDK。该适配器将 Runner 返回的事件流(event stream)转换为 outcome 信号,并将工具调用记录为 adapter 信号 资料来源:loopgain/integrations/openai_agents.py:1-60

已知问题与社区反馈

根据社区反馈,适配器在某些边缘场景下会出现静默失败:当外部框架的回调在 LoopGain 完成 _ensure_loaded() 之前被触发时,note_outcome()note_adapter() 会因为 self._mode 仍为 None 而提前 return,导致数据未被记录 资料来源:loopgain/integrations/__init__.py:1-40, loopgain/funnel.py:1-200。这一问题在所有适配器中表现一致,因为它们共享同一观测入口。修复方向包括在 note_outcome()note_adapter() 内部补齐 _ensure_loaded() 调用,或将模式判断改为 self._mode != _ENABLED and self._mode is not None

整体架构示意

flowchart LR
    A[外部框架<br>LangGraph/CrewAI/AutoGen/LangChain/OpenAI Agents] --> B[适配器层<br>loopgain/integrations/*]
    B --> C[Funnel 核心<br>_ensure_loaded + _mode]
    C --> D[LoopGain 学习循环]

资料来源:loopgain/integrations/langgraph.py:1-60, loopgain/integrations/crewai.py:1-60, loopgain/integrations/autogen.py:1-60, loopgain/integrations/langchain.py:1-60, loopgain/integrations/openai_agents.py:1-60

资料来源:loopgain/integrations/langgraph.py:1-60, loopgain/integrations/crewai.py:1-60, loopgain/integrations/autogen.py:1-60, loopgain/integrations/langchain.py:1-60, loopgain/integrations/openai_agents.py:1-60

遥测系统、CLI 与已知问题

LoopGain 在训练与评估流程中嵌入一个本地闭环的遥测通道,用于在用户侧采集 outcome 与 adapter 事件,并通过 python -m loopgain 提供的命令行工具查询当前模式与版本。本页汇总 loopgain 包内 funnel、telemetry 与 cli 模块的实现细节,以及社区中排名第一的已知缺陷,供新贡献者快速建立系统心智模型。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 数据流概览

继续阅读本节完整说明和来源证据。

概述

LoopGain 在训练与评估流程中嵌入一个本地闭环的遥测通道,用于在用户侧采集 outcomeadapter 事件,并通过 python -m loopgain 提供的命令行工具查询当前模式与版本。本页汇总 loopgain 包内 funneltelemetrycli 模块的实现细节,以及社区中排名第一的已知缺陷,供新贡献者快速建立系统心智模型。

遥测系统与 CLI 架构

遥测层由采集与持久化两个职责模块构成。loopgain/funnel.py 暴露 on_init()on_first_observe()note_outcome()note_adapter() 等 API,是用户在业务代码中唯一需要直接打交道的入口;底层写入则由 loopgain/telemetry.py 完成,事件以 JSONL 形式落到本地 XDG 目录 资料来源:loopgain/funnel.py:1-80 资料来源:loopgain/telemetry.py:20-55

_mode 字段决定遥测开关,其合法值为 _ENABLED_DISABLED,并通过 _ensure_loaded() 在首次调用 on_first_observe() 时懒加载,因此用户必须显式调用 on_init() 或触发首次观察,配置才会生效 资料来源:loopgain/funnel.py:40-65。CLI 入口由 loopgain/__main__.py 薄包装 loopgain/cli.py 中的 main(),目前提供 statusversion 两个子命令,前者打印当前 _mode 与最近一次上报时间戳,后者直接读取 loopgain/_version.py 中的 __version__ 资料来源:loopgain/cli.py:15-60 资料来源:loopgain/__main__.py:1-15 资料来源:loopgain/_version.py:1-10。启用或停用遥测的环境变量约定记录在 TELEMETRY.md 中,包含 LOOPGAIN_TELEMETRY 的取值与优先级 资料来源:TELEMETRY.md:1-40

数据流概览

flowchart LR
    A[用户代码] --> B[funnel.py<br/>note_outcome / note_adapter]
    B --> C{_ensure_loaded}
    C -->|已加载 _ENABLED| D[telemetry.py<br/>append JSONL]
    C -->|_mode is None 或 _DISABLED| E[静默跳过]
    D --> F[本地 XDG 目录]

已知问题与修复建议

社区排名第一的问题是 note_outcome()note_adapter()on_init() 之前的静默失败:

  • 触发条件:方法内部以 self._mode != _ENABLED 判定是否上报,但 _mode_ensure_loaded() 执行前为 None,因此不等式恒成立并提前 return 资料来源:loopgain/funnel.py:85-130`。
  • 影响范围:任何在 on_init()on_first_observe() 之前产生的事件都会被丢弃,且调用方不会收到异常或日志告警,排查难度较高。
  • 建议修复:将判断改为 self._mode in (None, _DISABLED) 并显式调用 _ensure_loaded(),或为 _mode is None 路径补充针对的单元测试。

此外,telemetry.py 在写入失败(如磁盘满或权限不足)时仅记录日志而不抛出,可能掩盖真实错误,建议在调试模式下输出完整 traceback 资料来源:loopgain/telemetry.py:60-90。CLI 当前尚未提供 telemetry on/off 子命令,用户只能通过环境变量切换,体验可进一步改进 资料来源:loopgain/cli.py:30-60

总结

LoopGain 的遥测与 CLI 设计保持精简,核心耦合点集中在 _mode 的初始化时序。贡献者在改动 funnel.py 时应优先修复 _mode is None 的静默失败路径,并同步更新 TELEMETRY.md,确保用户文档与运行时行为一致。

来源:https://github.com/loopgain-ai/loopgain / 项目说明书

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

medium 可能修改宿主 AI 配置

安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。

medium 能力判断依赖假设

假设不成立时,用户拿不到承诺的能力。

medium 来源证据:note_outcome() and note_adapter() silently fail when called before on_init() due to uninitialized _mode

可能增加新用户试用和生产接入成本。

medium 维护活跃度未知

新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。

Pitfall Log / 踩坑日志

项目:loopgain-ai/loopgain

摘要:发现 8 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:配置坑 - 可能修改宿主 AI 配置。

1. 配置坑 · 可能修改宿主 AI 配置

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
  • 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
  • 证据:capability.host_targets | https://news.ycombinator.com/item?id=48919562 | host_targets=claude_code, claude, chatgpt

2. 能力坑 · 能力判断依赖假设

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:README/documentation is current enough for a first validation pass.
  • 对用户的影响:假设不成立时,用户拿不到承诺的能力。
  • 证据:capability.assumptions | https://news.ycombinator.com/item?id=48919562 | README/documentation is current enough for a first validation pass.

3. 运行坑 · 来源证据:note_outcome() and note_adapter() silently fail when called before on_init() due to uninitialized _mode

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:GitHub 社区证据显示该项目存在一个运行相关的待验证问题:note_outcome() and note_adapter() silently fail when called before on_init() due to uninitialized _mode
  • 对用户的影响:可能增加新用户试用和生产接入成本。
  • 证据:community_evidence:github | https://github.com/loopgain-ai/loopgain/issues/1 | 来源讨论提到 python 相关条件,需在安装/试用前复核。

4. 维护坑 · 维护活跃度未知

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:未记录 last_activity_observed。
  • 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
  • 证据:evidence.maintainer_signals | https://news.ycombinator.com/item?id=48919562 | last_activity_observed missing
  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 证据:downstream_validation.risk_items | https://news.ycombinator.com/item?id=48919562 | no_demo; severity=medium

6. 安全/权限坑 · 存在评分风险

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:风险会影响是否适合普通用户安装。
  • 证据:risks.scoring_risks | https://news.ycombinator.com/item?id=48919562 | no_demo; severity=medium

7. 维护坑 · issue/PR 响应质量未知

  • 严重度:low
  • 证据强度:source_linked
  • 发现:issue_or_pr_quality=unknown。
  • 对用户的影响:用户无法判断遇到问题后是否有人维护。
  • 证据:evidence.maintainer_signals | https://news.ycombinator.com/item?id=48919562 | issue_or_pr_quality=unknown

8. 维护坑 · 发布节奏不明确

  • 严重度:low
  • 证据强度:source_linked
  • 发现:release_recency=unknown。
  • 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
  • 证据:evidence.maintainer_signals | https://news.ycombinator.com/item?id=48919562 | release_recency=unknown

来源:Doramagic 发现、验证与编译记录