惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
C
Cisco Blogs
博客园 - 叶小钗
P
Privacy International News Feed
Jina AI
Jina AI
Apple Machine Learning Research
Apple Machine Learning Research
T
Threatpost
IT之家
IT之家
博客园 - 聂微东
Know Your Adversary
Know Your Adversary
Help Net Security
Help Net Security
罗磊的独立博客
I
Intezer
S
Schneier on Security
博客园_首页
C
CERT Recently Published Vulnerability Notes
雷峰网
雷峰网
Cisco Talos Blog
Cisco Talos Blog
宝玉的分享
宝玉的分享
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Webroot Blog
Webroot Blog
TaoSecurity Blog
TaoSecurity Blog
MyScale Blog
MyScale Blog
P
Privacy & Cybersecurity Law Blog
T
The Exploit Database - CXSecurity.com
PCI Perspectives
PCI Perspectives
Security Latest
Security Latest
H
Heimdal Security Blog
S
Secure Thoughts
Hacker News: Ask HN
Hacker News: Ask HN
Y
Y Combinator Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Microsoft Security Blog
Microsoft Security Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
SecWiki News
SecWiki News
The GitHub Blog
The GitHub Blog
A
Arctic Wolf
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
T
Threat Research - Cisco Blogs
Engineering at Meta
Engineering at Meta
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
2026-06-15 Senior Agent Architect Interview Questions
quarktimes · 2026-06-15 · via DEV Community

quarktimes

Q1: [流式UI渲染中断与状态修复]

难度: Senior
领域: 生产化AI / Agent架构
对应工作: 今天修复 Flutter 聊天界面 AI 内容流式显示的打字机效果中断问题,排查文本追加逻辑和换行处理缺陷。

题目:
在一个 AI 对话 Agent 的前端展示中,SSE(Server-Sent Events)流式传输 AI 的回复内容。偶发情况下,打字机效果会中断,后续内容不再显示;而在尝试修复时,如果不小心修改了截断逻辑,会导致只显示第一行文字。请设计一套通用的流式状态更新机制,能够处理以下情况:

  1. 网络抖动导致的数据包乱序或延迟。
  2. Markdown 渲染库对未闭合标签的截断导致白屏。
  3. 状态更新并发竞态导致文本被覆盖而非追加。 请给出关键的状态管理代码逻辑,并解释如何设计日志系统来快速区分“后端数据发送停止”还是“前端渲染逻辑错误”。

答案要点:

  1. 核心思路:
    采用 累加器模式 结合 不可变状态更新,引入 Buffer 来处理流式片段,并确保 Markdown 渲染具备“容错”或“延迟渲染”机制。关键是将“网络数据接收”与“UI 渲染”解耦。

  2. 技术方案(伪代码示例,模拟 React/Flutter 通用逻辑):

# 伪代码:流式状态管理器
class StreamMessageHandler:
    def __init__(self, message_id):
        self.message_id = message_id
        self.full_content = ""  # 完整文本
        self.last_chunk = ""    # 上一次渲染的片段(用于防抖或增量渲染)
        self.is_complete = False

    def append_chunk(self, chunk: str):
        # 1. 数据校验与日志(关键:原始数据入参必须落盘/打点)
        self._log_debug(f"Received chunk: {repr(chunk)}")

        # 2. 核心累加逻辑(防止覆盖)
        self.full_content += chunk

        # 3. 状态更新(触发UI重绘)
        updated_content = self.full_content

        # 4. 换行/截断保护
        # 如果检测到只有第一行,可能是截断逻辑错误,此时不应修改 full_content
        if "\n" not in updated_content and len(updated_content) < 100:
             self._log_warning("Potential truncation detected")

        self._log_debug(f"Updated full content length: {len(updated_content)}")
        return updated_content

    def mark_complete(self):
        self.is_complete = True
        self._log_info(f"Stream complete. Final length: {len(self.full_content)}")

  1. 权衡分析:

    • 选择 A(全量重绘 vs 增量渲染): 全量重传给 Markdown 引擎性能开销大,但能保证格式正确(防止未闭合的 ** 导致整段加粗失效);增量渲染性能好,但极易出现样式闪烁或渲染错误。
    • 决策: 对于长文本(>500字),采用全量重绘配合防抖;对于短文本,可尝试增量。但在修复 Bug 阶段,优先全量重绘以确保数据完整性。
  2. 反面教训:

    • 只改截断不改追加: 今天在修复时,错误地以为文本太长被截断,结果修改了 Split 逻辑,导致只显示第一行。实际上问题在于 setState 时拿的是旧状态 oldText 而不是当前的 fullText
    • 日志缺失: 如果没有打印 chunk 的原始字节,永远不知道是后端没发数据,还是前端丢了数据。
  3. 量化指标:

    • 监控“流式中断率”:定义为 (预期Token数 - 实际渲染Token数) / 预期Token数。修复前约 2%,修复后应降至 0.01%。
    • 端到端延迟:Full Content 渲染完成时间与 SSE 结束时间的差值。

