诺未连续两年拿下微软AI黑客松冠军,我们做对了什么?

19 阅读13分钟

连续两年拿下微软 AI 黑客松金奖,我们到底写了什么代码?

2025 年「Eva」在微软中国区 Copilot AI 创新大赛拿了第一名,2026 年「Sales Deal Mate」在 Frontier Agentic Hackathon 又拿了智胜全能金奖。很多人问:你们是不是 prompt 写得特别好?

不是。真正的护城河在四层:A2A 多智能体编排、四阶段数据管线、Entra→Snowflake 权限复刻、Skill Engine 自进化规则引擎。这篇文章把架构、管线、SQL、技术选型全部拆开讲。


一、A2A 多智能体架构:为什么 Agent 调 Agent,不是 Tool 调 Tool

先看架构全貌。Sales Deal Mate 在 Microsoft Teams 中部署了 1 个主控 Agent + 4 个专属子 Agent

┌─────────────────────────────────────────────────┐
│              Microsoft Teams (唯一入口)            │
│  销售用自然语言对话 ← 所有输入/输出                │
└──────────────┬──────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────┐
│       主控 Agent (Orchestrator)                   │
│       Copilot Studio 可视化编排画布                │
│       · 意图路由 · 上下文管理 · 子Agent调度        │
└───┬──────────┬──────────┬──────────┬────────────┘
    │          │          │          │
┌───▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼────┐
│Tender │ │  KA   │ │  RFP  │ │Compl.  │
│Agent  │ │Agent  │ │Agent  │ │Agent   │
│每日扫标│ │客户全景│ │标书解析│ │双文档  │
│线索推送│ │关系挖掘│ │需求抽取│ │合规审查│
└───────┘ └───────┘ └───────┘ └────────┘

1.1 Agent-to-Agent(A2A),不是 Tool-to-Tool

这是整个架构最核心的设计决策。

传统做法(Tool-to-Tool):把每个功能封装成 REST API,由一个中央调度器按 if-else 或状态机调用。问题是:每次新增能力,调度器的路由逻辑都要改。三个子模块还行,十个就变成意大利面条。

我们的做法(Agent-to-Agent):在 Copilot Studio 的可视化编排画布上,主控 Agent 像"技术主管"一样调度子 Agent,只管"谁擅长什么",不关心内部实现。子 Agent 之间也可以互相调用——比如 KA Agent 发现客户近期有招标公告,可以直接触发 Tender Agent 的扫描任务。

// 伪代码:主控 Agent 的调度逻辑(不是真实代码,是 Copilot Studio 画布上的节点连接)
// 主控只做路由,不关心子 Agent 内部怎么干活

const orchestrate = async (userIntent, context) => {
  switch (classifyIntent(userIntent)) {
    case 'daily_tender_scan':
      return await agents.tender.scanAndPush({ region: context.userRegion });
    case 'ka_deep_dive':
      return await agents.ka.buildProfile({ accountId: context.accountId });
    case 'rfp_parse':
      return await agents.rfp.parse({ documentUrl: context.uploadedFile });
    case 'compliance_check':
      return await agents.compliance.crossCheck({
        proposalId: context.proposalId,
        rfpId: context.rfpId,
      });
  }
};

⚠️ 注意:以上是逻辑示意。实际编排在 Copilot Studio 的低代码画布中完成,不是手写 JS。

1.2 为什么选 Copilot Studio 而非 LangChain/LlamaIndex?

这是每次分享都会被问到的问题。我们的决策逻辑:

维度Copilot StudioLangChain/LlamaIndex
企业身份集成Entra ID 原生对接,零配置需要自己接 OAuth/OIDC
Teams 集成Adaptive Card 原生输出需要自建 Bot + Bot Framework
多 Agent 编排可视化 Agent Flow,非技术人员可维护Python 代码,需要开发者维护
客户运维客户 IT 团队无需 Python 技能客户需要招懂 AI 框架的人

结论:这是给企业客户的交付项目,不是内部工具。可维护性 > 技术炫技。


二、四阶段数据管线:从 RFP 的 312 页到 47 条结构化评分

RFP Agent 是整个项目最重的一个子 Agent。它的任务是:用户上传一份 312 页的 PDF 标书 → Agent 解析出所有需求 → 逐条与应答书对照评分 → 给出修订建议。

技术难点就一个:标书不是纯文本,是表格、图章、手写批注、合并单元格的大杂烩。

管线分四步走:

