当前位置: 首页 > news >正文

Langflow 框架中 Prompt 技术底层实现分析

Langflow 框架中 Prompt 技术底层实现分析

1. Prompt 技术概述

Langflow 是一个基于 LangChain 的可视化 AI 工作流构建框架,其 Prompt 技术是整个系统的核心组件之一。Prompt 技术主要负责:

  • 模板化处理:支持动态变量替换的提示词模板
  • 变量验证:确保模板变量的合法性和安全性
  • 类型转换:将各种数据类型转换为字符串格式
  • 与 LLM 集成:将处理后的 Prompt 传递给语言模型

2. 核心类和接口分析

2.1 PromptComponent 类

位置base/langflow/components/processing/prompt.py

class PromptComponent(Component):display_name: str = "提示词模板"description: str = "创建带有动态变量的提示词模板。"documentation: str = "https://docs.langflow.org/components-prompts"icon = "braces"trace_type = "prompt"name = "Prompt Template"priority = 0  # 设置优先级为0,使其首先出现inputs = [PromptInput(name="template", display_name="模板",info="提示词模板,支持使用 {变量名} 格式的动态变量。"),MessageTextInput(name="tool_placeholder",display_name="工具占位符",tool_mode=True,advanced=True,info="工具模式的占位符输入。",),]outputs = [Output(display_name="提示词", name="prompt", method="build_prompt"),]

核心功能

  • 继承自 Component 基类,提供组件化的 Prompt 处理能力
  • 支持动态模板更新和前端节点同步
  • 实现了 build_prompt() 方法生成最终的 Message 对象

2.2 DefaultPromptField 类

位置base/langflow/inputs/inputs.py

class DefaultPromptField(Input):name: strdisplay_name: str | None = Nonefield_type: str = "str"advanced: bool = Falsemultiline: bool = Trueinput_types: list[str] = DEFAULT_PROMPT_INTUT_TYPESvalue: Any = ""  # Set the value to empty string

核心功能

  • 定义了 Prompt 字段的基本属性
  • 支持多行文本输入
  • 默认接受 Message 类型的输入

2.3 Message 类

位置base/langflow/schema/message.py

class Message(Data):text_key: str = "text"text: str | AsyncIterator | Iterator | None = Field(default="")sender: str | None = Nonesender_name: str | None = Nonefiles: list[str | Image] | None = Field(default=[])session_id: str | UUID | None = Field(default="")timestamp: Annotated[str, timestamp_to_str_validator] = Field(default_factory=lambda: datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S %Z"))# ... 其他字段

3. 关键实现细节

3.1 变量提取机制

位置base/langflow/interface/utils.py

def extract_input_variables_from_prompt(prompt: str) -> list[str]:"""Extract variable names from a prompt string using Python's built-in string formatter.Uses the same convention as Python's .format() method:- Single braces {name} are variable placeholders- Double braces {{name}} are escape sequences that render as literal {name}"""formatter = Formatter()variables: list[str] = []seen: set[str] = set()# Use local bindings for micro-optimizationvariables_append = variables.appendseen_add = seen.addseen_contains = seen.__contains__for _, field_name, _, _ in formatter.parse(prompt):if field_name and not seen_contains(field_name):variables_append(field_name)seen_add(field_name)return variables

实现原理

  • 使用 Python 内置的 string.Formatter 类解析模板
  • 遵循 Python .format() 方法的约定
  • 单花括号 {name} 表示变量占位符
  • 双花括号 {{name}} 表示转义序列,渲染为字面量 {name}
  • 通过集合去重确保变量唯一性

3.2 变量验证机制

位置base/langflow/base/prompts/api_utils.py

def validate_prompt(prompt_template: str, *, silent_errors: bool = False) -> list[str]:input_variables = extract_input_variables_from_prompt(prompt_template)# Check if there are invalid characters in the input_variablesinput_variables = _check_input_variables(input_variables)if any(var in _INVALID_NAMES for var in input_variables):msg = f"Invalid input variables. None of the variables can be named {', '.join(input_variables)}. "raise ValueError(msg)try:PromptTemplate(template=prompt_template, input_variables=input_variables)except Exception as exc:msg = f"Invalid prompt: {exc}"logger.exception(msg)if not silent_errors:raise ValueError(msg) from excreturn input_variables

验证规则

  1. 字符验证:禁止使用特殊字符(空格、逗号、括号等)
  2. 保留字检查:禁止使用系统保留的变量名
  3. LangChain 兼容性:通过 LangChain 的 PromptTemplate 验证模板格式

无效字符集合

_INVALID_CHARACTERS = {" ", ",", ".", ":", ";", "!", "?", "/", "\\", "(", ")", "[", "]",
}_INVALID_NAMES = {"code", "input_variables", "output_parser", "partial_variables", "template", "template_format", "validate_template",
}

3.3 变量修复机制

def _fix_variable(var, invalid_chars, wrong_variables):if not var:return var, invalid_chars, wrong_variablesnew_var = var# Handle variables starting with a numberif var[0].isdigit():invalid_chars.append(var[0])new_var, invalid_chars, wrong_variables = _fix_variable(var[1:], invalid_chars, wrong_variables)# Temporarily replace {{ and }} to avoid treating them as invalidnew_var = new_var.replace("{{", "ᴛᴇᴍᴘᴏᴘᴇɴ").replace("}}", "ᴛᴇᴍᴘᴄʟᴏsᴇ")# Remove invalid charactersfor char in new_var:if char in _INVALID_CHARACTERS:invalid_chars.append(char)new_var = new_var.replace(char, "")if var not in wrong_variables:wrong_variables.append(var)# Restore {{ and }}new_var = new_var.replace("ᴛᴇᴍᴘᴏᴘᴇɴ", "{{").replace("ᴛᴇᴍᴘᴄʟᴏsᴇ", "}}")return new_var, invalid_chars, wrong_variables

修复策略

  • 移除数字开头的字符
  • 临时替换双花括号避免误处理
  • 移除所有无效字符
  • 恢复双花括号的原始格式

4. Prompt 模板系统实现

4.1 模板处理流程

位置base/langflow/base/prompts/api_utils.py

def process_prompt_template(template: str, name: str, custom_fields: dict[str, list[str]] | None, frontend_node_template: dict[str, Any]
):"""Process and validate prompt template, update template and custom fields."""# Validate the prompt template and extract input variablesinput_variables = validate_prompt(template)# Initialize custom_fields if Noneif custom_fields is None:custom_fields = defaultdict(list)# Retrieve old custom fieldsold_custom_fields = get_old_custom_fields(custom_fields, name)# Add new variables to the templateadd_new_variables_to_template(input_variables, custom_fields, frontend_node_template, name)# Remove old variables from the templateremove_old_variables_from_template(old_custom_fields, input_variables, custom_fields, frontend_node_template, name)# Update the input variables field in the templateupdate_input_variables_field(input_variables, frontend_node_template)return input_variables

处理步骤

  1. 模板验证:验证模板格式和变量合法性
  2. 字段初始化:初始化自定义字段字典
  3. 旧字段处理:获取并处理旧的自定义字段
  4. 新变量添加:将新发现的变量添加到模板
  5. 旧变量清理:移除不再使用的变量
  6. 字段更新:更新输入变量字段

4.2 动态字段管理

def add_new_variables_to_template(input_variables, custom_fields, template, name) -> None:for variable in input_variables:try:template_field = DefaultPromptField(name=variable, display_name=variable)if variable in template:# Set the new field with the old valuetemplate_field.value = template[variable]["value"]template[variable] = template_field.to_dict()# Check if variable is not already in the list before appendingif variable not in custom_fields[name]:custom_fields[name].append(variable)except Exception as exc:raise HTTPException(status_code=500, detail=str(exc)) from exc

动态管理特性

  • 自动为新变量创建输入字段
  • 保留现有变量的值
  • 避免重复添加相同变量
  • 异常处理确保系统稳定性

5. 变量处理机制

5.1 数据类型转换

位置base/langflow/base/prompts/utils.py

def dict_values_to_string(d: dict) -> dict:"""Converts the values of a dictionary to strings."""from langflow.schema.message import Messaged_copy = deepcopy(d)for key, value in d_copy.items():# it could be a list of data or documents or stringsif isinstance(value, list):for i, item in enumerate(value):if isinstance(item, Message):d_copy[key][i] = item.textelif isinstance(item, Data):d_copy[key][i] = data_to_string(item)elif isinstance(item, Document):d_copy[key][i] = document_to_string(item)elif isinstance(value, Message):d_copy[key] = value.textelif isinstance(value, Data):d_copy[key] = data_to_string(value)elif isinstance(value, Document):d_copy[key] = document_to_string(value)return d_copy

转换规则

  • Message 对象:提取 text 属性
  • Data 对象:调用 get_text() 方法
  • Document 对象:提取 page_content 属性
  • 列表类型:递归处理每个元素
  • 深拷贝:避免修改原始数据

5.2 模板格式化

位置base/langflow/schema/message.py

def format_text(self):prompt_template = PromptTemplate.from_template(self.template)variables_with_str_values = dict_values_to_string(self.variables)formatted_prompt = prompt_template.format(**variables_with_str_values)self.text = formatted_promptreturn formatted_prompt

格式化流程

  1. 创建 LangChain PromptTemplate 对象
  2. 将所有变量值转换为字符串
  3. 使用 LangChain 的格式化方法
  4. 更新 Message 对象的 text 属性

6. 与 LLM 的集成方式

6.1 Message 创建流程

@classmethod
def from_template(cls, template: str, **variables):instance = cls(template=template, variables=variables)text = instance.format_text()message = HumanMessage(content=text)contents = []for value in variables.values():if isinstance(value, cls) and value.files:content_dicts = value.get_file_content_dicts()contents.extend(content_dicts)if contents:message = HumanMessage(content=[{"type": "text", "text": text}, *contents])prompt_template = ChatPromptTemplate.from_messages([message])instance.prompt = jsonable_encoder(prompt_template.to_json())instance.messages = instance.prompt.get("kwargs", {}).get("messages", [])return instance

集成特性

  • 创建 LangChain 兼容的 HumanMessage
  • 支持多模态内容(文本 + 文件)
  • 生成 ChatPromptTemplate 对象
  • JSON 序列化支持

6.2 LLM 模型集成

位置base/langflow/base/models/model.py

class LCModelComponent(Component):_base_inputs: list[InputTypes] = [MessageInput(name="input_value", display_name="输入", info="发送给模型的输入内容。"),MultilineInput(name="system_message",display_name="系统提示",info="大模型的系统消息.",advanced=False,),BoolInput(name="stream", display_name="Stream模式", info=STREAM_INFO_TEXT, advanced=True),]async def text_response(self) -> Message:output = self.build_model()result = await self.get_chat_result(runnable=output, stream=self.stream, input_value=self.input_value, system_message=self.system_message)self.status = resultreturn result

集成机制

  • 接受 Message 类型的输入
  • 支持系统消息设置
  • 异步处理支持流式输出
  • 统一的模型接口抽象

7. 应用示例

7.1 基础 Prompt 模板示例

# 创建一个简单的问答模板
class SimpleQAPrompt:def __init__(self):self.template = "问题:{question}\n请提供详细的答案:"def create_prompt(self, question: str) -> Message:# 使用 langflow 的 Message.from_template 方法return Message.from_template(template=self.template,question=question)# 使用示例
qa_prompt = SimpleQAPrompt()
message = qa_prompt.create_prompt("什么是人工智能?")
print(message.text)
# 输出:问题:什么是人工智能?
#      请提供详细的答案:

7.2 多变量复杂模板示例

# 创建一个代码生成模板
class CodeGenerationPrompt:def __init__(self):self.template = """
你是一个专业的 {language} 程序员。任务:{task}
要求:
- 编程语言:{language}
- 代码风格:{style}
- 包含注释:{include_comments}请生成高质量的代码:
"""def create_prompt(self, language: str, task: str, style: str = "简洁", include_comments: bool = True) -> Message:return Message.from_template(template=self.template,language=language,task=task,style=style,include_comments="是" if include_comments else "否")# 使用示例
code_prompt = CodeGenerationPrompt()
message = code_prompt.create_prompt(language="Python",task="实现一个二分查找算法",style="Pythonic",include_comments=True
)

8. 技术特点总结

8.1 设计优势

  1. 类型安全:通过 Pydantic 模型确保数据类型安全
  2. 可扩展性:组件化设计支持自定义 Prompt 组件
  3. 兼容性:与 LangChain 生态系统完全兼容
  4. 验证机制:完善的变量验证和错误处理
  5. 多模态支持:支持文本、图片等多种内容类型

8.2 性能优化

  1. 微优化:在变量提取中使用局部绑定优化性能
  2. 深拷贝:避免修改原始数据的副作用
  3. 缓存机制:支持模板缓存减少重复处理
  4. 异步支持:支持异步处理提高并发性能

8.3 安全特性

  1. 变量过滤:严格的变量名验证防止注入攻击
  2. 文件路径检查:限制文件访问路径确保安全
  3. 异常处理:完善的异常处理机制
  4. 输入验证:多层次的输入验证确保数据安全

Langflow 的 Prompt 技术实现体现了现代 AI 框架的设计理念:安全、可扩展、高性能,为构建复杂的 AI 应用提供了坚实的基础。

http://www.xdnf.cn/news/1408015.html

相关文章:

  • 第2.4节:大模型之LLaMA系列(Meta)
  • 项目跑起来之前的那些事
  • shell的原理和Linux的指令效果演示
  • Rust 登堂 之 枚举和整数(八)
  • K8s学习笔记(一)——
  • 试试 Xget 加速 GitHub 克隆仓库
  • React前端开发_Day12_极客园移动端项目
  • Windows中如何将Docker安装在E盘并将Docker的镜像和容器存储在E盘的安装目录下
  • IDM(Internet Download Managerv 6.38)破除解版下载!IDM 下载器永久免费版!提升下载速度达5倍!安装及使用
  • Google 的 Agent2Agent 协议 (A2A):带示例的指南
  • Java试题-选择题(26)
  • Swin Transformer基本原理与传统Transformer对比图解
  • Lua基础知识精炼
  • vim-plugin AI插件
  • 运筹说 第141期 | 启发式算法:用简单规则、破解复杂问题
  • 网络端口与服务对应表 - 白帽子安全参考指南
  • C#基础(③CMD进程)
  • LLM记账智能体-MCP服务-实现步骤与效果展示
  • @Value注解的底层原理(一)
  • (一) aws上微服务
  • C++ 快速复习指南(上半部分)
  • 我开发了一个自动还原源码的小工具
  • AI辅助编程日记和chat历史开源Series 1:VSCode + GitHub Copilot 自动下载及安装软件
  • 《打破 “慢“ 的黑箱:前端请求全链路耗时统计方案》
  • Vue3 响应式基础
  • 前端学习——JavaScript基础
  • 创维LB2004_安装软件教程
  • 37. 解数独
  • GaRe:面向非约束户外照片集的可重光照 3D 高斯溅射技术简要解析
  • Android开发-活动页面