企业智能推荐 Agent:从自然语言需求到可验证推荐清单
摘要
本文介绍一个企业智能推荐 Agent 的完整实现:系统将自然语言需求转换为结构化查询,通过候选召回、单主体核验、身份校验、硬条件复核和两阶段排序生成带证据的推荐清单,并使用 50 条综合测试用例验证当前离线实现。
企业智能推荐 Agent:从自然语言需求到可验证推荐清单
写在前面
企业推荐表面上是一个搜索任务,实际包含需求理解、条件确认、代码映射、候选召回、主体核验、字段冲突处理、硬条件复核和结果排序。任何一个环节失真,最终推荐都可能偏离用户目标。
本项目实现了一个受控工作流 Agent。系统接收文本、语音转写文本或需求文件,将自然语言条件转换为结构化意图,调用企业候选检索和主体信息核验工具,再通过两阶段排序生成带证据的推荐清单。大语言模型负责理解和解释,数据访问、身份校验、条件判断和排序由确定性代码完成。
当前完成范围只包括企业智能推荐任务。本文依次说明整体架构、Agent 状态机、推荐数据链路、排序方法、前后端实现和离线评估。核心结论是:此类业务 Agent 的可靠性主要来自明确的工具边界、核验后的条件复查、可追溯证据和分层测试,而不是让模型自由决定全部流程。
1. 项目概览
项目 | 当前实现 |
|---|---|
任务目标 | 根据地区、行业、成立时间、资本和经营状态等条件生成企业推荐清单 |
输入形式 | 自然语言、语音转写文本、文本类需求文件 |
工作流 | 九节点 LangGraph 状态机 |
数据链路 | 候选检索、主体核验、双源合并和条件复核 |
默认数量 | 最多召回 100 家、核验 20 家、最终推荐 5 家,均可配置 |
排序方法 | 词面匹配、语义相似度、经营范围聚焦度、业务证据和 RRF 融合 |
服务架构 | 独立前端、REST 后端、异步运行资源和 SQLite 短期状态 |
评测集 | 50 条综合测试用例 |
当前结果 | 50/50 用例通过;8 个合成排序案例的 |
这里的 50/50 表示当前离线测试满足预先定义的契约和断言,不等于真实企业库上的推荐准确率。排序指标也只来自合成数据,后文会单独说明测试范围。
2. 为什么使用受控工作流
企业推荐并不是开放式聊天。用户通常会给出地区、产业方向、企业状态、成立年限、资本区间和推荐数量,这些条件需要稳定映射到工具参数。如果让大语言模型直接拼接接口请求或自由决定筛选逻辑,容易出现字段缺失、单位误解、条件被忽略和结果无法复现等问题。
项目采用 LLM,Large Language Model,大语言模型,与确定性工作流分工:
能力 | 大语言模型负责 | 确定性代码负责 |
|---|---|---|
需求理解 | 识别地区、行业和筛选意图 | 使用 schema 校验字段和类型 |
条件补全 | 生成结构化追问 | 保存已确认槽位,防止旧值被覆盖 |
数据访问 | 判断需要哪些信息 | 调用工具、分页、超时和错误处理 |
排序解释 | 根据证据生成推荐理由 | 计算分数、复核硬条件和稳定排序 |
最终输出 | 将结构化证据转成可读文本 | 约束字段来源并验证输出结构 |
这种分工使模型不能直接访问数据库或第三方接口,也不能生成任意查询语句。所有工具调用都使用结构化 JSON,输入和输出经过契约校验。
3. 整体架构
系统由独立工作台、版本化 REST API、LangGraph 工作流、确定性数据工具和短期状态仓储构成。REST,Representational State Transfer,表述性状态转移,用于定义前后端资源接口;API,Application Programming Interface,应用程序编程接口,是前端访问任务、运行、数据集和事件的唯一入口。

