做AI Agent开发,最容易被低估的就是基础设施。看起来好像用LangChain搭个Agent,把工具一注册,项目就能跑,但真到了要做“问数项目”这种必须对接真实数据源、执行真实SQL查询的业务型Agent时,前期底座搭得牢不牢,直接决定你是每天偷着乐还是半夜起来撕代码。在LCODER这个系列里,我们正在从零搭一个问数项目智能体,上一篇拆了整体思路,这篇直接进入基础设施搭建,讲清楚这个“地基”到底怎么打、为什么这么打。
如果你也准备做类似的事——让用户用自然语言提问,Agent自己完成查表、写SQL、出结果——那这篇内容应该能帮你省掉不少弯路。下面我会把基础设施的每一个模块,包括环境选型、模型网关、会话层、数据接入、SQL安全、缓存、向量库、可观测性、评估集,全部过一遍,并且给出我实测下来的具体方案和坑位提示。
1. 问数Agent的基础设施包含哪些部分
很多同学一上来就急着写Agent逻辑,结果做到一半发现连数据源管理都没做,每个工具函数里各写各的数据库连接,模型Key散落在不同文件里,换个模型要改十几处代码。这不是开发Agent,这是给未来埋雷。
1.1 从一条查询请求反推“地基清单”
我先带你从一条真实请求出发,看看系统到底需要哪些基础能力。
假设用户问:“上个月华东区各品类销量排名前五的产品有哪些”。这条请求从进入系统到返回答案,大致要经历以下环节:
- 接收请求:需要一个API服务,负责鉴权、限流、参数校验;
- 识别意图:Agent判断这是数据查询类问题,且涉及“华东区”“上个月”“销量排名”等业务词;
- 检索知识:从元数据中找到“华东区”对应的地区字段、从哪张表统计销量、“上个月”如何映射到时间条件;
- 生成SQL:LLM根据业务字段和表结构生成一条SELECT语句;
- 执行SQL:连接数据库执行查询,拿到结果集;
- 组织回答:把数字结果整理成可读的文本或图表数据。
这个过程看起来很短,但背后需要的东西不少:模型网关、会话管理、元数据同步、向量检索、SQL安全校验、缓存策略、日志追踪、评测回归。这些不是“锦上添花”,而是问数Agent能不能稳定工作的底座。
1.2 先定原则:为什么基础设施决定Agent成败
我见过太多Agent Demo,跑通一次就发朋友圈,但实际上线之后全是问题。问数项目尤其如此,它不像聊天机器人那样容忍模糊,数据的准确性、查询的安全性、响应的时间上限都是硬指标。
所以我在设计基础设施时,给自己定了三个原则:
- 统一入口,禁止散装调用。所有模型调用、数据库连接、外部工具,都必须走统一封装后的服务,不能各个工具函数自己new一个client。这条原则能救命,后面接第二个数据源、切换模型时你就懂了。
- 凡是外部依赖,都要有降级和超时。数据库卡死、模型超时、向量库不可用,这类情况在真实环境一定会遇到。基础设施层必须提前留好兜底方案。
- 从第一天就把可观测性和评估做进去。Agent的推理链路比传统接口长很多,不提前埋点,出了问题根本没法定位是哪一步错了。
这三条原则听起来朴素,但真能一直坚持下来,项目后期会非常省心。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境选型与工程初始化
基础环境这块没什么高深内容,但选型不对后面会很拧巴。我按实际踩坑经验,把推荐方案和理由写清楚。
2.1 开发机、运行时与依赖管理
问数Agent的日常开发主要是写Python服务、调试LangGraph流程、连各种数据源做验证,资源消耗不算夸张。
- 开发机配置:16GB内存起步,32GB会更舒服。主要是IDE、Docker、本地向量库、偶尔跑个小模型同时开的时候,内存很容易吃紧。
- Python版本:3.10或3.11都行,不建议用3.12以下太旧的环境。第三方库对新版本兼容性已经很好,但个别依赖锁版本时会有坑。
- 包管理器:我建议用
uv,创建虚拟环境和安装依赖都极快,比pip+venv省太多时间。如果你还是习惯poetry,也可以,但要锁定版本。 - 核心依赖:FastAPI、LangChain/LangGraph、SQLAlchemy 2.x、OpenAI SDK(或任意兼容OpenAI协议的SDK)、Qdrant客户端、Redis客户端、pydantic-settings、structlog。
有个非常关键的提醒:LangChain系列库的版本兼容性非常“娇气”,升级小版本都可能引发依赖冲突,尤其是pydantic版本。锁版本是必须做的事。我的项目里直接用了具体的版本号,而不是^或者>=,避免哪天别人拉完代码跑不起来。
2.2 目录结构设计:按“层”而不是按“页面”划分
问数Agent工程涉及的东西杂,我建议一开始就把目录按职责分层,而不是按功能散放。下面是我实际用的目录结构:
code复制lcondor_qa_agent/
├── app/
│ ├── api/ # HTTP接口层:FastAPI路由、请求模型
│ ├── agent/ # Agent编排层:LangGraph流程、工具、提示词
│ │ ├── graph.py
│ │ ├── tools/
│ │ └── prompts/
│ ├── core/ # 核心基础能力:模型网关、配置、安全
│ │ ├── llm_gateway.py
│ │ ├── session.py
│ │ ├── security.py
│ │ └── config.py
│ ├── data/ # 数据接入层:数据源注册、SQL执行器、元数据同步
│ │ ├── sources.py
│ │ ├── executor.py
│ │ └── metadata.py
│ ├── memory/ # 记忆与缓存:Redis客户端、向量库
│ │ ├── cache.py
│ │ └── vector_store.py
│ └── observability/ # 日志、追踪、评估埋点
│ ├── logger.py
│ └── tracing.py
├── eval/
│ ├── datasets/
│ └── runner.py
├── scripts/
└── pyproject.toml
一眼看过去,核心就分成api、agent、core、data、memory、observability这几大块。我的体会是“core”和“data”一定要分清楚,模型网关放在core,数据源管理放在data,Agent编排放在agent,这样多人协作时互不干扰。
2.3 全局配置与密钥管理的落地方式
配置管理是我刚开始不重视、后来吃了大亏的地方。问数项目涉及模型Key、多个数据库DSN、Redis地址、向量库地址,这些环境相关的东西如果写死在代码里,换环境就是灾难。
我直接用pydantic-settings统一管理,一个settings.py搞定:
python复制class Settings(BaseSettings):
app_name: str =
