
🧠 基础的prompting技术中,都是通过样例提示,激活模型本身的推理功能,但在现实的情况中,依然存在着仅仅依靠模型本身的知识是无法解决的,例如:① 数据库知识不足 ② 模型能力缺乏等。在这些情况下,往往需要外部的知识和能力来辅助模型,因此,本文将RAG技术和ReAct技术作为进阶的prompting技术进行介绍。
技术组合 | 用途 | 优点 | 场景示例 |
|---|---|---|---|
ReAct | 模型边思考边调用工具 | 强逻辑推理 + 动态行动 | 搜索、计算、知识问答 Agent |
RAG | 提取外部知识 + 多步推理 | 上下文可靠 + 推理清晰 | 智能问答、企业文档搜索、知识库助手 |
检索增强生成(Retrieval Augmented Generation,RAG)将信息检索组件与文本生成模型结合起来,通过向外部知识库查询相关信息,并将其作为上下文嵌入到 Prompt 中,指导模型在 Few-shot 场景下完成更精准的生成任务。这种方式有效弥补了大模型记忆局限、提升了知识覆盖广度与事实准确性。
⭐ langchain代码
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
from langchain.llms import OpenAI
# 1. 加载文档并分块
loader = TextLoader("my_doc.txt")
docs = loader.load_and_split()
# 2.将文本内容向量化
embedding = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
db = FAISS.from_documents(docs, embedding)
# 3. 构建 QA 链(RAG)
qa = RetrievalQA.from_chain_type(
llm=OpenAI(), # 本地模型也可以
retriever=db.as_retriever() #检索
)
query = "请问这个文档的核心内容是什么?"
answer = qa.run(query)
print(answer)⭐ 为了更灵活的调用外部知识以及对模型的选用,我们继续采用手动实现的方式,不采用框架的方式,主要是调整本地知识库向量化和检索的代码:
# 文本嵌入
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2")
doc_embeddings = model.encode(["段落1", "段落2", "段落3"]) # 文档向量
# 向量检索
import faiss
index = faiss.IndexFlatL2(doc_embeddings.shape[1])
index.add(doc_embeddings)
# 查询
query = "你想问什么?"
query_vec = model.encode([query])
D, I = index.search(query_vec, k=3)
retrieved_docs = [文档[i] for i in I[0]]
# 拼接检索结果 + prompt 输入 LLM
context = "\n".join(retrieved_docs)
prompt = f"请根据以下文档回答问题:\n{context}\n问题:{query}\n回答:"另一种常见的外部知识获取方式是调用外部工具。由于语言模型本身的知识来自预训练语料,其知识库具有时效性限制,难以覆盖实时或特定领域的信息。例如,当我们询问“当前厦门的天气”时,模型本身无法获取准确答案。这时,通过调用外部 API 工具来弥补模型知识的不足就变得尤为关键。为实现这一能力,ReAct(Reason + Act) 提示工程范式被提出。它允许大模型在推理过程中“边思考(Reason),边行动(Act)”,即模型可以根据问题内容主动决定是否调用某个工具、调用哪个工具,并基于工具返回的结果进一步推理和生成回答。这种“思考—行动—再思考”的方式提升了模型处理复杂任务的能力。与其他 Agent 类方法类似,ReAct 也需要通过 Few-shot 样例 进行提示设计,帮助模型学习在何种情况下调用工具,以及如何将工具的反馈信息融入最终答案中。
⭐ langchain使用 ReAct
from langchain.agents import initialize_agent, Tool
from langchain.agents.agent_types import AgentType
from langchain.tools import DuckDuckGoSearchRun
from langchain.llms import OpenAI # 替换为本地模型也可
# 定义工具(例如:搜索 + 计算器)
search = DuckDuckGoSearchRun()
tools = [
Tool(name="Search", func=search.run, description="Search the web"),
]
# 初始化 agent(ReAct 模式)
agent = initialize_agent(
tools=tools,
llm=OpenAI(),
agent=AgentType.REACT_DOCSTORE,
verbose=True,
)
# 执行任务
response = agent.run("德国的人口除以2是多少?")
print(response)AgentType.REACT_DOCSTORE 这个字段提供的标准 few-shot 示例:
Question: 巴黎的天气如何? Thought: 我需要查一下天气。 Action: Search Action Input: "巴黎" Observation: 当前巴黎天气为晴天,22℃ Thought: 我知道了天气。 Final Answer: 巴黎现在是晴天,气温 22℃。
⭐ 为了更灵活的调用工具以及对模型的选用,我们需要对模型、函数进行封装:
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
from langchain.llms import HuggingFacePipeline
# 加载本地模型和分词器
model_name_or_path = "/root/autodl-tmp/deepseek-llm-7b-chat"
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_name_or_path, trust_remote_code=True, device_map="auto"
)
# 创建生成 pipeline
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512)
# 转换为 LangChain 可识别的模型
llm = HuggingFacePipeline(pipeline=pipe)from langchain.agents import Tool
# 自定义函数
def square(x: str) -> str:
try:
number = float(x)
return str(number ** 2)
except:
return "请输入有效数字"
# 封装为 Tool
square_tool = Tool(
name="Square Calculator",
func=square,
description="计算一个数字的平方,例如输入 '5'"
)from langchain.prompts import PromptTemplate
from langchain.agents import initialize_agent, AgentType
custom_prompt = PromptTemplate.from_template("""
你是一个智能代理,有能力使用以下工具来解决用户问题。
示例:
Question: 5 的平方是多少?
Thought: 我可以使用平方计算器来求出结果。
Action: Square Calculator
Action Input: "5"
Observation: 25
Thought: 我已经得到了答案。
Final Answer: 5 的平方是 25。
Question: {input}
Thought:
""")
# 初始化 agent
agent = initialize_agent(
tools=[square_tool],
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
prompt=custom_prompt,
verbose=True
)🟢 可以发现, 当我们在采用ReAct技术的过程中,langchain框架是通过initialize_agent进行初始化的,这也说明了我们逐渐向 AI-agent技术靠近了。
🔴 但是在严格意义上它还只是”单轮任务代理”,目前还缺乏:1️⃣多轮状态记忆 2️⃣长期目标规划 3️⃣动态工具注册、调用多个 API 的能力 4️⃣消息结构的显式控制
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。