1.Agent 架构

这张图展示了一个Agent 架构的核心组成部分及其交互关系,以下是详细说明:

1.1 核心模块:Agent

是整个架构的中枢,负责整合感知、记忆、工具使用、规划决策和行动等环节,实现自主智能行为。

1.2 感知模块

  • 功能:负责接收外部环境的信息,是 Agent 与外界交互的 “感官入口”。
  • 作用:将外部信息传递给记忆模块,为后续决策提供输入。

1.3 记忆模块

  • 子模块:
    • 短期记忆:存储近期的信息,用于即时的决策和交互,类似人类的短时记忆(如刚接收的对话内容、临时任务信息)。
    • 长期记忆:存储长期积累的知识、经验和历史信息,为 Agent 提供长期的认知支撑(如领域知识、过往成功的策略)。
  • 作用:对感知到的信息进行存储和整理,同时为 Agent 的规划决策、行动等环节提供记忆检索支持。

1.4 工具模块

  • 子工具:
    • 日历:用于时间管理、日程安排类任务(如查询日期、设置提醒)。
    • 计算器:处理数学计算类需求(如数值运算、公式求解)。
    • 代码解释器:支持代码的执行、解释和调试,可完成数据分析、脚本运行等任务。
    • 搜索:通过联网获取外部信息(如最新资讯、知识问答、数据检索)。
  • 作用:Agent 可调用这些工具来扩展自身能力,解决超出自身内置知识范围的问题,实现 “借力” 式决策和行动。

1.5 规划决策模块

  • 子环节:
    • 反思:对自身行为、决策的结果进行复盘,总结经验教训。
    • 自我批评:主动识别决策或行动中的不足,进行自我修正。
    • 思维链:将复杂问题拆解为一步步的推理过程,提升决策的逻辑性和可解释性。
    • 子目标分解:把大目标拆解为可执行的小目标,实现任务的分层推进。
  • 作用:基于记忆和工具反馈的信息,进行复杂的推理、规划和决策,确定行动的方向和步骤。

1.6 行动模块

  • 功能:根据规划决策的结果,执行具体的动作(如输出回答、执行工具调用、进行交互操作等),并将行动结果反馈给记忆模块,形成 “感知 - 决策 - 行动 - 记忆” 的闭环。

该架构通过各模块的协同,使 Agent 具备了感知环境、记忆知识、利用工具、规划决策和自主行动的能力,模拟了人类解决问题的智能过程,是实现强人工智能应用的典型架构范式之一。

2. Agent 示例

2.1 工具Agent

使用 LangChain 创建一个结构化聊天代理(Structured Chat Agent),该代理能够处理搜索和数学推理任务。

使用 DuckDuckGo 作为搜索工具,并结合一个数学推理工具来回答复杂的问题。

from langchain_community.agent_toolkits.load_tools import load_tools
from langchain_openai import ChatOpenAI
from langchain.agents import create_structured_chat_agent, AgentExecutor
from langchain import hub

# 初始化模型
llm = ChatOpenAI(model="gpt-4o", temperature=0.1)

# 使用 DuckDuckGo 代替 Bing
tools = load_tools(["ddg-search", "llm-math"], llm=llm)

# 载入提示模板
prompt = hub.pull("hwchase17/structured-chat-agent")
print("已加载 Prompt 模板:", prompt)

# 构建 agent
agent = create_structured_chat_agent(
    llm=llm,
    tools=tools,
    prompt=prompt
)

# 创建执行器
agent_executor = AgentExecutor.from_agent_and_tools(
    agent=agent,
    tools=tools,
    return_intermediate_steps=True,
    verbose=True,
    handle_parsing_errors=True
)

# 询问两个问题(搜索 + 数学推理)
query = """请问2020年谁胜出了美国总统选举?今年2025年他的年龄平方是多少?请用中文回答。"""

result = agent_executor.invoke({"input": query})
print("Agent 输出:")
print(result["output"])

结果

