Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 45 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,58 @@
# Research Code Collection

用于维护研究项目的代码、配置和最小运行说明。公开版本仅包含经过筛选的源码与新编写的合成示例。
**Agent 多层记忆与中文文本分类实验工程。** 两个独立 Python 子项目,覆盖上下文组装、异步会话、实验有效性检查、分类基线与服务批处理。

| 项目 | 代码入口 | 当前可验证的范围 |
[![Code and publication checks](https://github.com/Darssal/Research-Code-Collection/actions/workflows/checks.yml/badge.svg)](https://github.com/Darssal/Research-Code-Collection/actions/workflows/checks.yml)

[MemLab](#memlab--agent-多层记忆) · [文本分类](#招聘文本三分类) · [工程笔记](docs/ENGINEERING_NOTES.md) · [验证与来源](#验证与来源)

## MemLab / Agent 多层记忆

面向并行会话,分离近期上下文、热缓存、持久化元数据与向量检索,提供统一记忆接口和实验控制组件。

| 技术问题 | 实现机制 | 入口 |
| --- | --- | --- |
| 成像测井裂缝解释 | [FracLogGPT-Lite](https://github.com/Darssal/FracLogGPT-Lite) | 既有独立仓库:实验阶段编排、推理恢复、视觉对比解码与文本标签评测 |
| 招聘文本分类 | [job-text-classification](projects/job-text-classification/) | TF-IDF + 随机森林基线、可选 BERT 分类、外部聊天服务的批处理适配 |
| 多层记忆实验 | [memlab](projects/memlab/) | 上下文组装、缓存与持久化接口、并发会话实验入口、离线逻辑测试 |
| 记忆如何放置与取回 | L0–L3 分层、重要度准入、大对象指针、异步批量写入 | [记忆管理器](projects/memlab/memlab/memory_manager/manager.py) |
| 检索内容如何进入上下文 | 相关性筛选、版本与文本去重、注入预算、直接证据绕过 | [上下文策略](projects/memlab/memlab/memory_manager/l0.py) |
| 并发会话如何保留归属 | ContextVar 隔离日志上下文,记录缓存与降级路径 | [会话日志](projects/memlab/memlab/session_logging.py) |
| 哪些运行可进入汇总 | 有效性条件、失效阶段回滚和重跑计划 | [实验控制](projects/memlab/memlab/pipeline/control_plane.py) |

各子项目独立安装,具体依赖、运行命令和验证边界见各自 README。分类服务适配器不包含检索索引或知识库建设;memlab 的完整实验需要另行配置外部服务。
`Python 3.12` · `asyncio` · `Redis` · `PostgreSQL` · `Qdrant`

## 从这里开始
[项目与安装](projects/memlab/) · [架构](projects/memlab/docs/ARCHITECTURE.md) · [53 项离线测试的覆盖范围](projects/memlab/docs/TESTING.md)

1. 阅读对应项目的 README,先运行合成示例或离线测试。
2. 按项目说明配置自己的数据路径和服务环境变量。
3. 将运行输出保留在本地;提交前运行公开边界检查。
## 招聘文本三分类

识别环保、人工智能与其它招聘文本(其它在接口中使用标签 `否`),提供本地基线、可选 BERT 和外部聊天服务适配器。

- **数据与评测**:CSV / JSONL 接口、固定种子分层划分、重复文本检查;先划分再拟合 TF-IDF,按实际类别顺序对齐概率与指标。
- **服务批处理**:超时、有界重试、非临时错误快速结束、并发保序;默认预测产物只保留 ID、标签与错误状态。
- **可运行示例**:24 条新编写的合成文本,CPU 执行本地随机森林流程,16 项回归测试覆盖核心行为。

```bash
python tools/check_publication.py --help
python -m unittest discover -s tests -v
cd projects/job-text-classification
python -m pip install -e .
python -m job_text_classification demo
```

## 维护约定
`Python` · `scikit-learn` · `TF-IDF` · `Random Forest` · `ThreadPoolExecutor`

[数据接口与运行](projects/job-text-classification/) · [分类实现](projects/job-text-classification/src/job_text_classification/baseline.py) · [服务适配](projects/job-text-classification/src/job_text_classification/http_adapter.py) · [回归测试](projects/job-text-classification/tests/test_regressions.py)

## 相关项目 / FracLogGPT-Lite

[FracLogGPT-Lite](https://github.com/Darssal/FracLogGPT-Lite) 在独立仓库维护成像测井裂缝解释的多模态实验流程:LoRA-SFT、DPO / SimPO、可恢复推理与视觉对比解码。

[项目介绍](https://github.com/Darssal/FracLogGPT-Lite) · [无 GPU 验证](https://github.com/Darssal/FracLogGPT-Lite/blob/main/docs/QUICKSTART.md) · [双分支解码](https://github.com/Darssal/FracLogGPT-Lite/blob/main/src/fraclog/vcd.py)

## 设计与验证

[工程笔记](docs/ENGINEERING_NOTES.md)连接问题、机制、小例子和测试,涵盖推理恢复、上下文与会话隔离、分类评测与失败处理。

每个子项目独立安装。分类 demo 与 MemLab 单元测试可离线运行;MemLab stub / E2E 需要另行配置基础设施。持续集成检查分类、记忆组件及公开文件边界,详见 [Actions](https://github.com/Darssal/Research-Code-Collection/actions/workflows/checks.yml)。

## 验证与来源

- 真实语料、测井图像、论文正文与审稿材料、模型权重、检查点、预测结果、日志和本地环境文件不进入仓库。
- 示例数据须为新编写的合成内容。公开示例不能从真实数据中抽样或简单替换姓名得到。
- 凭据从环境变量读取,接口地址由使用者配置;不提交真实密钥和私有服务地址。
- 本仓库重新建立 Git 历史,不导入原实验目录的提交历史。
- 没有附带模型训练成绩或论文性能表。合成示例与单元测试只能验证相应代码行为。
2026-10-18 验证记录:分类 16 项、MemLab 53 项离线测试通过。合成示例用于检查流程;BERT 训练、真实 HTTP 服务、数据库与 DeerFlow 集成、论文性能实验尚未在公开版整理中运行。

详细规则见 [公开范围](docs/PUBLICATION_SCOPE.md)、[贡献与维护](CONTRIBUTING.md) 和 [第三方来源](THIRD_PARTY.md)。检查器是提交前的辅助检查,新增文件仍需人工检查其来源、内容与公开范围。
源码、配置、测试与合成示例可以公开;真实语料、论文材料、权重、运行输出和凭据保留在本地。第三方框架与模型的来源见 [THIRD_PARTY.md](THIRD_PARTY.md),提交规则见 [CONTRIBUTING.md](CONTRIBUTING.md) 与[公开范围](docs/PUBLICATION_SCOPE.md)。
62 changes: 62 additions & 0 deletions docs/ENGINEERING_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# 工程实现与设计取舍

这份说明沿着源码中的三条路径展开:多模态实验的阶段衔接与解码、Agent 记忆的上下文组装与运行控制、文本分类的数据划分与服务批处理。例子用于解释代码行为;模型效果和真实服务性能需要独立实验。

## 1. FracLogGPT-Lite:让阶段衔接与预测恢复有明确语义

**问题。** 多阶段训练会产生多个 checkpoint;长时间推理可能中断,也可能重复写入。视觉对比解码则要求两条图像分支在同一文本前缀上比较下一 token 的分数。

**机制。**

- **阶段交接:** [`run_pipeline.py`](https://github.com/Darssal/FracLogGPT-Lite/blob/main/scripts/run_pipeline.py) 从配置读取阶段顺序,发现已有阶段产物,并将 `${checkpoint:sft}` 等占位符解析为下游输入。[`checkpoints.py`](https://github.com/Darssal/FracLogGPT-Lite/blob/main/src/fraclog/checkpoints.py) 通过 adapter、trainer state 或权重文件识别 checkpoint;在子目录候选中按修改时间选择最新项。命令预演允许保留尚未生成的占位符。
- **稳定样本键:** [`predictions.py`](https://github.com/Darssal/FracLogGPT-Lite/blob/main/src/fraclog/predictions.py) 优先使用 `id`,其次使用 `image` 或 `images[0]`。恢复时只处理未完成的键;结果去重时,同键保留最后一条。输出文件旁的 `.lock` 目录以排他创建方式阻止同时写入。
- **同步对比解码:** [`vcd.py`](https://github.com/Darssal/FracLogGPT-Lite/blob/main/src/fraclog/vcd.py) 将原图和扰动图的下一 token logits 按 `original + α × (original − perturbed)` 融合,只采样一次,再将同一 token 追加到两个分支。批处理路径把两个分支放在同一 batch 中维护缓存;HF `generate` 路径限制为确定性解码,以保持分支一致。

**小例子。** 已有结果含 `id:sample-a`,输入为 `sample-a`、`sample-b` 时,恢复模式只推理 `sample-b`。若两个分支对同一前缀分别给出不同的下一 token,融合后选出的 token 必须同时进入两边;让分支各自采样会使后续 logits 对应不同文本历史,失去直接对比的条件。

**设计取舍。** 以图像路径派生键依赖路径稳定;移动文件或同图多问时应提供显式且唯一的 `id`。目录锁处理并发互斥,没有实现进程崩溃后的自动租约回收。checkpoint 的“最新”指修改时间,不等于最佳验证分数或最大训练步数。缓存路径的单元测试验证张量与状态行为,实际模型、设备和 Transformers 版本的兼容性仍需集成验证。

**测试入口:** [阶段恢复](https://github.com/Darssal/FracLogGPT-Lite/blob/main/tests/test_run_pipeline.py) · [预测过滤、去重与互斥锁](https://github.com/Darssal/FracLogGPT-Lite/blob/main/tests/test_predictions.py) · [分支配对、字段对齐与缓存](https://github.com/Darssal/FracLogGPT-Lite/blob/main/tests/test_vcd.py) · [无 GPU 使用指南](https://github.com/Darssal/FracLogGPT-Lite/blob/main/docs/QUICKSTART.md)

## 2. MemLab:控制上下文注入,并记录运行是否有效

**问题。** 更多记忆不一定应该全部放进提示:候选可能重复、相关性不足,或与现有工具证据重叠。多个异步会话共享记忆管理器时,日志归属也不能依赖反复覆盖的全局回调。实验成功执行后,还需要判断其配置和记录是否满足比较条件。

**机制。**

- **上下文组装:** [`l0.py`](../projects/memlab/memlab/memory_manager/l0.py) 先保留近期消息,再按检索分数排序候选;过滤低相关项,按键与版本去重,并用规范化文本前 512 个字符的哈希去除重复内容。选中记忆受注入预算约束,最终组装还会从前部裁剪消息。 [`manager.py`](../projects/memlab/memlab/memory_manager/manager.py) 在已有直接工具证据时可绕过检索,并返回检索跳过原因、缓存命中和降级轨迹。
- **分层放置:** 同一管理器按重要度与对象大小选择 L0 近期上下文、L1 Redis、L2 Postgres / Qdrant 或 L3 对象存储。大对象可保存为正文加指针;异步写入队列提供批处理与背压策略。服务失败会进入降级记录,后台写入失败会向调用方暴露。
- **并发归属:** [`session_logging.py`](../projects/memlab/memlab/session_logging.py) 安装共享操作 logger,从 `ContextVar` 读取当前 agent。会话 worker 设置上下文并在 `finally` 中恢复;A、B 会话交错执行时,各自的操作仍读取各自上下文。初始化和独立后台批次没有唯一会话归属时,字段可以为空。
- **运行有效性:** [`control_plane.py`](../projects/memlab/memlab/pipeline/control_plane.py) 区分 accepted、invalid 和 diagnostic 等状态。新格式运行只有在已接受、汇总链有效、非诊断且未被替代时才进入正式报告;旧格式保留环境、复现和真实模型标志的兼容检查。失效运行记录异常、确定最早回滚阶段并生成重跑计划。[`summary_builder.py`](../projects/memlab/memlab/metrics/summary_builder.py) 据此排除不合格运行。

**小例子。** 近期消息已经包含所需工具证据时,策略可以直接组装上下文,并记录 `direct_tool_evidence_present`;无需为了“使用记忆”再次检索。另一条运行即使生成了答案,若 manifest 被标记为 diagnostic,也不会成为正式对比表中的有效样本。

**设计取舍。** token 数按 `ceil(len(text) / 4)` 估算,属于启发式预算;它不是模型 tokenizer 的精确计数,单条过长的最终用户消息也不会被该裁剪循环删除。文本去重只比较规范化后的前缀,并非语义去重。默认 `hash_embedding` 用于确定性实验,不等同于经过训练的语义嵌入模型。`ContextVar` 解决异步调用上下文的日志归属,没有使跨服务写入成为事务,也不会为所有后台工作自动补上会话身份。有效性门禁约束报告输入,不能替代实验设计与人工判断。

**测试入口:** [检索绕过策略](../projects/memlab/tests/test_memory_manager_policy.py) · [L3 指针化与降级轨迹](../projects/memlab/tests/test_system_rebaseline.py) · [交错会话日志归属](../projects/memlab/tests/test_stub_event_attribution.py) · [失效运行与回滚](../projects/memlab/tests/test_control_plane.py) · [汇总排除与作用域](../projects/memlab/tests/test_branch_audit.py) · [指标分母](../projects/memlab/tests/test_metrics_denominator.py)

## 3. 招聘文本分类:隔离训练信息,明确批处理失败

**问题。** 在划分数据前拟合 TF-IDF 会把验证文本带入词表;分类器的内部类别顺序也可能与输出约定不同。批量调用外部服务时,超时、非法响应和认证失败需要终止语义,并发完成顺序不能改变记录与预测的对应关系。

```mermaid
flowchart LR
A[带标签文本] --> B[检查重复并分层划分]
B --> C[训练集拟合 TF-IDF 与随机森林]
B --> D[保留验证集]
C --> E[预测验证文本]
D --> E
E --> F[按固定标签顺序计算指标]
```

**机制。**

- **先 split,后 fit:** [`data.py`](../projects/job-text-classification/src/job_text_classification/data.py) 检查标签,拒绝去空白、大小写规范化后相同的文本,再用固定种子按类别划分。 [`cli.py`](../projects/job-text-classification/src/job_text_classification/cli.py) 只把训练子集交给 `fit`;验证文本仅经过已拟合流水线的 `predict`。字符二至四元组 TF-IDF 与随机森林封装在 scikit-learn `Pipeline` 中。
- **按 `classes_` 对齐概率:** [`baseline.py`](../projects/job-text-classification/src/job_text_classification/baseline.py) 将 `predict_proba` 的每列先映射到分类器的真实类别,再按固定公共标签顺序输出。未参与训练的类别填入 `0.0`;指标计算还检查输入记录与预测的 ID 顺序一致。
- **有界 HTTP 调用:** [`http_adapter.py`](../projects/job-text-classification/src/job_text_classification/http_adapter.py) 为请求配置 timeout 和最大 attempts,失败后有限退避;除 429 外的 4xx 直接结束。响应大小和标签范围受检查。`ThreadPoolExecutor.map` 保留输入顺序,每条失败记录也会返回状态;CLI 写出结果后在有失败时返回退出码 2。输出保留记录 ID、标签、状态和概率,不写入输入原文、服务回复正文或凭据。

**小例子。** 分类器内部顺序为 `[人工智能, 环保]`,返回概率 `[0.2, 0.8]` 时,公开结果仍按 `[环保, 人工智能, 否]` 输出 `{环保: 0.8, 人工智能: 0.2, 否: 0.0}`。并发处理中第一条较慢、第二条先完成,最终结果仍以第一条、第二条排列;认证失败不会用完全部重试次数。

**设计取舍。** 拒绝规范化重复文本是明确的划分约束,没有解决语义近重复、同公司岗位泄漏或时间漂移;正式研究还需要独立测试方案。固定标签映射使接口稳定,不代表三类预测已经校准。保序意味着慢请求会影响后续结果交付;当前实现收集全部结果,不提供流式完成通知。timeout 约束请求等待,不是整个任务的严格总时限。该 HTTP 适配器遵循 `message / mode / textResponse` 协议,不包含知识库、索引或检索链路。

**测试入口:** [`test_regressions.py`](../projects/job-text-classification/tests/test_regressions.py) 覆盖训练词表隔离、固定种子与重复文本、概率列映射、记录对齐、模型保存加载、超时与非法响应、401 快速失败、并发保序及输出不含原文。运行方法见[项目 README](../projects/job-text-classification/README.md)。
10 changes: 7 additions & 3 deletions projects/job-text-classification/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# 招聘文本三分类:无原始数据的代码整理版
# 招聘文本三分类 / 本地基线与服务批处理

将招聘文本分为“环保 / 人工智能 / 否”三类,提供中文字符 TF-IDF + 随机森林、可选 BERT 基线,以及外部聊天服务的 HTTP 适配器。默认示例仅在 CPU 上处理 24 条新编写的虚构文本,无需原始语料、模型权重、GPU 或 API。
识别环保、人工智能与其它招聘文本(接口标签分别为 `环保`、`人工智能`、`否`),提供中文字符 TF-IDF + 随机森林、可选 BERT 基线,以及外部聊天服务的 HTTP 适配器。默认示例仅在 CPU 上处理 24 条新编写的虚构文本,无需原始语料、模型权重、GPU 或 API。

本工程基于本地研究脚本 `bert_classifier.py`、`bert_classifier_bert.py` 和 `3.py` 的功能进行重新组织与修复。原先名为 `bert_classifier.py` 的脚本实际使用 TF-IDF 和随机森林,现已按真实方法命名。此版本用于展示代码组织、分类流程与失败处理,不提供论文结果,也不表示论文的完整复现或作者贡献认定。
核心实现包括训练词表隔离、固定标签概率对齐、预测输出最小化,以及带超时、有界重试和并发保序的外部服务批处理。

[快速运行](#快速运行) · [数据与基线](#数据接口与本地基线) · [HTTP 适配](#可选-http-服务适配) · [设计取舍](../../docs/ENGINEERING_NOTES.md)

## 快速运行

Expand Down Expand Up @@ -61,6 +63,8 @@ python -m job_text_classification http --input data/authorized_jobs.jsonl --outp

## 公开范围与验证

本工程基于原研究脚本的分类与批处理功能重新组织。原先名为 `bert_classifier.py` 的脚本实际使用 TF-IDF 和随机森林,公开版按真实方法命名;BERT 保留为可选路径。这里的验证针对代码流程,不提供论文效果或个人贡献归属的证明。

- 保留:数据接口、训练与推理代码、HTTP 适配、全新合成例子和回归测试。
- 排除:原始岗位语料、Excel、论文及审稿材料、真实输出、服务地址、密钥、模型与既有实验指标。
- 回归测试覆盖:训练词表隔离、概率列对齐、固定指标标签顺序、重复文本划分限制、模型保存加载、HTTP 超时/非法响应/认证失败、并发保序和输出不带原文。
Expand Down
Loading
Loading