news 2026/9/1 6:59:24

LLM记忆结构化:用AST与数据流实现可回放程序分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LLM记忆结构化:用AST与数据流实现可回放程序分析

在决定动手写 Lemmalog 之前,我正被一个具体问题困住:LLM 明明可以在对话里记住前置代码、字段类型、函数调用关系,可这些“记忆”一旦离开对话框,就变成一段无法被程序分析工具消费的文本。我想要的不是让模型在聊天窗口里显得聪明,而是让 LLM 的记忆能够进入程序分析流程,成为可以回放、校验和合并到静态检查结论里的证据。Lemmalog 就是围绕这个目标诞生的实验项目:它把 LLM 分析代码时产生的记忆,转换为结构化、带行号、带置信度的日志,再交给 AST 与数据流分析器使用。

这篇文章会完整还原 Lemmalog 从想法到最小实现的过程。我会先讨论为什么普通聊天式记忆不足以支撑程序分析,再给出一个可运行的 Python 实验项目,逐步实现记忆采集、AST 标注、数据流检查和报告生成。最后会总结我实际踩过的记忆污染、数值精度和上下文截断问题,以及这些经验在更大项目里如何转化为工程决策。如果你也想把 LLM 的能力接入静态分析、代码审查或 Agent 工具链,这篇文章可以当成一条可复现的路线图。

1. 先重新理解 LLM 记忆:它不是一个词,而是三层结构

LLM 记忆在技术讨论里经常被当成一个笼统的概念,但实际上它至少包含三种差异很大的形态。如果一开始就把它们混在一起设计,后面所有模块都会变得别扭。Lemmalog 的第一步,不是写代码,而是把记忆重新分层。

1.1 我最初把 LLM 记忆等同于上下文窗口,这是第一个错误

刚开始我理所当然地认为:LLM 的记忆就是 Prompt 里的上下文窗口。只要把足够多的代码片段、之前的问答记录、模型返回的摘要塞进messages,模型就能记住之前看过什么。

这个思路在单次会话里勉强能用,遇到真实仓库就会暴露问题。一个中型项目的代码量往往远大于上下文窗口,而且窗口内的内容会随每次新请求不断移动。更麻烦的是,上下文窗口里的内容是线性文本,没有稳定的地址。程序分析需要的是“文件user_service.py第 42 行的user_id类型是什么”,而不是“刚才好像提到这个字段可能是字符串”。文本记忆没有行号,没有结构,没有版本,自然也无法被静态检查器稳定消费。

1.2 三个分层:上下文记忆、向量记忆和符号记忆

为了让后续设计可讨论,我建议把 LLM 记忆拆成三层:

记忆层级表现形式易失性适合程序分析的程度
上下文记忆Prompt 中的 token 序列、对话轮次、临时摘要高,会话关闭后基本消失低,无法稳定定位代码位置
向量记忆文本或代码切块后的 embedding 向量,存储在向量库中中,可以持久化,但向量本身不可解释中,只能按相似度召回,不能直接作为程序事实
符号记忆AST 节点、符号表、类型约束、函数调用关系、分析结论低,结构化,可查询可校验高,正是程序分析需要的输入

上下文记忆解决“当前对话里发生了什么”,向量记忆解决“历史资料里哪些内容相似”,符号记忆解决“代码内部到底长什么样、有哪些约束”。Lemmalog 的核心判断是:程序分析不能直接依赖前两种记忆,必须先把它们翻译成符号记忆。

1.3 Lemmalog 的目标:把三层记忆汇成一份可回放日志

Lemmalog 并不是真的把向量库塞进程序分析器,而是做一个翻译层:上下文记忆先被转成结构化事件;向量记忆被转成可比较相似度的证据;符号记忆由 AST 分析产生,作为最终结论的骨架。

每一份记忆在 Lemmalog 里都被记录成一个条目,包含memory_id、来源类型、代码片段、文件路径、行号、置信度和创建时间。这样 LLM 丢给分析器的就不是一段含糊的“我记得这里有问题”,而是一条可以被审计、被复现、被合并进规则引擎的结构化记录。把记忆当成日志来设计,是 Lemmalog 和普通 LLM 辅助工具最大的区别。

