LangChain 动态 prompt

LangChain 动态 prompt

flyfish

版本

Name: langchain

Version: 1.2.13

@dynamic_prompt 装饰器 实现

文末有源码

expert的回答

Agent 启动成功 (输入 exit/quit 退出)

支持角色:默认(user) / 专家(expert) / 新手(beginner)

User: 解释一下什么是异步编程

Assistant FINAL:

用户询问的是关于异步编程的概念解释。这是一个技术问题,我需要使用专业的技术术语来详细解释异步编程。

异步编程是计算机科学中的一个重要概念,我应该从以下几个方面来解释:

  1. 基本定义
  2. 与同步编程的对比
  3. 核心概念(回调、Promise、async/await等)
  4. 应用场景
  5. 优缺点

这个问题不需要使用任何工具函数,因为这是一个纯概念性的技术解释问题。

异步编程详解

一、基本定义

异步编程(Asynchronous Programming) 是一种编程范式,允许程序在执行某些耗时操作(如 I/O 操作、网络请求、文件读写等)时,不阻塞主线程,而是继续执行其他任务,待耗时操作完成后通过回调、事件或 Promise 等方式通知程序。

二、同步 vs 异步对比

特性 同步编程 异步编程
执行方式 顺序执行,阻塞等待 非阻塞,并发执行
线程占用 长时间占用线程 释放线程资源
响应性 较差 较好
代码复杂度 较低 较高
适用场景 简单任务 I/O 密集型、网络请求

三、核心概念

1. 回调函数(Callback)

javascript 复制代码
// 异步操作完成后执行的函数
fs.readFile('file.txt', (err, data) => {
    if (err) throw err;
    console.log(data);
});

2. Promise

javascript 复制代码
// 表示异步操作最终完成或失败的对象
fetch('/api/data')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error(error));

3. async/await

javascript 复制代码
// 基于 Promise 的语法糖,使异步代码看起来像同步
async function fetchData() {
    try {
        const response = await fetch('/api/data');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error(error);
    }
}

4. 事件循环(Event Loop)

复制代码
┌─────────────────────────────────────┐
│           调用栈 (Call Stack)        │
├─────────────────────────────────────┤
│  任务队列 (Task Queue)              │
│  ┌─────────────────────────────┐   │
│  │ 回调函数 1 → 回调函数 2 → ... │   │
│  └─────────────────────────────┘   │
├─────────────────────────────────────┤
│  微任务队列 (Microtask Queue)       │
│  (Promise.then, process.nextTick)   │
└─────────────────────────────────────┘

四、典型应用场景

场景 说明
网络请求 HTTP 请求、API 调用
文件 I/O 读写文件、数据库操作
定时器 setTimeout、setInterval
事件监听 用户交互、消息队列
流式处理 大数据流、实时数据

五、优缺点分析

✅ 优点

  • 提高性能:不阻塞主线程,充分利用系统资源
  • 增强响应性:UI 不会因后台任务而卡顿
  • 可扩展性:支持高并发场景
  • 资源效率:减少线程创建和切换开销

❌ 缺点

  • 代码复杂度:回调地狱、错误处理困难
  • 调试困难:调用栈不清晰,难以追踪
  • 内存泄漏风险:事件监听器未正确清理
  • 执行顺序控制:需要额外机制保证顺序

六、最佳实践

javascript 复制代码
// 1. 使用 async/await 替代嵌套回调
// 2. 统一错误处理机制
// 3. 避免内存泄漏(及时取消订阅)
// 4. 使用 Promise.all 并行处理多个异步任务
// 5. 合理设置超时和重试机制

异步编程是现代 Web 开发、Node.js、移动应用等领域的核心技术,理解其原理对于构建高性能、响应式应用至关重要。

beginner的回答

Agent 启动成功 (输入 exit/quit 退出)

支持角色:默认(user) / 专家(expert) / 新手(beginner)

User: 解释一下什么是异步编程

Assistant FINAL:

用户想了解什么是异步编程。这是一个编程概念,我需要用简单易懂的语言来解释,避免使用太多技术术语。

异步编程是编程中的一个重要概念,我应该用生活中的类比来帮助理解。让我用简单的方式解释:

  1. 什么是异步编程
  2. 为什么需要它
  3. 用生活中的例子说明
  4. 与同步编程的对比

我不需要使用任何工具,因为这是一个概念解释问题,不需要计算或获取时间。

什么是异步编程?

让我用一个生活中的例子来解释:

🍳 同步编程 vs 异步编程

同步编程(排队等待)

想象你在餐厅点餐:

  • 你点餐后,必须站在柜台前等待
  • 厨师做好一道菜,你才能继续点下一道菜
  • 如果一道菜需要10分钟,你就得等10分钟

异步编程(并行处理)

现在想象另一种方式:

  • 你点餐后,拿到一个号码牌
  • 你可以去旁边玩手机、聊天
  • 等菜做好了,号码牌会响,你再去取
  • 在等待期间,你可以做其他事情

💡 核心概念

异步编程 就是让程序在等待某些操作(比如读取文件、网络请求)完成时,不卡住等待,而是继续做其他事情。

🌰 实际例子

javascript 复制代码
// 同步:一个接一个
下载图片1 → 等待完成 → 下载图片2 → 等待完成 → 下载图片3

// 异步:同时开始
下载图片1 → 继续下载图片2 → 继续下载图片3 → 等所有完成

✅ 异步编程的好处

好处 说明
不卡顿 用户界面不会卡住
效率高 可以同时处理多个任务
响应快 用户不用长时间等待

⚠️ 需要注意

  • 代码逻辑可能更复杂
  • 需要处理"回调"或"Promise"
  • 错误处理要更小心

