自我介绍
面试官你好,我叫刘玄昊,目前在瑞典查尔姆斯理工大学读计算机系统与网络方向的硕士,预计 2027 年毕业。本科是哈尔滨工业大学深圳校区计算机科学与技术专业。
我目前在做的是硕士论文相关的 agent 项目,方向是面向代码库的自动漏洞发现、审计、修复的全套工作流。具体来说,就是能够覆盖三种情景,处理 issue、检查 PR 中的安全问题,对整个代码库进行扫描发现漏洞,修复,且给出分析,供人阅读。
技术上,主要使用 python、langchain 构建多阶段的 agent,这是 agent 的部分,产品化方面,接入了 github app 和 github actions 进行实际的测试,在真实的仓库里通过 webhook 相应 issue 和 PR,效果良好;理论方面,在 patcheval 这个 CVE 漏洞数据集上,230 个 任务中成功了 78 个,接近最佳水平。
我认为我个人的优势是比较了解 coding agent 的设计,也能从设计原型出发推进到产品。
HR:
论文方向就是 AI Agent 代码安全审查与修复
目前课程和论文主体工作都已经比较靠后了,系统实现大部分完成,也有阶段性实验结果。现在主要还剩补充实验、结果分析、论文文本整理,以及后续和导师确认答辩、提交或发表 conference 相关事项。下半年可能需要回学校处理一次毕业相关流程,大概就1-2天吧,但时间会提前协调,不会影响实习的稳定性。
项目亮点
和背景,相关工作不同
端到端
起点可以是没有任何触发条件,也就是不一定需要 问题描述 和 PR 的代码提交——我们有自己的 agent 扫描过程,可以从整个代码库扫描。
终点也不只是只产出补丁,而是会将补丁按照一定的规则进行合并,避免审阅者看到非常多零散的补丁,或者说 PR 而感到困惑。
内部设计方面
关于内部设计亮点,首先要说明的是我们的 agent 工作流,核心的部分是 analyzer、mitigate 和 verifier,字面意思就是分析、修复、验证。
亮点是引入了一个 agent 的反馈循环,mitigate 产出补丁后,verifier 会去验证补丁,以及 analyzer 结论的正确性,如果判断有问题,那么就会返回到 mitigate 返工。
你可以认为这是 reflection 的变体。
组件方面 - 记忆机制
我们引入了 skills、mcp,也引入了记忆机制。
记忆机制是这样的,他的形态类似于 skills,是 一个全量加载的 memory.md 搭配 topic 目录下的众多文件。
当主要的 agent 结束工作后,他们的记录,或者说完整轨迹会被记录下来(JSONL),然后首先提供给 extractor 做初步的提取,得到 observation,这就是粗经验。
接着还有一个专门的 maintainer 会去将这些粗经验整理到 memory 的目录,同时也能做去重、清除碎片、消解矛盾事实的任务。
细节
这个问题最开始是从 Agent 编辑工具里暴露出来的。很多 coding agent 的 edit 工具都是 old_string -> new_string 这种形式,要求模型给出一段原文,再给出替换后的文本。但如果目标文件原本是 CRLF 换行,而模型在输出 old_string 时通常会默认使用 LF 换行,那么这段 old_string 和文件里的真实字节内容就对不上,编辑工具会找不到匹配位置,导致替换失败。
更麻烦的是,这类错误 Agent 自己很难纠正。它会反复认为自己复制了正确的代码片段,但实际上只是换行符不一致;于是可能连续多次 edit 失败,直到达到工具调用次数或运行时间上限。
所以后来我在项目里改造了 Agent 的 edit 工具,对 old_string 做了换行的模糊匹配,兼容 LF、CRLF 以及末尾换行差异,再定位并替换目标内容。这样可以显著减少因为换行符不一致导致的编辑失败。
难点 / 遇到过什么困难
讲一个破除思维定式的话题吧。
虽然我现在说我的项目有 对代码库全仓扫描 这个功能,但是一开始我们其实是没有做这种东西的,因为我们当时认为不太可行。
直到今年1、2月的时候听说了 claude code security,宣传页传说可以对任何代码库进行扫描分析、修复漏洞,当时我们就震惊了,也在和同学、导师探讨这东西可能是怎么做到的。
我们当时的观点是认为代码库的体量大了之后,用大模型去扫描,发现问题就有很高的成本,所以可能是用了比较便宜或者轻量的模型。但是这和它 agent 的工作原理无关。我们还是不知道他是如何扫描的。比较没有头绪。
然后还有一个影响就是,我们当时也正好在做调研,有关于自动漏洞修复这块的,不管说 agent,还是说 benchmark,他们都是从一个给定的任务描述开始的,而并不是从什么都没有的代码库开始的,这也给我有了一个深刻的印象,就是基本没有人去做从零开始的“端到端”。
所以当导师再次说能不能做端到端的时候,我给出了否定的回答,当时来看理由是比较充分的,但是导师不满意。于是我又继续去想办法。
于是我们想到的朴素的办法就是让 agent 读代码文件,而不是给出代码库访问权限,来给出可能的漏洞候选。比如代码库有29个文件,那么就并发数为 8,然后其实也很快就处理完了,这是时间上;而从 token 消耗来看,其实我们忽略了一个非常重要的点,就是像这样的,比较单一的任务,其实就接近于一次 llm 调用,其 token 消耗是远低于 agent 的,所以哪怕是扫描了代码库,其整体消耗还是不如 agent 的。
没想到效果还意外的好!而且这种办法的好处就是覆盖率非常高,很难出现说 agent 不去主动选择读取某些文件而导致漏洞误报的情况。朴实的办法反而效果很好。