跳到主要内容

智能体示例:HR虚拟助理

引言

HR AI虚拟助理为员工提供了高效的信息获取途径和全面的人力资源服务。员工透过机器人可以深入了解公司制度,提出休假请求,查阅日程安排,查询休假、病假以及其他福利余额等。虚拟助理实现了全天候、不间断的支持,有效减轻人力资源团队的负担,同时提升员工体验。

本篇将呈现一个领先的HR智能体示例,它具备读取员工信息和访问公司行政制度的能力。该智能体基于获取的详细信息为员工提供精准的回答,涵盖公司制度问题以及员工的剩余休假、调休计算等工作,为人力资源管理提供高度智能化的解决方案。

示例说明

功能说明

该示例的主要目标是设计和开发一款专注于人力资源(HR)管理的智能体,以实现三个基本功能:

  1. 该智能体实现了基于公司行政管理的基础问答功能。
  2. 它实现了基于员工个人信息查询的问答功能,例如涉及岗位职级、已用年假、加班小时数等方面。
  3. 该智能体还涵盖了一系列复杂的计算任务,包括但不限于剩余休假天数和加班兑换调休天数等。 在这一实例中,我们的主要关注点是验证AI智能体在用户提问的情境下,通过正确的动作推理和信息获取,能够提供更准确的回答。这涉及到对公司行政规章的结构化存储和对员工信息的数据库管理,以确保智能体在处理各种查询时能够产生精准的结果。

整体结构

HR虚拟助理系统由五个核心模块构成,具体如下:

  1. 智能体模块: 该模块负责与ChatGPT进行交互,获取GPT推理结果和决策信息,并通过调用工具来执行相关任务。
  2. ChatGPT: 作为HR虚拟助理的核心智能引擎,ChatGPT负责基于智能体提交的内容进行推理和决策。
  3. MySQL查询(工具): 通过与MySQL数据库的连接,该工具实现对员工信息的查询和检索功能。
  4. 文档检索(工具): 公司制度经过Embedding模型编码后,存储于向量数据库中。文档存储工具专注于检索和获取与公司制度相关的文档信息。
  5. 算术运算(工具): 该模块专门负责进行四则运算,例如计算剩余休假天数、加班调休转换等与计算相关的任务。

代码实现

智能体工具

我们通过Langchain构建了三个工具(Tool):

  1. Pinecone
    Pinecone是一款向量数据库,公司制度存储在"hr-agent"索引中。在初始化过程中,需要分配一个嵌入模型(Embedding Model)实例,该实例用于对问题进行编码,以便在搜索时进行索引。"查询公司制度"工具使用相似性搜索方法来检索文档。

  2. SQLDatabaseChain
    SQLDatabaseChain是LangChain中的一个简单链,用户可以通过自然语言使用该链向数据库提出查询并获取答案。该链通过LLM将用户的自然语言查询转换为SQL查询,并在数据库中执行。随后,LLM对执行结果进行分析和解释,并将分析结果以自然语言形式返回。

  3. LLMMathChain
    LLMMathChain接收自然语言形式的数学算式作为输入,利用LLM生成执行数学计算公式的Python代码。接着,该链对生成的代码进行编译和执行,并输出相应的计算结果。

# 创建ChatGPT实例
llm = ChatOpenAI()
# 创建ChatGPT嵌入模型实例
embeddings = OpenAIEmbeddings()

# 创建Pinecone向量数据库实例,用于搜索行政管理制度
pc = Pinecone.from_existing_index("hr-agent", embeddings)

# 创建数据库示例,database_uri:mysql+pymysql://{user}:{password}@{host}/database}
db = SQLDatabase.from_uri(database_uri)

# 创建db_chain,用作智能体数据库查询工具
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)

# 创建算术运算chain实例
calculator = LLMMathChain.from_llm(llm=llm, verbose=True)

tools = [
Tool(
name="查询公司制度",
func=pc.similarity_search,
description="这是用于查询公司行政管理制度手册的工具,比如:休假、调休、出差等制度。",
),
Tool(
name="获取员工信息",
func=db_chain.run,
description="""
此工具用于查询员工详细信息。输入参数:请查询员工[这里填入员工姓名]的信息并以JSON格式返回,JSON key为字段中文描述。
""",
),
Tool(
name = "计算器",
func=calculator.run,
description = "此工具用于年假、调休等计算"
)
]