Stage 1 — 原始文档解析 (Ingest)

工具: Azure Document Intelligence
能力:
  - OCR + Layout + Table Extraction (标准三件套)
  - 技术规格章节自动识别 (自定义模型)
  - BoQ 表格结构还原 (合并单元格必须解开)
  - 图章/印章/手写批注剥离 (这些东西对 NLP 是噪音)

这里有一个工程细节值得说:Azure Document Intelligence 默认不支持 "技术规格章节" 的语义识别。我们针对客户标书的版式特征(固定字体、固定缩进层级、固定编号规则),训练了一个轻量的自定义模型,准确率从 72% 提高到 94%。

Stage 2 — 语义切片 + 向量化 (Chunk)

工具: Azure OpenAI text-embedding-3-large
策略: section-aware chunking (按章节边界切分,非固定窗口)
元数据: 每片携带 { doc_id, 章节标题, 页码 }
向量: 3072 维 → pgvector 入库
切分结果: 487 chunks

为什么不按固定 token 窗口切?因为标书的结构性太强——「第三章 技术要求」和「第四章」,语义断点非常明确。如果按 512-token 固定窗口硬切,一条完整的技术需求可能被切成两半。section-aware chunking 的语义完整性大幅提升,代价是为每个文档类型维护一份章节边界配置文件。

Stage 3 — 混合检索 (Retrieve)

这是召回质量最关键的一步:

Round 1: pgvector + BM25 Hybrid Search
  - 语义检索 (vector) + 关键词检索 (BM25) 并行
  - 召回 Top-50 候选文档
  - Recall: 96%

Round 2: Cross-Encoder 重排
  - 对 Top-50 做精细语义匹配
  - 精排 Top-5
  - NDCG: 0.91

为什么不用纯向量检索?因为标书中有大量术语精确匹配的需求,比如 "ISO 50001"、"Niagara Framework"、"BACnet/IP",这些术语即便语义空间里距离不远,但我们不能依赖语义近似去"猜",必须精确命中

BM25 解决了精确匹配,向量解决了语义匹配,Cross-Encoder 做最终仲裁。三管齐下,NDCG 达到 0.91。

Stage 4 — 应答判分 (Score)

模型: Azure OpenAI GPT-4 class
Prompt 策略: 结构化判分 + 强制解释链
输出: 逐条 { 需求ID, 评分(满足/部分/缺失), 引用出处, 修订建议 }
消耗: 1840 tokens / 次
结果: 47 条需求, 3 缺失, 5 部分满足

判断分 Prompt 的设计原则是:不允许模型只说"满足",必须引用标书原文中的页码和段落作为证据。 这让评分结果可审计——你随时可以回到标书原文档验证每一个判断。


三、Entra → Snowflake 权限复刻:数据不出微软生态

企业级 AI 项目最大的坎不是模型,是安全合规。客户的第一反应永远是:"我的客户数据会不会被 AI 模型吃掉?"

我们的答案是:四层安全护栏,端到端同一身份。

架构全貌

Layer 1: 销售用户 (user@company · Sales-East)
           ↓ OAuth 2.0 / OIDC
Layer 2: Microsoft Entra ID (Identity Provider)
           ↓ on-behalf-of token
Layer 3: Agent Delegated ConnectorSnowflake RLS
Layer 4: Snowflake Row Access Policy + Dynamic Masking

行级安全的灵魂:Snowflake Row Access Policy

-- Snowflake Worksheet: row_access_demo.sql · LIVE QUERY

-- 销售用户 · East region · 仅可见自己负责的 60+ KA
SELECT opp_id, account_name, amount, owner
FROM SALES_DB.OPPORTUNITY_VW;

-- Snowflake 自动应用 Row Access Policy ↓
-- OPP-1023 │ Shanghai BizPark  │ ¥ 2.8M │ user@company
-- OPP-1041 │ Nanjing Tower     │ ¥ 1.2M │ user@company
-- [masked] │ ████████████████  │ ███████ │ ████  ← 跨区记录

关键设计:没有服务账号。整个链路从用户登录 Teams → Entra ID 签发 Token → Agent 拿到 on-behalf-of token → Snowflake 根据 Token 中的用户身份字段自动应用 RLS。没有"超级管理员"绕过权限的情况。

四道护栏

层次机制解决的问题
① 身份贯通Entra ID 全链路同一 Token无服务账号代答
② 数据隔离Snowflake RLS + Dynamic Masking行级 + 字段级双重隔离
③ 数据驻留Purview DLP + 分类标签数据不出微软生态
④ 全链路审计trace_id 贯穿所有 Agent 调用满足企业级合规要求

