LangChain 框架核心概念与实战应用
简介
本文介绍 LangChain 框架,它能够将大型语言模型与其他计算或知识来源相结合,从而实现功能更加强大的应用。接着,对 LangChain 的关键概念进行了详细说明,并基于该框架进行了一些案例尝试,旨在帮助读者更轻松地理解 LangChain 的工作原理。
LangChain 是一个用于构建基于大型语言模型应用的开源框架,通过将 LLM 与外部知识库、计算逻辑结合增强模型能力。本文详细介绍了 LangChain 的六大核心组件:模型、提示词、索引、存储、链和代理,并通过代码示例展示了如何在问答系统、图片生成及结构化数据输出等场景中使用这些组件。同时探讨了 LangChain 在智能客服、个性化推荐等领域的应用前景,帮助开发者快速上手并构建功能强大的 AI 应用。

本文介绍 LangChain 框架,它能够将大型语言模型与其他计算或知识来源相结合,从而实现功能更加强大的应用。接着,对 LangChain 的关键概念进行了详细说明,并基于该框架进行了一些案例尝试,旨在帮助读者更轻松地理解 LangChain 的工作原理。
近期,大型语言模型 (LLM) 如 GPT 系列模型引领了人工智能领域的一场技术革命。开发者们都在利用这些 LLM 进行各种尝试,虽然已经产生了许多有趣的应用,但是单独使用这些 LLM 往往难以构建功能强大的实用应用。
LangChain 通过将大型语言模型与其他知识库、计算逻辑相结合,实现了功能更加强大的人工智能应用。简单来说,个人理解 LangChain 可以被视为开源版的 GPT 插件,它提供了丰富的大语言模型工具,可以在开源模型的基础上快速增强模型的能力。
在此,我总结了最近对 LangChain 的学习内容,欢迎各位同学前来交流。LangChain 使得语言技术的运用更加活跃多元,它有望在人工智能领域发挥重要作用,推动我们工作效率的变革。我们正处在人工智能爆发的前夜,积极拥抱新技术将会带来全新的体验。
LangChain 提供了一系列的工具帮助我们更好的使用大语言模型 (LLM)。可以认为主要有 6 种不同类型的工具:
LangChain 的一个核心价值就是它提供了标准的模型接口;然后我们可以自由的切换不同的模型,当前主要有两种类型的模型,但是考虑到使用场景,对我们一般用户来说就是使用一种模型即文本生成模型。
说到模型,大家就理解模型就是 ChatGPT 就可以。单纯的模型只能生成文本内容。
语言模型 (Language Models) 用于文本生成,文字作为输入,输出也是文字。 普通 LLM:接收文本字符串作为输入,并返回文本字符串作为输出。 聊天模型:将聊天消息列表作为输入,并返回一个聊天消息。
from langchain.schema import HumanMessage
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
llm = OpenAI()
chat_model = ChatOpenAI()
print(llm("say hi!"))
print(chat_model.predict("say hi!"))
文本嵌入模型 (Text Embedding Models) 把文字转换为浮点数形式的描述:
这些模型接收文本作为输入并返回一组浮点数。这些浮点数通常用于表示文本的语义信息,以便进行文本相似性计算、聚类分析等任务。文本嵌入模型可以帮助开发者在文本之间建立更丰富的联系,提高基于大型语言模型的应用的性能。
from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
text = "This is a test document."
query_result = embeddings.embed_query(text)
doc_result = embeddings.embed_documents([text])
print(doc_result)
提示词是我们与模型交互的方式,或者是模型的输入,通过提示词可以让模型返回我们期望的内容,比如让模型按照一定的格式返回数据给我们。
LangChain 提供了一些工具,可以方便我们更容易的构建出我们想要的提示词,主要工具如下:
语言模型提示词模板 PromptTemplates,提示模板可以让我们重复的生成提示,复用我们的提示。它包含一个文本字符串('模板'),从用户那里获取一组参数并生成提示,包含:
from langchain import PromptTemplate
template = """
I want you to act as a naming consultant for new companies.
What is a good name for a company that makes {product}?
"""
prompt = PromptTemplate(
input_variables=["product"],
template=template,
)
prompt.format(product="colorful socks")
# -> I want you to act as a naming consultant for new companies.
# -> What is a good name for a company that makes colorful socks?
聊天模型提示词模板 ChatPrompt Templates,ChatModels 接受聊天消息列表作为输入。列表一般是不同的提示,并且每个列表消息一般都会有一个角色。
from langchain.prompts import (
ChatPromptTemplate,
PromptTemplate,
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
template="You are a helpful assistant that translates {input_language} to {output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template="{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
# get a chat completion from the formatted messages
print(chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages())
示例选择器 Example Selectors,如果有多个案例的时候,使用 ExampleSelectors 选择一个案例让提示词使用:
from langchain.prompts.example_selector.base import BaseExampleSelector
from typing import Dict, List
import numpy as np
class CustomExampleSelector(BaseExampleSelector):
def __init__(self, examples: List[Dict[str, str]]):
self.examples = examples
def add_example(self, example: Dict[str, str]) -> None:
"""Add new example to store for a key."""
self.examples.append(example)
def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
"""Select which examples to use based on the inputs."""
return np.random.choice(self.examples, size=2, replace=False)
examples = [
{"foo": "1"},
{"foo": "2"},
{"foo": "3"}
]
# Initialize example selector.
example_selector = CustomExampleSelector(examples)
# Select examples
print(example_selector.select_examples({"foo": "foo"}))
# Add new example to the set of examples
example_selector.add_example({"foo": "4"})
print(example_selector.examples)
# Select examples
print(example_selector.select_examples({"foo": "foo"}))
输出解析器 OutputParsers,可以让 LLM 输出更加结构化的信息:
主要的 Parsers:
可以看到我们定义了 Joke 类,然后 PydanticOutputParser 可以让 LLM 按照我们定义对象的格式返回数据给我们。
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field, validator
from typing import List
model_name = 'text-davinci-003'
temperature = 0.0
model = OpenAI(model_name=model_name, temperature=temperature)
# Define your desired data structure.
class Joke(BaseModel):
setup: str = Field(description="question to set up a joke")
punchline: str = Field(description="answer to resolve the joke")
# You can add custom validation logic easily with Pydantic.
@validator('setup')
def question_ends_with_question_mark(cls, field):
if field[-1] != '?':
raise ValueError("Badly formed question!")
return field
parser = PydanticOutputParser(pydantic_object=Joke)
prompt = PromptTemplate(
template="Answer the user query.\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()}
)
joke_query = "Tell me a joke."
_input = prompt.format_prompt(query=joke_query)
output = model(_input.to_string())
print(parser.get_format_instructions())
print(output)
print(parser.parse(output))
索引可以让文档结构化,从而 LLM 可以直接更好的和文档交互;比如用于答疑,知识库等,LLM 先从文档中获取答案。
LangChain 在索引这块也提供了许多有用的函数和工具,方便我们从外部加载与检索不同的文档数据。
在数据索引这块,LangChain 提供的主要工具:
图中的 FAISS 是一种向量存储的服务;
给一个案例,了解下不同工具的用法: 首先加载文档; 然后分隔文档为不同区块; 然后转换为向量存储; 将向量存储转换为检索器,交给 LangChain,用于问答;
import os
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.indexes import VectorstoreIndexCreator
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.llms import OpenAI
# 创建文本加载器
loader = TextLoader('/Users/aihe/Downloads/demo.txt', encoding='utf8')
# 加载文档
documents = loader.load()
# 文本分块
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# 计算嵌入向量
embeddings = OpenAIEmbeddings()
# 创建向量库
db = Chroma.from_documents(texts, embeddings)
# 将向量库转换为检索器
retriever = db.as_retriever()
# 创建检索问答系统
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=retriever)
# 运行问题答案检索
query = "如何申请租户?"
print(qa.run(query))
print(qa.run("能否说明下你可以提供的功能?"))
默认情况下 Agent 和 Chain 都是无状态的,也就是用完之后不知道上次的对话内容是什么。每次的 query 都是独立的。
但是在有些应用中,记住上一次的会话内容是比较重要的,比如聊天,LangChain 对于也提供了一些相关的工具类。
from langchain import ConversationChain, OpenAI
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
memory.chat_memory.add_user_message("你好!")
memory.chat_memory.add_ai_message("你好吗?")
llm = OpenAI(temperature=0)
chain = ConversationChain(llm=llm,
verbose=True,
memory=memory)
chain.predict(input="最近怎么样!")
print(chain.predict(input="感觉很不错,刚和 AI 做了场对话."))
链可以让我们把多个组件组合成一个应用,比如我们创建一个链,这个链可以接受用户的输入,然后通过 PromptTemplate 格式化用户的输入为提示词,然后把这个提示词输入给 LLM。
我们也可以把一些链组合在一起,构建更复杂的链。
一个简单的案例:
# 引入所需模块和类
from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI
from langchain import PromptTemplate
from langchain.prompts.chat import (
ChatPromptTemplate, # 引入对话模板类
HumanMessagePromptTemplate, # 引入人类消息模板类
)
# 创建人类消息模板类
human_message_prompt = HumanMessagePromptTemplate(
prompt=PromptTemplate(
template="给我一个制作{product}的好公司名字?", # 输入模板,其中 product 为占位符
input_variables=["product"], # 指定输入变量为 product
)
)
# 创建对话模板类
chat_prompt_template = ChatPromptTemplate.from_messages([human_message_prompt])
# 创建 OpenAI 聊天模型对象
chat = ChatOpenAI(temperature=0.9)
# 创建 LLMChain 对象,将聊天模型和对话模板传入
chain = LLMChain(llm=chat, prompt=chat_prompt_template)
# 运行 LLMChain 对象,并输出结果
print(chain.run("袜子"))
代理是使用 LLM 作为思考工具,决定当前要做什么。我们会给代理一系列的工具,代理根据我们的输入判断用哪些工具可以完成这个目标,然后不断的运行工具,来完成目标。
代理可以看做是增强版的 Chain,不仅绑定模板、LLM,还可以给代理添加一些工具。
Agent 是一个智能代理,它负责根据用户输入和应用场景,在一系列可用工具中选择合适的工具进行操作。Agent 可以根据任务的复杂性,采用不同的策略来决定如何执行操作。
有两种类型的 Agent:
对于简单的任务,动作代理更为常见且易于实现。对于更复杂或长期运行的任务,计划 - 执行代理的初始规划步骤有助于维持长期目标并保持关注。但这会以更多调用和较高延迟为代价。这两种代理并非互斥,可以让动作代理负责执行计划 - 执行代理的计划。
Agent 内部涉及的核心概念如下:
代理的执行流程:
一个案例:
# 引入所需模块和类
from langchain.agents import load_tools # 引入加载工具函数
from langchain.agents import initialize_agent # 引入初始化代理函数
from langchain.agents import AgentType # 引入代理类型类
from langchain.llms import OpenAI # 引入 OpenAI 语言模型类
import os # 引入 os 模块
# 创建 OpenAI 语言模型对象,设定 temperature 为 0,即关闭随机性
llm = OpenAI(temperature=0)
# 加载所需工具,包括 serpapi 和 llm-math
tools = load_tools(["serpapi", "llm-math"], llm=llm)
# 初始化代理对象,设定代理类型为 ZERO_SHOT_REACT_DESCRIPTION,输出详细信息
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# 运行代理对象,向其提问特朗普的年龄和年龄除以 2 的结果
agent.run("特朗普今年多少岁?他的年龄除以 2 是多少?")
上述代码中关于 Agent 有个初始化的阶段,agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,代理类型决定了代理如何使用工具、处理输入以及与用户进行交互。从而为用户提供有针对性的服务。其中可以选择的类型如下:
initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
官方已经默认提供了一系列的工具箱,发 Gmail 邮件,数据库查询,JSON 处理等;还有一些单个的工具列表,都可以在文档中看到:
我们通过一个自定义的工具,了解下工具怎么用,因为后面再使用 LangChain 的时候我们做的也就是不断的自定义工具。
编写工具的时候,要准备:
假设我们需要构建一个基于 LLM 的问答系统,该系统需要从指定的数据源中提取信息以回答用户的问题。我们可以使用 LangChain 中的数据增强生成功能与外部数据源进行交互,获取所需的数据。然后,将数据输入到 LLM 中,生成回答。记忆功能可以帮助我们在多次调用之间保持相关状态,从而提高问答系统的性能。此外,我们还可以使用智能代理功能实现系统的自动优化。最后,通过 LangChain 提供的评估提示和链实现,我们可以对问答系统的性能进行评估和优化。
实现了一个基于语言模型的文本生成图片工具,调用不同的工具函数来最终生成图片。主要提供了以下几个工具:
import base64
import json
import os
from io import BytesIO
import requests
from PIL import Image
from pydantic import BaseModel, Field
from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.chat_models import ChatOpenAI
from langchain.llms import OpenAI
from langchain.tools import BaseTool, StructuredTool, Tool, tool
from langchain import LLMMathChain, SerpAPIWrapper
def generate_image(prompt: str) -> str:
"""
根据提示词生成对应的图片
Args:
prompt (str): 英文提示词
Returns:
str: 图片的路径
"""
url = "http://127.0.0.1:7860/sdapi/v1/txt2img"
headers = {
"accept": "application/json",
"Content-Type": "application/json"
}
data = {
"prompt": prompt,
"negative_prompt": "(worst quality:2), (low quality:2),disfigured, ugly, old, wrong finger",
"steps": 20,
"sampler_index": "Euler a",
"sd_model_checkpoint": "cheeseDaddys_35.safetensors [98084dd1db]",
"batch_size": 1,
"restore_faces": True
}
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
response_data = response.json()
images = response_data['images']
for index, image_data in enumerate(images):
img_data = base64.b64decode(image_data)
img = Image.open(BytesIO(img_data))
file_name = f"image_{index}.png"
file_path = os.path.join(os.getcwd(), file_name)
img.save(file_path)
print(f"Generated image saved at {file_path}")
return file_path
else:
print(f"Request failed with status code {response.status_code}")
def random_poem(arg: str) -> str:
"""
随机返回中文的诗词
Returns:
str: 随机的中文诗词
"""
llm = OpenAI(temperature=0.9)
text = """
能否帮我从中国的诗词数据库中随机挑选一首诗给我,希望是有风景,有画面的诗:
比如:山重水复疑无路,柳暗花明又一村。
"""
return llm(text)
def prompt_generate(idea: str) -> str:
"""
生成图片需要对应的英文提示词
Args:
idea (str): 中文提示词
Returns:
str: 英文提示词
"""
llm = OpenAI(temperature=0, max_tokens=2048)
res = llm(f"""
Stable Diffusion is an AI art generation model similar to DALLE-2.
Below is a list of prompts that can be used to generate images with Stable Diffusion:
- portait of a homer simpson archer shooting arrow at forest monster, front game card, drark, marvel comics, dark, intricate, highly detailed, smooth, artstation, digital illustration by ruan jia and mandy jurgens and artgerm and wayne barlowe and greg rutkowski and zdislav beksinski
- pirate, concept art, deep focus, fantasy, intricate, highly detailed, digital painting, artstation, matte, sharp focus, illustration, art by magali villeneuve, chippy, ryan yee, rk post, clint cearley, daniel ljunggren, zoltan boros, gabor szikszai, howard lyon, steve argyle, winona nelson
- ghost inside a hunted room, art by lois van baarle and loish and ross tran and rossdraws and sam yang and samdoesarts and artgerm, digital art, highly detailed, intricate, sharp focus, Trending on Artstation HQ, deviantart, unreal engine 5, 4K UHD image
- red dead redemption 2, cinematic view, epic sky, detailed, concept art, low angle, high detail, warm lighting, volumetric, godrays, vivid, beautiful, trending on artstation, by jordan grimmer, huge scene, grass, art greg rutkowski
- a fantasy style portrait painting of rachel lane / alison brie hybrid in the style of francois boucher oil painting unreal 5 daz. rpg portrait, extremely detailed artgerm greg rutkowski alphonse mucha greg hildebrandt tim hildebrandt
- athena, greek goddess, claudia black, art by artgerm and greg rutkowski and magali villeneuve, bronze greek armor, owl crown, d & d, fantasy, intricate, portrait, highly detailed, headshot, digital painting, trending on artstation, concept art, sharp focus, illustration
- closeup portrait shot of a large strong female biomechanic woman in a scenic scifi environment, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, warframe, illustration, thomas kinkade, tomasz alen kopera, peter mohrbacher, donato giancola, leyendecker, boris vallejo
- ultra realistic illustration of steve urkle as the hulk, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha
I want you to write me a list of detailed prompts exactly about the idea written after IDEA. Follow the structure of the example prompts. This means a very short description of the scene, followed by modifiers divided by commas to alter the mood, style, lighting, and more.
IDEA: {idea}""")
return res
class PromptGenerateInput(BaseModel):
"""
生成英文提示词所需的输入模型类
"""
idea: str = Field()
class GenerateImageInput(BaseModel):
"""
生成图片所需的输入模型类
"""
prompt: str = Field(description="英文提示词")
tools = [
Tool.from_function(
func=random_poem,
name="诗歌获取",
description="随机返回中文的诗词"
),
Tool.from_function(
func=prompt_generate,
name="提示词生成",
description="生成图片需要对应的英文提示词,当前工具可以将输入转换为英文提示词,以便方便生成",
args_schema=PromptGenerateInput
),
Tool.from_function(
func=generate_image,
name="图片生成",
description="根据提示词生成对应的图片,提示词需要是英文的,返回是图片的路径",
args_schema=GenerateImageInput
),
]
def main():
"""
主函数,初始化代理并执行对话
"""
llm = OpenAI(temperature=0)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("帮我生成一张诗词的图片?")
if __name__ == '__main__':
main()
参考上面的索引部分:
import os
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.indexes import VectorstoreIndexCreator
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.llms import OpenAI
# 创建文本加载器
loader = TextLoader('/Users/aihe/Downloads/demo.txt', encoding='utf8')
# 加载文档
documents = loader.load()
# 文本分块
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# 计算嵌入向量
embeddings = OpenAIEmbeddings()
# 创建向量库
db = Chroma.from_documents(texts, embeddings)
# 将向量库转换为检索器
retriever = db.as_retriever()
# 创建检索问答系统
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=retriever)
# 运行问题答案检索
query = "如何申请租户?"
print(qa.run(query))
print(qa.run("能否说明下你可以提供的功能?"))
参考上述概念,提示词工具中提供了 OutputParser 可以把我们的对象转换为提示词,告诉 LLM 要返回什么结构的内容。
import requests
from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatOpenAI
from langchain.tools import StructuredTool
from pydantic import BaseModel, Field
def post_message(type: str, param: dict) -> str:
"""
当需要生成人群、分析画像、咨询问题时,使用如下的指示:url 固定为:http://localhost:3001/
如果请求是生成人群,请求的 type 为 crowd; 如果请求是分析画像,请求的 type 为 analyze; 如果是其他或者答疑,请求的 type 为 question;
请求 body 的 param 把用户指定的条件传进来即可
"""
result = requests.post("http://localhost:3001/", json={"type": type, "param": param})
return f"Status: {result.status_code} - {result.text}"
class PostInput(BaseModel):
# body: dict = Field(description="""格式:{"type":"","param":{}}""")
type: str = Field(description="请求的类型,人群为 crowd,画像为 analyze")
param: dict = Field(description="请求的具体描述")
llm = ChatOpenAI(temperature=0)
tools = [
StructuredTool.from_function(post_message)
]
agent = initialize_agent(tools, llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("我想生成一个性别为男并且在 180 天访问过淘特的人群?")
原本做聊天机器人,需要一些前端代码,但是已经有相应的开源工具,帮我们把 LangChian 的各种组件做了可视化,直接拖拽即可,我们直接使用 LangFlow;
pip install langflow
然后运行命令:
langflow
如果和本地的 LangChain 有冲突,可以使用 Docker 运行 langflow:
FROM python:3.10-slim
RUN apt-get update && apt-get install gcc g++ git make -y
RUN useradd -m -u 1000 user
USER user
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH
WORKDIR $HOME/app
COPY --chown=user . $HOME/app
RUN pip install langflow>=0.0.71 -U --user
CMD ["langflow", "--host", "0.0.0.0", "--port", "7860"]
在界面上配置 LangChain 的三个组件:在最右下角是对应的聊天窗口,输入下 openai 的 key。
开始聊天验证下我们的配置:
全程基本上不用怎么写代码,只需要了解 LangChain 的组件是做什么的,基本上就可以搭出一款简单的聊天机器人。
其它的 LangChain 组件代理、内存、数据索引也是都可以使用的。
LangChain 为构建基于大型语言模型的应用提供了一个强大的框架,将逐步的运用到各个领域中,如:智能客服、文本生成、知识图谱构建等。随着更多的工具和资源与 LangChain 进行集成,大语言模型对人的生产力将会有更大的提升。
应用场景构思:
现在有个平台已经实现了大部分:底层为 OpenAI 模型,使用 zapier 来实现将万种工具连接起来。可以在这个平台上配置各种工具,模型会根据你的目标选择相应的动作。工作内容自动化在不远处很快就会实现。
本文介绍了 LangChain 框架,它能够将大型语言模型与其他计算或知识来源相结合,从而实现功能更加强大的应用。接着,对 LangChain 的关键概念进行了详细说明,并基于该框架进行了一些案例尝试,旨在帮助读者更轻松地理解 LangChain 的工作原理。
展望未来,LangChain 有望在各个领域发挥巨大作用,促进我们工作效率的变革。我们正处于 AI 爆发的前夜,积极拥抱新技术将会带来完全不同的感觉。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online