前端提交需求后,后端创建任务和运行资源。工作流先完成需求解析与代码映射,再请求用户确认查询条件。确认后才进入候选召回和逐主体核验。每个阶段会记录结构化事件,中间候选、核验结果、合并画像和最终推荐分别保存为可查询数据集。
架构中最重要的边界有三条。
第一,前端不能直接调用模型或数据工具,只能通过 REST API 获取任务状态和结果。
第二,工作流不能根据聊天文本反向解析表格。候选集、核验集、合并画像和最终推荐都是独立的结构化数据资产。
第三,推荐理由只能引用证据包中的字段,不能补充数据源没有提供的信息。
4. 九节点 Agent 工作流
当前 LangGraph 图包含九个业务节点:
4.1 需求解析与中断恢复
collect_intent 将用户输入转成结构化意图。系统关注的字段包括目标地区、行业方向、经营状态、成立年限、注册资本、实缴资本,以及召回、核验和推荐数量。
例如,一条匿名化需求可以转换为:
当地区、行业或用户明确要求的字段不完整时,工作流不会猜测,而是进入 interrupt 状态。已确认字段保存在同一任务的短期状态中,用户补充信息后从需求解析节点恢复。新任务不会继承旧任务条件。
4.2 地区和行业代码映射
自然语言地区可能存在同名区县、简称和层级缺失。行业描述也可能是业务概念,而不是标准分类代码。resolve_codes 使用本地确定性索引完成代码映射,不把整棵代码树交给模型临时猜测。
映射结果需要同时保留代码、名称、层级和父级关系。遇到同名地区时,系统返回候选层级让用户确认,不能将多个父级下的同名区域合并查询。行业索引则使用离线向量和词面匹配寻找候选代码,再由工作流确定最终查询参数。
4.3 查询确认
工具调用前,系统将最终地区、行业、资本、成立年限和数量参数整理成确认卡。只有用户确认后,运行才进入数据查询阶段。
这个节点解决了一个常见问题:模型正确识别了用户的修改意图,但默认参数在后续请求中又覆盖了新值。当前实现把最终数量参数冻结在确认快照中,满足:
后续工具严格使用该快照,不再重新推断数量。
5. 从候选召回到最终推荐
推荐链路采用先扩大召回、再核验收缩的结构。默认最多召回 100 家,初筛后核验 20 家,最终返回 5 家。默认值可以调整,但流程顺序不变。

