我用 FastGPT + TextIn xParse 做了个招标文件智能审查助手,这才是文档解析该有的样子
我用 FastGPT + TextIn xParse 做了个招标文件智能审查助手,这才是文档解析该有的样子
说实话,我之前对 PDF 解析这件事一直没什么感觉。做了大半年 AI 工具体验,大部分时间都在跟模型参数、prompt 工程较劲,文档解析这个环节基本是黑盒——丢进去一个 PDF,系统返回一段文本,好不好用全看命。
直到最近老板扔过来一个需求,要我搭一个招标文件智能审查 Agent,才第一次把文档解析这件事从头到尾掰开看了。结果发现,这个环节被严重低估了。
起因:老板要做一个招标 Agent
事情的起因很简单。上个月在 GitHub 上刷到了 FastGPT 这个开源项目,我之前一直有关注,也写过几期工具体验视频。最近老板看到我在折腾这个东西,就让我拿它搭一个能帮公司业务部门审招标文件的 Agent。
https://github.com/labring/FastGPT

说实话接到这个需求的时候我心里有点虚。之前做 AI 工具体验,基本都是拿短文本或者普通文档去测,效果都还行。但招标文件完全不是一个量级的东西。
先说痛点。我们公司业务部门经常要投标,一份招标文件动辄五六十页,里面最折磨人的就是几类内容:
表格。资格审查表、符合性审查表、评分细则表,全是多列表格,有的表格里面还有嵌套,评分标准字段里夹杂着编号、条件、证明材料要求。这种表格人工读都要反复确认好几遍,更别说让机器来处理。
数字。项目预算、付款比例、分值权重、履约保证金比例、服务期限,每一个数字都不能搞错。48 万预算的项目你少看一个零,或者把价格分占比 10% 看成 90%,投标策略就全偏了。
条款关联。评分标准和投标材料要求之间有对应关系,资格条件和证明材料之间有对应关系,合同条款和履约风险之间有对应关系。这些关联散落在不同章节里,人工交叉核对非常耗时。
格式混乱。招标文件 PDF 的排版五花八门,有的表格跨页,有的有页眉页脚,有的有水印,有的表格列宽不一样。如果 PDF 解析不能处理好这些,后面所有基于文档内容的分析都是在垃圾数据上做运算。
业务部门现在的做法是一个人花两三天时间把招标文件从头到尾读一遍,手动整理出一份投标响应清单。效率低不说,还容易漏项。去年就出过一次事,一个评分项的材料要求被漏掉了,废标。
老板的需求很明确:能不能让 AI 帮我们把招标文件读一遍,自动提取关键条款、评分规则、风险点,输出一份可以直接用的投标准备清单。
我手上正好有一份真实的政府采购招标文件,65 页,项目预算 48 万,服务类采购。就拿它来做测试。
环境准备:WSL 里跑 FastGPT
我的开发环境是 WSL(Ubuntu),部署 FastGPT 这一步按 GitHub 上的教程走就行了,不复杂。配好 MongoDB/PG 和向量库之后,把模型接上。
我接入的是 GPT5.5 和一个索引模型:

这里先说清楚三个东西各自干什么:
- GPT5.5:负责最终回答,包括条款分析、风险判断、投标建议生成。它不负责解析 PDF。
- 索引模型:负责把招标文件内容向量化,后续用户提问时做召回用。
- TextIn xParse:负责把 PDF 文件解析成结构化的 Markdown。它不是索引模型,它解决的是 PDF 进入知识库之前的"清洗"问题。
这三个东西各司其职,不要搞混。
创建 Agent
FastGPT 工作台点创建应用,选对话类型,命名叫"招标文件智能审查助手"。


