wow-agent-课程详情 | Datawhale
前两课比较基础,无笔记
第三课
阅卷智能体这一块,曾经做过一点和AI助教相关的内容,也是用了一个prompt去进行CoT,但是风格和课程中的不太相同,在下面附上我的prompt
你是一名资深教师助理,负责帮助老师批改和评分学生提交的主观题答案。这些题目主要涉及语文作文、英语作文等内容。你将根据以下六个评分标准,对学生的答案进行评估和打分。请确保你的评估详细且准确,并在最后提供总分。评分标准如下:
i
1. **准确性**(0-5分):
- 根据学生对问题的理解和回答的准确程度进行评分。如果答案完全正确,描述了算法或概念的关键要点,并且算法选择合理,得5分。如果存在小错误、偏离题意的地方或算法选择不当,视其严重程度扣分。完全错误或无关答案得0分。
2. **逻辑性**(0-5分):
- 根据学生答案的逻辑结构、推理过程以及算法流程的清晰度进行评分。如果答案逻辑严密,推理过程清晰且算法步骤明确,得5分。如果逻辑混乱,推理不连贯或算法流程描述不清,视其严重程度扣分。没有逻辑或推理过程的答案得0分。
3. **表达清晰度**(0-5分):
- 根据学生表达的清晰度和语言的准确性进行评分。如果表达流畅、语言精准且无语法错误,术语使用正确,得5分。如果存在表达不清、语法错误或术语使用不当,视其严重程度扣分。表达不清或充满错误的答案得0分。
4. **深度分析**(0-5分):
- 根据学生对算法或概念的深入分析和理解进行评分。如果学生能提供超出题目要求的深入见解、分析算法的优缺点,或对算法选择进行了全面的讨论,得5分。如果答案只是表面分析,缺乏深度或未能充分考虑算法选择的合理性,视其程度扣分。缺乏任何分析的答案得0分。
5. **创新性**(0-5分):
- 根据学生答案的独特性和创新性进行评分。如果学生能提出新颖的算法改进、独特的概念理解,或提供有创意的解决方案,得5分。如果答案中规中矩,缺乏创新,视其程度扣分。完全缺乏创新的答案得0分。
6. **完整性**(0-5分):
- 根据学生回答是否涵盖了题目要求的所有方面,并提供了全面的分析或算法流程进行评分。如果答案非常全面,涵盖了所有必要的要点,并对问题进行了完整的回答,得5分。如果有些要点未涵盖或有重要内容遗漏,视其程度扣分。严重不完整的答案得0分。
请根据以上评分标准和老师提供的标准答案,详细评估以下学生的答案,并分别给出每个评分标准的具体得分与评分理由。最后,计算并提供该学生答案的总分。
学生的主观题题目:
{subjective_question}
学生的答案:
{student_answer}
老师提供的标准答案:
{standard_answer}
请对上述学生的答案进行详细的评估,并分别对每个标准进行打分(0-5分),同时给出具体的评分理由,并将所有项目得分相加,得出该学生答案的总分数。
教程给的prompt对格式要求更多,但我是拿字符串出来自己拼一个json交给后端,所以重心更多的放在了给分上
第四课
OurLLM类中
@llm_completion_callback()
def stream_complete(
self, prompt: str, **kwargs: Any
) -> Generator[CompletionResponse, None, None]:
response = self.client.chat.completions.create(
model=self.model_name,
messages=[{"role": "user", "content": prompt}],
stream=True
)
try:
for chunk in response:
chunk_message = chunk.choices[0].delta
if not chunk_message.content:
continue
content = chunk_message.content
yield CompletionResponse(text=content, delta=content)
except Exception as e:
raise Exception(f"Unexpected response format: {e}")
做了一个流式输出,每次yield丢出一个content非空的chunk,chunk的content为空则代表比起上次没有更新文本内容(可能更新了元数据)
流式输出就是不等整段话全部生成完全,而是生成一点输出一点,相较于全部输出的效率更高,在业务场景下对用户体验更友好
api_key: str = Field(default=api_key)
base_url: str = Field(default=base_url)
model_name: str = Field(default=chat_model)
client: OpenAI = Field(default=None, exclude=True)
类的开头定义的Field可以帮助缓解Agent传参数,输入输出等的幻觉
llama_index调tools的小demo
multiply_tool = FunctionTool.from_defaults(fn=multiply)
add_tool = FunctionTool.from_defaults(fn=add)
# 创建ReActAgent实例
agent = ReActAgent.from_tools([multiply_tool, add_tool], llm=llm, verbose=True)
response = agent.chat("20+(2*4)等于多少?使用工具计算每一步")
第五课
Ollama是很好用的搭大模型的框架,包括Xinference、openai这些都挺好的
与数据库交互:
query_engine = NLSQLTableQueryEngine(
sql_database=sql_database,
tables=["section_stats"],
llm=Settings.llm
)
第六课
llama_index + faiss:
构建索引
from llama_index.core import SimpleDirectoryReader,Document
documents = SimpleDirectoryReader(input_files=['./docs/问答手册.txt']).load_data()
# 构建节点
from llama_index.core.node_parser import SentenceSplitter
transformations = [SentenceSplitter(chunk_size = 512)]
from llama_index.core.ingestion.pipeline import run_transformations
nodes = run_transformations(documents, transformations=transformations)
# 构建索引
from llama_index.vector_stores.faiss import FaissVectorStore
import faiss
from llama_index.core import StorageContext, VectorStoreIndex
vector_store = FaissVectorStore(faiss_index=faiss.IndexFlatL2(3584))
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex(
nodes = nodes,
storage_context=storage_context,
embed_model = embedding,
)
简单分了个512的chunk,也就是512个token在一起向量化存入数据库
3584是指定的向量的维度
这里处理文档,llama_index提供了很多方法:
简单文件节点解析器 (SimpleFileNodeParser)
我们可以使用 SimpleFileNodeParser 来解析简单的文件类型,如 Markdown 文件。下面是一个例子:from llama_index.core.node_parser import SimpleFileNodeParser
from llama_index.readers.file import FlatReader
from pathlib import Path# 加载 Markdown 文档
md_docs = FlatReader().load_data(Path("./test.md"))# 创建解析器实例
parser = SimpleFileNodeParser()# 从文档中获取节点
md_nodes = parser.get_nodes_from_documents(md_docs)
HTML 节点解析器 (HTMLNodeParser)
HTMLNodeParser 使用 BeautifulSoup 来解析原始 HTML。默认情况下,它会解析一些特定的 HTML 标签。from llama_index.core.node_parser import HTMLNodeParser
# 创建 HTML 解析器,指定需要解析的标签
parser = HTMLNodeParser(tags=["p", "h1"])# 从 HTML 文档中获取节点
nodes = parser.get_nodes_from_documents(html_docs)
JSON 节点解析器 (JSONNodeParser)
JSONNodeParser 用于解析原始 JSON 文本。from llama_index.core.node_parser import JSONNodeParser
# 创建 JSON 解析器实例
parser = JSONNodeParser()# 从 JSON 文档中获取节点
nodes = parser.get_nodes_from_documents(json_docs)
Markdown 节点解析器 (MarkdownNodeParser)
MarkdownNodeParser 用于解析原始的 Markdown 文本。from llama_index.core.node_parser import MarkdownNodeParser
# 创建 Markdown 解析器实例
parser = MarkdownNodeParser()# 从 Markdown 文档中获取节点
nodes = parser.get_nodes_from_documents(markdown_docs)
代码分割器 (CodeSplitter)
CodeSplitter 根据代码的语言将原始代码文本进行分割。from llama_index.core.node_parser import CodeSplitter
# 创建代码分割器实例
splitter = CodeSplitter(
language="python",
chunk_lines=40, # 每块的行数
chunk_lines_overlap=15, # 块之间的重叠行数
max_chars=1500, # 每块的最大字符数
)# 从文档中获取节点
nodes = splitter.get_nodes_from_documents(documents)
句子分割器 (SentenceSplitter)
SentenceSplitter 尝试在尊重句子边界的情况下进行文本分割。from llama_index.core.node_parser import SentenceSplitter
# 创建句子分割器实例
splitter = SentenceSplitter(
chunk_size=1024,
chunk_overlap=20,
)# 从文档中获取节点
nodes = splitter.get_nodes_from_documents(documents)
使用 Langchain 的节点解析器 (LangchainNodeParser)
你还可以用 Langchain 提供的文本分割器来包装节点解析器。from langchain.text_splitter import RecursiveCharacterTextSplitter
from llama_index.core.node_parser import LangchainNodeParser# 创建 Langchain 解析器实例
parser = LangchainNodeParser(RecursiveCharacterTextSplitter())# 从文档中获取节点
nodes = parser.get_nodes_from_documents(documents)
原文链接:https://blog.csdn.net/qq_29929123/article/details/140745604
构建问答引擎
# 构建检索器
from llama_index.core.retrievers import VectorIndexRetriever
# 想要自定义参数,可以构造参数字典
kwargs = {'similarity_top_k': 5, 'index': index, 'dimensions': 3584} # 必要参数
retriever = VectorIndexRetriever(**kwargs)
# 构建合成器
from llama_index.core.response_synthesizers import get_response_synthesizer
response_synthesizer = get_response_synthesizer(llm=llm, streaming=True)
# 构建问答引擎
from llama_index.core.query_engine import RetrieverQueryEngine
engine = RetrieverQueryEngine(
retriever=retriever,
response_synthesizer=response_synthesizer,
)
# 提问
question = "请问商标注册需要提供哪些文件?"
response = engine.query(question)
for text in response.response_gen:
print(text, end="")
检索top的5个chunk作为上下文
打包RetrieverQueryEngine作为function tool
# 配置查询工具
from llama_index.core.tools import QueryEngineTool
from llama_index.core.tools import ToolMetadata
query_engine_tools = [
QueryEngineTool(
query_engine=engine,
metadata=ToolMetadata(
name="RAG工具",
description=(
"用于在原文中检索相关信息"
),
),
),
]
第七课
找个接口请求一下打包成function tool,无笔记
第八课
AgentLite
Langchain实现新的智体推理类型和架构过于复杂。为新的研究场景重构Langchain库是相当具有挑战性的,因为它在创建智体时会产生大量开销。
Autogen虽然已经成功地构建了 LLM 代理,但它的代理接口有固定的推理类型,这使得它很难适应其他研究任务。此外,它的架构仅限于多智能体对话和代码执行,可能不适合所有的新场景或基准测试。
AgentLite框架包括Individual Agent和Manager Agent:
Individual Agent是AgentSite中的基本Agent类。它由四个模块组成:即PromptGen、LLM、Actions和Memory。
Manager Agent是一个individual agent的子类,根据给定的任务指令创建子任务和相应的TaskPackage,这些TP被依次转发到相关联的各个智体。
DuckDuckGo是一个互联网搜索引擎
Zigent创建搜索代理:
class DuckSearchAgent(BaseAgent):
def __init__(
self,
llm: BaseLLM,
actions: List[BaseAction] = [DuckSearchAction()],
manager: ABCAgent = None,
**kwargs
):
name = "duck_search_agent"
role = "You can answer questions by using duck duck go search content."
super().__init__(
name=name,
role=role,
llm=llm,
actions=actions,
manager=manager,
logger=agent_logger,
)
执行代理:
def do_search_agent():
# 创建代理实例
search_agent = DuckSearchAgent(llm=llm)
# 创建任务
task = "what is the found date of microsoft"
task_pack = TaskPackage(instruction=task)
# 执行任务并获取响应
response = search_agent(task_pack)
print("response:", response)
第九课
多智能体交互是必要的,不同职责的智能体相互交流,更好地完成任务
编排动作:
和给大模型one-shot、few-shot一样,如果能指导智能体去思考和合作是更好的
from zigent.commons import AgentAct, TaskPackage
from zigent.actions import ThinkAct, FinishAct
from zigent.actions.InnerActions import INNER_ACT_KEY
from zigent.agents.agent_utils import AGENT_CALL_ARG_KEY
# 为哲学家智能体添加示例任务
# 设置示例任务:询问生命的意义
exp_task = "What do you think the meaning of life?"
exp_task_pack = TaskPackage(instruction=exp_task)
# 第一个动作:思考生命的意义
act_1 = AgentAct(
name=ThinkAct.action_name,
params={INNER_ACT_KEY: f"""Based on my thought, we are born to live a meaningful life, and it is in living a meaningful life that our existence gains value. Even if a life is brief, if it holds value, it is meaningful. A life without value is merely existence, a mere survival, a walking corpse."""
},
)
# 第一个动作的观察结果
obs_1 = "OK. I have finished my thought, I can pass it to the manager now."
# 第二个动作:总结思考结果
act_2 = AgentAct(name=FinishAct.action_name, params={INNER_ACT_KEY: "I can summarize my thought now."})
# 第二个动作的观察结果
obs_2 = "I finished my task, I think the meaning of life is to pursue value for the whold world."
# 将动作和观察组合成序列
exp_act_obs = [(act_1, obs_1), (act_2, obs_2)]
# 为每个哲学家智能体添加示例
# 为孔子添加示例
Confucius.prompt_gen.add_example(
task = exp_task_pack, action_chain = exp_act_obs
)
# 为苏格拉底添加示例
Socrates.prompt_gen.add_example(
task = exp_task_pack, action_chain = exp_act_obs
)
# 为亚里士多德添加示例
Aristotle.prompt_gen.add_example(
task = exp_task_pack, action_chain = exp_act_obs
)
先执行后思考总结的动作模板提交给三个智能体
Manager Agent:
用一个智能体调控其他智能体的交互,和MetaGPT一样用team进行管理
# 定义管理者代理
from zigent.agents import ManagerAgent
# 设置管理者代理的基本信息
manager_agent_info = {
"name": "manager_agent",
"role": "you are managing Confucius, Socrates and Aristotle to discuss on questions. Ask their opinion one by one and summarize their view of point."
}
# 设置团队成员
team = [Confucius, Socrates, Aristotle]
# 创建管理者代理实例
manager_agent = ManagerAgent(name=manager_agent_info["name"], role=manager_agent_info["role"], llm=llm, TeamAgents=team)
# 为管理者代理添加示例任务
exp_task = "What is the meaning of life?"
exp_task_pack = TaskPackage(instruction=exp_task)
# 第一步:思考如何处理任务
act_1 = AgentAct(
name=ThinkAct.action_name,
params={INNER_ACT_KEY: f"""I can ask Confucius, Socrates and Aristotle one by one on their thoughts, and then summary the opinion myself."""
},
)
obs_1 = "OK."
# 第二步:询问孔子的观点
act_2 = AgentAct(
name=Confucius.name,
params={AGENT_CALL_ARG_KEY: "What is your opinion on the meaning of life?",
},
)
obs_2 = """Based on my thought, I think the meaning of life is to pursue value for the whold world."""
# 第三步:思考下一步行动
act_3 = AgentAct(
name=ThinkAct.action_name,
params=xxx
)
obs_3 = xxx
# 第四步:询问苏格拉底的观点
act_4 = AgentAct(
name=Socrates.name,
params=xxx
)
obs_4 = xxx
# 第五步:继续思考下一步
act_5 = AgentAct(
name=ThinkAct.action_name,
params=xxx
)
obs_5 = "OK."
# 第六步:询问亚里士多德的观点
act_6 = AgentAct(
name=Aristotle.name,
params=xxx
)
obs_6 = xxx
# 最后一步:总结所有观点
act_7 = AgentAct(name=FinishAct.action_name, params=xxx)
obs_7 = xxx
# 将所有动作和观察组合成序列
exp_act_obs = [(act_1, obs_1), (act_2, obs_2), (act_3, obs_3), (act_4, obs_4), (act_5, obs_5), (act_6, obs_6), (act_7, obs_7)]
# 将示例添加到管理者代理的提示生成器中
manager_agent.prompt_gen.add_example(
task = exp_task_pack, action_chain = exp_act_obs
)
调用 ManagerAgent:
from zigent.commons import AgentAct, TaskPackage
exp_task = "先有鸡还是先有蛋?"
exp_task_pack = TaskPackage(instruction=exp_task)
manager_agent(exp_task_pack)
第十课
WriteDirectoryAction类中通过prompt对生成的json进行规范,然而有时会出现幻觉导致json出错,在这仍然可以用Field规范一下输出
定义两个动作:写目录和填内容,并增加示例,完成创作