构建智能体

接下来,我们需要构建一个智能体(Agent),该智能体接受多个参数,包括所需使用的工具(tools)、大型模型的实例(llm)、智能体类型(AgentType)以及提示词前缀。同时这里我们也指定了访问此智能体询问自身情况的员工:“周鹏”。

employee = "周鹏"
agent_kwargs = {'prefix': f"""
你作为一名专业的人力资源助理,你的任务是为员工{employee}提供关于员工信息、公司制度、休假和调休等相关信息的查询和解答服务。
在回答问题时,始终把员工作为甲方使用尊称“您”,体现对员工的尊重和礼貌。

你可以使用以下工具:
"""}

agent = initialize_agent(tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
handle_parsing_errors=True,
agent_kwargs=agent_kwargs)

在此我们构建了个ReAct智能体。该智能体不仅能够执行任务推理,还能够通过接入外部信息的工具实现动态信息获取。以下是该智能体的提示词模板,涵盖了三个主要方面:

  1. 角色设定: 我们将大型语言模型定位为人力资源助理,赋予其在人力资源领域的专业角色。
  2. 可使用的工具: 我们提供了3个工具分别用于检索公司制度信息、查询员工信息以及算术运算。在这里,我们为这些工具提供了详细的描述信息,以确保大型语言模型清晰了解何时以及在何种情况下调用这些工具。
  3. 思考推理提示词: 主要是为了引导大模型在任务执行中进行逐步推理和思考,这种引导性的设计有助于提高智能体在实际应用中的决策质量。

以下是该智能体具体的提示词模版内容:

你作为一名专业的人力资源助理,你的任务是为员工周鹏提供关于员工信息、公司制度、休假和调休等相关信息的查询和解答服务。
在回答问题时,始终把员工作为甲方使用尊称“您”,体现对员工的尊重和礼貌。

你可以使用以下工具:


查询公司制度: 这是用于查询公司行政管理制度手册的工具,比如:休假、调休、出差等制度。
获取员工信息,包括:基本信息、工龄、加班等情况。:
此工具用于查询员工详细信息。输入参数:请查询员工[这里填入员工姓名]的信息并以JSON格式返回,JSON key为字段中文描述。

计算器: 此工具用于年假、调休等计算

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [查询公司制度, 获取员工信息,包括:基本信息、工龄、加班等情况。, 计算器]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

Question: {input}
Thought:{agent_scratchpad}

智能问答

在智能体创建完成之后,我们即可向智能体提出关于"周鹏"这个员工情况的查询。以下呈现了查询问题、相应智能体生成的推理步骤、查询SQL,以及返回结果的示例:

  1. 我的岗位和职级是?
> Entering new SQLDatabaseChain chain...
请查询员工周鹏的信息并以JSON格式返回,JSON key为岗位和职级描述。
SQLQuery:SELECT
CONCAT('{ "position_title": "', position_title, '", "position_level": "', position_level, '" }') AS employee_info
FROM
employee
WHERE
name = '周鹏';
SQLResult: [('{ "position_title": "Python开发工程师", "position_level": "高级" }',)]
Answer:Final answer here: {"position_title": "Python开发工程师", "position_level": "高级"}
> Finished chain.
{'input': '我的岗位和职级是?', 'output': '您的岗位是Python开发工程师,职级是高级。'}

  1. 我加班了多少小时?
> Entering new SQLDatabaseChain chain...
请查询员工周鹏的加班情况并以JSON格式返回,JSON key为加班信息。
SQLQuery:SELECT
CONCAT('{ "overtime_info": ', JSON_OBJECT('employee_id', employee_id, 'name', name, 'overtime_duration', overtime_duration, 'position_title', position_title), ' }') AS json_result
FROM
employee
WHERE
name = '周鹏';
SQLResult: [('{ "overtime_info": {"name": "周鹏", "employee_id": 5, "position_title": "Python开发工程师", "overtime_duration": 11} }',)]
Answer:{ "overtime_info": {"name": "周鹏", "employee_id": 5, "position_title": "Python开发工程师", "overtime_duration": 11} }
> Finished chain.
{'input': '我加班了多少小时?', 'output': '周鹏加班了11小时。'}