简单总结:异步编程就像"一边等水烧开,一边切菜",而不是"等水烧开了再切菜"。这样能更高效地利用时间!

完整代码

python 复制代码
from datetime import datetime
import json

from dataclasses import dataclass
from langchain.agents.middleware import dynamic_prompt, ModelRequest

from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from langchain.tools import tool


# =====================================
# vLLM 配置
# =====================================

VLLM_BASE_URL = "http://192.168.1.3:8000/v1"
VLLM_API_KEY = "empty"
VLLM_MODEL_NAME = "Qwen3.5-35B-A3B"


# =====================================
# LLM 初始化
# =====================================

llm = ChatOpenAI(
    model=VLLM_MODEL_NAME,
    base_url=VLLM_BASE_URL,
    api_key=VLLM_API_KEY,
    temperature=0,
)


# =====================================
# 定义上下文数据类(存储动态参数)
# =====================================
@dataclass
class Context:
    """Agent 上下文:用于动态提示词的参数传递"""
    user_role: str = "user"  # 角色:user(默认)/expert(专家)/beginner(新手)


# =====================================
# 动态提示词中间件
# =====================================
@dynamic_prompt
def dynamic_system_prompt(request: ModelRequest) -> str:
    """
    根据上下文的 user_role 动态生成系统提示词
    """
    # 从运行时上下文获取用户角色
    user_role = request.runtime.context.user_role
    base_prompt = "You are a helpful AI assistant."

    # 专家模式:技术细节、专业术语
    if user_role == "expert":
        prompt = f"{base_prompt} Provide detailed technical responses, use professional terminology."
    # 新手模式:简单解释、无术语、通俗易懂
    elif user_role == "beginner":
        prompt = f"{base_prompt} Explain concepts simply and avoid jargon, use easy-to-understand language."
    # 默认模式:通用助手
    else:
        prompt = base_prompt

    return prompt


# =====================================
# 定义工具(Tools)
# =====================================

@tool
def multiply(a: int, b: int) -> int:
    """Multiply two numbers"""
    print("\n[TOOL EXECUTE] multiply 被调用")
    print(f"[TOOL INPUT] a={a}, b={b}")
    result = a * b
    print(f"[TOOL RESULT] {result}\n")
    return result


@tool
def add(a: int, b: int) -> int:
    """Add two numbers"""
    print("\n[TOOL EXECUTE] add 被调用")
    print(f"[TOOL INPUT] a={a}, b={b}")
    result = a + b
    print(f"[TOOL RESULT] {result}\n")
    return result


@tool
def get_time() -> str:
    """Get current system time"""
    print("\n[TOOL EXECUTE] get_time 被调用")
    now = str(datetime.now())
    print(f"[TOOL RESULT] {now}\n")
    return now


tools = [multiply, add, get_time]


# =====================================
# 创建 Agent:使用动态提示词+上下文
# =====================================

agent = create_agent(
    model=llm,
    tools=tools,
    # 移除静态 system_prompt,使用动态中间件
    middleware=[dynamic_system_prompt],
    # 绑定上下文数据结构
    context_schema=Context
)


# =====================================
# 调试函数
# =====================================

def print_messages(messages):
    print("\n========== 发送给大模型的 Messages ==========")
    for m in messages:
        role = m["role"]
        content = m["content"]
        print(f"\nROLE: {role}")
        print("CONTENT:")
        print(content)
    print("\n============================================\n")


def print_response(resp):
    print("\n========== 大模型返回完整结果 ==========")
    for msg in resp["messages"]:
        print("\nROLE:", msg.type)
        print("CONTENT:")
        print(msg.content)
    print("\n=======================================\n")


# =====================================
# CLI:支持传入角色上下文(动态提示词生效)
# =====================================

def main():
    print("\nAgent 启动成功 (输入 exit/quit 退出)")
    print("支持角色:默认(user) / 专家(expert) / 新手(beginner)\n")

    while True:
        query = input("User: ")
        if query.lower() in ["exit", "quit"]:
            break

        messages = [{"role": "user", "content": query}]

        # ========================
        # 调用时传入上下文角色
        # 可自由切换:expert / beginner / user
        # ========================
        result = agent.invoke(
            {"messages": messages},
            # 动态传递角色,这里默认用 expert,可以改成 beginner 测试
            context=Context(user_role="expert")
        )

        # 输出结果
        print("Assistant FINAL:")
        print(result["messages"][-1].content)
        print()


if __name__ == "__main__":
    main()
相关推荐
only-qi2 小时前
一篇文章讲明白:RAG + MCP + Skills + LangChain + LangGraph
ai·langchain·rag·langgraph·mcp·skills
qq_5470261793 小时前
LangChain 消息与对话(Messages & Chat)
人工智能·microsoft·langchain
专职3 小时前
langchain实现Rag基础教程
langchain
Dontla4 小时前
黑马大模型RAG与Agent智能体实战教程LangChain提示词——53、Agent智能体——Agent项目Agent创建(react_agent.py)
langchain
云和数据.ChenGuang7 小时前
langchain安装过程中的故障bug
人工智能·langchain·bug·langsmith·langchain-core
zbdx不知名菜鸡8 小时前
langchain与langgraph 有什么区别?
人工智能·深度学习·langchain·langgraph
怕浪猫9 小时前
第5章 输出解析:让模型返回结构化数据
langchain·llm·ai编程
风雨中的小七10 小时前
和AI一起搞事情#2:边剥龙虾&边做个中医技能来起号
prompt
链上杯子19 小时前
《2026 LangChain零基础入门:用AI应用框架快速搭建智能助手》第8课(完结篇):小项目实战 + 部署 —— 构建网页版个人知识库 AI 助手
人工智能·langchain