然后是提示词。招标文件这个场景对 prompt 的要求比较特殊:模型不能自由发挥,不能编造条款,数字必须和原文一致。我写了一份强约束的系统提示词:
你是一个专业的招标文件审查与投标响应分析助手,擅长从招标文件、采购需求、评分办法、资格审查表、符合性审查表和合同条款中提取关键信息,并给出可执行的投标建议。
当前应用用于分析经过 FastGPT PDF 增强解析后的招标文件内容。当前部署中,PDF 增强解析接入的是 TextIn xParse 的 pdf_to_markdown 能力,因此你应充分利用解析后的 Markdown 结构、表格、标题层级和条款内容进行回答。
你的工作目标:
1. 快速定位招标文件中的关键条款。
2. 提取项目基础信息、资格要求、评分规则、合同要求、付款方式、履约保证金、服务期限等内容。
3. 识别投标风险、废标风险、响应偏离风险和履约风险。
4. 给出清晰、可执行的投标响应建议。
5. 回答时尽量引用招标文件中的原始依据,包括章节名、条款名、表格名或原文片段。
回答规则:
1. 必须优先依据知识库或文件内容回答。
2. 如果资料中没有找到明确依据,不要编造,直接说明"当前招标文件中未检索到明确说明"。
3. 涉及金额、时间、比例、分值、保证金、期限等数字时,必须保持原文一致。
4. 涉及风险判断时,需要说明风险来源、影响和建议处理方式。
5. 不要输出思考过程,只输出结论、依据和建议。
6. 用户要求总结时,优先使用表格。
7. 用户要求风险分析时,按"高风险 / 中风险 / 低风险"分级。
8. 用户要求投标建议时,输出可直接用于投标准备的清单。
默认输出结构:
一、结论摘要
二、关键依据
三、风险点
四、响应建议
五、待人工确认事项
开场白我也控制得很简短:
你好,我可以帮你审查招标文件。你可以问我项目预算、资格要求、评分规则、付款方式、履约保证金、合同风险、废标风险,或让我生成一份投标准备清单。

到这里 Agent 本身的搭建其实很快,难点不在这里,在于后面 PDF 解析的质量对比。
TextIn xParse 到底在干什么
在进入对比测试之前,我得先把 xParse 的位置说清楚。
TextIn xParse 是合合信息(TextIn)面向 AI 场景做的智能文档解析服务。它做的事情用一句话说就是:把 PDF 等非结构化文档转换成结构化的 Markdown/JSON,让后面的知识库和模型更容易理解。
在 FastGPT 里,我用的是它的 pdf_to_markdown 接口。招标文件里到处是表格、编号、合同条款,PDF 原本是给人看的,RAG 需要的是给机器检索的文本。xParse 做的就是把 PDF 里的标题、段落、表格、图片整理成 Markdown 结构,让后面的知识库切片和召回更稳定。
FastGPT 目前通过"PDF 增强解析"这个开关来控制是否调用 xParse。在界面上看到的是一个复选框,但底层是一套完整的调用链路。我先从源码层面把这个链路理清楚。
注册 TextIn xParse 并获取密钥
要用 xParse 的 PDF 解析能力,先得有一个 TextIn 的账号。
打开 xParse 产品页面:
https://www.textin.com/market/detail/xparse?from=5h21yksktg

注册完成后进入控制台,找到 x-ti-app-id 和 x-ti-secret-code,把这两个值复制下来,后面配置 FastGPT 要用。
整个注册流程不复杂,主要是拿到这两个凭证。
配置 TextIn 密钥
拿到 App ID 和 Secret Code 之后,配置到 FastGPT 的环境配置文件里。
FastGPT 的环境配置文件在:
runtime/fastgpt-docker/config.json
对应的结构如下:
{
"systemEnv": {
"customPdfParse": {
"url": "",
"key": "",
"doc2xKey": "",
"textinAppId": "你的 App ID",
"textinSecretCode": "你的 Secret Code",
"price": 0
}
}
}
几个关键字段说明一下:
textinAppId:在 TextIn 开放平台注册后获得的 App ID。textinSecretCode:对应的 Secret Code。url:自定义 PDF 解析服务地址。注意,这个字段如果填了值,优先级最高,会直接走自定义服务,不会走 TextIn。doc2xKey:Doc2X 的密钥,和 TextIn 是两个不同的服务。price:FastGPT 内部展示解析价格用的字段,跟 TextIn 侧实际计费无关。
我的部署里 url 留空,textinAppId 和 textinSecretCode 都配好了,所以打开 PDF 增强解析后会走 TextIn xParse。
从源码追踪完整调用链路
这是这篇文章最核心的部分。我之前看过很多测评文章,写到"我开了增强解析,效果更好了"就结束了。但我总觉得不够——我到底怎么确定勾了那个复选框之后走的是 TextIn?总不能只凭感觉。
所以我直接翻了 FastGPT 的源码。
第一步:Agent 配置页保存文件上传设置
Agent 的编辑表单在 projects/app/src/pageComponents/app/detail/Edit/ChatAgent/EditForm.tsx。在第 487 行左右,有一个 FileSelectConfig 组件:
<FileSelectConfig
forbidVision={!selectedModel?.vision}
value={appForm.chatConfig.fileSelectConfig}
onChange={(e) => {
setAppForm((state) => ({
...state,
chatConfig: {
...state.chatConfig,
fileSelectConfig: e
}
}));
}}
/>

