文章目录
- 前言
- 一、数据库查询神器:SQLDatabase(PostgreSQL 实战)
- 1.1 这玩意儿是干嘛的
- 1.2 安全这块,拿捏得死死的
- 1.3 看看效果
- 二、消除大模型幻觉:DuckDuckGo 联网检索工具
- 2.1 先说幻觉这回事
- 2.2 一行接入,拒绝内卷
- 2.3 完整可运行代码
- 2.4 看看效果
- 三、最实用日常工具:PythonREPL 代码解释器
- 3.1 它是什么
- 3.2 注意,别让它乱跑
- 3.3 完整可运行代码
- 3.4 看看效果
- 结语
P.S. 推荐一个大神的教程给想要了解或者学习人工智能知识的读者,这个教程里内容讲解通俗易懂且风趣幽默,对我帮助很大。我想与大家分享这个宝藏教程,请点击下方链接查看, 传送门https://blog.csdn.net/qq_74013365
前言
先说个扎心的事实:现在的程序员,一半时间在写 Prompt,另一半时间在跟大模型的幻觉作斗争,剩下那点时间,用来怀疑人生。
今天不整那些唬人的架构图,咱们直接翻一翻 LangChain 社区这个百宝箱,挑三件趁手的兵器出来晒晒。件件都是那种"不贵、好用、关键时刻能救命"的货色。
一、数据库查询神器:SQLDatabase(PostgreSQL 实战)
1.1 这玩意儿是干嘛的
让大模型直接写 SQL?胆子不小。这就好比让刚学会写字的小学生给你写起诉状——字是认识了,写出来你敢用吗?
SQLDatabase 干的事儿很朴素:先把表结构、字段、样例数据全摸清楚,再喂给模型。相当于考试前有人帮你把重点画好了,还顺手贴上了便利贴。
更省心的是,它原生支持 MySQL、PostgreSQL、SQLite、SQL Server,不用你自己去适配语法,开箱即用。比某些买回来还要自己拧三天螺丝的家具强多了。
1.2 安全这块,拿捏得死死的
它支持表白名单,还内置了一道"只读"紧箍咒。你想让它删个表?工具反手一句"仅支持只读查询,禁止修改数据库",比你家路由器管得还宽。
以前手写 SQL 是把青龙偃月刀,能杀敌也能伤己;现在这把刀配了刀鞘、上了锁,还得刷脸才能用。
importosfromdotenvimportload_dotenvfromlangchain_community.utilities.sql_databaseimportSQLDatabasefromlangchain_openaiimportChatOpenAIfromlangchain.agentsimportcreate_agentfromlangchain_core.toolsimporttoolfromlanggraph.checkpoint.memoryimportInMemorySaver load_dotenv()# 连接PostgreSQL数据库db=SQLDatabase.from_uri("postgresql+psycopg2://postgres:123456@127.0.0.1:5432/mydb",include_tables=["users","articles"],sample_rows_in_table_info=2,)# 安全封装SQL查询工具(仅只读)@tooldefquery_sql(sql:str)->str:"""执行PostgreSQL只读查询,禁止修改、删除、新增数据"""forbidden=["drop","delete","alter","insert","update","truncate"]ifany(kinsql.lower()forkinforbidden):return"仅支持只读查询,禁止修改数据库"try:returndb.run(sql)exceptExceptionase:returnf"SQL执行失败:{str(e)},请修正语法重试"# 初始化Agentllm=ChatOpenAI(model=os.getenv('DASHSCOPE_MODEL'),base_url=os.getenv('DASHSCOPE_BASE_URL'),api_key=os.getenv('DASHSCOPE_API_KEY'))checkpointer=InMemorySaver()agent=create_agent(model=llm,tools=[query_sql],checkpointer=checkpointer,system_prompt=f"你是数据分析助手,根据表结构生成正确SQL,返回自然语言结果。表结构:{db.get_table_info()}")defchat_db(question:str):res=agent.invoke({"messages":[("user",question)]},config={"configurable":{"thread_id":"sql_demo"}})returnres["messages"][-1].contentif__name__=="__main__":print(chat_db("查询所有用户信息"))print(chat_db("查询10篇文章按时间倒叙"))1.3 看看效果
你瞅瞅,模型自己就把用户列表查出来了,还顺手把最近十篇文章按时间排好了序。张三李四王五赵六孙七,读起来跟背百家姓似的——就差"周吴郑王"了。
1. **张三** (zhangsan) - 邮箱: zhangsan@example.com - 昵称: 张三 - 头像: https://example.com/avatar/1.jpg - 状态: 正常 2. **李四** (lisi) - 邮箱: lisi@example.com - 昵称: 李四 - 头像: https://example.com/avatar/2.jpg - 状态: 正常 3. **王五** (wangwu) - 邮箱: wangwu@example.com - 昵称: 王五 - 头像: https://example.com/avatar/3.jpg - 状态: 正常 4. **赵六** (zhaoliu) - 邮箱: zhaoliu@example.com - 昵称: 赵六 - 头像: https://example.com/avatar/4.jpg - 状态: 正常 5. **孙七** (sunqi) - 邮箱: sunqi@example.com - 昵称: 孙七 - 头像: https://example.com/avatar/5.jpg - 状态: 正常 以下是按创建时间倒序排列的最近 10 篇文章: | 序号 | 文章标题 | 创建时间 | |------|----------|----------| | 1 | PostgreSQL 入门指南 | 2026-10-04 09:04:39 | | 2 | Nodejs 开发RESTful接口 | 2026-10-04 09:04:39 | | 3 | React 组件设计思路 | 2026-10-04 09:04:39 | | 4 | Docker 容器基础命令 | 2026-10-04 09:04:39 | | 5 | TypeScript 类型体操 | 2026-10-04 09:04:39 | | 6 | Nginx反向代理配置 | 2026-10-04 09:04:39 | | 7 | Git 工作流规范 | 2026-10-04 09:04:39 | | 8 | Redis缓存设计 | 2026-10-04 09:04:39 | | 9 | Linux 常用运维命令 | 2026-10-04 09:04:39 | | 10 | 前端工程化Vite | 2026-10-04 09:04:39 | **注意:** 示例数据中所有文章的 `created_at` 时间戳相同,实际数据库中会显示真实的发布时间顺序。二、消除大模型幻觉:DuckDuckGo 联网检索工具
2.1 先说幻觉这回事
大模型幻觉是什么?就是它不懂,但它敢答。像极了酒桌上那位喝了二两就上知天文、下知地理的朋友——你问他明朝有几个皇帝,他能当场给你编一部穿越小说,还带分卷的。
平时聊天,幻觉就当个乐子听;可一到医疗、法律、金融这些场合,幻觉就是事故现场,谁也笑不出来。
解决办法千千万,最朴素的思路就一条:不懂你就搜啊!
2.2 一行接入,拒绝内卷
DuckDuckGoSearchRun,一行初始化,不用自己对接 API。以前你想让模型联网,得先跟搜索引擎的 API 文档大战三百回合,赢了才能接上;现在一行代码,模型就学会了"不懂先搜"。这学习速度,比我当年学会用百度还快。
装起来也省事,一条命令搞定:
uvaddduckduckgo-search ddgs2.3 完整可运行代码
importosfromdotenvimportload_dotenvfromlangchain.agentsimportcreate_agentfromlangchain_community.toolsimportDuckDuckGoSearchRunfromlangchain_openaiimportChatOpenAIfromlanggraph.checkpoint.memoryimportInMemorySaver load_dotenv()# 初始化国内可用的联网检索工具search_tool=DuckDuckGoSearchRun()# 初始化基础组件llm=ChatOpenAI(model=os.getenv('DASHSCOPE_MODEL'),base_url=os.getenv('DASHSCOPE_BASE_URL'),api_key=os.getenv('DASHSCOPE_API_KEY'),temperature=0)checkpointer=InMemorySaver()# 创建检索Agentagent=create_agent(model=llm,tools=[search_tool],checkpointer=checkpointer,system_prompt="遇到不确定的技术概念、常识知识、实时信息,主动调用联网搜索工具,基于检索到的权威内容作答,严禁编造信息。")defchat_search(question:str):res=agent.invoke({"messages":[("user",question)]},config={"configurable":{"thread_id":"search_agent_demo"}})returnres["messages"][-1].contentif__name__=="__main__":print(chat_search("LangGraph是什么?核心优势有哪些?"))print(chat_search("大模型幻觉的成因和主流解决方案"))2.4 看看效果
提问"LangGraph 是什么",它引经据典给你讲得明明白白;再问幻觉的成因,它把 RAG、微调、提示词工程挨个梳理了一遍,比复习资料还齐全。
有了搜索引擎当外挂,模型终于从"一本正经地胡说八道",进化成了"一本正经地引用资料"。建议给它评个进步奖。
**LangGraph** 是由 LangChain 团队开发的一个开源库,专门用于构建**有状态(Stateful)、多步(Multi-step)**的 AI Agent 应用。 简单来说,如果说传统的 LLM 应用像是一条线性的流水线(Chain),那么 LangGraph 就是让开发者可以构建复杂的**流程图(Graph)**,从而创建出具备自我修正、循环思考能力的智能体。 以下是关于 LangGraph 的详细解释及其核心优势: ### 1. LangGraph 是什么? LangGraph 是一个**低级别的编排框架(Orchestration Framework)**。它不直接提供高级别的业务逻辑封装,而是提供构建复杂工作流的"积木"。 * **核心模型**:它将应用程序建模为一个**图(Graph)**。 * **节点(Nodes)**:代表具体的步骤或动作(例如:调用一个 LLM、查询数据库、执行一段 Python 代码)。 * **边(Edges)**:代表节点之间的连接和控制流(例如:如果 A 成功则去 B,否则去 C;或者从 B 回到 A 进行重试)。 * **定位**:它是 LangChain 生态系统的下一代核心组件,旨在取代传统的 `LangChain Chains`,因为 Chain 很难处理复杂的循环和状态管理。 --- ### 2. 核心优势有哪些? LangGraph 解决了传统 LLM 应用开发中的几个痛点,其核心优势主要体现在以下五个方面: #### ① 原生支持循环(Cycles)—— Agent 的核心 这是 LangGraph 与传统 Chain 最大的区别。 * **问题**:传统的线性流程无法处理"思考-行动-观察"的循环(如 ReAct 模式)。如果一个 Agent 发现第一步做错了,它需要回头重新做,这在普通 Chain 中很难实现。 * **优势**:LangGraph 允许你在图中设置**循环边**。这使得构建具备自我反思、自我纠错能力的 Agent 变得非常简单。 #### ② 强大的状态管理(State Management) * **问题**:在多步应用中,如何优雅地传递数据(Context)是一个难题。 * **优势**:LangGraph 提供了一个统一的**状态字典(State Dictionary)**。所有节点共享同一个状态对象,你可以轻松地在不同步骤间传递和更新数据,而不需要在每个函数之间手动传递大量参数。 #### ③ 持久化执行与检查点(Durable Execution & Checkpointing) * **问题**:如果 Agent 运行了 10 分钟突然崩溃或网络中断,之前的进度就丢失了。 * **优势**:LangGraph 内置了**检查点(Checkpoints)**机制。它可以自动保存当前的状态快照。即使应用重启,也可以从上次停止的地方继续运行(Resume),这对于长时间运行的复杂任务至关重要。 #### ④ 人类介入(Human-in-the-Loop) * **问题**:在生产环境中,关键决策往往需要人工审核。 * **优势**:LangGraph 允许你在图的任意节点设置**中断(Interrupt)**。当程序运行到该节点时,它会暂停并等待人类的指令(例如:"批准这个操作"或"修改这个参数"),然后再继续执行。这极大地提高了 AI 应用在金融、医疗等高风险场景的安全性。 #### ⑤ 细粒度的控制流(Fine-grained Control Flow) * **优势**:你可以精确控制每一步的执行顺序。 * **条件路由**:根据上一步的结果动态决定下一步去哪里。 * **并行执行**:可以同时启动多个独立的子图或节点进行处理。 * **错误处理**:可以定义专门的错误处理节点,当某个步骤失败时自动跳转到修复逻辑。 ### 总结 如果你只需要简单的问答机器人,使用标准的 LangChain Chain 可能就够了;但如果你想构建**复杂的、需要多步推理、具备记忆能力、或者需要人工审核的智能体应用**,LangGraph 是目前最主流且强大的选择。 大模型(LLM)的"幻觉"(Hallucination)是指模型生成的内容在表面上看起来通顺、合理,但实际上包含事实错误、逻辑矛盾或完全虚构的信息。 这是目前制约大模型在医疗、法律、金融等高风险领域落地的最大瓶颈之一。以下是关于其成因及主流解决方案的详细解析: ### 一、 大模型幻觉的成因 大模型产生幻觉并非因为它有"主观恶意",而是由其底层机制决定的: 1. **概率预测的本质(Next-Token Prediction)** * **原理**:大模型本质上是一个极其复杂的"文本补全"工具。它的任务是根据上文预测下一个字出现的概率最高是什么。 * **问题**:它追求的是"语义上的连贯性"和"统计上的合理性",而不是"事实上的真实性"。如果训练数据中某种错误的搭配出现频率很高,模型就会认为那是正确的。 2. **训练数据的局限性与噪声** * **数据污染**:互联网数据本身包含大量谣言、错误信息和过时知识。 * **缺乏特定领域知识**:通用大模型可能没有经过足够深度的垂直领域(如量子物理、罕见病)训练,遇到不懂的问题时,它会尝试用通用的语言模式去"编造"一个看似合理的解释。 3. **上下文窗口与注意力机制的限制** * **遗忘现象**:当输入信息量极大(超过上下文窗口)时,模型可能会忽略关键约束条件,或者混淆不同来源的信息,导致张冠李戴。 * **长尾分布**:对于生僻的知识,模型往往无法准确召回,从而产生幻觉。 4. **提示词(Prompt)的模糊性** * 如果用户的问题模棱两可,或者指令不够清晰,模型为了完成任务,往往会倾向于"过度发挥",补充一些不存在的信息来填补空白。 --- ### 二、 主流解决方案 目前业界主要通过**"外部辅助"**和**"内部优化"**两个维度来缓解幻觉: #### 1. 检索增强生成 (RAG, Retrieval-Augmented Generation) —— 最核心方案 这是目前解决幻觉最有效的手段。 * **原理**:在回答之前,先让模型去向量数据库或搜索引擎中查找相关的真实文档片段,然后将这些片段作为"参考资料"喂给模型。 * **优势**:强制模型基于给定的事实进行回答(Grounding),大幅减少了凭空捏造的可能。 * **关键点**:需要配合高质量的切片(Chunking)和重排序(Re-ranking)技术,确保检索到的内容是准确的。 #### 2. 微调 (Fine-Tuning) * **监督微调 (SFT)**:使用高质量、无幻觉的标准问答对(Q&A pairs)对模型进行训练,让它学习正确的回答范式。 * **人类反馈强化学习 (RLHF / DPO)**:通过人工对模型的输出进行打分和排序,奖励那些诚实、准确的答案,惩罚那些胡编乱造的答案,从而从价值观层面抑制幻觉。 #### 3. 提示词工程优化 (Prompt Engineering) * **思维链 (Chain of Thought, CoT)**:要求模型"一步步思考"(Let's think step by step)。研究表明,强迫模型展示推理过程可以显著降低幻觉率,因为逻辑链条比直接给出结论更不容易出错。 * **少样本提示 (Few-Shot Prompting)**:在Prompt中提供几个正确的示例,引导模型模仿正确的格式和内容。 * **明确边界**:在Prompt中加入指令,如"如果你不知道答案,请直接说不知道,不要编造"。 #### 4. 自我反思与验证 (Self-Reflection & Verification) * **多路投票 (Self-Consistency)**:让模型针对同一个问题生成多个不同的回答,然后由另一个模块(或模型自身)进行投票,选择最一致的那个答案。 * **批判者模式 (Critic Mode)**:构建两个Agent,一个负责生成答案,另一个专门负责挑刺和验证。如果验证不通过,生成者必须重写。 #### 5. 引入外部工具与校验层 (Guardrails) * **代码执行**:对于数学计算或逻辑问题,不让模型直接算,而是让它写Python代码,通过运行代码得到结果。 * **引用溯源**:强制要求模型在每句话后面标注信息来源(Citation)。如果模型无法提供来源,系统自动判定为不可信。 ### 总结 目前没有任何单一技术能彻底消除幻觉。**最佳实践通常是组合拳**: > **RAG(提供事实依据) + 思维链(提升推理能力) + 严格的数据清洗(源头治理)** 随着模型参数量的增大和训练数据的净化,幻觉率正在逐渐降低,但在高可靠性要求的场景中,依然需要依靠上述技术手段进行人工干预和校验。 进程已结束,退出代码为 0三、最实用日常工具:PythonREPL 代码解释器
3.1 它是什么
PythonREPLTool,字面意思:让 Agent 自己写 Python、自己跑。你只管提问,它负责写代码、执行、交结果。
以前是你写代码让机器干活,现在是 AI 写代码让机器干活,你在旁边看。那一刻,你终于体会到了老板的快乐:活儿都是别人干的,锅……大概率也是别人的。
3.2 注意,别让它乱跑
这里必须敲黑板:生产环境一定要做沙箱隔离。这工具权限有多大?相当于你把家里钥匙配了三把,还递给一个陌生人说"随便用"。不隔离,分分钟家被搬空,连猫都保不住。
3.3 完整可运行代码
importosfromdotenvimportload_dotenvfromlangchain_experimental.utilitiesimportPythonREPLfromlangchain_openaiimportChatOpenAIfromlangchain.agentsimportcreate_agentfromlanggraph.checkpoint.memoryimportInMemorySaverfromlangchain_core.toolsimportTool load_dotenv()# 初始化代码执行工具python_repl=PythonREPL()# 封装成Agent可用的toolrepl_tool=Tool(name="python_repl",description="Python代码执行器。用于做数学计算、数据运算。输入必须是合法python代码,需要输出结果请用print()打印",func=python_repl.run,)llm=ChatOpenAI(model=os.getenv('DASHSCOPE_MODEL'),base_url=os.getenv('DASHSCOPE_BASE_URL'),api_key=os.getenv('DASHSCOPE_API_KEY'),temperature=0)checkpointer=InMemorySaver()agent=create_agent(model=llm,tools=[repl_tool],checkpointer=checkpointer,system_prompt="遇到数学计算、统计、数据处理问题,请主动写Python代码执行,用运行结果回答用户。")defchat_python(question:str):res=agent.invoke({"messages":[("user",question)]},config={"configurable":{"thread_id":"python_demo"}})returnres["messages"][-1].contentif__name__=="__main__":print(chat_python("计算1~100的平方和"))print(chat_python("生成斐波那契数列前20项并求和"))3.4 看看效果
1 到 100 的平方和,338350,一秒出结果,比算工资都快。斐波那契前 20 项也整整齐齐排好了队,还自觉把总和报上了。
你让模型口算试试?它可能给你回一句"我觉得大概是……",后面跟一长串自信的胡话。现在好了,代码一跑,答案比你的工资条还精确。
1~100的平方和为:338350 斐波那契数列的前20项为: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765] 这20项的总和为:17710结语
三件兵器介绍完毕,总结一下:SQLDatabase 治"乱写 SQL",DuckDuckGo 治"胡编乱造",PythonREPL 治"手算不靠谱"。三件套凑齐,一个能查、能搜、能算的 Agent 直接上岗,比某护肤品牌的三件套实用多了。
其实 LangChain 社区的好东西远不止这些,今天先晒这三件。剩下的,等你入坑之后慢慢挖——毕竟自己动手挖出来的宝藏,才有开盲盒的快乐嘛。
最后说句掏心窝子的:工具再好,也别忘了,真正写出好代码的,还是你本人。嗯,至少目前是。
P.S. 推荐一个大神的教程给想要了解或者学习人工智能知识的读者,这个教程里内容讲解通俗易懂且风趣幽默,对我帮助很大。我想与大家分享这个宝藏教程,请点击下方链接查看,传送门https://blog.csdn.net/qq_74013365