注意:LLM 记忆不适合直接作为静态分析的事实来源,但它非常适合作为“待验证的线索来源”。Lemmalog 尊重这层边界:模型负责提示,AST 负责证实,两者缺一不可。

2. 搭建最小实验环境:Lemmalog 的模块边界与数据流

Lemmalog 的实验版本不需要微调模型,也不需要搭建完整向量数据库。目标是在普通个人开发机上跑通“记忆 -> 日志 -> AST 标注 -> 问题报告”的完整链路,然后再考虑生产化。

2.1 依赖、Python 版本与实验环境的取舍

实验环境使用 Python 3.10 及以上版本,核心依赖只用了标准库:ast用于解析代码,json用于读写日志,dataclasses用于定义数据模型。额外推荐安装numpy,用于向量相似度计算;如果暂时不处理 embedding,也可以不装。

资源要求说明
Python3.10+标准库已经覆盖 AST、JSON、命令行参数处理
numpy1.24+可选,用于计算记忆向量之间的余弦相似度
LLM 接口本地模型或 API 均可实验阶段可以先用模拟输出替代,便于调试
操作系统Linux / macOS / Windows示例命令以 Bash 为主,Windows 下注意激活虚拟环境的方式不同

在实验阶段,我不建议一开始就接入真实模型。更稳妥的顺序是:先把记忆格式和程序分析链路跑通,再用一个fake_llm_annotate函数模拟 LLM 输出,最后才替换成真实模型调用。这样可以避免把模型输出不确定性和程序分析逻辑纠缠在一起。

2.2 模块划分与数据流

Lemmalog 分成四个模块:

memory: 负责采集、压缩、持久化 LLM 记忆 analysis: 负责解析 AST、标注节点、执行数据流检查 report: 负责生成人可读和机器可读的报告 cli: 负责命令行入口,把上述模块串起来

数据流方向是单向的:

LLM 交互输出 -> memory 模块写入 JSONL 记忆文件 memory 文件 -> analysis 模块按文件路径和行号召回相关记忆 AST 解析 -> 与记忆条目合并成带注释的节点列表 数据流检查 -> 输出问题列表 report 模块 -> 生成 lemmalog.json 和控制台摘要

这个单向流非常重要。它保证了每一次分析都是从固定输入开始,可以复现;同时也保证了 LLM 幻觉只影响“标注内容”,不会直接修改 AST 的客观结构。

2.3 目录结构与核心文件说明

我建议使用一个扁平目录作为实验基线:

lemmalog/ ├── __init__.py ├── cli.py ├── memory/ │ ├── __init__.py │ ├── entry.py │ ├── store.py │ └── compress.py ├── analysis/ │ ├── __init__.py │ ├── ast_builder.py │ ├── annotator.py │ └── checkers.py └── report/ ├── __init__.py └── builder.py

创建目录后,先用最小文件结构验证一遍:

mkdir -p lemmalog/memory lemmalog/analysis lemmalog/report python -m venv .venv source .venv/bin/activate pip install numpy

这一步不是可有可无。目录结构提前固定,后续写代码时模块边界不会漂移;虚拟环境隔离也能避免系统 Python 环境被装乱。

3. 实现记忆采集:从 LLM 输出中沉淀结构化的记忆条目

记忆采集是整个 Lemmalog 的地基。如果采集阶段丢失行号、路径和置信度,后续分析阶段再努力也无法弥补。这一节我会从最简数据模型开始,逐步加入压缩和去重逻辑。

3.1 记录原始交互:不是保存对话,而是保存可回放事件

聊天记录不适合直接作为程序分析输入,因为用户提问和模型回答里夹杂了大量与代码无关的内容。Lemmalog 需要的是“这一次 LLM 观察到了什么”的可回放事件。

我用一个MemoryEntry数据类表示一条记忆:

# lemmalog/memory/entry.py from dataclasses import dataclass, asdict, field from datetime import datetime, timezone from uuid import uuid4 @dataclass class MemoryEntry: kind: str # context / summary / annotation / issue content: str # LLM 对该代码片段的核心判断 code_snippet: str = "" # 原始代码片段 path: str = "" # 文件路径 line: int = -1 # 行号 score: float = 0.0 # 置信度,0~1 created_at: str = field(default_factory=lambda: datetime.now(timezone.utc).isoformat()) memory_id: str = field(default_factory=lambda: uuid4().hex) def to_json(self): return asdict(self)

kind字段用来区分这条记忆是上下文背景、代码摘要、还是模型给出的缺陷判断。score字段是后续过滤幻觉的关键:当模型说“我确定”,它并不一定真的确定,但我们至少可以通过置信度让分析器做不同的处理。

3.2 记忆压缩与去重:摘要、关键行号和置信度

LLM 每次交互产生的原始文本很多,直接写入 JSONL 会让记忆文件迅速膨胀。压缩不是简单截断,而是保留分析器真正关心的字段。

我用最简单的方式定义压缩规则:

  • 同一pathline下只保留置信度最高的一条记录。
  • 同一pathline下如果出现多条高置信度但内容矛盾的记录,标记为conflict
  • code_snippet超过 200 个字符时,只保留首尾各 50 个字符,并增加省略标记。
# lemmalog/memory/compress.py from .entry import MemoryEntry def should_keep(new_entry: MemoryEntry, old_entry: MemoryEntry) -> bool: if new_entry.score == old_entry.score: return new_entry.created_at > old_entry.created_at return new_entry.score > old_entry.score def compress_memories(entries): best = {} for entry in entries: key = (entry.path, entry.line) if key not in best: best[key] = entry continue old = best[key] if old.kind == "issue" and entry.kind == "issue" and old.content != entry.content: entry.kind = "conflict" if should_keep(entry, old): best[key] = entry return list(best.values())

压缩规则必须放在采集阶段,而不是分析阶段。如果分析阶段再去压缩,说明记忆已经污染了分析结果,回退成本会更高。

3.3 用 JSONL 持久化记忆,避免复杂数据库依赖

实验阶段不需要 MySQL 或 Postgres,JSONL 足够。每一行是一条独立的 JSON 对象,天然支持追加写入,也方便用grepjq排查。

# lemmalog/memory/store.py import json from .entry import MemoryEntry def append_memory(path: str, entry: MemoryEntry) -> None: with open(path, "a", encoding="utf-8") as f: f.write(json.dumps(entry.to_json(), ensure_ascii=False) + "\n") def load_memories(path: str): entries = [] with open(path, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line: continue obj = json.loads(line) entries.append(MemoryEntry(**obj)) return entries

检查记忆文件是否写入成功:

cat .lemmalog/memory.jsonl

此时应该看到每行一个 JSON 对象,内容包含pathlinescorecontent等字段。如果某一行的line-1,说明这条记忆没有锚定到具体代码行,分析阶段要格外小心。

4. 把记忆变成程序分析:AST、符号标注和数据流检查

记忆采集完成后,下一步是把记忆与代码的客观结构绑定。这个阶段我不再依赖 LLM 的判断,而是用 Python 标准库ast解析代码,然后把相关记忆作为“证据”附加到 AST 节点上。

4.1 为什么最终要落到 AST:LLM 记忆不能直接作为程序事实

程序分析要求结论可复现。同一份代码,今天分析结果必须和明天一样。LLM 输出本身有随机性,直接让它判断“有没有未定义变量”是不稳定的。

AST 给出了代码的客观语法结构:哪些地方定义变量,哪些地方读取变量,哪些节点是函数调用,哪些节点是赋值。Lemmalog 的做法是让 AST 负责“事实”,让 LLM 记忆只负责“线索”。例如,LLM 说build_config函数里api_key可能未定义,AST 就去检查这个变量是否在所有分支里都有赋值。如果 AST 确认未定义,才把这条线索升级为问题。

4.2 用 ast 模块构建最小语法树