5.1 候选召回与去重
候选检索按固定页大小循环请求,直到达到召回上限、数据源返回无更多结果,或实际候选不足。每页完成后记录运行事件和原始响应摘要,便于定位缺页、空结果和接口异常。
召回结果先按照主体信用标识、实体标识或规范化名称去重。同一主体出现多条记录时,优先保留字段更完整、经营范围信息更充分的记录。这样可以避免重复主体占用核验名额。
5.2 初筛只决定核验顺序
高级检索结果包含企业名称、经营范围、地区、状态和部分资本信息,但这些字段不一定都具有最终权威性。因此初筛只用于决定哪些候选优先进入核验队列,不直接决定最终推荐。
初筛同时考虑关键词和语义相关性:
查询向量只计算一次,候选文本采用批量编码,避免逐条重复调用 embedding。Embedding 是将文本转换为数值向量的表示方法,用于计算需求与候选描述之间的语义相似度。
5.3 单主体核验与有界执行
进入核验队列后,每个候选分别调用主体信息核验工具,补充基础状态、信用标识、注册资本、成立时间、地区和经营范围。当前默认使用单路执行,代码支持受控并发范围,但未获得上游并发能力确认前不自动提高并发。
单家核验失败不会中止整个任务。系统将超时、未命中、契约错误和身份不一致记录为行级结果,继续处理其他候选。只有系统性契约错误才会使当前运行失败。
6. 身份校验、字段合并与硬条件复核
这一阶段决定了候选是否有资格进入最终排序,也是整个系统中最关键的可靠性设计。
6.1 先校验身份,再合并字段
候选检索和主体核验可能返回名称相似但实际不同的主体。系统不能仅凭名称相同就合并两份记录。两侧同时存在实体标识或统一信用标识时,必须完全一致;冲突记录标记为 identity_mismatch,不得进入合并画像和最终评分。
身份通过后,字段按照固定来源规则合并。主体核验结果用于最终基础字段,候选检索结果用于召回证据和缺失字段补充。每个合并字段保留原值、选中值、来源和冲突状态。
6.2 只复核用户明确提出的条件
初筛阶段的数据可能不完整,因此用户的硬条件需要在主体核验后重新检查。当前复核范围包括经营状态、地区、成立时间、注册资本和实缴资本。
系统只检查用户明确提出的限制。用户未限制的字段不能被隐式添加为淘汰条件。资本单位无法归一化、两侧金额冲突或地区代码冲突时,字段状态标记为 unverifiable 或冲突状态,不能写成符合条件。
复核结果使用结构化数组保存:
这种结构使前端能够展示企业被排除的具体原因,也让测试可以直接断言硬条件违规率。
7. 两阶段排序
最终排序版本采用行业相关性优先策略。它不把信息完整度直接当成行业相关性,也不允许资料丰富但业务无关的候选挤入前列。
7.1 终排特征
最终分数由五部分组成:
语义相似度衡量需求与企业综合文本的向量距离。词面相似度同时检查名称、经营范围和其他业务文本,并使用 N-Gram,连续 N 元字符片段,补充近似字符串匹配。经营范围聚焦度将长文本切成片段,取与需求最相关的局部内容,避免大段通用描述稀释核心业务。
RRF,Reciprocal Rank Fusion,倒数排名融合,将语义、词面和经营范围三个排序列表进行融合。它不要求不同特征具有相同数值尺度,能降低单一特征偶然偏高造成的排序波动。
业务证据只占较小权重,用于确认经营状态、主体标识、经营范围、资本和地区等基础信息是否完整。完整度可以增强可信度,但不能替代行业相关性。
7.2 质量参考线不参与强制淘汰
系统保留质量参考线,用于展示较高、中等或证据有限等匹配提示。它不会自动淘汰已经通过硬条件复核的企业。最终返回数量由用户确认的 recommendation_limit 决定,避免质量标签和业务数量要求相互混淆。
8. 证据包与推荐理由
最终推荐不是一组分数,而是结构化证据包。每条推荐至少包含主体基本信息、排序依据、字段来源、条件复核结果和推荐理由。
推荐理由由大语言模型生成,但输入只能来自证据包。模型不能补充未被工具返回的融资、专利、客户或经营表现。生成结果还需要通过 schema 校验,字段缺失时重新生成或显式失败。
这种方式把自然语言解释和可审计字段绑定在一起。读者可以知道为什么推荐,也可以继续检查证据是否足够。
9. 前后端与可观测性
系统采用独立前端和 REST 后端。前端不直接导入 Python 工作流,也不从聊天文本中解析表格,而是查询四类数据集:
数据集 | 主要内容 |
|---|---|
候选召回集 | 原始候选、去重信息和初筛顺序 |
核验结果集 | 每个候选的核验状态、错误和身份判断 |
合并画像集 | 身份一致后的字段合并结果与来源 |
最终推荐集 | 终排名次、参考分、证据和推荐理由 |

