Skip to content

AI chat模块

  • 不同的Agent有不同的提示词,上下文注入

  • SSE流式传输,麻烦的点在于EventSource有状态,并且需要持续建立长连接,以及网络不好会出现波动。

  • “高质量Prompt模板库”是怎么回事?

    • mcp+markdown的库,可以直接复制,也可以通过mcp进行检索
    • 通过mcp进行检索相关文件
  • “记忆库(Memory Bank)”是如何工作的?

    • 形成“Prompt-代码实现”的配对数据。
    • 我们会先用用户的Prompt去“记忆库”中做一次向量相似度检索。如果找到高度相似的历史交互,我们会把之前的成功代码作为高质量的示例(Few-shot Example)注入到新的Prompt中,极大地提升了生成代码的准确性和一致性。
  • 你提到的上下文注入,如果项目文件很大,上下文很容易就超出模型的Token限制了,你们是如何解决这个问题的?做了哪些截断或摘要策略?

    • 智能分块 (Chunking):当用户选择一个文件或目录作为上下文时,我们不会直接读取全部内容。而是在后台用一个基于AST(抽象语法树)的解析器,将代码拆分成更小的、有意义的块(Chunk),比如一个函数、一个React组件的class或function定义等。每个块都保持了其上下文的完整性。

    • 向量化与检索:我们将这些代码块转换成向量,并存在一个临时的内存向量数据库中。当用户发起提问时,我们会同时对用户的问题(Prompt)也进行向量化,然后用它去检索最相关的Top-K(比如Top 5)个代码块。

“记忆库”听起来很像Fine-tuning的数据准备过程。你认为它和直接对模型进行微调相比,各有什么优劣?

迭代效率提升50%是如何统计的?是基于Story Point、工时,还是其他的量化指标? - 统计过去的工时

实现了打字机效果:

- 方案:
    - innerHTML,然后批量setState;是一个不太好的方案
    - 直接使用setState
    - 使用raf,适用于高性能场景,一般是过度优化

为什么采用 Server-Sent Events (SSE) 结合 Fetch API 的 ReadableStream(而不是EventSource)?

核心需求::能够发起一个携带复杂数据(prompt、上下文等)的POST请求,并以流的形式接收响应,从而实现打字机效果

方案对比: - EventSource - 好处: - api简洁易用 - 会自动重连 - 缺点: - 只能用GET请求,不能用POST请求, 所以不方便发送上下文 - 也无法自定义请求头 - axios - 不支持响应流,只能整体返回resolve - fetch api - 缺点、问题: - 支持流式返回,麻烦一点点,但是需要手动重连 - 数据流的边界切分问题(需要处理不完整的消息) - 服务器推送的 SSE 事件流通常遵循一个简单的文本格式,即每个事件以 data: 开头,以两个换行符 \n\n 结尾; - 就是加入一个缓冲区变量,然后按照两个换行符进行切分,封成一个完整的事件即可。 - 中断控制:使用 AbortController 提供用户完全的控制权 - 好处: - 最关键的是,它允许我们访问响应体(Response Body)作为一个可读流(ReadableStream),这使得我们可以在前端手动地、一块一块地(chunk by chunk)读取服务器发送过来的数据流。

手动重连的方案:带抖动的指数退避

就是重连操作间隔指数增加:2、4、8、16等等。 同时每次都加一点 Random数据,避免客户端同时断线又同时重连触发。

追问:

  • 响应延迟降低了约80%,如何衡量?

    • 通过performance api进行测量,基于历史数据,网络良好的情况下,跑通链路并回复,需要5秒。
    • 我们在循环接收时,
  • 你提到将答案采信率提升了50%,这个数据是如何度量的?你们做了A/B测试吗?还是通过用户调研问卷?

    • 通过埋点以及A/B测试来反映方案是否更有效
    • 测试”回复率“, 比如复制相关的文本,或者点赞
      • A组(无来源)的“回答复制率”稳定在10%左右。
      • B组(有来源)的“回答复制率”则达到了15%。
  • 在处理流式响应时,如果一个数据块正好把一个JSON元数据对象从中间截断了,你的前端解析器要如何处理才不会崩溃并能正确拼接?

  • RAG的来源可视化方案听起来不错,但如果来源文档非常多,比如十几个,UI上会很杂乱。你对这种情况做了哪些优化或取舍?

  • 你提到的上下文注入,如果项目文件很大,上下文很容易就超出模型的Token限制了,你们是如何解决这个问题的?做了哪些截断或摘要策略?

  • “记忆库”听起来很像Fine-tuning的数据准备过程。你认为它和直接对模型进行微调相比,各有什么优劣?

  • 迭代效率提升50%是如何统计的?是基于Story Point、工时,还是其他的量化指标?

    • 我们会统计