Python 标准库把源码解析为 AST 非常方便:

# lemmalog/analysis/ast_builder.py import ast def build_ast(source_code: str): try: return ast.parse(source_code) except SyntaxError as exc: raise ValueError(f"无法解析代码: {exc}") from exc

这里的异常处理不能省。LLM 记忆再准确,遇到语法非法的代码也无法工作。错误信息要带上具体行号和列号,方便排查。

4.3 用记忆标注 AST 节点:让分析器看到“为什么”

AST 本身只有结构和位置,没有语义判断。Lemmalog 需要一个MemoryAnnotator,它遍历函数定义、赋值和调用节点,然后在记忆文件里查找对应的pathline

# lemmalog/analysis/annotator.py import ast from collections import defaultdict class MemoryAnnotator(ast.NodeVisitor): def __init__(self, memories): self.memories = memories self.index = defaultdict(list) for m in memories: self.index[(m.path, m.line)].append(m) self.annotations = [] def _annotate(self, node, node_type): related = self.index.get((getattr(node, "path", ""), node.lineno), []) if related: self.annotations.append({ "node_type": node_type, "name": getattr(node, "name", ""), "lineno": node.lineno, "memory": [m.content for m in related if m.kind != "conflict"], "conflicts": [m.content for m in related if m.kind == "conflict"], }) def visit_FunctionDef(self, node): self._annotate(node, "FunctionDef") self.generic_visit(node) def visit_Assign(self, node): self._annotate(node, "Assign") self.generic_visit(node) def visit_Call(self, node): self._annotate(node, "Call") self.generic_visit(node)

这个实现的关键点是:记忆必须通过pathline定位到 AST 节点,而不是通过文本相似度硬套。如果找不到对应的记忆,节点仍然会进入后续分析,只是没有额外证据。

4.4 数据流检查:从未定义变量场景看分析结果

我写了一个简化版未定义变量检查器,只处理最基本的赋值和读取场景。它不会处理作用域嵌套,也不处理闭包,但足以展示 Lemmalog 的分析链路。

# lemmalog/analysis/checkers.py import ast class UndefinedNameChecker(ast.NodeVisitor): def __init__(self): self.defined = set() self.used = [] def visit_Assign(self, node): for target in node.targets: if isinstance(target, ast.Name): self.defined.add(target.id) self.generic_visit(node) def visit_FunctionDef(self, node): # 先记录函数名本身已定义,再进入函数体 self.defined.add(node.name) self.generic_visit(node) def visit_Name(self, node): if isinstance(node.ctx, ast.Load): self.used.append((node.id, node.lineno)) self.generic_visit(node) def check(self): return [ {"name": name, "lineno": lineno} for name, lineno in self.used if name not in self.defined ]

实际运行时会发现,这个检查器会把print这类内置函数也算作未定义。实验阶段可以接受,但生产环境必须维护一份内置函数白名单,否则会产生大量误报。

4.5 把检查结果与记忆合并成完整证据

分析器不能只输出“第几行有未定义变量”,还要输出“LLM 当时为什么觉得这里有风险”。我把 AST 检查结果和记忆标注合并在一起,生成最终报告。

# lemmalog/report/builder.py def build_report(annotations, issues, source_path): return { "tool": "Lemmalog", "source_path": source_path, "annotations": annotations, "issues": issues, "issue_count": len(issues), }

到这里,Lemmalog 已经完成了从记忆到程序分析的转换:问题列表不再是模型随口说的“感觉有问题”,而是“AST 检查证实这里可能未定义,并且 LLM 记忆里有一条相关提示”。

5. 验证报告:用两个最小用例确认 Lemmalog 真的可用

写完核心模块后,必须用确定性的输入验证整条链路。验证的目标不是“程序能运行”,而是“输入、输出、退出码和报告内容都符合预期”。

5.1 验证用例一:未定义变量应该被准确报告

创建一个示例文件:

# examples/leak.py def build_config(env): if env == "prod": api_key = "sk-test-123" return api_key print(build_config("dev"))

先构造一条 LLM 记忆,写入记忆文件:

{"kind": "issue", "content": "build_config 中 api_key 只在某些分支赋值,return 时可能未定义", "code_snippet": "return api_key", "path": "examples/leak.py", "line": 4, "score": 0.9, "created_at": "2025-01-01T00:00:00+00:00", "memory_id": "test-001"}

然后运行命令行:

python -m lemmalog analyze examples/leak.py --memory .lemmalog/memory.jsonl

预期控制台输出会包含一条 issue:

[issue] examples/leak.py:4: build_config 中 api_key 只在某些分支赋值,return 时可能未定义 (score=0.90)

同时,AST 检查器会报告lineno=4api_key不在已定义集合中。两条信息合并,这条问题就从“模型猜测”变成了“有代码证据的建议”。

5.2 验证用例二:LLM 记忆中的类型漂移信息应能影响结论

第二个用例测试的是记忆如何补充只有语义层面才能发现的问题:

# examples/items.py def get_items(): return [1, 2, 3] items = get_items() items.append("hello")

AST 检查器不会发现类型问题,因为append("hello")是合法调用。但如果 LLM 记忆里有“get_items 返回 list[int]”这样的符号信息,Lemmalog 就应该在items.append的位置输出类型漂移提示。

{"kind": "annotation", "content": "get_items 返回 list[int],后续 append 参数应为 int", "code_snippet": "items.append", "path": "examples/items.py", "line": 5, "score": 0.75}

运行后报告里应该出现类型漂移提示,即便它不是严格的数据流错误。

5.3 预期输出与退出码检查

Lemmalog 的退出码设计如下:

退出码含义适合场景
0分析完成,没有问题CI 中表示通过
1分析完成,发现 issue 或高风险提示CI 中表示需要人工处理
2内部错误或输入不合法说明命令或文件本身有问题

验证时必须同时检查三件事:命令行是否正常退出,退出码是否符合预期,报告 JSON 中是否包含对应的memory_id。只看到屏幕上有文字还不够,因为文字可能来自错误路径。

6. 我踩过的坑:记忆污染、数值精度和上下文截断

实验能跑通之后,紧接着就是各种奇奇怪怪的问题。下面三个坑是我在实际试错中遇到最多的,几乎每个都和“记忆不干净”有关。

6.1 坑一:把 LLM 的推测性描述当成真实代码事实

最常见的错误是记忆内容本身是错的,但程序分析器照单全收。比如模型说“配置项debug默认是 True”,实际上代码里根本没有这个变量,但分析器照样把它标注到某个节点上。

出现这种问题不是因为模型笨,而是因为程序分析器把“记忆里的内容”当成了“代码事实”。LLM 在生成回答时会补全缺失信息,这种补全对对话是友好的,对静态分析却是灾难。

解决方式分三步:

  • 每个记忆条目必须有score,低于阈值的记忆不能直接参与问题判定。
  • 程序分析器只把记忆当作“候选线索”,最终结论必须由 AST 或数据流检查确认。
  • 当记忆内容与 AST 结构冲突时,以 AST 为准,并在报告中标记memory_conflict

注意:不要为了提高召回率把低置信度记忆直接算成 issue。宁可漏报,也不要让分析器输出一堆无法追责的“幻觉问题”。

6.2 坑二:FP16、FP32、BF16 精度影响向量检索相似度

如果 Lemmalog 使用 embedding 向量召回记忆,数值精度问题会直接影响结果。FP16 可以节省显存和存储,但会损失小数值的精度;BF16 的指数范围和 FP32 接近,但尾数精度更低;FP32 最稳定,但占用空间最大。

精度存储占用数值稳定性推荐场景
FP324 字节/元素实验阶段、对精度敏感的记忆检索
FP162 字节/元素显存紧张但能接受轻微精度损失
BF162 字节/元素中,指数范围大但尾数精度有限大模型推理时常用,检索时要做归一化

