AgentType
LangChain 提供了多种智能体类型,可以根据具体需求选择合适的类型。常见的智能体类型包括:
| AgentType | 核心机制 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
ZERO_SHOT_REACT_DESCRIPTION |
ReAct + 工具描述 |
简单任务 + 工具组合 | 快速集成、无需训练数据 | 输出格式自由,可控性较低 |
STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION |
结构化输出 + ReAct |
结构化工具调用 | 高可控性,格式严格 | 依赖工具描述清晰度 |
OPENAI_FUNCTIONS |
OpenAI 函数调用 | OPENAI 模型场景 | 高效,强耦合 OPENAI | 仅限 OPENAI 模型 |
CONVERSATIONS_REACT_DESCRIPTION |
多轮对话 + ReAct |
多轮交互任务 | 上下文感知、灵活性高 | 需配置记忆模块 |
AUTO_GPT |
自主代理循环 | 复杂任务自动化 | 自主决策、长期目标 | 实验性,稳定性待验证 |
STRUCTURED_CHAT |
严格结构化输出 | 数据提取、表单填写 | 格式标准化、可控性强 | 灵活性低 |
初始化智能体
智能体是一个可以使用一组工具来完成任务的系统。initialize_agent 用于创建一个智能体(agent),它可以使用一组工具(tools)来完成任务。智能体通过与语言模型(LLM)交互,决定何时以及如何使用这些工具
initialize_agent 来自于 langchain 这个包
python
from langchain.agents import initialize_agent, AgentType
agent = initialize_agent(
tools=create_calc_tools(),
llm=llm,
agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True, # 打开调试
)
print("工具函数计算结果:", resp)
传入 verbose=True 可以打开调试模式,看到智能体的思考过程
Thought 是智能体的思考过程,Action 是智能体决定使用哪个工具以及传入什么参数,Observation 是工具函数的返回结果
bash
> Entering new AgentExecutor chain...
Thought: 需要使用加法工具来计算两个数的和。
Action:
{ "action": "add", "action_input": { "a": 100, "b": 100 } }
css
Observation: 200
> Finished chain.
工具函数计算结果: {'input': '100+100=?', 'output': 200}
结构化返回
我们现在返回的是一个纯文本,我们希望返回的是一个 json,因为 json 在处理大模型之间的调用时更为高效和灵活
JsonOutputParser 可以将大模型的输出解析为 json 格式
我们需要定义一个 output_schema,告诉 JsonOutputParser 我们希望返回的 json 格式
python
from pydantic import BaseModel, Field
from langchain_core.output_parsers import JsonOutputParser
class Output(BaseModel):
args: str = Field(description="输入的参数")
output: str = Field(description="返回的结果")
think: str = Field(description="思考过程")
parser = JsonOutputParser(pydantic_object=Output)
format_instructions = parser.get_format_instructions()
prompt = chat_prompt_template.format_messages(
role="计算",
domain="使用工具进行数学计算",
question=f"""
请阅读下面的问题,并返回一个严格的 JSON 对象,不要使用 Markdown 代码块包裹
格式要求:
{format_instructions}
问题:
100+100=?
""",
)
PythonREPL
之前开发的 add 工具函数只能进行加法运算,在我们实际的开发中,肯定不可能这么简单
但是我们又不可能去开发所有的工具函数,这样工作量太大
PythonREPL 是一个内置的工具,可以让大模型直接执行 Python 代码
python
from langchain_experimental.tools.python.tool import PythonREPLTool
python_repl = PythonREPLTool()
ret = python_repl.run("print(1 + 1)")
print(ret) # 输出 2
在你使用 PythonREPL 工具时,请务必小心,因为它允许执行任意的 Python 代码,这可能会带来安全风险
bash
Python REPL can execute arbitrary code. Use with caution.
用智能体编写一个网站
python
from langchain_experimental.tools.python.tool import PythonREPLTool
from langchain.agents import initialize_agent, AgentType
from langchain.prompts import PromptTemplate
from bailian.common import llm
tools = [PythonREPLTool()]
tool_names = ["PythonREPLTool"]
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
)
prompt_template = PromptTemplate.from_template(
template="""
尽你所能回答以下问题或执行用户命令,你可以使用以下工具: [${tool_names}]
--
请按照以下格式进行思考:
\```
# 思考的过程
- 问题:你必须回答的问题
- 思考:你考虑应该怎么做
- 行动:要采取行动,应该是[{tool_names}]中的一个
- 行动输入:行动的输入
- 观察:行动的结果
...(这个思考/行动/行动输入/观察可以重复N次)
# 最终答案
对原始输入问题的最终答案
\```
--
注意:
- PythonREPLTool 工具的入参是python代码,不允许添加 ```python 或 ```py 等标记
--
要求:{input}
"""
)
prompt = prompt_template.format(
tool_names=", ".join(tool_names),
input="""
要求:
1. 向 /Users/uccs/Desktop/project/ai/ai-agent/.tmp 下写入一个新文件,名称为 index.html
2. 写一个在线教育产品的官网,包含3个tab,分别是 首页、实战课、体系课和关于我们
3. 首页包含3个模块,分别是:热门课程、上新课程、爆款课程
4. 关于我们展示平台的联系方式等基本信息
""",
)
agent.invoke({"input": prompt})
解析器
LangChain 输出解析器(Output Parsers)是将大语言模型(LLM)的原始文本响应转换为结构化、可操作数据的关键组件。输出解析器通过提供格式化指令并解析模型输出,实现文本到结构化数据的高效转换。
基础解析器
基础解析器处理最简单的数据格式转换:
StrOutputParser:直接提取模型返回的原始文本,不做任何结构化处理CommaSeparatedListOutputParser:将逗号分隔的文本转换为Python列表。例如,将"apples, bananas, oranges"解析为['apples', 'bananas', 'oranges']BooleanOutputParser:解析文本为布尔值(True/False)。模型输出必须是"yes"或"no"(不区分大小写),解析器会统一转为大写后判断SimpleJsonOutputParser:将文本简单处理后转换为JSON格式,通常用于模型已经正确输出JSON的情况
StrOutputParser
python
from bailian.common import llm, chat_prompt_template
from langchain_core.output_parsers import StrOutputParser
parser = StrOutputParser()
chain = chat_prompt_template | llm | parser
resp = chain.invoke(
input={
"role": "计算",
"domain": "数学计算",
"question": "100+200 = ?",
}
)
print(resp)
# 结果
# 100 + 200 = **300**
CommaSeparatedListOutputParser
python
from bailian.common import llm, chat_prompt_template
from langchain_core.output_parsers import CommaSeparatedListOutputParser
parser = CommaSeparatedListOutputParser()
chain = chat_prompt_template | llm | parser
resp = chain.invoke(
input={
"role": "计算",
"domain": "数学计算",
"question": "100*200 = ?",
}
)
print(resp)
# 结果
# ['100乘以200等于20000。因此,$100 \\times 200 = 20000$。']
Pydantic 解析器
Pydantic 解析器通过 Pydantic 模型定义复杂结构,提供更严格的验证和数据校验:
PydanticOutputParser:将模型输出解析为Pydantic定义的模型对象。需要预先定义Pydantic模型,支持嵌套数据结构和类型验证PydanticToolsParser:专门处理OpenAI工具调用中的Pydantic对象,将工具调用参数解析为Pydantic模型
Pydantic 解析器适合需要严格验证的数据结构,如用户信息、订单详情等,确保输出的完整性和正确性
函数调用解析器
函数调用解析器处理支持OpenAI函数调用的模型(如GPT-4)的响应:
OutputFunctionsParser:解析模型返回的函数调用参数,通常返回JSON格式的函数参数JsonOutputFunctionsParser:提取函数调用中的JSON参数
这些解析器专为需要调用特定函数或工具的场景设计,常见于Agent系统或复杂任务处理
时间/枚举解析器
处理特定类型的数据:
DatetimeOutputParser:将文本解析为标准日期时间格式("%Y-%m-%dT%H:%M:%S.%fZ")EnumOutputParser:将文本解析为预定义的枚举值,适用于需要严格限制输出选项的场景。
DatetimeOutputParser
python
from bailian.common import llm
from langchain.output_parsers import DatetimeOutputParser
from langchain.prompts import ChatPromptTemplate
parser = DatetimeOutputParser()
instructions = parser.get_format_instructions()
prompt = ChatPromptTemplate.from_messages(
[
("system", f"必须按照以下格式返回日期时间:{instructions}"),
("human", "请将以下自然语言转换为标准日期时间格式:{text}"),
]
)
chain = prompt | llm | parser
resp = chain.invoke({"text": "二年零二五年五月一日下午十点十分"})
print(resp)
# 结果
# 2025-05-01 22:10:00
正则解析器
通过正则表达式提取特定模式的数据:
RegexParser:单字段正则匹配。RegexDictParser:多字段正则提取为字典。- 正则解析器适合需要灵活匹配文本模式的场景,如提取电话号码、邮箱地址等。
复合解析器
处理复杂或多部分的输出:
CombiningOutputParser:组合多个解析器,将文本通过分隔符拆分后分别解析。RetryWithErrorOutputParser:在解析失败时重试并尝试修复输出。- 复合解析器提供了更强大的处理能力,可以应对复杂或多任务的输出场景。
强校验解析器
提供更严格的输出验证:
GuardrailsOutputParser:基于Guardrails库,对输出进行强校验,支持自定义规则(如过滤不当内容、校验数据格式)。
Guardrails 解析器特别适合安全敏感场景,确保输出内容符合预设规则和标准。