SSE vs. WebSocket 的选型

- 就是更加轻量,对服务器压力更小。
- 以服务器生成为主,也没必要全双工。

如何量化效率提升?

  • 从最近几个月上线的项目中,分析需求规模以及从提出到上线的时间。
  • 然后对比使用AI之后的迭代时间。

AST相关的细节:

AST是做什么的?

  • 主要目的是为了静态分析:Babel,Eslint,Webpack,Vue,Typescript(类型检查和代码转换)

Rag中使用ast来做什么?

  • 通过@babel/parser将代码字符串转化为AST对象,然后通过逻辑单元进行分块
追问:
  • AST 解析的鲁棒性:如果用户注入的上下文代码本身存在语法错误,AST 解析会直接失败。你的系统如何优雅地处理这种情况?是降级为普通文本切分,还是直接向用户报错?

    • 降级为通过缩进和空行进行文本切分。
  • 性能瓶颈:当用户注入一个上万行的巨型文件(例如 vendor.js)时,在主线程中进行 AST 解析和遍历可能会导致界面卡死。你如何设计一个异步、非阻塞的 AST 处理流水线?会考虑使用 Web Worker 吗?

  • Source Map 的作用:你用 @babel/generator 从修改后的 AST 生成了新代码,但此时代码的行号、列号都变了。如果需要对生成后的代码进行调试或错误定位,你该如何处理?(答案指向 Source Map 的生成与消费)

  • 宏与代码生成:除了分析代码,AST 更强大的能力在于代码生成 (Codegen)。你了解 Babel 插件或宏 (Macros) 的工作原理吗?你能否设计一个 Babel 宏,比如 log.macro,它能自动在编译时给 log(variable) 语句注入变量名和文件名,变成 console.log("variable in file.js:", variable)?

  • CST vs. AST:你了解具体语法树 (Concrete Syntax Tree, CST) 和 AST 的区别吗?为什么 Prettier 选择使用 CST 而不是 AST 来进行代码格式化?(提示:CST 保留了包括空格、注释、括号在内的所有源码信息)

  • 安全风险:如果解析的 JavaScript 代码来自不受信任的第三方,直接 eval 或 new Function 执行 AST 转换后的代码存在哪些安全风险?你如何设计一个安全的沙箱环境来执行这些代码?

http请求断联的细节:

  • 这里的fetch是手动进行重连的,那么重连之后,连上之前和连上之后,原先的http请求会怎么处理呢?

    • 首先,原先的请求以及挂了,什么都没了。所以你新的请求需要携带所有信息。
    • 重连之前:
      • 抛出错误,并且会戛然而止。
      • 需要在UI当中更新指示器,说网络有问题。
    • 重连之后(新连接建立成功):
      • 清楚之前的流,重新加载。
  • 幂等性与服务器端:你每次重连都发送了完全一样的请求。如果这个请求不是幂等的(比如是一个创建订单的请求),重连可能会导致重复创建。对于一个 AI 对话服务,虽然看似幂等,但如果服务器为每个请求生成唯一的 trace_id 并记录日志,重连也会产生多条日志。你如何从架构层面(客户端与服务器端配合)来解决重连导致的副作用问题?(提示:客户端生成唯一的请求ID,并在请求头中传递)

  • 流式响应的“断点续传”:你提到每次重连都是从头开始。这对于短对话没问题,但如果模型正在生成一篇万字长文,已经输出了 80%,此时断线重连,用户会眼睁睁看着已经出现的内容被清空,然后从头再来一遍。这体验极差。你会如何设计一个支持**“断点续传”**的流式协议?(提示:服务器在每个数据块中附带一个 sequence_id 或 token_offset,客户端重连时在请求头中加入 Last-Received-Sequence-ID)

  • 用户体验的细节:在等待重连的几秒钟内,界面上的输入框应该是可编辑的还是禁用的?如果用户在重连期间修改了输入框里的 Prompt,重连成功后,是应该用旧的 Prompt 继续请求,还是用新的 Prompt 发起一个全新的请求?哪种是更合理的交互?

  • AbortController 的角色:在你的重连逻辑中,如果用户在等待重连时,不想等了,直接关闭了对话窗口或点击了“取消”按钮。你如何确保那个正在 setTimeout 等待的重连任务被彻底取消,避免不必要的后台请求?

本站访客数 人次 本站总访问量