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_init、on_first_observe、note_outcome、note_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...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
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
关键约束与最佳实践
- 初始化顺序:必须先触发
on_init()或on_first_observe(),使_ensure_loaded()把_mode从None切换到_ENABLED,否则note_outcome()与note_adapter()会因状态未初始化而静默返回。资料来源:loopgain/funnel.py:1-80 - 协议一致性:新增或修改分类逻辑时需遵循
PROTOCOL_v2_classifier.md中描述的字段定义与判定顺序,以保证RESULTS_v2_classifier.md记录的可复现性指标不退化。资料来源:PROTOCOL_v2_classifier.md:1-120 RESULTS_v2_classifier.md:1-80 - 测试覆盖:
tests/test_classifier.py提供了分类器的单元测试,覆盖正常轨迹、边界轨迹与异常轨迹三类输入,建议在修改classifier.py后同步扩展该文件。资料来源:tests/test_classifier.py:1-60
相关参考
- 公开 API 由
loopgain/__init__.py导出,开发者可通过from loopgain import Classifier直接使用分类能力。资料来源:loopgain/__init__.py:1-40 - 协议演进历史与基准结果分别记录在
PROTOCOL_v2_classifier.md与RESULTS_v2_classifier.md中,升级分类协议前应先通读两份文档以避免破坏向后兼容性。资料来源:PROTOCOL_v2_classifier.md:1-120 RESULTS_v2_classifier.md:1-80
资料来源: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() 等观...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
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 的对话型代理运行时。适配器将 UserProxyAgent 与 AssistantAgent 之间的消息轮次视作 outcome 事件,把函数调用(function call)映射为 adapter 信号 资料来源:loopgain/integrations/autogen.py:1-60。
LangChain 适配器
loopgain/integrations/langchain.py 主要覆盖 LangChain 的 Chain 与 CallbackHandler 接口。适配器通过自定义 CallbackHandler 监听 on_chain_start、on_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 在训练与评估流程中嵌入一个本地闭环的遥测通道,用于在用户侧采集 outcome 与 adapter 事件,并通过 python -m loopgain 提供的命令行工具查询当前模式与版本。本页汇总 loopgain 包内 funnel、telemetry 与 cli 模块的实现细节,以及社区中排名第一的已知缺陷,供新贡献者快速建立系统心智模型。
遥测系统与 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(),目前提供 status 与 version 两个子命令,前者打印当前 _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 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
可能增加新用户试用和生产接入成本。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
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 发现、验证与编译记录