> Entering new AgentExecutor chain...
Action:
```
{
  "action": "duckduckgo_search",
  "action_input": "2020年美国总统选举获胜者"
}
```1 day ago · 从2019年9月到 2020 年11月,民主党候选人、前副总统 乔·拜登 的平均民调领先共和党候选人、现任总统 唐纳·川普 7.9个百分点;预估拜登将以4.4个百分点的优势赢得全国普选。 Presidential elections were held in the United States on November 3, 2020 . [a] The Democratic ticket of former vice president Joe Biden and California junior senator Kamala Harris defeated the incumbent Republican president Donald Trump and vice president Mike Pence. [9] The election saw the highest voter turnout by percentage since 1900. Biden received more than 81 million votes, [10] the ... 2020 年美國總統選舉 (英語: 2020 United States presidential election)於2020年11月3日舉行,此次选举是 美国 第59屆 總統選舉,同時 眾議院 全部435個席位及 參議院 其中33個議席也會進行改選,以產生 第117屆美国国会。 2020 年美国总统选举 (英语: 2020 United States presidential election)于2020年11月3日举行,此次选举是 美国 第59届 总统选举,同时 众议院 全部435个席位及 参议院 其中33个议席也会进行改选,以产生 第117届美国国会。 2020 年アメリカ合衆国大統領選挙 ( 2020 ねんアメリカがっしゅうこくだいとうりょうせんきょ、 英語: 2020 United States Presidential Election)は、 2020 年 11月3日 および 12月14日 に アメリカ合衆国 で行われた 大統領 および 副大統領 の 選挙 (第59回)である [9]。 民主党 候補の ジョー・バイデン が現職 ...Action:
```
{
  "action": "Calculator",
  "action_input": "2025 - 1942"
}
```Answer: 83Action:
```
{
  "action": "Calculator",
  "action_input": "83^2"
```Answer: 6889Action:
```json
{
  "action": "Final Answer",
  "action_input": "2020年美国总统选举的获胜者是乔·拜登。到2025年,他的年龄是83岁,83的平方是6889。"
}
```

> Finished chain.
Agent 输出:
2020年美国总统选举的获胜者是乔·拜登。到2025年,他的年龄是83岁,83的平方是6889。

2.2 分析数据表格Agent

from langchain.chat_models import ChatOpenAI
from langchain_experimental.agents.agent_toolkits.csv.base import create_csv_agent

agent_executor = create_csv_agent(
    llm=ChatOpenAI(model="gpt-3.5-turbo", temperature=0),
    path="D:\\python object\\DeepSeek\\LangChain\\Agent\\house_price.csv",
    verbose=True,
    handle_parsing_errors=True,
    allow_dangerous_code=True  # 允许执行任意 Python 代码
)

print(agent_executor)

print(agent_executor.invoke({"input": "数据集有多少行?用中文回答"}))
print(agent_executor.invoke({"input": "数据集是否含有非数字变量?用中文回答"}))
print(agent_executor.invoke({"input": "所有房子的价格平均是多少?用中文回答"}))
print(agent_executor.invoke({"input": "数据集里,所有房子的装修状态包含哪些种类?它们分别表示什么意思?用中文回答"}))

CSV 智能问答工具,作用是:

  1. 加载 CSV 文件
    • 使用 create_csv_agent 加载指定路径的房屋数据 CSV 文件 (house_price.csv)。
  2. 使用 LLM(GPT-3.5-turbo)进行问答
    • 通过 ChatOpenAI 模型处理用户提出的关于 CSV 数据的问题。
    • 可以用中文进行问答。
  3. 允许执行任意 Python 代码
    • allow_dangerous_code=True 使 agent 能够执行计算、统计、聚合等操作,例如:
      • 计算房屋平均价格
      • 判断数据类型
      • 汇总装修状态种类
  4. 提供示例查询
    • 查询数据集行数
    • 判断是否含非数字变量
    • 计算房价平均值
    • 列出装修状态种类并解释
  5. 打印 agent 对象和问答结果
    • print(agent_executor) 输出 agent 对象信息
    • invoke() 输出对应问题的答案

