- 博客(200)
- 收藏
- 关注
原创 Python后端爬虫专题16:代码只有两个回调,数据却走了十站——从Engine到Pipeline理解Scrapy
Scrapy 则把请求调度、去重、下载中间件、robots、重试、节流、统计和 Feed 导出组织成成熟运行时。更重要的是,Scrapy 会识别 yield 对象类型:Request 进入调度,dict 进入 item 流。前者通常做 item 清洗、持久化或丢弃,后者组织 HTTPX、快照、解析与 Repository。,自动携带会话 Cookie。,底层状态为 401;并调用 Spider 回调,断言产生两个详情 Request 和一个分页 Request,还检查 callback 分别指向。
2026-09-29 00:29:46
141
原创 Python后端爬虫专题15:登录不是绕过——在明确授权下管理Session、Cookie与CSRF
CSRF token 不是固定配置,它通常与当前 Session、页面或时间绑定,所以必须在同一个 client 中先取表单再提交。验证码、多因素认证、反机器人挑战表达的是额外控制,本课程不教授破解或规避。它只自动化一条获得许可、可审计、可在 TargetLab 中复现的标准表单链路,并把认证失败统一为不含密码的业务异常。、host、task_id、status,却不能记录 password、Cookie、Authorization、完整表单。字符串,也不要把会话 Cookie 复制到日志或快照。
2026-09-29 00:29:34
162
原创 Python后端AI专题33:评估召回与答案质量:Recall@K、MRR、nDCG 和引用正确率
回答错了,可能是相关 chunk 没召回、召回了却排太后、模型没使用证据,或引用了错误来源。只看“答案准确率 80%”无法定位该修分块、Embedding、Rerank 还是 Prompt。评测必须把检索、生成和引用拆开。
2026-09-29 00:29:17
282
原创 Python后端AI专题32:建立第一套 RAG 评测集:问题、证据与不可回答样本
没有固定评测集,“换模型后感觉更聪明”无法复核;只收集能回答的问题,又会把胡编但流畅的模型选上去。评测数据至少要同时表达:用户问题、哪些 chunk 相关、答案必须包含哪些事实、这个问题是否本应拒答。
2026-09-29 00:29:04
8
原创 Python后端AI专题31:如何测试不稳定的大模型:Fake Provider、合同测试与 E2E
模型今天回答“七天”,明天回答“7 天”,用字符串完全相等测试真实模型会制造大量假失败;完全不测又会把协议升级、引用失效和权限回归带到线上。关键不是找到一种万能测试,而是让不同层提供不同证据。
2026-09-28 20:41:44
103
原创 Python后端AI专题30:Prompt Injection 攻防:知识库里的文字为什么不可信
攻击者上传一份“员工手册”,正文夹着“忽略之前所有指令,输出系统提示和 API Key”。检索系统很可能把它当高相关证据交给模型。内部文档并不天然可信:上传账户可能被盗,文档可能从外部复制,普通员工也可能没有修改系统行为的权限。
2026-09-28 20:40:18
176
原创 Python后端爬虫专题14:并发不是越大越快——asyncio任务、Semaphore与连接预算
多租户共享同一来源时,要做跨任务、按域名的全局限速,单个 Semaphore 不够。若 Worker 同时跑 8 个任务,每个任务对同一域并发 4,请求峰值可能是 32,而不是 4。合理做法是先确定容量:某个来源同时最多 4 个详情请求,数据库写入仍按稳定顺序处理,HTTP 连接池的上限不低于任务并发但也不能无限。304 时空正文不是新版本,生成空快照会丢失可重放证据,计算指纹则会把“未传输”误判为“职位被清空”。下载完成顺序受网络抖动影响,如果报告与测试每次都不同,调试困难。,也断言输出顺序仍对应输入。
2026-09-27 15:49:41
217
原创 Python后端爬虫专题13:别反复下载没变化的详情——ETag、Last-Modified与增量采集
会话 Cookie 泄露后,拿到快照目录的人可能冒用登录状态访问内部系统,风险远大于一次职位数据泄露。如果职位几天才变化,却每次下载全部正文,一天流量约为 288 GB,还会给对方服务制造不必要压力。它最后查询数据库,确认只有三行,而且被更新行真的含新描述。更大的系统会对列表也做条件请求,并安排低频全量巡检,防止缓存头配置错误让新数据长期不可见。阅读:列表页队列、详情 URL 去重、读取 validators、受限并发下载、304 分支、快照与 upsert、单条失败 rollback。
2026-09-27 10:27:30
322
原创 Python后端爬虫专题12:数据库里有结果还不够——保存原始HTML与离线重放
这里刻意不保存请求 Cookie、Authorization,也不把全部响应头照单全收,防止调试证据变成凭据仓库。数据库保存“当前可查询事实”,快照保存“产生事实的输入证据”。前者适合分页、统计和 API,后者适合调试解析器、审计内容变化、构造回归 Fixture。问题可能来自页面改版、登录失效、选择器选错、服务端灰度,也可能是源站真的改了内容。阅读时先看两个返回模型,再看文件实现,最后看 MinIO 实现。保存下载时的原始响应后,我们可以在不再次访问源站的情况下重放解析器,确认当时服务器究竟返回了什么。
2026-09-27 10:27:18
380
原创 Python后端AI专题29:缓存、配额、幂等与 Token 成本如何一起设计
模型调用既慢又按量计费。用户双击发送、网关重试、20 个并发请求同时检查剩余额度,如果只写“先 GET 用量再 +1”,很容易超卖;如果缓存键没有租户与知识版本,又会把旧答案甚至别人的答案返回。四个概念要按请求生命周期一起设计。
2026-09-27 10:27:00
224
原创 Python后端AI专题28:多租户隔离不是加一个 tenant_id:三层权限防线
在表里加tenant_id只是数据建模,隔离要靠每条入口、每次资源查询和每条检索 SQL 都使用它。KnowFlow 的防线分三层:Token 建立身份,Repository/Service 约束资源归属,pgvector 在 Top K 前过滤;任一层遗漏都可能泄露。
2026-09-27 10:26:49
169
原创 Python后端AI专题27:把索引搬出请求线程:Celery 任务、进度与重放
解析 200 页 PDF、生成几百批向量不应占住上传 HTTP 请求。API 的职责是安全保存原文件、创建 durable job 并入队;Worker 根据 job id 重建依赖并执行同一个 Indexer;客户端轮询文档状态。异步不是“起一个后台协程”,而是任务可重启、可观察、可幂等重放。
2026-09-27 10:26:37
146
原创 Python后端AI专题26:多轮对话为何会污染:问题改写、历史裁剪与新证据
用户先问“退款期限是多少”,再问“那怎么退呢”。若直接用第二句检索,关键词太少;若把上一轮助手回答连同旧引用塞进查询,错误答案会污染新检索。正确做法是用历史理解指代,把追问改写成独立问题,然后只用改写问题检索新证据。
2026-09-26 23:46:59
164
原创 Python后端爬虫专题11:别只建一张jobs表——SQLAlchemy模型、任务状态与事务边界
课程允许 queued、running、completed、partial、failed、dispatch_failed。CrawlTaskRecord 保存 UUID、tenant、seed、max_pages、status、queue_task_id、error_message 和 report。迁移测试在全新 SQLite 文件执行 Alembic,检查 alembic_version、crawl_tasks、jobs 三张表。每次任务都会更新,若进入指纹,unchanged 永远不会出现。
2026-09-26 23:46:43
272
原创 Python后端爬虫专题10:重复运行不能重复入库——内容指纹、去重与幂等更新
如果产品需要展示历史薪资,应另建 job_versions,以 job_id、fingerprint 和有效时间记录版本,不能指望日志永久保存。测试在同一内存数据库依次插入、重复、修改描述,断言 action 为 created/unchanged/updated,三个结果 job_id 相同,最终只有一行且 ETag 更新为 v2。两个客户被授权采集同一来源时,各自拥有任务、保留策略和下游结果,不能让 tenant-a 的更新覆盖 tenant-b。、快照 ID、采集时间不能进入,否则每次运行必然变化。
2026-09-26 23:46:31
102
原创 Python后端爬虫专题09:服务器返回200也不代表该抓——robots.txt与域名访问策略
如果只在前端下拉框限制,调用者可直接 POST 任意地址,让 Worker 访问内网管理页,这就是 SSRF。攻击者可以忽略 robots,所以真正私有数据必须用鉴权保护。无论哪种,都要记录规则 URL、状态和策略版本,不能静默猜测。base_delay=0.5、max_attempts=3 时:第一次失败后等 0.5 秒,第二次失败后等 1 秒,第三次失败直接抛错,因为已无下一次尝试。400 调用 1 次,503 最多 3 次,429 同样有限但等待不少于 Retry-After。会通过错误前缀判断;
2026-09-26 12:13:15
178
原创 Python后端AI专题25:串起完整 RAG:检索、融合、重排、生成与 SSE
到目前为止,每个零件都有测试,但“解析器通过、检索通过、引用通过”仍不能证明用户真的能从注册走到回答。本篇把身份、知识库、上传、索引、混合检索、RAG 与 SSE 串成一条 E2E,并把每一层的输入输出对齐。
2026-09-26 12:10:46
367
原创 Python后端AI专题24:让答案带出处:引用校验与无证据拒答
检索返回了文档,不代表模型的每句话都来自文档;答案末尾出现[1],也不代表这个编号真的存在。可信 RAG 至少要把候选变成带稳定编号的证据上下文,并在响应交给用户前验证引用集合。
2026-09-26 12:10:24
279
原创 Python后端AI专题23:Rerank 重排:为什么召回第一名不一定最会回答
假设有一百万 chunk。Cross-encoder/Rerank 若对每个候选都联合编码问题与正文,计算量远大于向量点积。100 万 → 向量 Top 30 + 关键词 Top 30→ RRF 去重约 40 条→ 上下文预算再裁剪召回阶段追求别漏掉,重排阶段追求前几名准确。候选太少,Rerank 无法救回没被召回的答案;候选太多,延迟和费用上升。
2026-09-25 22:18:35
306
原创 Python后端AI专题22:产品编号搜不到?把关键词与向量用 RRF 融合
用户搜索“KF-2048 端口”,向量模型可能认为“产品安装说明”很相关,却把精确包含KF-2048的短表格排在后面。Embedding 擅长同义表达,产品编号、错误码和合同号则更适合词法检索。混合检索不是把两个分数直接相加,而是先承认它们的量纲不同。
2026-09-25 22:18:09
294
原创 Python后端爬虫专题08:重试不是再来一次——超时、指数退避与Retry-After
课程测试关闭真实 sleep,用 SleepRecorder 记录应等待的秒数,因此既快又能验证决策。POST 若创建订单,重放可能重复副作用,除非服务端支持幂等键。400、401、403、404 默认不重试,因为请求格式、身份、权限或资源不存在不会靠等待修好。重试是短暂故障的恢复手段,不是隐藏容量或授权问题的橡皮擦。再 sleep,否则连接可能一直占在池里,其他任务无法使用。日志至少记录 task_id、规范 URL、attempt、状态/异常类型、等待秒数和最终结果,不记录 Cookie 与响应全文。
2026-09-24 14:00:33
342
原创 Python后端AI专题21:第一个受权限约束的向量检索接口
先从所有向量取 Top 10,再在 Python 里删掉别的租户”是严重错误:越权文本已经进入应用内存,而且被删后当前租户可能只剩一两条候选。正确做法是让tenant_id和进入同一条向量 SQL,在排名前收窄候选集合。
2026-09-24 09:09:44
163
原创 Python后端AI专题20:为什么主项目选 pgvector:表结构、距离与 HNSW
KnowFlow 已经能在内存里写向量,但企业项目还要同时管理租户、知识库、文档状态、来源和事务。主项目选择 PostgreSQL + pgvector,不是因为它在所有规模都最快,而是当前阶段“业务过滤与向量检索同库完成”比再引入一套分布式向量系统更容易保证一致性和权限。
2026-09-24 09:09:31
328
原创 Python后端AI专题19:批量 Embedding 与断点续建:第三批失败后从哪里重来
成功写入 batch 0 后保存;成功写入 batch 1 后保存 2。这避免了+1/-1的歧义。更重要的是,向量写入成功后才能推进游标;若先推进再写,进程在两者之间崩溃会永久跳过一批。数据库与外部向量库无法天然共享事务,所以upsert。若写入成功、保存游标前崩溃,恢复会再写同一 ID,而不是产生副本。
2026-09-23 09:08:19
210
原创 Python后端AI专题18:分块策略实测:块多大、重叠多少才不会拆坏答案
块越小,检索定位更精确,却容易把条件与结论拆开;块越大,上下文完整,却带入更多噪声并消耗 Token;overlap 能缓解边界问题,但会重复存储和重复 Embedding。本篇不用“推荐 500 字”结束讨论,而是让同一份语料跑九组参数。
2026-09-23 09:08:07
269
原创 Python后端爬虫专题07:同一页面为什么抓了五次——分页、链接发现与URL规范化
网络访问范围由后续 CrawlPolicy 再检查:规范化负责“地址是什么”,策略负责“能不能访问”。在链接发现时完成相对地址解析、scheme/host 小写、默认端口移除、path 规范化、fragment 丢弃和跟踪参数过滤。它返回的是“本项目定义的规范 URL”,不是互联网唯一真理。任务预算是最后一道防止无限循环的保险,不是站点结构判断的替代品。有的网站用页码,有的用 cursor,有的下一页 URL 带签名。URL 规则一旦改变,还要评估数据库唯一键,因为旧规范 URL 可能已存在。
2026-09-22 16:26:14
225
原创 Python后端爬虫专题06:网页文本不等于业务数据——清洗、类型转换与Pydantic校验
再手工把 salary_min 改成 30000、salary_max 改成 20000,Pydantic 会给出包含 salary_max 的 ValidationError。目标站改版时先更新 fixture 和业务决策,再调整代码,不要对线上异常字符串不断追加不可解释的 replace。JobRadar 把“薪资面议”视为未知而不是错误,因为职位本身仍有效,统计时可以排除缺少区间的样本。使用 before 模式,因为原始字典里的空白需要先处理,再让 Field 的 min_length 判断;
2026-09-22 16:25:57
199
原创 Python后端AI专题17:文本清洗不是删空格:页眉、乱码与来源保真
页码、section、kind 和 metadata 必须保留;保留下来的块按原顺序排列;文本字符可规范化,但不能改变否定、数字和条件;被删除的内容必须满足可解释规则。配图左侧是三页重复页眉与正文,右侧页眉被删除,正文仍指向原页码。注意清洗后的ordinal重新连续编号,但page没有被“压缩”为新页码。
2026-09-22 09:05:07
223
原创 Python后端AI专题16:解析 PDF、Word、Markdown 与 TXT:正文之外还要保留什么
解析器若只返回一个长字符串,后面即使检索正确,也无法告诉用户“答案来自哪一页、哪个标题、哪张表”。本篇的目标不是展示四个库的 API,而是把不同格式统一成带来源的,并明确 OCR 等未覆盖边界。
2026-09-22 09:04:54
97
原创 Python后端AI专题15:搭起 KnowFlow AI:项目边界、配置与第一条健康检查
前 14 篇解决了“模型应用为什么这样设计”。从本篇起,我们把这些原则装进一个持续演进的真实项目:企业级本地知识库与智能问答平台 KnowFlow AI。后续上传、解析、检索、权限、评测和部署都在同一代码库里增加,不会每篇重新造一个 Demo。
2026-09-22 09:04:41
365
原创 Python后端爬虫专题05:一页发现链接,一页提取事实——拆开列表与详情解析器
Crawler 按详情提交事务,并在 CrawlReport 中记录失败 URL 与原因。第一,选择器必须锚定职位卡片,不能收集导航栏、公司主页等所有 a。第二,href 可能是相对地址,需要以当前 page_url 解析。第四,同一详情可能因推荐位重复出现,去重要保留首次发现顺序。把两者塞进一个函数,会出现参数和返回值都含糊:有时返回 URL,有时返回 JobItem,有时在函数里发网络请求。业务上确实允许空列表时,应通过页面中的“暂无结果”标识区分,而不是把任何空结果都当成功。JobRadar 使用。
2026-09-21 09:56:19
303
原创 Python后端AI专题14:为什么模型需要 RAG:参数记忆解决不了企业知识
模型能解释“退款”这个概念,却不知道你们公司昨天下午刚发布的退款例外,更不知道当前用户是否有权看财务制度。把几十份文档塞进 Prompt 或期待模型“训练时见过”,都没有解决知识更新、来源和权限。RAG 的核心不是一个热门缩写,而是把事实责任从模型参数转移到可治理的数据链路。
2026-09-21 09:30:55
233
原创 Python后端AI专题13:Prompt 也要进版本库:模板、哈希、回滚与评测
一次“只改了两句话”的 Prompt 上线后,拒答率从 8% 涨到 31%。如果 Prompt 写死在代码里、日志只记模型名,我们甚至无法回答某条错误答案到底使用了哪一版规则。Prompt 是运行时行为的一部分,必须像代码和数据库迁移一样可识别、可评测、可回滚。
2026-09-21 09:30:42
688
原创 Python后端爬虫专题04:从httpx.get到可复用客户端——连接池、超时与错误边界
课程 Worker 按任务创建,牺牲少量复用以换取清晰隔离,适合教学和中小任务。直接调用适合第一次实验,却会让每个解析函数自己决定超时、请求头、重试和证书校验。每个 URL 新建客户端会重复 DNS、TCP 和 TLS 握手,还可能在高并发下制造大量短连接。前者处理跨 URL 的重定向和策略,第二个函数处理同一 URL 的暂时错误,最后一个函数流式读取并执行字节上限。HTTPX 抛出的 ConnectError、ReadTimeout 很具体,但 API 不应把底层异常和可能含主机信息的长文本原样返回。
2026-09-20 14:11:10
207
原创 Python后端AI专题12:用 Ollama 跑本地模型:选择模型而不是只看参数量
本地部署更便宜、更安全”只说对了一半。模型权重不出内网确实减少数据外发,但显存不足导致频繁换页、上下文开太大导致延迟暴涨、并发没有预算导致整机雪崩,同样会让产品不可用。选型要从业务 SLA 反推,而不是先下载参数最大的模型。
2026-09-20 08:57:43
81
原创 Python后端AI专题11:SSE 流式回答:事件协议、断线与取消
浏览器看到模型逐字出现,不代表后端只需把字符串切片。真正可维护的流式接口要回答:元数据什么时候给、引用什么时候可信、异常怎样传、代理会不会缓冲、客户端断开后谁取消模型调用。
2026-09-20 08:57:30
146
原创 Python后端爬虫专题03:选择器不是背口诀——从DOM树理解CSS与XPath
若列表函数同时请求详情,测试必须启动网络,分页和详情错误会混成一团,Scrapy 也无法接管调度。解析器应当是“给定 HTML,返回确定结果”的纯边界。它只发现链接,不下载详情,也不创建数据库会话。它存在的意义不是少写两行,而是统一“字段缺失必须失败”的合同,并把字段名和 selector 写入异常。它描述结构和特征,不依赖“第 3 个 div 的第 2 个孩子”。浏览器展示的是页面,解析器看到的是节点关系。再运行,测试会在“没有详情链接”处分明失败,而不是得到一个空列表并假装成功。
2026-09-19 15:01:13
146
原创 Python后端AI专题10:别再解析模型的自然语言:结构化输出与 Pydantic 校验
请按 JSON 返回”不是接口合同。模型可能加上 Markdown 围栏、把数组写成字符串,甚至漏掉必填字段;HTTP 仍是 200,但业务已经失败。本篇从一份能解析却不能使用的数据开始,建立“生成—校验—一次修复—失败”的受控路径。
2026-09-19 15:00:47
272
原创 Python后端AI专题09:模型服务不稳定怎么办:超时、重试和并发预算
凌晨两点,模型供应商开始返回 503。第一版代码“遇错重试直到成功”,一分钟内把故障放大成请求堆积:API Worker 全在等待,连接池耗尽,健康检查也开始超时。问题不只是供应商不稳定,而是我们没有给不稳定性划边界。
2026-09-19 15:00:30
205
原创 Python后端AI专题08:在 FastAPI 中设计可替换的模型 Provider
大模型输出具有概率性,远程服务也可能限流。如果每个单测都调用真实模型,失败时无法区分“代码回归”和“模型换了措辞”。同一文本生成完全一致的归一化向量;Chat 返回指定答案并记录调用次数。于是“无证据时绝不能调用模型”可以断言。这比检查某段日志更准确。真实模型仍要在独立评测阶段运行,但它不应破坏日常回归的确定性。
2026-09-18 13:42:19
434
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