我在实验里遇到的现象是:用 FP16 存向量后,两条语义非常相似、本来应该召回的记忆,相似度从 0.92 掉到 0.88,结果低于阈值,分析器丢掉了关键线索。排查方法是把同一个记忆库分别在 FP32 和 FP16 下算一遍相似度,对比 TopK 结果是否一致。生产环境如果必须用低精度,建议在写入向量库前先做向量归一化,并且把阈值留出 0.05 左右的余量。

6.3 坑三:上下文窗口太小时,记忆被截断导致张冠李戴

LLM 调用时如果 Prompt 太长,有的接口会静默截断,或者按 token 数截断,但不会告诉你丢掉了哪一部分。Lemmalog 早期经常出现“记忆内容和行号对不上”的情况,后来发现是前置代码超过了模型最大输入长度,模型回答时补全了一个看起来合理但错误的行号。

排查路径是:在采集记忆时记录本次请求的 token 估算值,如果接近模型上下文上限,就给这条记忆打上truncated标记。分析阶段遇到truncated标记的记忆,最多把它当低置信度提示,不能作为高置信度证据。

6.4 从错误结论倒推记忆链路的排查顺序

当 Lemmalog 输出了一个明显错误的问题时,我建议按照固定顺序排查:

  1. 先看报告 JSON 里的memory_id,确认问题到底来自 AST 检查还是记忆标注。
  2. 再到memory.jsonl里按memory_id找到原始记忆,检查pathline是否正确。
  3. 检查score是否低于阈值,低置信度记忆是否被错误升级成 issue。
  4. 检查code_snippet和 AST 节点行号是否一致,是否存在上下文截断导致的行号漂移。
  5. 如果涉及向量检索,用相同 query 重新计算 Top5 相似度,确认精度和阈值设置没有导致漏召回。
  6. 如果以上都正常,最后才检查程序分析器本身的作用域处理是否有误。

这套顺序的核心逻辑是:先怀疑输入,再怀疑配置,最后才怀疑代码逻辑。因为程序分析器只要输入稳定,输出就稳定,最不可控的永远是 LLM 记忆部分。

7. Lemmalog 的边界与生产化建议:从个人脚本到团队工具

Lemmalog 作为实验项目是成功的,但离真正进入团队工具链还有很多距离。这一节我会说明学习环境与生产环境的差异,并给出可以复用的落地检查清单。

7.1 学习环境可以单脚本直跑,生产环境要分层服务化

学习环境里,python -m lemmalog analyze一条命令就能完成所有事。生产环境会遇到完全不同的约束:记忆库可能很大,不能每次全量扫描;多条流水线可能同时分析不同分支;分析报告需要包含 Git 版本、触发人、代码评审上下文;敏感信息不能随便写入日志和向量库。

一个更合理的生产架构是:

  • memory-service:负责写入、检索、压缩记忆,存储层使用真正的向量数据库。
  • analysis-service:接收代码快照和记忆检索结果,执行 AST 和数据流分析。
  • report-service:生成报告、维护历史记录、对接 CI 回调。
  • 每个服务都带trace_id,这样一份报告里的每个结论都能追溯到原始记忆和代码版本。

7.2 落地前必须处理的权限、版本、日志和回滚

程序分析工具会读取大量源代码,如果处理不当,它本身就是安全风险。LLM 记忆里可能包含密钥、内部接口地址、未公开的业务逻辑。生产环境必须做到:

  • 记忆内容写入前先做脱敏,密钥和 Token 必须用环境变量或密钥管理服务引用。
  • 每次分析都记录 Git commit hash,报告与代码版本强绑定。
  • 记忆文件按日期快照,分析器使用只读视图,避免误写污染历史数据。
  • 分析服务要有独立日志文件,日志里不要打印完整代码片段,只打印路径和行号。

7.3 下一步扩展:Agent 记忆、微调、LLM wiki 式知识库如何取舍

很多人在 Lemmalog 跑通后会想继续扩展,最常见的方向有三个。