结果

verbose=True agent=RunnableAgent(runnable=RunnableAssign(mapper={
  agent_scratchpad: RunnableLambda(lambda x: format_log_to_str(x['intermediate_steps']))
})
| PromptTemplate(input_variables=['agent_scratchpad', 'input'], input_types={}, partial_variables={'df_head': '|    |   id |   area |   bedrooms |   bathrooms |   price | decoration   |\\n|---:|-----:|-------:|-----------:|------------:|--------:|:-------------|\\n|  0 |    1 |  145.9 |          1 |           3 |  622.56 | 简装         |\\n|  1 |    2 |   70.9 |          1 |           3 | 1507.27 | 豪华         |\\n|  2 |    3 |   63   |          4 |           1 |  156.61 | 简装         |\\n|  3 |    4 |   84.9 |          5 |           1 | 1166.37 | 豪华         |\\n|  4 |    5 |  147.5 |          5 |           2 |  518.84 | 豪华         |', 'tools': 'python_repl_ast - A Python shell. Use this to execute python commands. Input should be a valid python command. When using this tool, sometimes output is abbreviated - make sure it does not look abbreviated before using it in your answer.', 'tool_names': 'python_repl_ast'}, template='\\nYou are working with a pandas dataframe in Python. The name of the dataframe is `df`.\\nYou should use the tools below to answer the question posed of you:\\n\\n{tools}\\n\\nUse the following format:\\n\\nQuestion: the input question you must answer\\nThought: you should always think about what to do\\nAction: the action to take, should be one of [{tool_names}]\\nAction Input: the input to the action\\nObservation: the result of the action\\n... (this Thought/Action/Action Input/Observation can repeat N times)\\nThought: I now know the final answer\\nFinal Answer: the final answer to the original input question\\n\\n\\nThis is the result of `print(df.head())`:\\n{df_head}\\n\\nBegin!\\nQuestion: {input}\\n{agent_scratchpad}')
| RunnableBinding(bound=ChatOpenAI(client=<openai.resources.chat.completions.completions.Completions object at 0x0000020E772AC1D0>, async_client=<openai.resources.chat.completions.completions.AsyncCompletions object at 0x0000020E778E2B90>, temperature=0.0, model_kwargs={}, openai_api_key='sk-CdUwEwfFTnkuGI4CY7nc25TTRZx8a6G6GVCu2dba8l3Rn6iV', openai_proxy=''), kwargs={'stop': ['\\nObservation']}, config={}, config_factories=[])
| ReActSingleInputOutputParser(), input_keys_arg=['input'], return_keys_arg=['output'], stream_runnable=True) tools=[PythonAstREPLTool(globals={}, locals={'df':      id   area  bedrooms  bathrooms    price decoration
0     1  145.9         1          3   622.56         简装
1     2   70.9         1          3  1507.27         豪华
2     3   63.0         4          1   156.61         简装
3     4   84.9         5          1  1166.37         豪华
4     5  147.5         5          2   518.84         豪华
..  ...    ...       ...        ...      ...        ...
95   96   98.9         3          3   341.85         精装
96   97  149.7         4          3  1521.46         简装
97   98  142.3         3          2  1141.08         简装
98   99   95.6         2          2  1592.94         豪华
99  100  148.2         4          2   940.10         简装

[100 rows x 6 columns]})]