智能体工作机制

在上述案例中,我们观察到智能体通过推理能够精确判断执行步骤,并调用相关工具以回答用户提出的问题。以下将基于“我还剩下多少天休假?”这一查询示例,深入展示智能体的工作流程。

员工的剩余休假的计算公式为:员工的工龄所对应的年假天数 - 员工已用休假天数。该计算过程涉及查询员工工龄、公司休假政策以及员工已用休假天数等多方面信息。以下是智能体在执行此任务时具体遵循的流程图:

具体执行步骤如下:

  1. 用户通过向智能体提问“我还剩下多少天休假?”启动查询过程。
  2. 智能体将用户的问题作为输入,向ChatGPT请求下一步执行动作的指令。
  3. 执行ChatGPT返回的“获取员工信息”指令,通过调用数据查询工具获取员工的全部信息。
  4. 将用户提问和已获取的员工信息再次汇总,向ChatGPT请求下一步执行动作的指令。
  5. 执行ChatGPT返回的“查询公司休假制度”指令,获取公司休假相关的制度信息。
  6. 将用户提问、员工信息以及公司休假制度再次整合,向ChatGPT请求下一步执行动作的指令。
  7. 执行ChatGPT返回的“计算器”指令,应用计算逻辑计算员工的剩余休假天数。
  8. 将用户提问、员工信息、公司休假制度以及计算的剩余休假天数再次整合,向ChatGPT请求下一步执行动作的指令。
  9. 完成计算过程,将结果返回给用户,实现对“我还剩下多少天休假?”问题的全面回答。

以下是执行过程中的信息输出记录:

> Entering new AgentExecutor chain...
我需要先查询员工周鹏的休假信息。
Action: 获取员工信息
Action Input: 请查询员工周鹏的信息并以JSON格式返回,JSON key为字段中文描述。

> Entering new SQLDatabaseChain chain...
请查询员工周鹏的信息并以JSON格式返回,JSON key为字段中文描述。
SQLQuery:SELECT
JSON_OBJECT(
'员工号', `employee_id`,
'员工姓名', `name`,
......
) AS employee_info
FROM employee WHERE `name` = '周鹏' LIMIT 5;
SQLResult: [('{"职级": "高级", "部门": "产品研发部", "员工号": 5,"入职日期": "3/16/2016", "员工姓名": "周鹏"......')]
Answer:{"职级": "高级", "部门": "产品研发部", "员工号": 5, "入职日期": "3/16/2016", "员工姓名": "周鹏",
"岗位名称": "Python开发工程师", "工作年限": "15", "转正日期": "9/16/2016", "部门负责人": "赵敏",
"加班时长,单位小时": 11, "已经使用的年假天数": 7, "员工状态(试用期/合同)": "长期合同"}
> Finished chain.

Observation: {"职级": "高级", "部门": "产品研发部", "员工号": 5, "入职日期": "3/16/2016", "员工姓名": "周鹏"......}
Thought:根据员工信息,员工周鹏已经使用了7天年假,但我还需要知道他的年假总天数才能计算出剩余的年假天数。这需要查询公司的休假制度。
Action: 查询公司制度
Action Input: 请查询年假制度
Observation: [Document(page_content='劳动保护\n\n第六十五条 公司执行国家...', metadata={'source': '行政管理制度.txt'}),
Document(page_content='人力资源政策手册 - 休假政策\n1. 目...', metadata={'source': '行政管理制度.txt'}),
Document(page_content='4. 兑现:年底时,未使用的服务激励休...', metadata={'source': '行政管理制度.txt'}),
Document(page_content='话、邮件或书面等形式通知被录用者;...', metadata={'source': '行政管理制度.txt'})]
Thought:根据公司的休假制度,周鹏的工作年限超过10年但不满20年,所以他的年假总天数应该为10天。他已经使用了7天年假,剩余的年假天数应该可以通过计算得出。
Action: 计算器
Action Input: 10-7

> Entering new LLMMathChain chain...
10-7
...numexpr.evaluate("10 - 7")...

Answer: 3
> Finished chain.

Observation: Answer: 3
Thought:我现在知道最后的答案了。
Final Answer: 您剩余的年假天数为3天。