面试官视角:

  • 如果候选人提到 "Markdown 的 Ast Parser 在解析不完整流时的行为"(如 * 单独出现会吃掉后续字符),说明他真的做过流式渲染(加分,+20)。
  • 如果候选人只说 "使用 setInterval 轮询" 或者 "直接 innerHTML += chunk",说明他没做过复杂流式场景,不懂 XSS 风险和渲染性能(扣分,-20)。
  • 常见错误回答:"这是后端的问题,让后端发快点。"
  • 可以追问:"如果 SSE 连接断开了,前端怎么知道是发完了还是断网了?你的 HTTP 状态码或者事件监听是怎么设计的?"

Q2: [Title Agent 的多阶段编排与评分]

难度: Senior
领域: Agent架构 / Prompt工程
对应工作: 今天验收了 ai-developer-knowledge-hub 项目中的 Title Agent,该 Agent 需生成 3 个候选标题、评分并选出最佳标题。

题目:
你需要设计一个 Title Generation Agent,输入是一段长文本,输出是唯一的最佳标题。为了质量,不能只让 LLM 生成一个结果。你需要设计一个工作流:先生成 N 个候选,然后对 N 个候选评分,最后选出最高分。这里有三种架构方案,你会选哪种,为什么?
方案 A:Single Prompt,一次要求 LLM 输出 JSON [{"title": "...", "score": 10}, ...]
方案 B:ReAct 循环,第一步 Tool Call 生成候选,第二步 Tool Call 进行评分。
方案 C:DAG(有向无环图)编排,并行调用 3 个独立的 LLM 实例各生成 1 个标题,再聚合到一个 Judge Agent 评分。
请给出代码架构(伪代码),并分析在 Token 成本和响应延迟上的 Trade-off。

答案要点:

  1. 核心思路:
    选用 方案 C(DAG 编排)。因为生成标题是“发散性任务”,并行调用可以减少首字延迟且增加多样性;评分是“收敛性任务”,需要全局视角。A 方案容易导致评分注水或候选雷同,B 方案串行导致延迟叠加。

  2. 技术方案(以 LangChain/LangGraph 风格伪代码):

from typing import List

# 1. 并行生成节点
def generate_candidates(context: str) -> List[str]:
    # 通过 Promise.all 或 ThreadPool 并行调用 3 次,System Prompt 稍作区分(如不同温度或角色)
    prompts = [
        f"Generate a catchy title for: {context}",
        f"Generate a professional title for: {context}",
        f"Generate a keyword-focused title for: {context}"
    ]
    # 并行执行
    return [llm.invoke(p) for p in prompts]

# 2. 评分节点
def rate_titles(titles: List[str], context: str) -> dict:
    judge_prompt = f"""
    Context: {context}
    Candidates: {titles}
    Rate each candidate 1-10 based on relevance and click-through rate.
    Return JSON with the best title.
    """
    response = llm.invoke(judge_prompt)
    return parse_json(response) # {"best_title": "...", "reasoning": "..."}

# 3. 编排逻辑
def run_title_agent(context: str):
    # Step 1: 并行生成
    candidates = generate_candidates(context)

    # Step 2: 评分 (串行或并行)
    best_choice = rate_titles(candidates, context)

    return best_choice["best_title"]

  1. 权衡分析:

    • 方案 A (Single Prompt): 成本最低(1次调用),但 LLM 对自己的作品评分通常有偏差,且很难输出结构化的对比分析。
    • 方案 B (ReAct): 逻辑清晰,但如果 N 很大,Latency = T_gen + T_rate + T_gen + T_rate... 线性增长不可接受。
    • 方案 C (DAG): Latency = Max(T_gen1, T_gen2, T_gen3) + T_rate。性能最优,质量最高(因为不同 Prompt 激发不同创造力)。成本略高(4次调用),但对于标题生成这种高频但低成本场景完全可接受。
  2. 反面教训:

    • 在实际开发 Title Agent 时,如果只用一个 Prompt 要求“生成3个并选最好的”,LLM 往往会偷懒,生成 3 个几乎同义的标题,导致选择无效。
    • 必须在 Prompt 中强制要求 JSON Schema,否则 Judge Agent 可能会返回自然语言,导致解析失败进入 Dead Loop。
  3. 量化指标:

    • 多样性得分: 3 个候选标题的编辑距离,平均应 > 30%。
    • 用户采纳率: 用户不修改直接发布的比例。

