这个项目是我今年做得最舒服的一次自动化改造。起因很朴素:我负责的品牌检测业务,每天要从好几个平台拉取商品页、帖子、号主发文,人工判断有没有蹭品牌词、仿冒标识、违规宣称、钓鱼缩写这类风险。以前这套流程靠人肉加半自动脚本,两三个人才能勉强跑完一轮,还经常漏。现在不一样了——我用 MCP 把采集、识别、判定、报告这些环节全部做成了标准化的外部工具,再用技能系统把这些工具编排进同一个 Agent,整套品牌检测流程就真的全自动跑起来了。这篇内容不是概念科普,是我从 0 到 1 把流程改造完之后的完整复盘,包括为什么选这套方案、技能怎么拆、MCP 工具怎么挂、踩了哪些坑。适合正在做 Agent 落地的开发者,也适合内部有大量重复“人肉巡检”流程想改造的团队参考。
1. 项目起因:人肉巡检扛不住了
先说品牌检测到底在干什么。很多人以为就是搜一下品牌名看有没有被提到,真落到业务层面,场景比这复杂得多。我们要管的至少是四类事情:第一是品牌词被抢,比如标题里故意插字符、加空格、用全半角混写绕过搜索;第二是仿冒标识,图片里的 Logo 被改色、变形、加小点缀然后当正品宣传;第三是违规宣称,拿官方品牌做背书,比如“官方合作”“厂家直供”“授权代理”但实际没有任何授权;第四是钓鱼缩写和近似词,把品牌名拼错一个字母蹭搜索流量。
1.1 品牌检测到底在检测什么
这四类风险还有一个共同点:它们散落在不同平台上,形态完全不一样。文本检测用关键词规则能处理一部分,但变体写法很难穷举;图片检测要靠视觉能力;合规判定又需要结合上下文逻辑。更麻烦的是,平台方给的数据接口字段有限,很多线索来自公开页面里的非结构化文本,甚至截图。
所以那种“写个脚本扫一遍”的思路天然不成立——数据源多样、判定维度多样、输出要求多样。过去团队的做法是:脚本把数据拉下来,落成表格,人再去筛。结果就是每天打开表格,几百行待确认记录,眼睛看花了还在漏。
1.2 以前的流程为什么又慢又漏
旧流程大概是这样的:每天定时抓取一批页面,正则匹配一堆关键词,把命中的记录导出来,然后人工一条条看上下文判断是不是真有风险。这里面有几个硬伤:
一是规则覆盖不全。攻击者会不断变体,人工维护正则词典永远慢半拍。二是上下文缺失。脚本只能告诉你“出现了这个词”,但判断不了它是在正常报道里提到品牌,还是在故意蹭流量。三是反馈链路太长。今天发现的漏检,改完规则,明天才能上线,中间一天的风险窗口根本堵不住。
我当时的想法是:能不能让一个 Agent 直接接管整个链路。从数据入口开始,拉完内容先自己判断哪些需要看,再看文本和图片,最后把风险分级、输出报告、推送告警。Agent 的模型能力能解决“上下文判断”这件事,而外部的数据抓取、规则库、图片识别服务则需要稳定的工具通道连进去。这就落到了 MCP 和技能系统上。
2. 技术选型:为什么是 MCP + 技能系统
方案选型的时候,我其实想过好几条路:纯 Prompt 堆逻辑、自建一套微服务编排、用现成的 LangChain 之类的框架。最后都否了,核心原因就两条:第一,我不想把流程里的每个细节都写死在 Prompt 里,不然模型换个版本,整个逻辑就要重写;第二,我不想让 Agent 直接去调底层 HTTP 接口,接口出入参、鉴权、超时这些问题不该由模型来猜。
2.1 MCP 是干嘛的
MCP(Model Context Protocol)解决的是模型和外部系统的连接问题。可以把它理解成给模型用的标准化“插头”:模型不需要知道每个平台接口长什么样,它只认识 MCP 协议定义好的消息格式,然后通过 MCP 服务器去调用实际功能。对这次的项目来说,MCP 最大的价值是让我把“拉取页面”“扫描品牌词”“查询规则库”“推送告警”这些能力全部声明成标准工具,Agent 只要按协议发出调用请求,剩下的事由工具侧完成。
我不需要为每个平台写一套专属 Prompt,也不需要教模型理解 HTTP 状态码和分页逻辑。工具接口长什么样、参数怎么填、返回什么结构,全部通过 MCP 的描述信息告诉 Agent。Agent 看到某条输入文本,判断需要扫描品牌词,就调用对应的 MCP 工具,传进去文本和品牌词列表,拿回结构化结果。
2.2 技能系统解决什么问题
技能系统在我这个项目里的定位,是“把 Agent 能做的事变成可注册、可组合、可复用的一组能力”。每一个技能都是一个独立单元,包含名称、描述、输入参数定义、执行函数和输出结构。Agent 在运行时会阅读技能列表的描述,像一个工具箱摆在它面前,它自己决定当前这一步该拿哪个工具。
设计上我特别强调“技能”和“工具”的分层。工具是具体执行层面的动作,比如“调用图片识别服务检测 Logo”“调用规则引擎跑一遍宣称词库”;技能是业务层面的能力,比如“判断某个商品页是否存在品牌侵权风险”。一个技能背后可能对应一个工具,也可能编排多个工具。例如“风险判定”这个技能,内部会先调规则引擎跑一次,再调大模型做语义分析,最后汇总分数。Agent 不需要关心内部有多少次调用,它只需要按技能名发起请求。
2.3 对比:纯 Prompt 方案差在哪
这个对比我实际踩过。早期原型我就用纯 Prompt 试过,把所有检测逻辑、判断标准、输出格式全写在系统提示词里,效果看起来还不错,但问题很快就来了。
第一是 Prompt 会越来越臃肿。品牌词库几百个词,不可能全塞进 Prompt;规则多了提示词超长,模型注意力被稀释,判定质量反而下降。第二是可维护性差。规则库要更新,得改 Prompt,再全量重跑一遍;技能系统里只需要把规则文件更新一下,工具逻辑不用动。第三是调用不透明。纯 Prompt 让模型“自己想怎么调就怎么调”,但没法严格约束它调用哪个数据源、按什么顺序。MCP 工具开放哪些能力、关闭哪些能力,是平台侧可控的。
我当时做了一张对比表,给自己理清思路:
| 维度 | 纯 Prompt 硬堆 | MCP + 技能系统 |
|---|---|---|
| 规则更新 | 改提示词,风险高 | 改工具内部逻辑,隔离干净 |
| 外部数据接入 | 模型自己猜接口格式 | 标准化协议,Agent 按描述调用 |
| 可观测性 | 只看到生成文本 | 每个工具调用有日志、参数、耗时 |
| 变更影响面 | 动一句可能影响全部输出 | 技能独立升级,影响可控 |
| 能力复用 | 换个任务基本重写 | 技能注册后通用 |
选型结论很明确:把确定性高的部分下沉到技能和工具,让大模型专注做判断和编排。这既是架构上的解耦,也大幅降低了误判率。
3. 全自动品牌检测 Agent 的整体设计
想清楚了技术路线,下一步就是把整个流程拆成可执行的架构。这个 Agent 本质上是一个循回执行的处理器:输入是一批待检测的任务,输出是一份带风险等级和证据链的检测报告。中间所有环节全部由 Agent 自动编排。
3.1 一条数据从头到尾怎么流转
我先把数据流转画成一条线,从采集到最终推送告警,总共六个阶段。第一阶段是采集:从各平台拉取商品页、帖子文本、图片列表。第二阶段是去重:同一商品在不同店铺重复上架,需要归并成一条主记录。第三阶段是识别:把文本和图片分别送入品牌词识别和 Logo 识别。第四阶段是判定:结合规则库和大模型的上下文理解,判断是否构成风险。第五阶段是分级:按影响范围、侵权程度、紧急程度打分,分成高、中、低三档。第六阶段是输出:生成结构化报告,并向指定通道推送告警。
这个流程里的“数据怎么流转”不是一个固定的硬编码顺序。Agent 拿到任务后,会先看任务描述,再对照技能列表,决定需要走哪些阶段、每阶段调用什么工具。比如一个纯文本帖子,没有图片,Agent 就会跳过图片识别,直接进入文本判定。如果一个任务只有图片没有文本,也会自动调整调用路径。这就是技能系统带来的灵活性。
3.2 六个核心技能的职责与动作清单
我把业务逻辑最终沉淀成了六个技能:
第一个是品牌词扫描,负责在文本里定位品牌词命中情况,包括变体处理。第二个是 Logo 识别,负责对图片链接做仿冒检测,返回匹配到的 Logo 类型和置信度。第三个是宣称合规分析,负责结合上下文判断文案是否存在违规背书。第四个是风险评分,把前面几项结果汇总,按规则输出风险等级。第五个是报告生成,把结果格式化为 Markdown 或 Excel 报告。第六个是告警推送,把高风险信息推到即时通讯群或个人。
为了让大家理解一个技能内部怎么设计,我拿“品牌词扫描”举例。这个技能不只做简单的字符串包含匹配,它内部做了三层:先是字符规范化,把全角转半角、大写转小写、去掉插入的特殊符号;再做变体词库匹配,里面收录了常见的替换写法;最后是上下文窗口截取,把命中词附近 N 个字一起返回,方便后续语义分析判断这是正常报道还是恶意蹭词。
3.3 MCP 服务层的工具设计
技能是 Agent 视角的“业务能力”,落到执行层就是 MCP 服务暴露的一个个工具。我在设计 MCP 工具时坚持一个原则:工具要原子化,每个工具只做一件事,参数尽量少,返回结构尽量稳定。
我列出最终暴露的 MCP 工具清单:
| MCP 工具名 | 输入 | 输出 | 对应技能 |
|---|---|---|---|
| fetch_platform_content | 平台类型、链接或搜索词、分页参数 | 标题、正文、图片列表、发布时间 | 采集 |
| deduplicate_records | 记录列表、去重字段 | 去重后的主记录和从记录映射 | 归并 |
| scan_brand_keywords | 文本、品牌词列表 | 命中词、位置、上下文片段 | 品牌词扫描 |
| detect_logo | 图片 URL 列表 | 各图片的 Logo 类型、置信度 | Logo 识别 |
| analyze_compliance | 文本、上下文、宣称规则 | 判定结果、命中规则、置信度 | 合规分析 |
| score_risk | 检测结果汇总 | 风险等级、分数、处置建议 | 风险评分 |
| build_report | 任务 ID | Markdown/Excel 报告内容 | 报告生成 |
| notify_alerts | 告警内容 | 推送结果 | 告警推送 |
这组工具的粒度经过几轮调整。最开始我把采集和去重做成了一个工具,结果 Agent 调用时参数非常混乱,有时候传了去重字段却忘了传分页参数。拆开之后,每个工具描述清晰,Agent 的调用成功率高了很多。工具设计上宁可多拆,不要贪大。
4. 从零到一搭建的完整实操过程
下面这部分是整个项目落地过程里,我觉得最值得记录的实操环节。不是“装好环境就能跑”的教程,而是把每一步的关键决策和参数选择讲清楚。
4.1 技能模块的开发与注册
技能模块的开发,我建议先定义清楚每个技能的输入输出,再写执行逻辑。以“品牌词扫描”为例,技能定义文件大概是这样的结构:
{ "skill": "品牌词扫描", "description": "在文本中扫描品牌词命中情况,返回命中位置和上下文。支持字符规范化和常见变体匹配。", "input_schema": { "type": "object", "required": ["text", "brands"], "properties": { "text": {"type": "string", "description": "待检测的原始文本"}, "brands": {"type": "array", "items": {"type": "string"}, "description": "品牌词列表"} } }, "output_schema": { "type": "object", "properties": { "hits": { "type": "array", "items": { "type": "object", "properties": { "brand": {"type": "string"}, "offset": {"type": "integer"}, "context": {"type": "string"} } } } } } }输入输出定义得越严格,Agent 调用时就越少自由发挥。我见过很多项目输出结构含糊,Agent 拿到结果后不知道怎么解析,最后只能又拼一个“后处理 Prompt”去收拾,这违背了结构化设计的初衷。
执行函数我直接用 Python 写,关键点是字符规范化和变体库。这段逻辑并不复杂,但效果直观:
def scan_brand_keywords(text: str, brands: list) -> dict: normalized = normalize_text(text) # 全角转半角、统一大小写 hits = [] for brand in brands: variants = generate_variants(brand) # 生成插入符号、同音替换等变体 for variant in variants: for pos in find_all(normalized, variant): context = extract_snippet(normalized, pos, length=80) hits.append({ "brand": brand, "variant": variant, "offset": pos, "context": context }) return {"hits": hits}生成变体这里最值得注意。单纯对品牌名做字母替换,比如把“o”替换成“0”,召回率能上去,但误报率也会增加。我在变体库里加了“仅记录不判死”的机制:命中变体时先标记为潜在风险,后续由语义分析技能判断上下文是否真的在恶意蹭词。这样规则负责召回,大模型负责判断,分工明确。
4.2 MCP 服务怎么接进来
MCP 服务的接入是整个项目里最技术化的部分。我采用的是比较轻量的做法:用 MCP 生态里常见的那套声明式工具定义,把上面那组工具逐个暴露成服务端口。
关键配置有三块。第一是工具注册,每个工具要有明确的名称、描述、输入 JSON Schema。第二是传输层,本地开发用标准输入输出调试,部署到线上后换成长连接传输。第三是鉴权,MCP 服务本身不鉴权,但暴露的每个工具内部要做好权限校验,因为 Agent 可能被恶意任务诱导去调用不该调的接口。
我自己写工具入口时有几个习惯:一是所有工具入口都做超时控制,外部接口三秒没返回就报错,不让 Agent 干等;二是所有返回都带status字段,成功返回ok,失败返回error和可读的错误信息;三是给每个调用生成 trace_id,方便排查问题时把 Agent 的决策日志和工具执行日志串起来。
@tool( name="analyze_compliance", description="对文本进行品牌宣称合规分析,返回命中的宣称规则和置信度", input_schema={ "text": {"type": "string"}, "rules": {"type": "array", "items": {"type": "string"}} } ) def analyze_compliance(text: str, rules: list) -> dict: hits = [] for rule in rules: # 实际项目里这里会调规则引擎,而不是简单匹配 if rule_keyword_in(text, rule): hits.append({"rule": rule, "matched": True}) return { "status": "ok", "hits": hits, "trace_id": generate_trace_id() }这里有个容易踩的坑:不要在 MCP 工具内部写太多大模型逻辑。我一开始把“合规分析”做成调用大模型直接返回判定结果,结果每次调用耗时十几秒,Agent 编排整个流程时频繁超时。后来改成工具内部先用规则引擎过滤一遍,只有规则命中的文本才临时调用大模型做语义确认,整体响应时间降到 2 到 3 秒。
4.3 让 Agent 自己决定调用顺序的调度逻辑
技能和工具都准备好了,最后一步是把它们装进 Agent。这一步也是全自动的关键:Agent 接到一个检测任务后,自己根据技能描述规划执行顺序。
我的实现思路是给 Agent 一个精简的“技能清单”和当前任务目标。Agent 先输出一个执行计划,计划里的每个动作指向一个技能。然后调度层按顺序执行,把上一步的输出作为下一步的输入。这样编排的好处是 Agent 可以动态跳过不需要的技能。比如图片识别需要图片 URL,如果任务里没有图片,Agent 自动跳过detect_logo。
一段简化后的调度逻辑是这样:
def run_detection(task): tasks = [] if task.get("text"): tasks.append("scan_brand_keywords") if task.get("images"): tasks.append("detect_logo") if task.get("text") or task.get("images"): tasks.append("analyze_compliance") if "scan_brand_keywords" in tasks or "detect_logo" in tasks: tasks.append("score_risk") results = {} for skill_name in tasks: kwargs = build_skill_params(skill_name, task, results) results[skill_name] = AGENT.invoke_skill(skill_name, **kwargs) if results[skill_name]["status"] != "ok": log_warning(skill_name, results[skill_name]["error"]) # 重试一次,再失败则跳过并记录 return build_final_report(task, results)我把调度逻辑从“模型自动输出任意动作序列”改成了“模型从技能清单里选择并排序”,而不是完全自由发挥。这很重要:完全自由的 Agent 容易产生幻觉,比如自己编一个不存在的工具名,或者跳过风险评分直接输出结论。受限的技能选择框架既保留灵活性,又保证了必须走的环节不会丢。
4.4 测试和压测:不止测“能不能跑”
全自动 Agent 的测试,我分了四层。第一层是单工具测试,每个 MCP 工具单独喂测试用例,验证出入参和错误处理。第二层是技能链路测试,固定几条典型输入,验证 Agent 是否选择了正确的技能组合。第三层是批量压测,把一周的历史数据灌进去跑一遍,重点看超时率和漏检率。第四层是回归测试,改完规则库或技能后,把之前的测试集再跑一次,确保没有把原本能判对的东西判错。
回归测试这步是最容易被偷懒跳过的,但也是最关键的。我有一次更新了变体库,新增了几十条变体写法,单测全过,结果回归测试发现一批旧记录被误伤,因为新变体把“某品牌培训课程”这种正常上下文也匹配上了。幸好回归测试跑得快,及时加了上下文过滤逻辑。
压测阶段我重点盯着两个指标:单任务平均耗时和工具调用成功率。最开始工具调用成功率只有 82%,大量失败集中在平台内容拉取和图片识别这两个外部服务上。拉取失败主要是有部分平台结构变化导致解析异常;图片识别失败主要是超时。针对这两块,我分别加了重试机制和更短的超时阈值,成功率提到了 99% 以上。
5. 踩坑实录与排查思路
全自动流程跑起来之后,真正折磨人的是各种不稳定因素。这一节我把我实际踩过的坑和排查方法整理出来,都是文档里不太会写的东西。
5.1 工具调用时好时坏,根因在超时
上线第一天,Agent 表现很正常,第三天开始就频繁报工具调用失败。看日志发现异常集中在同一个外部接口上,单一调用偶尔超时。问题在于 Agent 的编排逻辑是串行的,一个工具超时三秒,整个任务就卡住,后面所有步骤全部排队,看起来就像系统“抽风”。
解决办法有两个:一是给每个外部依赖加独立超时,不让一个慢接口拖垮整条链路,失败后立即走降级逻辑;二是加了重试和熔断,同一工具连续失败三次就暂时标记为不可用,任务转人工队列,而不是无限重试。现在线上工具的调用成功率稳定在 99% 以上,超时率基本归零。
5.2 上下文被检测素材塞爆
这个坑是隐藏最深的。Agent 处理长文本时,我把原文整个塞进上下文让大模型做合规判断。看起来没问题,但批量跑的时候,上下文长度很快就超出模型限制,输出结果开始漂移,错误率明显上升。
排查之后,我给“合规分析”技能加了三层文本处理:先截断,超过 3000 字的只保留标题、首段和品牌词命中附近的上下文;再压缩,把无关的导航、评论、重复内容删掉;最后分块,一个超长页面拆成多个片段分别判定,再汇总。这样处理之后,不仅上下文超限问题没了,判定质量还更好——模型不再被大段无关信息干扰。
5.3 误报漏报怎么平衡
品牌检测里最难的不是抓到风险,而是把误报率压到可接受范围。我试过把变体库调得很激进,结果大量正常内容被标记,告警群一上午被刷了几百条,运营同事直接抱怨。又试过把阈值调高,漏检率又上来了。
最后我总结出一个有效组合:规则负责高召回、宽进;大模型负责精判、宽出。规则阶段宁可多标,进入大模型判定阶段后,模型结合上下文给出误判置信度。置信度低的自动进入人工复核队列,置信度高的才直接推送。这样告警量降了一半,漏检率没有明显上升。
我整理了一张排查速查表,每次出问题先对着过一遍:
| 症状 | 可能原因 | 排查路径 |
|---|---|---|
| 工具频繁调用失败 | 外部接口超时、参数格式不符 | 查 trace_id 对应工具日志,看 response_time 和 error 字段 |
| 结果质量突然下降 | 上下文超限、被无关信息干扰 | 检查输入大小,确认是否走了截断和分块逻辑 |
| 大量误报 | 变体库过宽、未走语义判定 | 抽样看命中案例,分析上下文过滤是否生效 |
| 漏报率上升 | 阈值过严、规则库滞后 | 对比历史漏检样本,确认新变体是否入库 |
| Agent 跳过必要环节 | 技能描述不清、调度约束丢失 | 查看 Agent 执行计划输出,确认技能清单是否被正确传递 |
6. 改造后的效果与我的个人体会
从效果上看,这次改造的收益是实打实的。同一批任务,以前两三个人干一天的活,现在 Agent 全自动跑下来不到半小时,而且跑完还能自动生成一张带证据链的报告。漏检率相比旧流程下降了六成左右,主要原因是变体规则及时更新加上大模型上下文判断兜底。
6.1 效率数字对比
我用一组内部测试数据做对比:
| 指标 | 旧流程 | Agent 流程 |
|---|---|---|
| 单日覆盖数量 | 2000 条左右 | 1 万条以上 |
| 单轮耗时 | 6-8 小时 | 20-30 分钟 |
| 人工介入量 | 每条都要看 | 只处理中低置信度约 15% |
| 漏检率 | 基线 | 下降 60% 以上 |
| 告警响应 | 隔天反馈 | 实时推送 |
当然,这些数字有它特定的前提条件,主要变化来自重复劳动被消解。人不需要再机械地逐条翻记录了,而是集中精力处理 Agent 标出的中低置信度案例。这个角色变化让团队的实际处理效率提升了一个量级。
6.2 这套结构的复用空间
这套“MCP 工具 + 技能系统 + Agent 编排”的结构,并不只适用于品牌检测。我后来把同样的模式迁移到另外两个场景:一个是用户反馈工单的自动分类和优先级排序,另一个是竞品信息的周期性监测。两个场景的改动量都比想象中少很多——重新定义了技能和工具,Agent 调度核心逻辑几乎没动。
这也验证了我最初的设计判断:把业务逻辑隔离在技能层,把外部通道隔离在 MCP 工具层,Agent 只做编排和判断。以后算法模型升级、规则库调整、平台接口变化,都能各自独立演进,不会牵一发动全身。
最后说点实际的体会。这个项目做下来,我最深的感受是:全自动 Agent 不是把一切都交给模型自由发挥,而是把系统能力拆成边界清晰的模块,再由模型来做组合决策。确定性的事交给规则和工具,不确定性的事交给大模型,两者的分界线,就是整个系统稳定性的生命线。