工作台左侧用于对话、补充信息和调整运行参数;右侧分别展示任务概览、候选、核验、合并画像和最终推荐。运行过程以事件流展示当前阶段、完成数量和错误摘要。
后端将一次交互拆成三个资源:
资源 | 作用 |
|---|---|
| 保存当前推荐任务的短期槽位和确认状态 |
| 表示用户一次提交触发的异步执行 |
| 标识该运行产生的结构化中间结果 |
状态数据和工作流 checkpoint 保存在 SQLite 中。服务重启后,不能继续的运行会显式标记失败,不会伪造完成结果。事件只记录阶段、计数、耗时和错误码,不保存模型思维链或完整敏感数据。
10. 50 条综合问答测试集
项目建立了 50 条企业推荐综合测试用例。它们围绕用户问答主线组织,但测试对象不仅是自然语言回复,还覆盖代码映射、排序和安全边界。
测试类型 | 数量 | 验证内容 |
|---|---|---|
单轮需求理解 | 16 | 地区、行业、状态、年限、资本和数量参数 |
多轮补充与追问 | 14 | 缺失字段追问、槽位合并和确认恢复 |
地区与行业代码映射 | 8 | 同名地区、父级关系和行业代码召回 |
端到端排序 | 8 | 初筛、核验、硬条件复核和最终排序 |
安全与异常处理 | 4 | 越界任务、提示词注入和正常任务放行 |
合计 | 50 | 当前离线契约与工作流回归 |
10.1 测试执行边界
50 条用例采用三种执行方式。
单轮和多轮用例验证冻结后的结构化意图契约,检查字段和状态是否符合预期。它们没有默认调用在线大语言模型,因此不能解释为模型自然语言理解准确率。
代码知识用例运行本地地区与行业索引,验证目标代码是否出现在前若干召回结果中。
排序用例使用 8 组合成契约数据,包含人工定义的相关性标签、主体核验结果和硬条件。它们用于稳定比较排序版本,不调用真实企业全库。
10.2 结果与指标
当前 50 条用例全部通过,综合平均得分约为 0.9943。这个平均分来自不同类别评估器的归一化结果,不等于统一意义上的准确率。
排序部分采用以下指标:
指标 | 结果 | 含义 |
|---|---|---|
| 0.800000 | 前 5 个位置中,平均 80% 被标注为相关 |
| 0.964318 | 前 5 个结果的相关性顺序接近理想排序 |
| 1.000000 | 每个排序案例的首位结果均为相关候选 |
| 1.000000 | 合成候选池中的相关主体均进入前 20 |
硬条件违规率 | 0 | 最终推荐中没有出现复核不通过的主体 |

P@5 是 Precision at 5,前 5 精确率;NDCG@5 是 Normalized Discounted Cumulative Gain at 5,前 5 归一化折损累计增益;MRR 是 Mean Reciprocal Rank,平均倒数排名;Recall@20 是前 20 召回率。
这些结果说明当前代码在固定契约和合成数据上保持了较稳定的行为,尤其是硬条件复核没有出现违规。但它们不能证明真实全库召回率、在线模型理解准确率、外部服务稳定性或实际业务转化效果。
11. 当前限制
第一,意图测试主要验证结构化契约。真实用户表达可能包含更复杂的行业组合、地区歧义和条件冲突,需要单独运行在线模型评估。
第二,排序指标来自 8 个合成案例。合成数据能够稳定复现边界条件,但无法覆盖真实企业数据中的字段缺失、更新延迟、行业跨界和长尾分布。
第三,单主体核验当前默认串行执行。这种设置优先保证上游接口安全和顺序稳定,但当核验数量增加时,整体延迟会明显上升。
第四,推荐分数是候选间的相对排序依据,不是企业质量、投资价值或合作成功率。最终结果仍需要业务人员结合实际目标审阅。
第五,当前工作台和数据资产用于短期任务,不保存跨任务长期偏好。任务过期后,中间数据和导出资产应按策略清理。
12. 工程启发
企业推荐 Agent 最重要的不是让模型调用更多工具,而是把每一步的责任边界写清楚。
需求理解可以交给模型,但字段类型和数量关系必须由 schema 校验。候选召回可以使用宽松条件,但最终推荐必须基于核验后的字段重新检查硬条件。推荐理由可以由模型组织语言,但每个结论都要能回到证据字段。
评估也不能只准备若干看起来合理的问题。单轮意图、多轮补槽、代码映射、端到端排序和安全边界需要分别测试。只有把失败类型拆开,才能判断问题来自模型、知识映射、数据工具、合并规则还是排序算法。
小结
本项目完成了一条从自然语言需求到可验证推荐清单的企业智能推荐链路。系统通过 LangGraph 固定业务节点,通过 REST 资源隔离前后端,通过候选召回与单主体核验形成两阶段数据链路,再以身份校验、硬条件复核、融合排序和证据包约束最终输出。
50 条离线测试说明当前实现已具备稳定的契约、代码映射、排序和安全回归基础,但结果仍处于离线工程验证范围。下一步真正需要关注的不是继续增加抽象能力,而是使用脱敏真实快照扩展评测集,验证在线意图理解、外部数据稳定性、端到端延迟和业务人员对推荐结果的实际判断。