这里有一个容易被忽略的工程陷阱:Entra → Snowflake 的 OAuth 集成不是开箱即用的。Snowflake 默认支持外部 OAuth,但需要手动配置 SCIM 同步用户、创建 Security Integration、并为每个角色定义 Row Access Policy。这块我们踩了不少坑,值得单独写一篇文章。


四、Eva → Sales Deal Mate:从单兵到兵团的架构演进

2025 年的 Eva 拿奖后,很多同行说"你们赢在 prompt engineering"。但 2026 年的 Sales Deal Mate 拿奖后,没人再这么说了。

因为这次,架构层面的差异已经大到无法忽视。

Eva(2025):单智能体,垂直突破

Teams Chat → Copilot Studio Agent → Dynamics CRM + Power Automate

Eva 帮销售在 Teams 里找客户、生成跟进摘要、自动写 CRM 活动记录。本质是 "一个聊天 Bot + CRM connector"

Sales Deal Mate(2026):多智能体,横向覆盖

Teams Chat → 主控 Agent → Tender Agent / KA Agent / RFP Agent / Compliance Agent
                  ↓
          Snowflake + Azure AI Foundry + Document Intelligence + pgvector

核心差异不在技术栈,在架构理念:

维度Eva (2025)Sales Deal Mate (2026)
架构模式单 AgentA2A Multi-Agent
覆盖范围1 个场景(客户跟进)4 个场景(线索→成单)
编排方式Topic + FlowAgent Flow + MCP/Connector
数据层CRM onlySnowflake + pgvector + 3 知识库
安全Entra 基础身份Entra→Snowflake 权限复刻
可扩展性加功能 = 改 Flow加功能 = 加一个子 Agent

真正的技术拐点

Eva 到 Sales Deal Mate 的进化,本质上是回答了同一个问题:企业 AI 应该怎么交付?

一年前的答案是"做一个能解决单一问题的 Agent"。一年后的答案是"做一个能让 Agent 之间互相协作的平台"。平台化之后,边界的扩展成本从 O(n²) 降到了 O(1)——新增一个子 Agent 不需要动其他 Agent 的 Flow。


五、工程方法论:Skill Engine 自进化规则引擎

这篇文章前半部分讲的是「怎么让 Agent 跑起来」,后半部分要讲的是「怎么让 Agent 一直跑得对」。

核心痛点

一个真实的企业报价场景里,报价规则不是写死的:

  • "A 产品在华东区只能用 Tier 2 以下折扣"

  • "B 客户过去 12 个月有 3 次逾期,不能给账期"

  • "C 服务在 Q3 有促销,折扣率额外 -5%"

这些规则随时在变,不能让工程师每次手写。

Skill Engine 的闭环

# 伪代码:Skill Engine 的工作原理

# 1. 自动扫描端侧修正记录
feedback = azure_functions.timer_trigger(
    cron="0 */6 * * *",  # 每 6 小时
    query="""
        SELECT skill_name, corrected_value, context
        FROM sfdc.skill_feedback
        WHERE correction_count > 3  -- 被修正 3 次以上才触发
        AND status = 'pending_review'
    """
)

# 2. Azure OpenAI 生成候选规则
for item in feedback:
    candidate = azure_openai.complete(prompt=f"""
    基于以下修正记录,生成一条报价规则:
    原始建议: {item.original_value}
    修正后值: {item.corrected_value}
    业务上下文: {item.context}
    输出格式: JSON {{ "rule": "...", "priority": "..." }}
    """)

# 3. 经审批后写入规则库
sfdc.skill_rules.insert({
    "Content": candidate.rule,
    "Priority": candidate.priority,
    "Status": "approved"
})

⚠️ 以上是逻辑示意,实际部署在 Power Automate Cloud Flow + Azure Functions 组合上。

这个设计的巧妙之处在于:不是 AI 替代人类做决策,而是 AI 帮人类"发现"哪些隐性规则已经通过端侧修正被反复实践了。修正 3 次以上才触发,避免了偶发噪声污染规则库。


六、18 个月四阶段规划:AI 项目不是一次交付

很多 AI 项目的问题在于:一上来就要做"完整解决方案",结果半年后交付了一个没人用的巨兽。

我们的做法是把 18 个月拆成四个阶段,每个阶段独立上线、独立创造价值:

阶段时间目标关键交付
Phase 1月 1-3Excel→报价单,跑通最小闭环Sales Bot + BoQ 解析 + 格式转换
Phase 2月 4-8GCOE 价格策略自动化Skill Engine v1 + 配置驱动的定价规则
Phase 3月 9-14销售→成单全流程A2A Multi-Agent + RFP 管线
Phase 4月 15-18+企业级 AI 平台权限复刻 + 知识沉淀层 + 跨部门复用

四阶段规划的工程逻辑

Phase 1 的核心原则:绕开变革阻力。 我们不做"新系统",而是在销售最熟悉的 Excel 和报价流程上做增强。用户不需要学新工具,工作流不变——只是原来手动填 Excel 变半自动。这个设计让 Phase 1 的采纳率直接上了 90%。

Phase 2 把隐性知识变成可执行的规则。 Skill Engine 的价值在这一阶段集中体现——GCOE 的定价专家不需要"培训 AI",AI 通过观察端侧修正自动学习。

Phase 3 做横向扩展。 A2A 架构的关键优势在这里显现:新增 Tender Agent、RFP Agent、Compliance Agent,主控 Agent 不需要大规模重构。

Phase 4 做平台化。 权限复刻、知识沉淀层、跨部门复用——这是从"项目"到"产品"的质变。


七、技术选型复盘:几个真实决策

Q: 为什么选 pgvector 而不是 Pinecone/Weaviate/Milvus?

A: 客户已经在用 Azure PostgreSQL。 多引入一个向量数据库 = 多一套运维 + 多一套权限体系 + 多一套备份策略。pgvector 在 3072 维、5000 个 chunk 的规模下,召回率 96%,性能完全够用。

Q: 为什么选 Hybrid Search(pgvector + BM25)?

A: 标书场景有大量精确术语匹配需求。 "ISO 50001"、"BACnet/IP"、"Modbus RTU"——这些术语嵌入向量空间里距离不远的候选很多,但不能靠"语义近似"去猜。BM25 的精确词项匹配 + 向量的语义匹配 = 互补。

Q: 为什么选 Copilot Studio 可视化编排而不是代码编排?

A: 这是交付给客户的系统。 交付后客户 IT 团队需要能看懂、能改、能维护。Copilot Studio 的可视化画布让非 AI 工程师也能调整 Agent Flow 的决策逻辑。AI 项目的长期维护成本往往被低估——代码编排看起来更灵活,但对客户的运维团队来说,看懂一段 Python Agent 编排代码的成本远高于看懂一个可视化画布。

Q: Cross-Encoder 重排值得那 0.4 秒延迟吗?

A: 值。 从 Top-50 到 Top-5 的质量提升是决定性的——NDCG 从 0.73 提升到 0.91。对用户来说,多等 0.4 秒但看到的 5 条结果里有 4 条高度相关,好过秒出 5 条但有 2 条跑偏。


结语

写这篇文章的时候,Sales Deal Mate 的第 4 阶段还在路上。但回过头看这两年的技术决策,我觉得有几个原则值得分享:

  1. AI 项目的用户不是你和你的同事,是客户的业务人员。 他们不关心你的向量数据库是什么,只关心能不能少花 30 分钟填 Excel。

  2. 架构选型以可维护性为第一优先级。 Copilot Studio 而不是 LangChain,pgvector 而不是 Pinecone——每个决策背后都是「客户能不能自己维护」。

  3. 安全不是附加功能,是第一天就该考虑的架构约束。 数据不出微软生态、端到端身份贯通、行级安全——这些在原型阶段就应该跑通,而不是等客户审计时再补。

  4. 渐进交付 > 大爆炸。 18 个月分四阶段,每个阶段独立上线、独立创造价值。客户每个季度都能看到新东西,而不是一年半后打开一个没人用的巨兽。

  5. AI 不是替代人类做决策,是帮人类发现隐性规则。 Skill Engine 的设计哲学就在这里——修正 3 次以上的端侧行为才触发规则生成,剩下的交给人类审批。

关于诺未:我们是一家从 2011 年开始深耕微软生态的AI解决方案提供商,14 年里服务了 1000+ 企业客户。AI 时代到来后,我们把过去积累的工程经验全部"搬"到了 AI Agent 的落地实践里。如果你也在做企业级 AI 项目,欢迎交流。


本文基于真实项目技术架构撰写。部分客户信息已脱敏处理,具体性能数据来自 Azure AI Foundry Trace 记录。