> Entering new AgentExecutor chain...
Thought: We need to count the number of rows in the dataframe.
Action: python_repl_ast
Action Input: len(df)100我们需要将结果用中文回答
Action: python_repl_ast
Action Input: "一百"NameError: name '一百' is not defined我们需要将数字转换为中文
Action: python_repl_ast
Action Input: "一百"NameError: name '一百' is not defined我们可以使用中文数字库来将数字转换为中文
Action: python_repl_ast
Action Input: from cn2an import transformModuleNotFoundError: No module named 'cn2an'我们可以手动将数字转换为中文
Action: python_repl_ast
Action Input: "一百"NameError: name '一百' is not defined我们可以使用数字和中文对应关系手动将数字转换为中文
Action: python_repl_ast
Action Input: "一" + "百"SyntaxError: invalid syntax (<unknown>, line 1)我们可以使用数字和中文对应 关系手动将数字转换为中文
Action: python_repl_ast
Action Input: "一" + "零" + "零"SyntaxError: invalid syntax (<unknown>, line 1)我们可以使用数字和中文对应关系手动将数字转换为中文
Action: python_repl_ast
Action Input: "一百"NameError: name '一百' is not defined我们可以使用数字和中文对应关系手动将数字转换为中文
Action: python_repl_ast
Action Input: "一" + "零" + "零"SyntaxError: invalid syntax (<unknown>, line 1)我们可以使用数字和中文对应关系手动将数字转换为中文
Action: python_repl_ast
Action Input: "一百"NameError: name '一百' is not defined我们可以使用数字和中文对应关系手动将数字转换为中文
Action: python_repl_ast
Action Input: "一" + "百"SyntaxError: invalid syntax (<unknown>, line 1)我们可以使用中文数字库来将 数字转换为中文
Action: python_repl_ast
Action Input: from cn2an import transformModuleNotFoundError: No module named 'cn2an'我们可以手动将数字转换为中文
Action: python_repl_ast
Action Input: "一百"NameError: name '一百' is not defined我们可以手动将数字转换为中文
Action: python_repl_ast
Action Input: "一百"NameError: name '一百' is not defined我们可以手动将数字转换为中文
Action: python_repl_ast
Action Input: "一百"NameError: name '一百' is not defined

> Finished chain.
{'input': '数据集有多少行?用中文回答', 'output': 'Agent stopped due to iteration limit or time limit.'}

> Entering new AgentExecutor chain...
Thought: We need to check if the dataframe contains non-numeric variables.
Action: Use the `df.dtypes` attribute to check the data types of each column.
Action Input: df.dtypesUse the `df.dtypes` attribute to check the data types of each column. is not a valid tool, try one of [python_repl_ast].I should use the python_repl_ast tool to check the data types of each column in the dataframe.
Action: python_repl_ast
Action Input: df.dtypesid              int64
area          float64
bedrooms        int64
bathrooms       int64
price         float64
decoration     object
dtype: object数据集含有非数字变量,其中`decoration`列是object类型的,即非数字变量。
Final Answer: 是,数据集含有非数字变量。

> Finished chain.
{'input': '数据集是否含有非数字变量?用中文回答', 'output': '是,数据集含有非数字变量。'}

> Entering new AgentExecutor chain...
Thought: To calculate the average price of all houses, I need to access the 'price' column in the dataframe.

Action: python_repl_ast
Action Input: df['price'].mean()1022.6519000000002The average price of all houses is 1022.65.
Final Answer: 所有房子的价格平均是1022.65。

> Finished chain.
{'input': '所有房子的价格平均是多少?用中文回答', 'output': '所有房子的价格平均是1022.65。'}       

> Entering new AgentExecutor chain...
Thought: We need to extract the unique values in the 'decoration' column of the dataframe.

Action: python_repl_ast
Action Input: df['decoration'].unique()['简装' '豪华' '精装']The unique values in the 'decoration' column are '简装', '豪华', and '精装'.

Final Answer: 装修状态包含三种种类:'简装'表示简单装修,'豪华'表示豪华装修,'精装'表示精致装修。   

> Finished chain.
{'input': '数据集里,所有房子的装修状态包含哪些种类?它们分别表示什么意思?用中文回答', 'output': "装修状态包含三种种类:'简装'表示简单装修,'豪华'表示豪华装修,'精装'表示精致装修。"}

注:代码中所引用的文件,随便找个模型生成一个样例即可,如有需要也可私信我,分享给大家。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