也就是说,你在界面上对文件上传做的所有配置(包括文件数量、支持的文件类型、PDF 增强解析开关),最终都会存到:
appForm.chatConfig.fileSelectConfig
第二步:PDF 增强解析复选框
这个复选框在 projects/app/src/components/core/app/FileSelect.tsx 第 140 行:
{localValue.canSelectFile && feConfigs?.showCustomPdfParse && (
<HStack justifyContent={'flex-start'} spacing={1} mt={2}>
<Checkbox
isChecked={localValue.customPdfParse}
onChange={(e) => {
setLocalValue((state) => ({
...state,
customPdfParse: e.target.checked
}));
}}
>
<FormLabel>{t('app:pdf_enhance_parse')}</FormLabel>
</Checkbox>
<QuestionTip label={t('app:pdf_enhance_parse_tips')} />
</HStack>
)}

注意这里有两个前置条件:
localValue.canSelectFile为 true,也就是说你先得开启文件上传功能。feConfigs?.showCustomPdfParse为 true,这个是系统级配置,控制 PDF 增强解析功能是否对用户可见。
勾选之后,chatConfig.fileSelectConfig.customPdfParse 被设为 true。不勾就是 false。
第三步:运行时读取配置并传递
当用户在 Agent 对话中上传文件时,FastGPT 的对话调度模块会读取这个配置。在 packages/service/core/workflow/dispatch/ai/chat.ts 第 153 行:
const [filterMessages] = await Promise.all([
getChatMessages({
model: modelConstantsData,
maxTokens: max_tokens,
histories: chatHistories,
datasetCiteSystemPrompt: datasetCiteData.systemPrompt,
systemPrompt,
userChatInput,
userFiles,
requestOrigin,
maxFiles: chatConfig?.fileSelectConfig?.maxFiles || 20,
customPdfParse: chatConfig?.fileSelectConfig?.customPdfParse,
usageId,
runningUserInfo
}),
// ...
]);
customPdfParse 从 Agent 配置里取出,传给 getChatMessages。继续往下跟,文件内容解析时会走到 parseFileContentFromUrls 函数(位于 packages/service/core/workflow/utils/file.ts 第 227 行):
export const parseFileContentFromUrls = async ({
urls,
requestOrigin,
maxFiles,
teamId,
tmbId,
customPdfParse,
usageId
}: GetFileProps & {
urls: string[];
}) => {
const parseUrlList = urls
.map((url) => normalizeReadableFileUrl({ url, requestOrigin }))
.filter(Boolean)
.slice(0, maxFiles);
const readFilesResult = await Promise.all(
parseUrlList.map(async (url) => {
try {
if (await isInternalAddress(url)) {
return { success: false, name: '', url, content: PRIVATE_URL_TEXT };
}
const { name, content } = await getFileContentByUrl({
url,
teamId,
tmbId,
customPdfParse,
usageId
});
return { success: true, name, url, content };
} catch (error) {
return {
success: false,
name: '',
url,
content: getErrText(error, 'Load file error')
};
}
})
.filter(Boolean)
);
return readFilesResult;
};
customPdfParse 一路从 Agent 配置传递到这里的 getFileContentByUrl,再往下传给 readFileContentByBuffer。
第四步:底层解析路由判断
真正决定走哪个解析服务的地方在 packages/service/common/file/read/utils.ts。这个文件的核心是一个路由函数:
const pdfParseFn = async (): Promise<ReadFileResponse> => {
if (!customPdfParse) return systemParse();
if (global.systemEnv.customPdfParse?.url) return parsePdfFromCustomService();
if (global.systemEnv.customPdfParse?.textinAppId) return parsePdfFromTextin();
if (global.systemEnv.customPdfParse?.doc2xKey) return parsePdfFromDoc2x();
return systemParse();
};
let { rawText, formatText, imageList } = await (async () => {
if (extension === 'pdf') {
return await pdfParseFn();
}
return await systemParse();
})();
这段代码的判断逻辑非常清晰:
- 文件不是 PDF → 直接走默认解析
systemParse(),PDF 增强解析开关对这个场景没影响。 - 是 PDF 但
customPdfParse=false(没勾增强解析)→ 直接systemParse(),这就是 FastGPT 自带的 PDF 解析。 - 是 PDF 且
customPdfParse=true(勾了增强解析)→ 开始看系统环境变量里配了什么:- 配了
customPdfParse.url→ 走自定义解析服务(最高优先级)。 - 配了
textinAppId→ 走 TextIn xParse。 - 配了
doc2xKey→ 走 Doc2X。 - 什么都没配 → 回退到默认解析。
- 配了
在我的部署里,url 留空,textinAppId 和 textinSecretCode 都配了,所以勾选增强解析后会进入 parsePdfFromTextin()。
这里有一个很容易忽略的细节:如果你在系统配置里没有填 TextIn 的密钥,即使你在 Agent 配置里勾了 PDF 增强解析,最后还是走默认解析。因为 parsePdfFromTextin 函数开头会检查:
const parsePdfFromTextin = async (): Promise<ReadFileResponse> => {
const appId = global.systemEnv.customPdfParse?.textinAppId;
const secretCode = global.systemEnv.customPdfParse?.textinSecretCode;
if (!appId || !secretCode) return systemParse();
// ...
};
密钥不存在就直接回退。这保证了系统不会因为配置不完整就崩溃。
第五步:TextIn xParse 实际请求
最终调用 TextIn 的代码在 packages/service/thirdProvider/textin/index.ts:
export const useTextinServer = ({ appId, secretCode }: { appId: string; secretCode: string }) => {
const instance = createProxyAxios({
baseURL: 'https://api.textin.com/ai/service/v1',
timeout: 300000,
headers: {
'x-ti-app-id': appId,
'x-ti-secret-code': secretCode
}
});
const parsePDF = async (fileBuffer: Buffer) => {
const params = {
get_image: 'objects',
image_output_type: 'base64str',
parse_mode: 'auto',
dpi: 144,
markdown_details: 1,
table_flavor: 'md',
paratext_mode: 'none',
page_details: 0,
remove_watermark: 1
};
const { data } = await instance.post('/pdf_to_markdown', fileBuffer, {
params,
headers: { 'Content-Type': 'application/octet-stream' }
});
if (data.code !== 200) {
return Promise.reject(
`[Textin] API error: ${data.message || data.code || 'Unknown error'}`
);
}
const rawMarkdown = data.result?.markdown;
if (!rawMarkdown) {
return Promise.reject('[Textin] No markdown content in response');
}
const { text, imageList } = matchMdImg(rawMarkdown);
const pages = data.result?.pages?.length || data.result?.total_page_number || 1;
return { pages, text, imageList };
};
return { parsePDF };
};
这里有几个参数值得注意:
table_flavor: 'md':表格以 Markdown 语法输出。这对招标文件的评分标准表、资格审查表来说非常关键。paratext_mode: 'none':不输出页眉页脚等非正文内容。招标文件每一页都有"XXX招标文件"这样的页眉,如果不过滤掉,这些内容会干扰召回。markdown_details: 1:返回 Markdown 元素的详细信息。get_image: 'objects':识别页面内的子图像。remove_watermark: 1:去除水印。
TextIn 返回 Markdown 后,FastGPT 还会处理里面的图片:
const rawMarkdown = data.result?.markdown;
const { text, imageList } = matchMdImg(rawMarkdown);
然后把解析后的文本传回知识库或对话流程。
完整的调用链路总结:
Agent 界面勾选"PDF 增强解析"
→ chatConfig.fileSelectConfig.customPdfParse = true
→ chat.ts 读取配置,传给 parseFileContentFromUrls
→ parseFileContentFromUrls 调用 readFileContentByBuffer
→ utils.ts 判断:是 PDF 且 customPdfParse=true
→ 发现 textinAppId 已配置
→ 调用 parsePdfFromTextin()
→ 请求 https://api.textin.com/ai/service/v1/pdf_to_markdown
→ 返回 Markdown 格式文本
→ 进入知识库切片、向量化、召回
→ GPT5.5 基于召回内容生成回答
到这里,我对"勾一个复选框到底发生了什么"这件事有了完整的认知。不是玄学,是代码。
开始对比测试
理论说得再多不如直接跑。我准备了一组问题来对比默认解析和 TextIn xParse 增强解析的效果。
为了保证对比公平,控制变量:
- 同一份招标 PDF(65 页)
- 同一个 Agent(同一个提示词)
- 同一个 GPT5.5
- 同一个索引模型
- 同一批问题
唯一的变量就是:PDF 增强解析 开还是关。
第一组:不开启增强解析
先在文件上传配置里不勾"PDF 增强解析":

然后上传招标文件:

这个时候底层走的就是 systemParse(),FastGPT 自带的 PDF 解析,不经过 TextIn。
测试 1:付款方式
本项目的付款方式是什么?请列出支付节点、支付比例和触发条件,并说明依据来自哪个章节或表格。
默认解析:

增强解析:

这道题的答案在招标文件的采购需求前附表里:合同签订后 30 日内支付 50%,验收合格后 30 日内支付剩余。说实话两边的回答都能读到关键信息,但增强解析后的结构化程度更高,支付节点、比例、触发条件之间的关系对应更清楚。
对投标来说,这种关系对应正确比读出文字重要。你拿到一份招标文件要算成本的时候,需要的是"什么时候给多少钱"的清晰节点,而不是一段凑合能看懂的描述。
测试 2:综合评分占比
本项目综合评分满分是多少?技术资信分和价格分分别占多少?请给出原文依据。
默认解析:

增强解析:

原文里写得很清楚:满分 100 分,技术资信占 90%,价格分占 10%。技术资信占了九成权重,这说明这个项目不是拼价格的,业绩和人员配置才是决胜因素。
增强解析后的回答在章节引用上更明确。别小看这个"章节引用",实际投标时你需要拿着 Agent 的回答去招标文件里核实,能快速定位到原文在哪一页,比自己翻几十页文件要快得多。
测试 3:详细评分标准(重点)
请提取本项目详细评分标准,并按"类别、评分内容、评分标准、分值范围"整理成表格。
这是整个对比里差异最明显的一道题。
默认解析:

增强解析:

评分标准表是招标文件里最复杂的表格之一。它不是简单的两列,而是"类别—评分内容—评分标准—分值范围"多列结构,而且"评分标准"字段里面还有换行、编号、证明材料要求。
默认解析出来的内容能看出一些评分项,但列之间的关系容易混乱。比如"评分内容"和"分值范围"可能张冠李戴。增强解析后,Markdown 表格结构让模型在生成回答时能把每一列对应得更稳定。
这道题最能说明一个问题:PDF 解析的质量直接决定了 RAG 系统的上限。评分标准如果解析错了,后面所有关于投标策略的建议都建立在错误的数据上。
测试 4:投标人业绩评分
投标人业绩评分规则是什么?请按"业绩类型、单项得分、最高分、证明材料要求"整理成表格。
默认解析:

增强解析:

原文里有两类业绩:
- 交通强国建设评价研究项目业绩:每个 3 分,满分 9 分。
- 交通运输经济运行分析项目业绩:每个 2 分,满分 6 分。
还有证明材料要求:合同扫描件、业主单位证明材料(必要时)、未提供不得分。
增强解析后的表格结构更完整,业绩类型和对应的分值、材料要求之间的关系更准确。如果你要把 Agent 的回答直接转成投标准备清单,增强解析的结果可用性更高。
测试 5:人员配备评分
项目负责人和项目组其他人员分别如何评分?请输出评分项、得分条件、最高分和材料要求。
默认解析:

增强解析:

人员配备这个部分结构更复杂。分为"项目负责人"和"项目组其他人员"两大类,每类下面又细分多个评分项。默认解析容易把这些层级压平,"项目负责人"的要求可能混进"其他人员"里。
增强解析后,标题层级保留得更好,模型在区分两类人员的评分规则时更稳定。
实际投标中,人员材料需要提前收集(证书、社保、业绩证明、奖项),如果 Agent 能按人员类别分组列清楚,就能直接当作 checklist 用。
解析结果本身的差异
除了 Agent 的回答质量,我还对比了两种解析方式产出的原始文本形态。
开启增强解析后,请求日志能看到调用记录:

未增强的原始解析文本里能看到很明显的分割符号和排版残留:

默认解析的另一个效果:

增强解析后的内容明显更接近 Markdown 排版:

这两张图放在一起看,差距就很明显了。默认解析不是完全不能用,但表格和段落之间的关系更容易散。增强解析后的内容对后续的知识库切片和向量召回更友好。

为什么解析质量会影响 Agent 回答
很多人做文档问答会把注意力放在模型选型和 prompt 调优上。这没问题,但有一个前提经常被忽略:如果解析阶段已经把表格拆坏了,模型后面只能基于坏掉的内容回答,再怎么调也没用。
举个具体的例子。Agent 要回答"投标人业绩评分规则",需要从招标文件里正确拿到这些对应关系:
| 业绩类型 | 单项得分 | 最高分 | 材料要求 |
|---|---|---|---|
| 交通强国建设评价研究项目业绩 | 每个 3 分 | 9 分 | 合同扫描件,必要时补充业主证明 |
| 交通运输经济运行分析项目业绩 | 每个 2 分 | 6 分 | 合同扫描件,必要时补充业主证明 |
如果 PDF 解析把"每个 3 分"和第二类业绩混在一起,Agent 就会输出错误信息。在投标场景里,这可能导致你准备的业绩材料对应错了评分项,最后丢了本该拿到的分。
再看资格审查表和符合性审查表,它们完全依赖列结构(序号、评审指标、评审标准、格式及材料要求)。这类表格被拆成普通段落后,模型可能猜出部分内容,但稳定性会明显下降。
招标文件这种场景不允许猜。每一个数字、每一个条款对应关系都必须准确。
TextIn xParse 在这里的角色就是在文档进入知识库之前,把 PDF 结构尽量还原成机器可读的 Markdown。它的价值不在"回答更聪明",而在"输入更干净"。
整体效果
跑完这五组对比,这个招标文件智能审查助手已经可以完成一套实际工作:
- 提取项目基础信息(预算、期限、地点)
- 提取付款方式和履约要求
- 完整列出评分标准表
- 整理投标人业绩要求
- 按人员类别列出评分规则和材料清单
- 识别投标响应风险
- 生成投标准备清单
到这里,一个可以实际使用的招标 Agent 就搭好了。后面还能通过 FastGPT 的发布功能分享给团队成员使用:

xParse 和 FastGPT 的集成方式
最后再回顾一下 xParse 在 FastGPT 里的集成方式。它不是单独出现在工作流画布上的一个节点,而是集成在"PDF 增强解析"这个功能背后。

