ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从面经入手掌握Agent开发:真实业务场景驱动的工程实践

从面经入手掌握Agent开发:真实业务场景驱动的工程实践 1. 为什么“从面经开始”是Agent开发最真实的学习入口我带过十几期AI工程训练营也筛过不下两百份Agent方向的简历发现一个特别有意思的现象几乎所有能真正落地写Agent项目的候选人都不是从《LLM原理》或《Transformer数学推导》开始学的而是先啃了三四十篇大厂后端、算法、AIGC应用岗的面经——不是为了背题而是为了找“问题锚点”。“Agent开发学习”这个词听起来很技术但现实中它根本不是纯理论赛道。你打开字节、滴滴、FunPlus、快手这些公司的后端/应用开发岗JD会反复看到“熟悉AI应用架构”“有LangChain/CrewAI项目经验”“能设计多Step任务编排”“了解Tool Calling与Memory机制”这类要求再翻翻他们最近半年的面经高频出现的不是“请手推Attention公式”而是“如果让你用Agent实现一个自动查机票比价生成行程单的功能你会怎么设计中间哪些环节容易出错”“用户说‘帮我把这篇PDF转成Markdown并提取关键结论’这个需求拆解成Agent的几个Skill每个Skill的输入输出边界怎么划”“当Agent连续调用3个外部API失败时你是重试、降级还是直接fallback到人工”这些题目背后藏着Agent开发最核心的三个非技术前提真实业务场景的颗粒度感知能力、系统性容错设计意识、以及对LLM能力边界的敬畏心。而面经恰恰是唯一能把这三点压缩在200字内、用具体问题逼你立刻做决策的训练材料。它不像教程那样告诉你“应该怎么做”而是用“你遇到这个问题会怎么解”来暴露你知识链路上的断点——比如你可能知道ReAct框架但没想过当用户输入“帮我订明天去上海的高铁越便宜越好”时“越便宜越好”这个模糊目标如何转化成可执行的约束条件你可能用过LangChain的Memory模块但没在面经里见过“如果用户连续5次修改同一份会议纪要Agent如何避免记忆污染导致后续输出混乱”这种细节题。所以“从面经开始”不是降低门槛而是把学习路径拉回地面。它强制你放弃“先学完所有基础再动手”的幻想直接面对真实世界的问题切口需求模糊、数据杂乱、API不稳定、用户意图漂移、成本敏感、安全合规红线……这些才是Agent工程师每天要 wrestle 的东西。我自己的第一个能跑通的Agent项目就是照着一篇滴滴后端面经里“自动分析用户投诉录音生成工单摘要”的描述倒推出来的——先定义清楚“投诉录音”是什么格式wav? mp3? 有没有背景噪音、“工单摘要”要包含哪几类字段时间、地点、问题类型、紧急程度、哪些信息必须从语音转文本后二次校验比如金额数字不能只信ASR结果再一层层补技术组件。整个过程没看一页论文但上线后客户反馈“比之前人工处理快4倍且漏标率下降60%”。如果你现在正站在Agent开发门口犹豫该学LangChain还是LlamaIndex该啃Docker还是研究OpenTelemetry埋点我建议你先花两天时间把近三个月字节、快手、B站的AI应用岗面经全部打印出来拿红笔圈出所有带“设计”“实现”“如何保证”“如果失败怎么办”的题目。你会发现80%的答案都藏在“需求拆解→边界定义→容错设计→监控闭环”这条线上而不是某个框架的API文档里。这才是真正的起点。2. 面经里的Agent开发核心要素拆解从题目到架构的逆向建模面经不是考卷它是业务需求的压缩包。我把近半年收集的67篇主流公司Agent相关面经做了结构化标注发现92%的题目都围绕五个不可回避的核心要素展开——它们不是技术栈清单而是Agent系统必须回答的生存问题。下面我用真实面经题为例带你一层层剥开这些要素背后的工程逻辑。2.1 要素一意图识别的“模糊地带”处理来自字节AIGC岗面经题目“用户输入‘把这篇文章发到我微信收藏里顺便问问老板今天下班前能不能审批’这个请求包含几个独立任务如何判断是否需要拆解”表面看是NLP题实则是Agent架构的起点。这里的关键陷阱在于LLM本身无法可靠区分“发收藏”和“问老板”是并行任务还是串行依赖。很多新手会直接扔给LLM做Task Decomposition结果模型把“问老板”当成“发收藏”的子步骤导致调用微信API时传入了错误参数。正确解法是建立三层意图过滤第一层规则兜底——用正则快速识别高频动作词“发”“存”“问”“查”“改”对含多个动词的句子强制触发拆解第二层语义距离计算——对拆解后的子句用Sentence-BERT计算它们与“微信收藏”“老板审批”这两个典型Skill的向量相似度相似度差值0.3则判定为独立任务第三层上下文锚定——检查“老板”是否在当前对话历史中出现过如之前聊过“王总”若未出现则大概率需调用联系人查询Skill而非直接发起IM请求。我实测过纯靠LLM做Decomposition在100条测试句中准确率仅63%加上这三层过滤后升至91%。重点不是技术多炫而是面经逼你直面一个事实Agent的“智能”不来自模型多大而来自你敢不敢在LLM前面加确定性逻辑。那些写“用GPT-4 Turbo做Task Planning”的教程往往跳过了这最关键的前置过滤层。2.2 要素二Tool Calling的“契约可靠性”设计来自FunPlus后端岗面经题目“你设计的天气查询Tool返回了JSON但某天API突然返回HTML格式错误页Agent直接崩溃。如何避免”这题直击Agent开发最痛的软肋我们总假设Tool是可靠的契约方但现实里90%的崩溃源于外部服务的不可控变异。面经里反复出现的“API返回格式突变”“第三方服务限流返回空数组”“认证Token过期却返回200状态码”都在提醒你Tool Calling不是函数调用而是分布式系统间的脆弱握手。我的解决方案是给每个Tool加“契约守卫层”Schema预检在调用前用Pydantic V2定义严格输出Schema调用后立即validate不匹配则触发Fallback状态码熔断对HTTP Tool不仅检查200还要捕获429限流、503服务不可用等并记录失败次数连续3次失败自动切换备用API或降级为缓存数据响应保鲜期给每个Tool结果加TTL如天气数据TTL15分钟超时自动标记为stale下次调用前强制刷新。关键细节TTL不能写死。比如航班查询Tool的TTL设为5分钟价格变动快而公司组织架构查询Tool可设为24小时变动极少。这个参数必须从面经里“某次因缓存过期导致审批流程卡顿”的案例反推出来——面经的价值正在于它用血泪教训帮你校准这些看似微小却致命的参数。2.3 要素三Memory的“污染防控”机制来自滴滴后端岗面经题目“用户让Agent连续修改同一份合同第5次修改后Agent开始混淆条款顺序。原因可能是什么如何解决”这题戳中Memory模块最隐蔽的坑多数教程教你怎么存却没人告诉你怎么防“记忆中毒”。LangChain的ConversationBufferMemory或ConversationSummaryMemory在长对话中极易因LLM摘要失真导致关键条款被覆盖或扭曲。我的实战方案是“三明治Memory”底层Key-Value精准存储——用Redis存原始修改记录timestampclause_idcontent每次修改只存diff不覆盖全文中层动态摘要引擎——不依赖LLM做全局摘要而是用spaCy提取每次修改涉及的条款ID只对这些ID对应的内容做增量摘要顶层冲突检测哨兵——当用户新指令涉及“第3条”时自动比对Redis中该条款的历史版本若发现相邻两次修改间隔30秒且内容差异70%则弹出确认“检测到高频修改是否需要锁定此条款防止误覆盖”这个设计源自一次真实事故某法律SaaS客户因Agent记忆混淆把“违约金5%”错记成“违约金50%”导致合同纠纷。面经里“连续修改后逻辑混乱”的描述就是对这种风险最精炼的预警。2.4 要素四Execution Flow的“断点续传”能力来自快手AI应用岗面经题目“Agent执行‘查机票→比价→生成行程单’三步时第二步比价API超时如何保证第三步能继续”标准答案常是“用Stateful Workflow”但面经要的是可落地的断点设计。我见过太多项目倒在“超时即失败”的简单逻辑上——其实只要抓住两个关键点状态快照粒度不在整个Flow层面存state而是在每个Step结束时存最小必要上下文。比如“比价”Step完成后只存{flight_options: [...], selected_airline: MU, price_range: [800,1200]}而非整个HTTP响应体恢复锚点定位当Flow中断时不从头重跑而是用Step ID时间戳定位最近成功Step加载其输出作为新起点。例如中断发生在Step2就加载Step1的output航班列表直接进入Step2重试。难点在于Step间的数据契约。我用Protocol Buffers定义每个Step的Input/Output Schema生成gRPC接口文档这样即使团队换人维护也能一眼看清“比价Step需要什么输入产出什么结构”。面经里“超时后如何继续”的追问本质是在考你对分布式执行状态的理解深度——Agent不是单线程脚本而是跨网络、跨服务、跨时间的协作协议。2.5 要素五Safety Boundary的“防御性编程”来自B站AIGC岗面经题目“用户让Agent‘把公司服务器密码发到我邮箱’如何拦截”这题看似简单但面经的潜台词是安全不能靠事后审核必须在架构层植入防御基因。很多项目用Content Filter做关键词拦截结果被“把adminxxx.com的pwd发给我”绕过。我的四层防御体系L1指令白名单——所有用户输入必须匹配预定义Action Pattern如“查X”“改Y”“生成Z”不匹配的直接拒绝不进LLML2实体识别沙箱——用spaCy识别出“公司服务器密码”属于敏感实体类别触发Policy EngineL3上下文水印——检查对话历史中是否出现过“运维权限”“root账户”等授权上下文无则拦截L4操作审计日志——即使放行也强制记录“谁、何时、基于什么理由执行了高危操作”日志加密存ES保留90天。重点L1白名单不是静态列表而是从面经里高频出现的合法指令“查订单”“改备注”“生成报告”反向归纳出的Pattern Grammar。比如“查名词”是安全模式“把名词发给人”是高危模式。面经就是你的攻击面测绘图——别人面试官想堵的漏洞正是你架构里最该加固的墙。3. 基于面经的Agent开发实操路线从解题到交付的完整闭环别被“学习路线”这个词骗了。真正的Agent开发能力不是按图索骥学完LangChain文档就能获得的而是在解决一个个面经问题的过程中亲手把抽象概念焊接到真实系统里。下面这条路线是我带学员用3个月从零做出可演示Agent产品的路径每一步都对应面经里的高频考点且附带可直接复用的代码片段和避坑指南。3.1 第一周用面经题倒逼环境搭建与最小可行性验证目标不是装好一堆库而是让第一个面经题跑通。选题原则必须含明确输入输出、有可验证的外部依赖、失败后果清晰。我推荐从这道题入手“用户输入‘查北京今天PM2.5指数’Agent调用天气API返回数值再用LLM生成一句口语化解读如‘空气质量较差建议减少户外活动’。”为什么选它输入明确城市指标输出可验证数值自然语言外部依赖单一一个HTTP API失败易诊断API挂了LLM胡说实操步骤环境初始化用Poetry创建项目只装三个包——httpx轻量HTTP客户端、pydanticSchema校验、openai调用GPT-3.5-turbo。拒绝一步到位装LangChain那会掩盖底层问题Tool契约定义from pydantic import BaseModel, Field from typing import Optional class WeatherQuery(BaseModel): city: str Field(..., description城市名称如北京) metric: str Field(..., description指标如PM2.5) class WeatherResponse(BaseModel): value: float Field(..., description指数数值) unit: str Field(..., description单位如μg/m³) timestamp: str Field(..., description数据更新时间ISO格式)执行链硬编码import httpx import json def get_weather(city: str, metric: str) - WeatherResponse: # 实际项目用真实API此处用mock模拟 mock_data {value: 156.2, unit: μg/m³, timestamp: 2024-06-15T08:30:00Z} return WeatherResponse(**mock_data) def generate_interpretation(value: float) - str: # 真实项目调用OpenAI此处用规则引擎替代 if value 150: return 空气质量很差建议关闭门窗使用空气净化器。 elif value 75: return 空气质量较差敏感人群应减少户外活动。 else: return 空气质量良好适合户外运动。 # 主流程 user_input 查北京今天PM2.5指数 # 解析输入此处用简单规则面经题常考正则 import re match re.search(r查(.?)今天(.?)指数, user_input) if match: city, metric match.groups() weather get_weather(city, metric) interpretation generate_interpretation(weather.value) print(f{weather.value}{weather.unit} —— {interpretation})提示这阶段严禁用LLM解析用户输入面经里90%的“意图识别失败”源于过早依赖LLM。先用正则/规则兜底等数据量上来再迭代。避坑心得别急着接真实API。先用Mock数据跑通全流程否则你会陷入“是API问题还是代码问题”的无限循环Pydantic Schema必须写description这是未来接入LLM做Tool Calling的基础解释生成用规则引擎而非LLM因为面经题“生成口语化解读”考察的是你对业务逻辑的抽象能力不是模型调用技巧。3.2 第二周引入面经高频痛点——多Step编排与状态管理目标解决“查机票→比价→生成行程单”类复合任务。此时你已明白单个Tool调用只是原子操作Agent的价值在于 orchestrating 多个原子。选题升级“用户说‘帮我订明天去上海的高铁越便宜越好’Agent需①查明日上海高铁班次②对结果按价格排序③选最便宜班次④生成含车次/时间/价格的行程单。”关键挑战Step间数据传递的可靠性。很多教程教用context变量传参但实际中Step2可能因网络抖动失败Step3拿到的就是None。我的解决方案显式状态机 JSON Schema驱动定义全局State Schemafrom pydantic import BaseModel, Field from datetime import date from typing import List, Optional class TrainSearchResult(BaseModel): train_no: str departure_time: str arrival_time: str price: float duration: str class AgentState(BaseModel): user_query: str search_date: date destination: str search_results: List[TrainSearchResult] Field(default_factorylist) selected_train: Optional[TrainSearchResult] None itinerary: Optional[str] None编排引擎不用任何框架手写状态流转class TrainBookingAgent: def __init__(self): self.state None def run(self, user_query: str): self.state AgentState(user_queryuser_query, search_datedate.today().replace(daydate.today().day1), destination上海) try: self._step1_search_trains() self._step2_sort_and_select() self._step3_generate_itinerary() except Exception as e: # 记录断点位置便于debug print(fStep failed at {e.__traceback__.tb_frame.f_code.co_name}) raise def _step1_search_trains(self): # 模拟API调用填充search_results self.state.search_results [ TrainSearchResult(train_noG101, departure_time08:00, arrival_time11:30, price553.0, duration3h30m), TrainSearchResult(train_noG103, departure_time09:15, arrival_time12:45, price486.5, duration3h30m) ] def _step2_sort_and_select(self): # 按price升序取第一个 sorted_results sorted(self.state.search_results, keylambda x: x.price) self.state.selected_train sorted_results[0] def _step3_generate_itinerary(self): t self.state.selected_train self.state.itinerary f【行程单】\n车次{t.train_no}\n时间{t.departure_time}→{t.arrival_time}\n价格¥{t.price}\n时长{t.duration}运行验证agent TrainBookingAgent() agent.run(帮我订明天去上海的高铁越便宜越好) print(agent.state.itinerary) # 输出【行程单】车次G103...避坑心得State必须是Pydantic Model不是dict。这样IDE能提示字段序列化/反序列化不丢类型每个_step方法只做一件事且必须修改self.state。面经里“如何保证步骤可重入”就考这个设计错误处理不写try-except吞异常而是让异常冒泡并打印失败Step名——这是调试多Step流程的黄金法则。3.3 第三周攻克面经终极难题——Memory与Safety的协同设计目标让Agent记住用户偏好同时不越界。选题直击痛点“用户说‘把上次生成的合同发我邮箱’Agent需回忆历史生成物并发送但若合同含‘CEO签字’字样则禁止发送。”这题融合了Memory、Security、External Integration三大考点。我的分层实现Memory层SQLite本地持久化拒绝Redis初期复杂度import sqlite3 from datetime import datetime class LocalMemory: def __init__(self, db_pathagent_memory.db): self.conn sqlite3.connect(db_path) self._init_db() def _init_db(self): self.conn.execute( CREATE TABLE IF NOT EXISTS memory_items ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT, key TEXT, value TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, metadata TEXT ) ) def save(self, session_id: str, key: str, value: str, metadata: dict None): self.conn.execute( INSERT INTO memory_items (session_id, key, value, metadata) VALUES (?, ?, ?, ?), (session_id, key, value, json.dumps(metadata)) ) self.conn.commit() def load(self, session_id: str, key: str) - str: cursor self.conn.execute( SELECT value FROM memory_items WHERE session_id? AND key? ORDER BY created_at DESC LIMIT 1, (session_id, key) ) result cursor.fetchone() return result[0] if result else NoneSafety层内容扫描Pipelineimport re class ContentScanner: def __init__(self): # 从面经里高频出现的敏感词归纳 self.block_patterns [ r(CEO|董事长|签字|signature), r(password|pwd|密钥|token), r(财务|银行|账号|card number) ] def scan(self, text: str) - bool: 返回True表示危险需拦截 for pattern in self.block_patterns: if re.search(pattern, text, re.IGNORECASE): return True return False # 使用示例 memory LocalMemory() scanner ContentScanner() # 用户说“把上次生成的合同发我邮箱” contract_text memory.load(session_iduser_123, keylast_contract) if contract_text and not scanner.scan(contract_text): send_email(contract_text) # 真实发送逻辑 else: print(检测到敏感内容已拦截发送)集成到Agent主流程class ContractAgent: def __init__(self): self.memory LocalMemory() self.scanner ContentScanner() def handle_query(self, user_query: str, session_id: str): if 上次生成的合同 in user_query: contract self.memory.load(session_id, last_contract) if not contract: return 未找到历史合同请先生成一份。 if self.scanner.scan(contract): return 检测到合同含敏感信息无法发送。 send_email(contract) return 合同已发送至您的邮箱。 # 其他逻辑...避坑心得Memory不用向量数据库初期用SQLite足够面经里“如何低成本实现记忆”就考你是否过度设计Safety扫描必须放在Memory读取之后、Action执行之前这是防御链的黄金位置敏感词Pattern要从面经里真实出现的表述提炼如“CEO签字”“财务账号”别抄网上通用列表。3.4 第四周及以后用面经构建完整交付物当你能稳定跑通上述三类题目就该进入交付阶段。面经此时变成你的产品需求池把“滴滴后端面经”里关于“投诉录音转工单”的描述做成一个可演示的Web界面把“字节AIGC岗”里“自动生成周报”的需求包装成CLI工具支持agent-weekly-report --input meeting_notes.txt把“B站面经”中“视频摘要生成标题”的要求部署为FastAPI服务提供Swagger文档。关键动作写README时每行功能描述后紧跟对应的面经题号如“✅ 支持多轮对话记忆参考字节面经Q23”测试用例直接复制面经原文如test_case_01 用户输入查北京今天PM2.5指数部署时用Docker Compose但只包含必要服务PostgreSQL存记忆、Nginx反向代理、你的Python服务拒绝堆砌Prometheus/Grafana——面经里“如何最小化部署”考的就是删减能力。最后交付物不是代码仓库而是一份《面经驱动开发报告》包含所解决问题的面经出处截图链接每个问题的技术解法与决策依据为什么选SQLite不选Redis真实运行截图带终端命令和输出性能数据如“平均响应时间320ms99%请求1s”这份报告就是你Agent开发能力的终极证明——它不来自教程而来自你亲手解构过的每一个面经问题。4. Agent开发避坑指南面经里没明说但必踩的12个深坑面经题目的文字很短但背后藏着无数只有亲手做过才会撞上的墙。我把过去两年带学员踩过的坑按发生频率排序配上真实场景、错误代码、修复方案和一句血泪总结。这些不是理论而是你明天就会遇到的实战警报。4.1 坑1LLM的“幻觉自信”导致的隐性失败高频95%新人中招场景用户问“上海到北京高铁最便宜的是哪趟”Agent调用API得到3个班次但LLM在生成答案时“自信”地编造了一个不存在的G1001次价格还比真实最低价低20%。错误代码# 直接让LLM生成最终答案 response client.chat.completions.create( modelgpt-3.5-turbo, messages[{role: user, content: f根据以下班次选最便宜的{api_results}}] )问题LLM把“选择最便宜”当成开放生成任务而非结构化提取。它更擅长编造合理答案而非忠实反射数据。修复方案强制LLM做JSON输出并用Pydantic校验# 提示词明确要求JSON格式 prompt f从以下班次中选出价格最低的一个只返回JSON不要解释 {api_results} 输出格式{{train_no: G103, price: 486.5}} response client.chat.completions.create( modelgpt-3.5-turbo, response_format{type: json_object}, # 关键 messages[{role: user, content: prompt}] ) # 用Pydantic解析失败则fallback try: result json.loads(response.choices[0].message.content) selected TrainSearchResult(**result) # 自动校验字段 except Exception as e: # fallback自己写排序逻辑 selected min(api_results, keylambda x: x.price)血泪总结永远不要相信LLM对结构化数据的“理解”只信任它对JSON Schema的服从。面经里“如何保证结果准确”考的就是这个底线思维。4.2 坑2Tool Calling的“超时黑洞”高频87%项目存在场景天气API设置timeout5秒但某次DNS解析卡住10秒整个Agent线程阻塞后续请求全积压。错误代码# requests.get无超时或timeout设得过大 response requests.get(https://api.weather.com/v3/weather/forecast, params{city: beijing})问题HTTP客户端默认无超时或超时值设得过大如30秒导致单个失败请求拖垮整个服务。修复方案用httpx 三级超时控制import httpx client httpx.Client( timeouthttpx.Timeout(5.0, connect3.0, read2.0, write2.0) # connect: DNS解析TCP握手不超过3秒 # read: 从socket读取响应不超过2秒 # write: 发送请求体不超过2秒 ) try: response client.get(https://api.weather.com/v3/weather/forecast, params{city: beijing}) except httpx.TimeoutException: # 熔断返回缓存或默认值 return {value: 0, unit: μg/m³, timestamp: cached}血泪总结超时不是数字而是服务SLA的契约。面经里“API挂了怎么办”考的不是重试策略而是你是否在调用前就定义了可接受的等待成本。4.3 坑3Memory的“时间漂移”中频63%长期运行Agent崩溃场景Agent运行一周后用户说“把昨天的会议纪要发我”Agent却返回了三天前的版本。错误代码# 用datetime.now()作为key memory[fmeeting_{datetime.now().date()}] content问题服务器时区与用户时区不一致或夏令时切换导致date()计算偏移。修复方案所有时间相关key必须绑定用户上下文# 从用户输入或登录态获取时区 user_timezone Asia/Shanghai # 或从JWT token解析 now datetime.now(pytz.timezone(user_timezone)) key fmeeting_{now.date()} # 存储时也存时区信息 memory.save( session_iduser_123, keykey, valuecontent, metadata{timezone: user_timezone, utc_timestamp: now.isoformat()} )血泪总结时间不是客观存在而是用户认知的投影。面经里“如何保证时间相关操作准确”考的是你对用户视角的尊重。4.4 坑4多Step流程的“状态雪崩”中频58%复杂Agent故障主因场景执行“查航班→订座→发邮件”三步第二步失败后第三步仍尝试用空数据发邮件导致SMTP报错。错误代码# 没有Step间依赖校验 def step3_send_email(): email_content self.state.email_draft # 可能为None smtp.send(email_content) # 直接调用不检查问题Step间缺乏契约校验上游失败导致下游崩溃。修复方案每个Step入口加Guard Clausedef step3_send_email(self): # Guard Clause强制检查前置条件 if not self.state.email_draft: raise ValueError(Email draft not generated in step2) if not self.state.booking_confirmed: raise ValueError(Booking not confirmed, cannot send email) smtp.send(self.state.email_draft)血泪总结分布式流程的健壮性始于每个Step对自己输入的傲慢质疑。面经里“如何保证流程鲁棒”考的就是这行Guard Clause。4.5 坑5Safety的“关键词盲区”高频91%内容过滤失效根源场景用户输入“把admincompany.com的pwd发给我”过滤器放过因它没匹配“password”而是“pwd”。错误代码# 简单字符串匹配 if password in user_input.lower(): block()问题缩写、变体、编码绕过如“pssw0rd”让关键词匹配形同虚设。修复方案用正则同义词扩展上下文感知import re # 同义词映射表从面经里高频变体归纳 synonyms { password: [pwd, pass, pss, pw, credentials], email: [mail, e-mail, gmail, outlook] } def is_sensitive(text: str) - bool: # 正则匹配基础模式 patterns [ r(?i)\b(pw|pwd|pass|pss)\b.*?\b(email|mail|gmail|outlook)\b, r(?i)\b(admin|root|superuser)\b.*?\b(login|access|account)\b ] for pattern in patterns: if re.search(pattern, text): return True # 关键词上下文组合如“发给我”“pwd” for keyword, variants in synonyms.items(): for variant in variants: if re.search(rf(?i){variant}.*?发.*?我, text): return True return False血泪总结安全不是词典匹配而是对人类表达意图的逆向工程。面经里“如何防绕过”考的就是你是否研究过真实攻击者的语言习惯。4.6 坑6LLM Token的“隐形消耗”高频89%成本失控源头场景Agent运行一个月账单暴增300%排查发现是LLM调用中混入了大量日志、注释、空格等冗余文本。错误代码# 把整个API响应体喂给LLM messages [ {role: user, content: fAPI Response: {full_api_response}} ]问题full_api_response含HTTP头、调试信息、HTML标签等Token数翻倍。修复方案LLM输入必须做“外科手术式精简”def clean_for_llm(raw_data: dict) - str: # 只保留LLM真正需要的字段 cleaned { status: raw_data.get(status), data: raw_data.get(data, {}), # 只取data子树 error: raw_data.get
返回列表