Skip to content

[Bug] 聊天文件引用大量点不开或打开错误文件:缺少引用格式约定 + 解析退化到 basename 猜测 #1722

Closed

Description

@zszz3

What happened? / 问题描述

聊天回复中的文件引用大量点不开,或打开了错误的文件。

根因:系统提示词里没有任何文件引用格式约定(packages/agent-runtime/src/runtime.ts 的 defaultSystemPromptParts),模型随意输出反引号短文件名、行号范围、其他仓库/分支的相对路径;渲染端再把这些文本"猜"成文件:

  1. 渲染端 parseFileRefPosition / stripLineRef(apps/desktop/src/lib/chat-links.ts)只认 :line 与 :line:col,path:12-30、path#L12 不被识别为文件引用。
  2. 主进程 resolveChatFileRef(packages/host-runtime/src/chat-ref-resolve.ts)的尾段匹配会从完整路径一路退化到只剩 basename,并直接取第一个候选:带目录的引用会落到无关文件,同名文件多个时随意选一个。

本地统计(最近两周 77 个会话、1403 个助手回复中的文件引用,用当前渲染端识别 + 主进程解析器离线回放):

结果 占比
打开正确文件 64.7%
找不到文件(多为其他仓库或其他 git 分支的路径) 12.3%
渲染端不识别(主要是 :a-b 行号范围) 10.0%
打开了文件,但同名文件不唯一,可能是错的 7.2%
打开了文件,但仅部分路径匹配,大概率是错的 5.3%
项目外绝对路径被拒绝 0.5%

对照:Codex(新模型提示词)与 ZCode 都要求模型输出 [label](/absolute/path:line) 形式的 Markdown 链接,界面只按链接目标打开,不做 basename 模糊匹配。

Steps to reproduce / 复现步骤

在当前 main(3f365547d)上:

  1. resolvePreviewTarget("src/a.ts:12-30", root) 与 resolvePreviewTarget("src/a.ts#L12", root) 返回 null;src/a.ts:12 正常。
  2. 在一个只包含 crates/host-core/src/main.rs 的项目中,resolveChatFileRef("acp-server/src/main.rs", roots) 返回 crates/host-core/src/main.rs(matchedBy: path-suffix)。
  3. 项目中同时存在 a/runtime/runtime.ts 与 b/runtime.ts 时,resolveChatFileRef("runtime.ts", roots) 直接返回其中一个(matchedBy: basename)。
  4. 实际使用中:让 agent 解读另一个仓库或另一个分支的代码,回复里的文件名要么点不开,要么打开当前项目里的同名文件。

Expected behavior / 预期行为

  • 模型按统一格式输出文件引用,点击直接打开链接指定的文件并跳到对应行。
  • 无法确定唯一目标的引用保持普通文本(或让用户选择),绝不打开不相关的文件。
  • :12-30、#L12 等常见行号写法可识别并跳到起始行。

Actual behavior / 实际行为

约 1/3 的引用点不开或打开了错误文件;跨仓库、跨分支的会话里绝大多数引用不可用。

App version / 应用版本

0.21.0-beta.1(main 3f36554)

Operating system / 操作系统

macOS

Extra environment / 其他环境信息

darwin arm64

建议方向

  1. 系统提示词加入文件引用格式约定(详见下方评论)。
  2. 收紧解析:带目录的引用必须完整后缀匹配,不再退化到 basename;同名不唯一时不自动选择。
  3. 支持 :a-b、#L12、#L12-L20 位置写法。
  4. 后续可考虑优先用本会话工具实际读写过的文件路径解析短文件名。

Activity

  1. zszz3 commented on Oct 16, 2026

    @zszz3
    ContributorAuthor

    提示词修改建议

    在 packages/agent-runtime/src/runtime.ts 的 defaultSystemPromptParts 中,紧跟 "Visibility rules" 之后加一段文件引用规则。放在 [1:] 段里,自定义 SYSTEM.md 替换人设时也会保留。

    建议文本(基本沿用 Codex 新模型提示词,去掉了与 PI-Desktop 无关的部分):

    File references: when referencing a real local file, use a Markdown link with a short label and the absolute path as the target, for example [runtime.ts](/abs/path/packages/agent-runtime/src/runtime.ts:42).
    - Put an optional line number inside the target as :line or :line:column. Do not use line ranges.
    - If the path contains spaces, wrap the target in angle brackets: [My Report.md](</abs/path/My Project/My Report.md:3>).
    - Do not wrap file links in backticks, and do not put backticks inside the label or target.
    - Do not use file://, vscode://, or https:// for local files.
    - Only link files that exist on disk. A file you read from another Git revision or that no longer exists is not a local file: mention it as plain code text, or link the scratch copy you actually wrote.
    

    设计说明:

    • 为什么要绝对路径:主进程按链接目标精确解析,不再走 basename 模糊匹配;跨仓库的文件也能用同一种写法。
    • 为什么禁止行号范围:渲染端目前不识别 :a-b,而且范围对跳转没有额外价值。解析器仍应兼容范围写法(见 issue 第 3 点),因为历史消息和不遵守规则的模型还会产出这种写法。
    • 为什么写最后一条:本地统计里约 12% 的失败来自其他仓库或其他分支、磁盘上并不存在的文件。明确告诉模型这类引用写成普通文本,就不会产生"看起来能点、其实打不开"的链接。
    • 成本:约 120 tokens,计入每次请求的系统提示词。
    • 不在本次范围:会话压缩(compaction)提示词是否需要保留链接目标,建议单独评估。

    验证建议:在 runtime.test.ts 增加断言,覆盖 agent、plan、goal 三种模式,以及自定义 SYSTEM.md 替换人设的场景,确认最终系统提示词都包含这段规则;再用真实模型抽查几个会话,统计输出格式是否合规。

  2. SunkenCost commented on Oct 21, 2026

    @SunkenCost
    Contributor

    我在当前代码上把 issue 里提到的情况复现了::12-30 和 #L12 这两种行号格式没有被识别;带目录的文件引用有时会匹配到错误文件,同名文件有多个时也会直接选一个。

    我想跟进这个问题,先修正行号解析和文件匹配规则,并补上回归测试,避免路径不确定时误打开别的文件。如果维护者觉得这个方向合适,我会按 bug fix 提交 PR。

  3. zszz3 commented on Oct 22, 2026

    @zszz3
    ContributorAuthor

    2. 我在当前代码上把 issue 里提到的情况复现了::12-30 和 #L12 这两种行号格式没有被识别;带目录的文件引用有时会匹配到错误文件,同名文件有多个时也会直接选一个。
    我想跟进这个问题,先修正行号解析和文件匹配规则,并补上回归测试,避免路径不确定时误打开别的文件。如果维护者觉得这个方向合适,我会按 bug fix 提交 PR。

    我理解直接在system prompt里面加一段绝对路径的提示词可以更简单的解决这个问题?

  4. added 2 commits that reference this issue on Oct 22, 2026
    fb81b1f
    7a95fd0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions