LLM Agent 工程化平台(Text2SQL 智能问答 + 合同智能完善)

LLM Agent 工程化平台(Text2SQL 智能问答 + 合同智能完善)全栈 AI 应用开发
内容:Python / fastApi / LangGraph / LangChain / deepagents / Agent Loop/ MCP / 百炼 Qwen & DeepSeek / SQLite / asyncio/ vLLM

核心技术点:

  1. LangGraph StateGraph 工作流:选表 → 取表结构 → 生成 SQL → LLM 审查 → 执行 → 结果回流重试
  2. SQL 生成/审查分离(tool_choice 强制/自主/禁止调用工具)
  3. 多子代理编排(Orchestrator + Editor + Reviewer),写读权限隔离,Python 代码控制循环轮数 + checkpointer 上下文持久化
  4. 执行结果回环自纠错,最大轮数兜底转人工
  5. MCP Server(SSE)封装数据库工具,服务解耦独立部署
  6. 多模型接入与切换(百炼 Qwen / GLM / DeepSeek),轻量模型做审查降成本

基于这份简历和项目实际代码,我把面试官最可能问的问题按模块整理成 Q&A。每个回答都基于你项目的真实实现,可以直接背。
深度思考

Q1:介绍一下这个项目?

一个大模型 Agent 平台,两个场景:一是 Text2SQL,用户大白话提问,Agent 自动查表、写 SQL、审查、执行、给答案;二是合同智能完善,两个子代理一个改一个审,多轮打磨到合格。两个场景核心思想一样:AI 生成的结果不能自己说了算,必须有独立审查


Q2:为什么生成 SQL 后还要 LLM 审查?直接执行不行吗?

因为模型写的 SQL 可能“语法对但结果错”——比如 NOT IN 碰到 NULL、该用 UNION ALL 用了 UNION。这种错误执行不会报错,只会给用户一个错误数字,比崩溃更危险。加一道审查闸门,轻量模型一次调用,成本很低,挡住的却是错误答案。


Q3:工作流节点怎么设计的?

七个节点:查表名 → 查表结构 → 生成 SQL → 审查 → 执行,执行完有一条回环边回到生成节点。核心分工是:流程骨架代码写死——必先拿表名和表结构;决策交给模型——选哪张表、写什么 SQL、要不要重试。


Q4:模型怎么知道该查哪张表?

分两步,全靠流程“喂”信息。第一步,工作流开头固定先调工具,查出全部表名,11 张表名进了对话历史——模型拿到一份候选名单。第二步,模型自己挑——拿用户问题和表名做语义匹配,“账单”对应 invoice,就选了 invoices。选错了也有补救:后面生成 SQL 的节点没强制调工具,模型发现信息不够,可以自己再查一次表结构补上。


Q5:check_query 为什么审查后要替换原消息的 id?

消息配对问题。生成 SQL 那步产生一条带 tool_call 的消息,审查后又会产生一条新的——历史里就有两个 tool_call,但执行后只有一条工具结果消息。OpenAI 接口要求每个 tool_call 必须有配对的结果,不然下次调用直接报错。所以我用新消息的 id 覆盖旧的,LangGraph 按 id 去重,等于把“待审的 SQL”整体替换成“审完的 SQL”,消息链就干净了。这是我自己踩过的坑。


Q6:tool_choice 有哪几种取值,怎么用的?

四种:auto 自主决定、none 禁止调用、any/required 强制至少调一个、指定工具名强制调那个工具。项目里用到三种:查表结构和审查节点用 any——必须出结果,下游才不会断;生成 SQL 节点用 auto——模型信息够了可以直接回答,不然图会死循环。


Q7:合同系统为什么用 Python 控制循环,不让模型自己循环?

可靠性。模型自己循环可能忘记停、空转、提前放弃。所以设计成:Agent 只干一轮“改 + 审”,要不要来下一轮,Python 代码说了算——轮数上限、提前退出、耗尽转人工,全是确定性的。原则就是:确定性的事交给代码,不确定性的事交给模型


Q8:checkpointer 是怎么工作的?

每轮发给 Agent 的消息一模一样,就一句“请处理合同 X”,不在提示词里区分第几轮。因为同一个 thread_id 的历史会自动保存,第二轮模型能看到第一轮的完整过程,它自己就知道“该把上轮的审查意见传给修改员了”。好处是提示词极简,状态全交给框架管。


Q9:怎么保证循环收敛,不越改越差?

四道保险:① 审查员的问题清单必须逐条传给修改员,不许只说“按意见改”;② 修改员只改清单里的问题,没列的不动;③ 提示词里划了红线——不能用新的模糊词替换旧的,改完不能引入新问题;④ 最多 3 轮,还不行 Python 直接转人工。就算收敛失败,也一定有终点。


Q10:为什么 Editor 能写、Reviewer 只能读?

谁写谁审,审就白审了——它会认可自己的修改。Reviewer 的工具列表里只有读,物理上改不了合同;编排者也只有归档和升级两个工具。用工具权限做硬约束,比提示词说“你不许改”可靠得多


Q11:为什么要用 MCP,直接写函数不是更简单?

为了解耦。函数定义意味着工具和主程序绑在一个进程里。MCP 把数据库工具做成独立服务,主程序只按协议调用——工具可以独立部署升级,还能给别的 Agent 复用。而且这是行业标准协议,我的代码只改一个连接地址就能接上。


Q12:vLLM 比直接用 transformers 好在哪?

三点:PagedAttention 把显存像操作系统分页一样管理,利用率大幅提升;continuous batching 让请求随到随进,吞吐量翻好几倍;自带 OpenAI 兼容接口——我的 Agent 把 base_url 一改就能从云端切到本地模型,代码零改动。


Q13:不同环节怎么选模型?

按难度和成本分。生成 SQL、改合同这种重活用主力模型;审查、校对这种照着清单检查的活用 flash 小模型。另外我实际跑账单发现思考型模型多轮调用成本很高,就用 reasoning_effort 调低思考深度省了不少钱——这是实践出来的,不是拍脑袋。


Q14:遇到过什么坑?

举一个:接百炼的 GLM 模型时报"product is not activated",查了半天发现拥有业务空间不等于开通模型,要去模型广场打开对应模型卡片才生效。之后首次调用还报了个瞬时错误,重试就好了。我的排查思路是先分类——鉴权问题、服务开通问题还是代码问题——再逐段缩小范围。


Q15:项目有什么不足?

挑两点:一是没有系统评测,改进方向是构造几十条典型问题,统计 SQL 准确率做回归;二是选表纯靠语义猜,表一多容易选错,可以用向量检索先召回相关表再查结构。另外 checkpointer 目前是内存版,重启丢上下文,换成数据库持久化即可。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容