面试官视角:

  • 如果候选人提到 "Temperature 设置差异"(生成时用 0.7-1.0,评分时用 0.1),说明他懂 LLM 的参数控制(加分,+20)。
  • 如果候选人只选方案 A 并说“Prompt 写得好就行”,说明他缺乏工程化思维,忽略了 LLM 的概率特性(扣分,-10)。
  • 常见错误回答:“用 Map-Reduce。”(回答太泛,没有针对生成和评分的具体区别)。
  • 可以追问:“如果 3 个并行生成的标题都很烂,Judge Agent 必须选一个,怎么办?你的系统支持‘回炉重造’吗?”

Q3: [流式传输中的“第一行陷阱”与边界处理]

难度: Senior
领域: 生产化AI / 踩坑题
对应工作: 今天在修复打字机中断时,引入了一个新 Bug:修改导致只输出第一行。这是典型的“修了一个 Bug 引入两个 Bug”的场景。

题目:
在处理流式文本追加时,为了解决“文本过长导致渲染卡顿”,你决定在前端做一个优化:只在渲染前 100 个字符,后续丢弃(或者只保留前 3 行)。结果上线后,用户发现 AI 的回答永远只有半截话。请从代码层面分析,这种“截断逻辑”错在哪里?如果必须做“性能优化”(不能全量渲染长文本),正确的做法是什么?请写出修复后的代码逻辑。

答案要点:

  1. 核心思路:
    错误在于混淆了 “状态存储”“视图渲染”。状态必须永远完整,视图可以只显示一部分(如虚拟滚动或折叠)。但题目中描述的逻辑是在“追加阶段”就丢弃了数据,导致后续没有数据可追加。

  2. 技术方案:

// --- 错误做法 (今天的坑) ---
function onChunk(chunk) {
  // 致命错误:直接修改了需要持久化的 text 状态
  let currentText = getTextState();
  let newText = currentText + chunk;

  // 错误的截断逻辑:为了渲染快,把数据截断了,导致下次追加时 newText 永远只有第一行
  if (newText.includes('\n')) {
    newText = newText.split('\n')[0];
  }

  setTextState(newText);
}

// --- 正确做法 ---
let fullTextBuffer = ""; // 永久完整存储

function onChunk(chunk) {
  // 1. 追加逻辑:绝对完整
  fullTextBuffer += chunk;

  // 2. 渲染逻辑:可以只渲染一部分,但不能破坏 Buffer
  let displayText = fullTextBuffer;

  // 性能优化示例:如果是纯文本且超长,只渲染倒数 N 个字符(模拟打字机光标处)
  // 或者使用 CSS 虚拟列表
  /*
  if (fullTextBuffer.length > 5000) {
     displayText = "..." + fullTextBuffer.slice(-4000); // 视觉优化,不影响数据
  }
  */

  // 3. 状态更新
  updateUI(displayText); // 仅用于显示
}

  1. 权衡分析:

    • 内存 vs 完整性: 保留 fullTextBuffer 会占用内存。但对于聊天气泡场景,单个文本极少超过 10k token,内存开销可忽略。
    • 如果必须截断: 只有在明确不需要历史记录的场景(如实时日志控制台)才在接收层截断。对于 AI 对话,必须保留全文以便用户复制、重新生成或总结。
  2. 反面教训:

    • 今天的回归: 为了解决“显示中断”,怀疑是“太长了”,所以加了 split('\n')[0]。实际上后端还在源源不断发第二行、第三行,但前端状态里永远只有第一行,新的 chunk 追加到第一行后面,变成了 Line1Line2Line3... 且没有换行符,看起来就是一串乱码或只有第一行。
    • 调试时必须确认“输入源”和“状态变量”的值,而不是只看 UI。
  3. 量化指标:

    • 无。此题考查的是逻辑正确性,而非性能指标。

面试官视角:

  • 如果候选人能立刻指出 “数据源与视图分离” 的原则,说明有扎实的架构基础(加分,+20)。
  • 如果候选人开始纠结“后端是不是发了换行符”,说明还没意识到是前端逻辑写死了(扣分,-10)。
  • 常见错误回答:“增加 buffer 大小。”(方向错了,buffer 再大,逻辑只要截断就没用)。
  • 可以追问:“如果用户在流式输出中途点击了‘停止生成’,你的状态机怎么处理?此时 Buffer 是不是完整的?”