Agent 记忆适合解决“多轮分析任务里,工作记忆不共享”的问题。可以把短期工作记忆和长期知识记忆分开:短期记忆记录当前 PR 里改动了哪些文件,长期记忆记录项目历史结论和规则。但引入 Agent 会增加大量不可控的调用链,建议等到基础静态分析报告稳定后再做。

微调是最不推荐的扩展方向。Lemmalog 的核心价值是记忆格式和程序分析流程,而不是让模型记住更多代码。微调成本高、更新慢,而且无法保证输出结构稳定性。除非你有大量反复复现的领域规则,否则不需要动模型。

LLM wiki 式知识库适合整理文档和团队约定,但对程序分析来说,文档型知识不足以替代 AST 证据。它可以在分析结果生成后作为解释材料,而不应该进入问题判定逻辑。

7.4 可复用的发布前检查清单

每次把 Lemmalog 或类似工具部署到新环境前,建议逐项检查:

检查项验收标准
记忆写入格式每条记忆都有pathlinescorememory_id
置信度阈值低置信度记忆不会直接产生 issue
AST 解析语法错误能返回可读错误信息,而不是崩溃
行号对齐记忆行号与 AST 行号一致,不一致时降级为提示
精度策略向量库精度和相似度阈值已通过测试用例验证
上下文截断超长 Prompt 产生记忆时有truncated标记
报告可回放同一代码版本和记忆文件能稳定复现同一报告
敏感信息源码、日志、记忆文件中不出现明文密钥和 Token
CI 退出码有 issue 时退出码为 1,内部错误时退出码为 2
回滚方案记忆文件有快照,分析服务可以随时切回上一版本

Lemmalog 真正教会我的不是让 LLM 更聪明,而是让 LLM 的每次观察都留下可审计的痕迹。程序分析需要的不是一个会背代码的模型,而是一套能把模糊记忆转化成确定证据的流程。如果你也打算把 LLM 接入代码分析工具,我建议先从一个很小的记忆格式开始,先把 AST 证实、记忆追溯和报告回放这三件事做扎实,再考虑模型本身的升级。这条路比直接让模型大喊“这里有问题”要慢,但每一条结论都更值得信任。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 6:56:06

四、STL 容器与数据结构(进阶)(一)

四、STL 容器与数据结构()一句话总览:STL 容器的选择本质上是在“连续内存、节点结构、有序性、哈希查找、插入删除效率、缓存友好性”之间做权衡;vector 是默认首选,map/set 适合有序和范围查询,unordered…

作者头像 李华
网站建设 2026/9/1 6:55:21

QtBluetooth开发实战:环境配置、权限处理与HC-05设备扫描

简介:一份面向 Qt 开发者的蓝牙通讯实践资源,围绕 QtBluetooth 模块讲解如何实现设备搜索、连接与数据收发,适用于正在学习 Qt 蓝牙编程或需要快速搭建 BLE 与常规蓝牙调试工具的开发者。资源共 12 个文件,含 4 个 cpp 源文件、3 …

作者头像 李华
网站建设 2026/9/1 6:54:16

【计算机毕业设计单片机案例】 射频通信下的病房呼叫硬件终端与移动端管控系统设计 基于 STM32 或 51 单片机的 4 路病人呼叫信号采集报警系统设计(020205)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/1 6:54:07

基于J-Link RTT的嵌入式高效日志系统设计与优化

简介:这款源码包围绕Jlink RTT Viewer的日志优化而设计,面向使用ARM Cortex-M系列芯片的嵌入式开发者,旨在解决调试过程中日志缺乏时间标记、优先级不可视、中文乱码等常见问题。工程基于SEGGER的RTT实时终端库实现,提供了INFO、D…

作者头像 李华
网站建设 2026/9/1 6:51:46

OpenCV+MediaPipe人体姿态检测实战:关键点识别与动作判断源码解析

简介:该代码包是面向Python开发者的OpenCV与MediaPipe实时人体姿态检测工程,适合正在学习计算机视觉,或需要在项目中快速接入人体关键点识别功能的读者。压缩包仅7KB,共5个文件,包含Python主程序、txt依赖清单、Markdo…

作者头像 李华