从界面上看,用户只看到"PDF 增强解析"这个开关。但在底层,FastGPT 做了一个优先级路由:
if (!customPdfParse) return systemParse();
if (global.systemEnv.customPdfParse?.url) return parsePdfFromCustomService();
if (global.systemEnv.customPdfParse?.textinAppId) return parsePdfFromTextin();
if (global.systemEnv.customPdfParse?.doc2xKey) return parsePdfFromDoc2x();
return systemParse();
这个设计其实挺巧妙的。FastGPT 把第三方 PDF 解析服务抽象成了插件模式,TextIn xParse、Doc2X、自定义服务都能接入,通过环境变量切换。对于用户来说只需要勾一个复选框,不需要关心底下调的是谁。对于开发者来说,想要替换或扩展解析服务只需要改路由逻辑。
几个实际结论
第一,默认 PDF 解析不是废品。
普通文本类 PDF,默认解析已经够用。但招标文件、合同、财报这类强表格、强条款、强数字约束的文档,默认解析在结构保留上有明显短板。
第二,xParse 的核心价值是结构还原。
它不是让回答"更聪明"了,而是让进入知识库的文档"更干净"了。表格的列关系、标题的层级、页眉页脚的过滤、水印的去除——这些看似不起眼的事情,直接影响后面的召回质量和回答准确性。
第三,最能看出解析质量差异的问题不是"总结全文"。
真正能暴露差异的是这类问题:
请提取本项目详细评分标准,并按"类别、评分内容、评分标准、分值范围"整理成表格。
请提取资格审查表的全部评审指标,并按"序号、评审指标、评审标准、格式及材料要求"整理成表格。
请提取采购需求前附表中的付款方式、服务地点、服务期限和所属行业,并说明每项依据。
这些问题的回答依赖表格结构是否被正确解析。一问就知道差距在哪。
第四,做这类 Agent 时建议确认一遍代码链路。
我这次之所以能确定勾选"PDF 增强解析"后走的是 TextIn xParse,是因为从 UI 组件到 API 调用到最终请求地址都追了一遍。这个确认过程花的时间不多,但保证了文章的技术可信度,也避免了对功能的错误描述。
后续扩展方向
这个招标 Agent 目前是基础版本,后面有几个方向可以继续做:
1. 固定输出模板
让 Agent 直接输出结构化清单,包括项目基础信息表、资格审查清单、评分策略表、投标材料准备清单、风险点列表。用户不需要自己想怎么问,一键生成。
2. 多文件对比
实际招标场景经常有招标文件、补遗文件、合同模板、技术规范同时存在。可以让 Agent 对比多个文件之间是否有条款冲突。
3. 风险规则库
把常见废标风险、资格风险、报价风险整理成知识库,让 Agent 不只读当前招标文件,还能结合历史经验做提醒。
4. 结构化输出
如果要接入企业系统,可以让 Agent 输出 JSON 格式:
{
"projectName": "安徽交通强省建设评价指标构建及测算研究",
"budget": "48万元",
"servicePeriod": "合同签订后8个月内完成",
"paymentTerms": [
{
"node": "合同签订后30日内",
"ratio": "50%",
"condition": "合同签订"
},
{
"node": "项目验收合格后30日内",
"ratio": "剩余合同金额",
"condition": "验收合格"
}
]
}
这样结果就能写回业务系统,而不是只停在聊天窗口里。
写在最后
这次做招标文件智能审查助手,我最大的收获不是"又搭了一个 Agent",而是把文档解析、知识库召回和大模型推理这三件事的边界搞清楚了。
TextIn xParse 负责把 PDF 处理成适合 AI 的 Markdown,索引模型负责召回,GPT5.5 负责分析和生成。三个环节各自做好自己的事,Agent 的回答才会稳定。
同样的招标文件,同样的模型,同样的索引模型,只改 PDF 解析方式,回答质量就有明显差异。尤其是评分标准、资格审查、人员配备这种表格密集的内容,TextIn xParse 的效果更突出。
如果只是做普通聊天场景,文档解析的重要性可能感知不强。但进入招标、合同、财报、技术手册这类正式业务文档领域,解析质量直接影响 Agent 能不能真正落地使用。
这次体验下来,"文档解析是 RAG 的前置工程"这句话我算是真正理解了。
我自己魔改的Github项目地址,更适合喜欢使用xParse的宝子
https://github.com/kk520879/xParse_FastGPT
参考链接
- TextIn xParse 产品简介:https://docs.textin.com/xparse/overview
- TextIn xParse 快速启动:https://docs.textin.com/xparse/parse-quickstart
- TextIn
pdf_to_markdownAPI:https://www.textin.com/document/legacy/pdf_to_markdown - FastGPT 项目地址:https://github.com/labring/FastGPT
更多推荐


所有评论(0)