init
397
.github/workflows/build-book-en.yaml
vendored
Normal file
@@ -0,0 +1,397 @@
|
||||
# .github/workflows/translate.yml
|
||||
|
||||
name: Translate New and Specific EN Content
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 8 * * *' # 每天 UTC 时间 0 点运行 (北京时间16点)
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
translate-files:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository on the same commit
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Always copy specific root files
|
||||
run: |
|
||||
mkdir -p content/en
|
||||
echo "Force copying specific files..."
|
||||
cp -vf content/cn/_index.md content/en/_index.md || echo "Warning: content/cn/_index.md not found."
|
||||
cp -vf content/cn/about.md content/en/about.md || echo "Warning: content/cn/about.md not found."
|
||||
|
||||
echo "正在处理任意深度子目录下的 _index.md (不使用 nullglob)..."
|
||||
find content/cn/ -type f -name "_index.md" -print0 | while IFS= read -r -d $'\0' src_file; do
|
||||
# src_file 会是例如: content/cn/some/subdir/2025/_index.md
|
||||
# 这一步 find 已经确保了 src_file 是一个实际存在的文件,所以不需要额外的 -f 检查
|
||||
|
||||
relative_path_to_cn_content="${src_file#content/cn/}" # 例如: some/subdir/2025/_index.md
|
||||
|
||||
dest_file="content/en/${relative_path_to_cn_content}"
|
||||
dest_dir=$(dirname "$dest_file")
|
||||
|
||||
echo "找到源文件: $src_file"
|
||||
echo "目标路径: $dest_file"
|
||||
|
||||
# 创建目标目录
|
||||
mkdir -p "$dest_dir"
|
||||
|
||||
# 强制复制
|
||||
cp -vf "$src_file" "$dest_file" || echo "警告: 复制 $src_file 失败。"
|
||||
done
|
||||
|
||||
- name: Sync other new files from cn to en and identify them
|
||||
id: sync_new_files
|
||||
run: |
|
||||
echo "Syncing other new files, ignoring existing ones..."
|
||||
rsync_output_file="rsync_created_files.txt"
|
||||
rsync -avi --ignore-existing --exclude 'about.md' content/cn/ content/en/ | \
|
||||
grep '^>f\S* ' | awk '{print $2}' > "$rsync_output_file"
|
||||
echo "Rsync reported these new files (relative to content/en/):"
|
||||
cat "$rsync_output_file"
|
||||
|
||||
- name: Identify all files to translate
|
||||
id: find_changed_files
|
||||
run: |
|
||||
final_list_file="files_to_translate.txt"
|
||||
temp_list_file="temp_files_to_translate.txt"
|
||||
rsync_created_files="rsync_created_files.txt"
|
||||
en_dir="content/en"
|
||||
> "$temp_list_file"
|
||||
if [ -f "$en_dir/_index.md" ]; then
|
||||
echo "$en_dir/_index.md" >> "$temp_list_file"
|
||||
fi
|
||||
if [ -f "$en_dir/about.md" ]; then
|
||||
echo "$en_dir/about.md" >> "$temp_list_file"
|
||||
fi
|
||||
if [ -s "$rsync_created_files" ]; then
|
||||
while IFS= read -r file_path; do
|
||||
echo "$en_dir/$file_path" >> "$temp_list_file"
|
||||
done < "$rsync_created_files"
|
||||
fi
|
||||
if [ -s "$temp_list_file" ]; then
|
||||
sort -u "$temp_list_file" > "$final_list_file"
|
||||
else
|
||||
> "$final_list_file"
|
||||
fi
|
||||
rm -f "$temp_list_file" "$rsync_created_files"
|
||||
if [ ! -s "$final_list_file" ]; then
|
||||
echo "No files identified for translation."
|
||||
echo "continue=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Found files to translate:"
|
||||
cat "$final_list_file"
|
||||
echo "continue=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Set up Python and Install Dependencies
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Install dependencies
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
run: pip install google-generativeai PyYAML
|
||||
|
||||
- name: Translate changed files using Gemini
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
env:
|
||||
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
||||
run: |
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import yaml # For front matter processing
|
||||
import google.generativeai as genai
|
||||
|
||||
# --- Helper function to strip basic Markdown/HTML for description ---
|
||||
def strip_markdown_html(text):
|
||||
# Remove HTML tags
|
||||
text = re.sub(r'<[^>]+>', '', text)
|
||||
# Remove Markdown images 
|
||||
text = re.sub(r'\!\[.*?\]\(.*?\)', '', text)
|
||||
# Replace Markdown links [text](url) with text (keeping the text)
|
||||
text = re.sub(r'\[(.*?)\]\(.*?\)', r'\1', text)
|
||||
# Remove Markdown heading lines themselves
|
||||
text = re.sub(r'(?m)^\s*#{1,6}\s+.*(\r?\n|$)', '', text)
|
||||
# Remove or replace other common Markdown structural/emphasis characters
|
||||
text = text.replace('**', '').replace('__', '') # Bold
|
||||
text = text.replace('*', '').replace('_', '') # Italic / more bold
|
||||
text = re.sub(r'`(.*?)`', r'\1', text) # Inline code to text
|
||||
# Remove blockquote markers, list markers at line start (EXCEPT numbered for new logic)
|
||||
text = re.sub(r'(?m)^\s*>\s?', '', text)
|
||||
text = re.sub(r'(?m)^\s*[\-\+\*]\s+', '', text) # Keep numbered for now, handle later if needed for general stripping
|
||||
# text = re.sub(r'(?m)^\s*\d+\.\s+', '', text) # Don't strip numbered list markers here
|
||||
# Remove horizontal rules
|
||||
text = re.sub(r'(?m)^\s*(\-\-\-|\*\*\*|\_\_\_)\s*$', '', text)
|
||||
# Normalize whitespace
|
||||
text = re.sub(r'\s+', ' ', text).strip()
|
||||
return text
|
||||
|
||||
# --- Configure Gemini API ---
|
||||
try:
|
||||
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
|
||||
model = genai.GenerativeModel('gemini-1.5-flash-latest')
|
||||
except Exception as e:
|
||||
print(f"Error configuring Gemini API: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
# --- Translation function ---
|
||||
def translate_text(text_to_translate):
|
||||
if not text_to_translate.strip(): return ""
|
||||
prompt = f"""Task: Translate the following Chinese text to English.
|
||||
|
||||
Instructions:
|
||||
1. Preserve all original Markdown formatting meticulously. This includes, but is not limited to:
|
||||
- Headings (e.g., #, ##, ###)
|
||||
- Lists (ordered and unordered, e.g., 1., -, *)
|
||||
- Code blocks (```lang ... ``` or indented)
|
||||
- Inline code (`code`)
|
||||
- Bold text (**text** or __text__)
|
||||
- Italic text (*text* or _text_)
|
||||
- Links ([text](url))
|
||||
- Images ()
|
||||
- Blockquotes (> quote)
|
||||
- Horizontal rules (---, ***) - unless specifically instructed to remove them post-translation.
|
||||
- Tables
|
||||
- HTML tags if present in the original Markdown.
|
||||
2. Ensure line breaks and paragraph structure are maintained as in the original.
|
||||
3. Translate only the textual content. Do not translate code within code blocks or URLs.
|
||||
4. Return *only* the translated English text. Do not include any introductory phrases, explanations, or conversational remarks.
|
||||
|
||||
Chinese Text to Translate:
|
||||
---
|
||||
{text_to_translate}
|
||||
---
|
||||
Translated English Text:"""
|
||||
try:
|
||||
response = model.generate_content(prompt)
|
||||
translated_content = ""
|
||||
if response.parts:
|
||||
for part in response.parts:
|
||||
if hasattr(part, 'text'):
|
||||
translated_content += part.text
|
||||
else: # older versions might directly use response.text
|
||||
translated_content = response.text if hasattr(response, 'text') else ''
|
||||
|
||||
# Handle potential API error structure where response.text might not exist but parts do.
|
||||
# Also, ensure we don't fail if response or response.text is None.
|
||||
if not translated_content and hasattr(response, 'prompt_feedback'):
|
||||
print(f"Warning: Translation might have issues. Prompt feedback: {response.prompt_feedback}")
|
||||
return "" # Or handle as error
|
||||
|
||||
return translated_content.strip() if translated_content else ""
|
||||
|
||||
except Exception as e:
|
||||
print(f"An error occurred during translation: {e}")
|
||||
if hasattr(e, 'response') and hasattr(e.response, 'prompt_feedback'):
|
||||
print(f"Prompt Feedback: {e.response.prompt_feedback}")
|
||||
return None
|
||||
|
||||
# --- Main processing loop ---
|
||||
with open('files_to_translate.txt', 'r', encoding='utf-8') as f:
|
||||
files_to_translate = [line.strip() for line in f if line.strip()]
|
||||
|
||||
if not files_to_translate:
|
||||
print("No files listed in files_to_translate.txt. Exiting translation script.")
|
||||
sys.exit(0)
|
||||
|
||||
for filepath in files_to_translate:
|
||||
print(f"Processing file: {filepath}")
|
||||
if not os.path.exists(filepath):
|
||||
print(f" - Warning: File {filepath} not found. Skipping.")
|
||||
continue
|
||||
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
parts = content.split('---', 2)
|
||||
|
||||
if len(parts) == 3:
|
||||
front_matter_str_content = parts[1]
|
||||
body_to_translate = parts[2]
|
||||
|
||||
parsed_fm = {}
|
||||
fm_parse_success = False
|
||||
if front_matter_str_content.strip():
|
||||
try:
|
||||
loaded_fm = yaml.safe_load(front_matter_str_content)
|
||||
if isinstance(loaded_fm, dict):
|
||||
parsed_fm = loaded_fm
|
||||
fm_parse_success = True
|
||||
else:
|
||||
print(f" - Warning: Front matter in {filepath} is valid YAML but not a dictionary. FM modifications will be skipped.")
|
||||
except yaml.YAMLError as ye:
|
||||
print(f" - Error parsing YAML front matter in {filepath}: {ye}. FM modifications will be skipped.")
|
||||
else: # Empty front matter section (e.g. "--- \n ---")
|
||||
fm_parse_success = True
|
||||
|
||||
if not body_to_translate.strip():
|
||||
print(f" - Body of {filepath} is empty. Skipping translation, but will process front matter.")
|
||||
translated_body = ""
|
||||
else:
|
||||
print(" - Translating body...")
|
||||
translated_body = translate_text(body_to_translate)
|
||||
|
||||
if translated_body is None:
|
||||
print(f" - Failed to translate body for file: {filepath}. Skipping update for this file.")
|
||||
continue
|
||||
|
||||
# Requirement 1: Remove "---" from translated body content
|
||||
if translated_body.strip().startswith("---"):
|
||||
idx = translated_body.find("---")
|
||||
translated_body = translated_body[idx + 3:].lstrip()
|
||||
if translated_body.strip().endswith("---"):
|
||||
idx = translated_body.rfind("---")
|
||||
translated_body = translated_body[:idx].rstrip()
|
||||
|
||||
# --- Front Matter Modifications ---
|
||||
if fm_parse_success:
|
||||
base_fn = os.path.basename(filepath)
|
||||
|
||||
# Requirement 2.1: Title update specific to date files
|
||||
date_file_match = re.match(r"(\d{4})-(\d{2})-(\d{2})(?:[._-].*|\.md$)", base_fn)
|
||||
if date_file_match:
|
||||
year, month, day = date_file_match.groups() # Capture year, month, and day
|
||||
print(f" - Applying 'MM-DD-Daily' title rule for date file: {base_fn}")
|
||||
parsed_fm['title'] = f"{month}-{day}-Daily" # Use month and day
|
||||
|
||||
# NEW: Update 'next' field for _index.md
|
||||
if base_fn == "_index.md":
|
||||
if 'next' in parsed_fm and isinstance(parsed_fm.get('next'), str):
|
||||
current_next_val = parsed_fm['next']
|
||||
if current_next_val and not current_next_val.startswith('/en/'):
|
||||
# Prepend /en, ensuring no double slashes if current_next_val starts with /
|
||||
if current_next_val.startswith('/'):
|
||||
parsed_fm['next'] = '/en' + current_next_val
|
||||
else:
|
||||
parsed_fm['next'] = '/en/' + current_next_val
|
||||
print(f" - Updated 'next' field for _index.md to: {parsed_fm['next']}")
|
||||
elif not current_next_val:
|
||||
print(f" - 'next' field in _index.md is empty. Not modifying.")
|
||||
else:
|
||||
print(f" - 'next' field for _index.md already correctly prefixed or does not need update.")
|
||||
else:
|
||||
print(f" - 'next' field not found or not a string in _index.md front matter. Not modifying.")
|
||||
|
||||
# Requirement 2.2: Description update
|
||||
# NEW: Skip description update for about.md
|
||||
if base_fn == "about.md":
|
||||
print(f" - Skipping description update for {base_fn}")
|
||||
else:
|
||||
print(f" - Attempting to update description for: {base_fn} (from '1.' list item)")
|
||||
description_content_found = False
|
||||
# NEW: Regex to find the first numbered list item "1. " and capture its content
|
||||
numbered_list_match = re.search(r"^\s*1\.\s+(.*)", translated_body, re.MULTILINE)
|
||||
|
||||
if numbered_list_match:
|
||||
text_from_list_item = numbered_list_match.group(1).strip()
|
||||
if text_from_list_item: # Ensure the item itself isn't empty after "1. "
|
||||
plain_text_for_desc = strip_markdown_html(text_from_list_item)
|
||||
new_description = plain_text_for_desc[:297] # Truncate for "..."
|
||||
if len(plain_text_for_desc) > 300:
|
||||
new_description += "..."
|
||||
|
||||
if new_description: # Only set description if plain_text_for_desc is not empty
|
||||
parsed_fm['description'] = new_description
|
||||
description_content_found = True
|
||||
log_description_preview = new_description[:50].replace('\n', ' ')
|
||||
print(f" - Updated description from '1.' list item to: '{log_description_preview}...'")
|
||||
|
||||
if not description_content_found:
|
||||
if 'description' in parsed_fm:
|
||||
# If _index.md specifically should have description: '', this handles it
|
||||
# if no content from "1." is found for it.
|
||||
parsed_fm['description'] = ""
|
||||
print(f" - No valid content from '1.' list item. Cleared/set existing description to empty for {base_fn}.")
|
||||
else:
|
||||
# If the file is _index.md and it didn't have a description key,
|
||||
# and we want to enforce description: '' as per example:
|
||||
if base_fn == "_index.md":
|
||||
parsed_fm['description'] = ""
|
||||
print(f" - No valid content from '1.' list item. Set 'description: \"\"' for _index.md as per default.")
|
||||
else:
|
||||
print(f" - No valid content from '1.' list item. 'description' key not present and not added for {base_fn}.") # Corrected variable base_fm to base_fn
|
||||
# --- End of Front Matter Modifications ---
|
||||
|
||||
final_front_matter_str = ""
|
||||
if fm_parse_success and parsed_fm: # Only dump if parsing was successful and there's data
|
||||
try:
|
||||
# Ensure no "---" inside FM values
|
||||
for key, value in parsed_fm.items():
|
||||
if isinstance(value, str):
|
||||
parsed_fm[key] = value.replace('---', '')
|
||||
|
||||
final_front_matter_str = yaml.dump(
|
||||
parsed_fm,
|
||||
sort_keys=False,
|
||||
allow_unicode=True,
|
||||
Dumper=yaml.SafeDumper,
|
||||
default_flow_style=False
|
||||
).strip()
|
||||
except Exception as e_dump:
|
||||
print(f" - Error dumping YAML for {filepath}: {e_dump}. Using original front matter content if available.")
|
||||
final_front_matter_str = front_matter_str_content.strip() # Fallback
|
||||
elif front_matter_str_content.strip(): # FM parsing failed, but there was original FM
|
||||
final_front_matter_str = front_matter_str_content.strip()
|
||||
|
||||
# Assemble the new content
|
||||
if not final_front_matter_str and not translated_body.strip():
|
||||
new_content = "" # Completely empty file if nothing to write
|
||||
print(f" - Resulting file {filepath} would be empty. Writing empty file.")
|
||||
elif not final_front_matter_str: # No front matter, only body
|
||||
new_content = translated_body.lstrip()
|
||||
elif not translated_body.strip(): # Front matter, but no body
|
||||
new_content = f"---\n{final_front_matter_str}\n---"
|
||||
else: # Both front matter and body exist
|
||||
new_content = f"---\n{final_front_matter_str}\n---\n{translated_body.lstrip()}"
|
||||
|
||||
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(new_content)
|
||||
print(f" - Successfully translated and updated file: {filepath}")
|
||||
|
||||
else: # len(parts) != 3 (No valid Hugo front matter delimiter)
|
||||
print(f" - Could not find Hugo front matter delimiter (---) correctly in {filepath}. Attempting to translate whole file as body.")
|
||||
# Fallback: Translate the whole content if no delimiters found
|
||||
if not content.strip():
|
||||
print(f" - File {filepath} is empty. Skipping.")
|
||||
continue
|
||||
|
||||
translated_whole_body = translate_text(content)
|
||||
if translated_whole_body is None:
|
||||
print(f" - Failed to translate whole body for file: {filepath}. Skipping update.")
|
||||
continue
|
||||
|
||||
if translated_whole_body.strip().startswith("---"):
|
||||
idx = translated_whole_body.find("---")
|
||||
translated_whole_body = translated_whole_body[idx + 3:].lstrip()
|
||||
if translated_whole_body.strip().endswith("---"):
|
||||
idx = translated_whole_body.rfind("---")
|
||||
translated_whole_body = translated_whole_body[:idx].rstrip()
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(translated_whole_body)
|
||||
print(f" - Successfully translated whole file (no front matter found): {filepath}")
|
||||
|
||||
except Exception as e:
|
||||
print(f" - An error occurred while processing file {filepath}: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
shell: python
|
||||
|
||||
- name: Commit and push changes
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "chore(i18n): Auto-translate EN content with FM updates"
|
||||
file_pattern: "content/en/"
|
||||
commit_user_name: "GitHub Actions Bot"
|
||||
commit_user_email: "actions@github.com"
|
||||
397
.github/workflows/build-book-fr.yaml
vendored
Normal file
@@ -0,0 +1,397 @@
|
||||
# .github/workflows/translate.yml
|
||||
|
||||
name: Translate New and Specific FR Content
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 7 * * *' # 每天 UTC 时间 0 点运行 (北京时间15点)
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
translate-files:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository on the same commit
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Always copy specific root files
|
||||
run: |
|
||||
mkdir -p content/fr
|
||||
echo "Force copying specific files..."
|
||||
cp -vf content/cn/_index.md content/fr/_index.md || echo "Warning: content/cn/_index.md not found."
|
||||
cp -vf content/cn/about.md content/fr/about.md || echo "Warning: content/cn/about.md not found."
|
||||
|
||||
echo "正在处理任意深度子目录下的 _index.md (不使用 nullglob)..."
|
||||
find content/cn/ -type f -name "_index.md" -print0 | while IFS= read -r -d $'\0' src_file; do
|
||||
# src_file 会是例如: content/cn/some/subdir/2025/_index.md
|
||||
# 这一步 find 已经确保了 src_file 是一个实际存在的文件,所以不需要额外的 -f 检查
|
||||
|
||||
relative_path_to_cn_content="${src_file#content/cn/}" # 例如: some/subdir/2025/_index.md
|
||||
|
||||
dest_file="content/fr/${relative_path_to_cn_content}"
|
||||
dest_dir=$(dirname "$dest_file")
|
||||
|
||||
echo "找到源文件: $src_file"
|
||||
echo "目标路径: $dest_file"
|
||||
|
||||
# 创建目标目录
|
||||
mkdir -p "$dest_dir"
|
||||
|
||||
# 强制复制
|
||||
cp -vf "$src_file" "$dest_file" || echo "警告: 复制 $src_file 失败。"
|
||||
done
|
||||
|
||||
- name: Sync other new files from cn to en and identify them
|
||||
id: sync_new_files
|
||||
run: |
|
||||
echo "Syncing other new files, ignoring existing ones..."
|
||||
rsync_output_file="rsync_created_files.txt"
|
||||
rsync -avi --ignore-existing --exclude 'about.md' content/cn/ content/fr/ | \
|
||||
grep '^>f\S* ' | awk '{print $2}' > "$rsync_output_file"
|
||||
echo "Rsync reported these new files (relative to content/fr/):"
|
||||
cat "$rsync_output_file"
|
||||
|
||||
- name: Identify all files to translate
|
||||
id: find_changed_files
|
||||
run: |
|
||||
final_list_file="files_to_translate.txt"
|
||||
temp_list_file="temp_files_to_translate.txt"
|
||||
rsync_created_files="rsync_created_files.txt"
|
||||
en_dir="content/fr"
|
||||
> "$temp_list_file"
|
||||
if [ -f "$en_dir/_index.md" ]; then
|
||||
echo "$en_dir/_index.md" >> "$temp_list_file"
|
||||
fi
|
||||
if [ -f "$en_dir/about.md" ]; then
|
||||
echo "$en_dir/about.md" >> "$temp_list_file"
|
||||
fi
|
||||
if [ -s "$rsync_created_files" ]; then
|
||||
while IFS= read -r file_path; do
|
||||
echo "$en_dir/$file_path" >> "$temp_list_file"
|
||||
done < "$rsync_created_files"
|
||||
fi
|
||||
if [ -s "$temp_list_file" ]; then
|
||||
sort -u "$temp_list_file" > "$final_list_file"
|
||||
else
|
||||
> "$final_list_file"
|
||||
fi
|
||||
rm -f "$temp_list_file" "$rsync_created_files"
|
||||
if [ ! -s "$final_list_file" ]; then
|
||||
echo "No files identified for translation."
|
||||
echo "continue=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Found files to translate:"
|
||||
cat "$final_list_file"
|
||||
echo "continue=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Set up Python and Install Dependencies
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Install dependencies
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
run: pip install google-generativeai PyYAML
|
||||
|
||||
- name: Translate changed files using Gemini
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
env:
|
||||
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
||||
run: |
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import yaml # For front matter processing
|
||||
import google.generativeai as genai
|
||||
|
||||
# --- Helper function to strip basic Markdown/HTML for description ---
|
||||
def strip_markdown_html(text):
|
||||
# Remove HTML tags
|
||||
text = re.sub(r'<[^>]+>', '', text)
|
||||
# Remove Markdown images 
|
||||
text = re.sub(r'\!\[.*?\]\(.*?\)', '', text)
|
||||
# Replace Markdown links [text](url) with text (keeping the text)
|
||||
text = re.sub(r'\[(.*?)\]\(.*?\)', r'\1', text)
|
||||
# Remove Markdown heading lines themselves
|
||||
text = re.sub(r'(?m)^\s*#{1,6}\s+.*(\r?\n|$)', '', text)
|
||||
# Remove or replace other common Markdown structural/emphasis characters
|
||||
text = text.replace('**', '').replace('__', '') # Bold
|
||||
text = text.replace('*', '').replace('_', '') # Italic / more bold
|
||||
text = re.sub(r'`(.*?)`', r'\1', text) # Inline code to text
|
||||
# Remove blockquote markers, list markers at line start (EXCEPT numbered for new logic)
|
||||
text = re.sub(r'(?m)^\s*>\s?', '', text)
|
||||
text = re.sub(r'(?m)^\s*[\-\+\*]\s+', '', text) # Keep numbered for now, handle later if needed for general stripping
|
||||
# text = re.sub(r'(?m)^\s*\d+\.\s+', '', text) # Don't strip numbered list markers here
|
||||
# Remove horizontal rules
|
||||
text = re.sub(r'(?m)^\s*(\-\-\-|\*\*\*|\_\_\_)\s*$', '', text)
|
||||
# Normalize whitespace
|
||||
text = re.sub(r'\s+', ' ', text).strip()
|
||||
return text
|
||||
|
||||
# --- Configure Gemini API ---
|
||||
try:
|
||||
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
|
||||
model = genai.GenerativeModel('gemini-1.5-flash-latest')
|
||||
except Exception as e:
|
||||
print(f"Error configuring Gemini API: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
# --- Translation function ---
|
||||
def translate_text(text_to_translate):
|
||||
if not text_to_translate.strip(): return ""
|
||||
prompt = f"""Task: Translate the following Chinese text to French.
|
||||
|
||||
Instructions:
|
||||
1. Preserve all original Markdown formatting meticulously. This includes, but is not limited to:
|
||||
- Headings (e.g., #, ##, ###)
|
||||
- Lists (ordered and unordered, e.g., 1., -, *)
|
||||
- Code blocks (```lang ... ``` or indented)
|
||||
- Inline code (`code`)
|
||||
- Bold text (**text** or __text__)
|
||||
- Italic text (*text* or _text_)
|
||||
- Links ([text](url))
|
||||
- Images ()
|
||||
- Blockquotes (> quote)
|
||||
- Horizontal rules (---, ***) - unless specifically instructed to remove them post-translation.
|
||||
- Tables
|
||||
- HTML tags if present in the original Markdown.
|
||||
2. Ensure line breaks and paragraph structure are maintained as in the original.
|
||||
3. Translate only the textual content. Do not translate code within code blocks or URLs.
|
||||
4. Return *only* the translated French text. Do not include any introductory phrases, explanations, or conversational remarks.
|
||||
|
||||
Chinese Text to Translate:
|
||||
---
|
||||
{text_to_translate}
|
||||
---
|
||||
Translated French Text:"""
|
||||
try:
|
||||
response = model.generate_content(prompt)
|
||||
translated_content = ""
|
||||
if response.parts:
|
||||
for part in response.parts:
|
||||
if hasattr(part, 'text'):
|
||||
translated_content += part.text
|
||||
else: # older versions might directly use response.text
|
||||
translated_content = response.text if hasattr(response, 'text') else ''
|
||||
|
||||
# Handle potential API error structure where response.text might not exist but parts do.
|
||||
# Also, ensure we don't fail if response or response.text is None.
|
||||
if not translated_content and hasattr(response, 'prompt_feedback'):
|
||||
print(f"Warning: Translation might have issues. Prompt feedback: {response.prompt_feedback}")
|
||||
return "" # Or handle as error
|
||||
|
||||
return translated_content.strip() if translated_content else ""
|
||||
|
||||
except Exception as e:
|
||||
print(f"An error occurred during translation: {e}")
|
||||
if hasattr(e, 'response') and hasattr(e.response, 'prompt_feedback'):
|
||||
print(f"Prompt Feedback: {e.response.prompt_feedback}")
|
||||
return None
|
||||
|
||||
# --- Main processing loop ---
|
||||
with open('files_to_translate.txt', 'r', encoding='utf-8') as f:
|
||||
files_to_translate = [line.strip() for line in f if line.strip()]
|
||||
|
||||
if not files_to_translate:
|
||||
print("No files listed in files_to_translate.txt. Exiting translation script.")
|
||||
sys.exit(0)
|
||||
|
||||
for filepath in files_to_translate:
|
||||
print(f"Processing file: {filepath}")
|
||||
if not os.path.exists(filepath):
|
||||
print(f" - Warning: File {filepath} not found. Skipping.")
|
||||
continue
|
||||
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
parts = content.split('---', 2)
|
||||
|
||||
if len(parts) == 3:
|
||||
front_matter_str_content = parts[1]
|
||||
body_to_translate = parts[2]
|
||||
|
||||
parsed_fm = {}
|
||||
fm_parse_success = False
|
||||
if front_matter_str_content.strip():
|
||||
try:
|
||||
loaded_fm = yaml.safe_load(front_matter_str_content)
|
||||
if isinstance(loaded_fm, dict):
|
||||
parsed_fm = loaded_fm
|
||||
fm_parse_success = True
|
||||
else:
|
||||
print(f" - Warning: Front matter in {filepath} is valid YAML but not a dictionary. FM modifications will be skipped.")
|
||||
except yaml.YAMLError as ye:
|
||||
print(f" - Error parsing YAML front matter in {filepath}: {ye}. FM modifications will be skipped.")
|
||||
else: # Empty front matter section (e.g. "--- \n ---")
|
||||
fm_parse_success = True
|
||||
|
||||
if not body_to_translate.strip():
|
||||
print(f" - Body of {filepath} is empty. Skipping translation, but will process front matter.")
|
||||
translated_body = ""
|
||||
else:
|
||||
print(" - Translating body...")
|
||||
translated_body = translate_text(body_to_translate)
|
||||
|
||||
if translated_body is None:
|
||||
print(f" - Failed to translate body for file: {filepath}. Skipping update for this file.")
|
||||
continue
|
||||
|
||||
# Requirement 1: Remove "---" from translated body content
|
||||
if translated_body.strip().startswith("---"):
|
||||
idx = translated_body.find("---")
|
||||
translated_body = translated_body[idx + 3:].lstrip()
|
||||
if translated_body.strip().endswith("---"):
|
||||
idx = translated_body.rfind("---")
|
||||
translated_body = translated_body[:idx].rstrip()
|
||||
|
||||
# --- Front Matter Modifications ---
|
||||
if fm_parse_success:
|
||||
base_fn = os.path.basename(filepath)
|
||||
|
||||
# Requirement 2.1: Title update specific to date files
|
||||
date_file_match = re.match(r"(\d{4})-(\d{2})-(\d{2})(?:[._-].*|\.md$)", base_fn)
|
||||
if date_file_match:
|
||||
year, month, day = date_file_match.groups() # Capture year, month, and day
|
||||
print(f" - Applying 'MM-DD-Daily' title rule for date file: {base_fn}")
|
||||
parsed_fm['title'] = f"{month}-{day}-Daily" # Use month and day
|
||||
|
||||
# NEW: Update 'next' field for _index.md
|
||||
if base_fn == "_index.md":
|
||||
if 'next' in parsed_fm and isinstance(parsed_fm.get('next'), str):
|
||||
current_next_val = parsed_fm['next']
|
||||
if current_next_val and not current_next_val.startswith('/fr/'):
|
||||
# Prepend /fr, ensuring no double slashes if current_next_val starts with /
|
||||
if current_next_val.startswith('/'):
|
||||
parsed_fm['next'] = '/fr' + current_next_val
|
||||
else:
|
||||
parsed_fm['next'] = '/fr/' + current_next_val
|
||||
print(f" - Updated 'next' field for _index.md to: {parsed_fm['next']}")
|
||||
elif not current_next_val:
|
||||
print(f" - 'next' field in _index.md is empty. Not modifying.")
|
||||
else:
|
||||
print(f" - 'next' field for _index.md already correctly prefixed or does not need update.")
|
||||
else:
|
||||
print(f" - 'next' field not found or not a string in _index.md front matter. Not modifying.")
|
||||
|
||||
# Requirement 2.2: Description update
|
||||
# NEW: Skip description update for about.md
|
||||
if base_fn == "about.md":
|
||||
print(f" - Skipping description update for {base_fn}")
|
||||
else:
|
||||
print(f" - Attempting to update description for: {base_fn} (from '1.' list item)")
|
||||
description_content_found = False
|
||||
# NEW: Regex to find the first numbered list item "1. " and capture its content
|
||||
numbered_list_match = re.search(r"^\s*1\.\s+(.*)", translated_body, re.MULTILINE)
|
||||
|
||||
if numbered_list_match:
|
||||
text_from_list_item = numbered_list_match.group(1).strip()
|
||||
if text_from_list_item: # Ensure the item itself isn't empty after "1. "
|
||||
plain_text_for_desc = strip_markdown_html(text_from_list_item)
|
||||
new_description = plain_text_for_desc[:297] # Truncate for "..."
|
||||
if len(plain_text_for_desc) > 300:
|
||||
new_description += "..."
|
||||
|
||||
if new_description: # Only set description if plain_text_for_desc is not empty
|
||||
parsed_fm['description'] = new_description
|
||||
description_content_found = True
|
||||
log_description_preview = new_description[:50].replace('\n', ' ')
|
||||
print(f" - Updated description from '1.' list item to: '{log_description_preview}...'")
|
||||
|
||||
if not description_content_found:
|
||||
if 'description' in parsed_fm:
|
||||
# If _index.md specifically should have description: '', this handles it
|
||||
# if no content from "1." is found for it.
|
||||
parsed_fm['description'] = ""
|
||||
print(f" - No valid content from '1.' list item. Cleared/set existing description to empty for {base_fn}.")
|
||||
else:
|
||||
# If the file is _index.md and it didn't have a description key,
|
||||
# and we want to enforce description: '' as per example:
|
||||
if base_fn == "_index.md":
|
||||
parsed_fm['description'] = ""
|
||||
print(f" - No valid content from '1.' list item. Set 'description: \"\"' for _index.md as per default.")
|
||||
else:
|
||||
print(f" - No valid content from '1.' list item. 'description' key not present and not added for {base_fn}.") # Corrected variable base_fm to base_fn
|
||||
# --- End of Front Matter Modifications ---
|
||||
|
||||
final_front_matter_str = ""
|
||||
if fm_parse_success and parsed_fm: # Only dump if parsing was successful and there's data
|
||||
try:
|
||||
# Ensure no "---" inside FM values
|
||||
for key, value in parsed_fm.items():
|
||||
if isinstance(value, str):
|
||||
parsed_fm[key] = value.replace('---', '')
|
||||
|
||||
final_front_matter_str = yaml.dump(
|
||||
parsed_fm,
|
||||
sort_keys=False,
|
||||
allow_unicode=True,
|
||||
Dumper=yaml.SafeDumper,
|
||||
default_flow_style=False
|
||||
).strip()
|
||||
except Exception as e_dump:
|
||||
print(f" - Error dumping YAML for {filepath}: {e_dump}. Using original front matter content if available.")
|
||||
final_front_matter_str = front_matter_str_content.strip() # Fallback
|
||||
elif front_matter_str_content.strip(): # FM parsing failed, but there was original FM
|
||||
final_front_matter_str = front_matter_str_content.strip()
|
||||
|
||||
# Assemble the new content
|
||||
if not final_front_matter_str and not translated_body.strip():
|
||||
new_content = "" # Completely empty file if nothing to write
|
||||
print(f" - Resulting file {filepath} would be empty. Writing empty file.")
|
||||
elif not final_front_matter_str: # No front matter, only body
|
||||
new_content = translated_body.lstrip()
|
||||
elif not translated_body.strip(): # Front matter, but no body
|
||||
new_content = f"---\n{final_front_matter_str}\n---"
|
||||
else: # Both front matter and body exist
|
||||
new_content = f"---\n{final_front_matter_str}\n---\n{translated_body.lstrip()}"
|
||||
|
||||
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(new_content)
|
||||
print(f" - Successfully translated and updated file: {filepath}")
|
||||
|
||||
else: # len(parts) != 3 (No valid Hugo front matter delimiter)
|
||||
print(f" - Could not find Hugo front matter delimiter (---) correctly in {filepath}. Attempting to translate whole file as body.")
|
||||
# Fallback: Translate the whole content if no delimiters found
|
||||
if not content.strip():
|
||||
print(f" - File {filepath} is empty. Skipping.")
|
||||
continue
|
||||
|
||||
translated_whole_body = translate_text(content)
|
||||
if translated_whole_body is None:
|
||||
print(f" - Failed to translate whole body for file: {filepath}. Skipping update.")
|
||||
continue
|
||||
|
||||
if translated_whole_body.strip().startswith("---"):
|
||||
idx = translated_whole_body.find("---")
|
||||
translated_whole_body = translated_whole_body[idx + 3:].lstrip()
|
||||
if translated_whole_body.strip().endswith("---"):
|
||||
idx = translated_whole_body.rfind("---")
|
||||
translated_whole_body = translated_whole_body[:idx].rstrip()
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(translated_whole_body)
|
||||
print(f" - Successfully translated whole file (no front matter found): {filepath}")
|
||||
|
||||
except Exception as e:
|
||||
print(f" - An error occurred while processing file {filepath}: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
shell: python
|
||||
|
||||
- name: Commit and push changes
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "chore(i18n): Auto-translate EN content with FM updates"
|
||||
file_pattern: "content/fr/"
|
||||
commit_user_name: "GitHub Actions Bot"
|
||||
commit_user_email: "actions@github.com"
|
||||
398
.github/workflows/build-book-ja.yaml
vendored
Normal file
@@ -0,0 +1,398 @@
|
||||
# .github/workflows/translate.yml
|
||||
|
||||
name: Translate New and Specific JA Content
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 23 * * *' # 每天 UTC 时间 0 点运行 (北京时间早上7点)
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
translate-files:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository on the same commit
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Always copy specific root files
|
||||
run: |
|
||||
mkdir -p content/ja
|
||||
echo "Force copying specific files..."
|
||||
cp -vf content/cn/_index.md content/ja/_index.md || echo "Warning: content/cn/_index.md not found."
|
||||
cp -vf content/cn/about.md content/ja/about.md || echo "Warning: content/cn/about.md not found."
|
||||
|
||||
echo "正在处理任意深度子目录下的 _index.md (不使用 nullglob)..."
|
||||
find content/cn/ -type f -name "_index.md" -print0 | while IFS= read -r -d $'\0' src_file; do
|
||||
# src_file 会是例如: content/cn/some/subdir/2025/_index.md
|
||||
# 这一步 find 已经确保了 src_file 是一个实际存在的文件,所以不需要额外的 -f 检查
|
||||
|
||||
relative_path_to_cn_content="${src_file#content/cn/}" # 例如: some/subdir/2025/_index.md
|
||||
|
||||
dest_file="content/ja/${relative_path_to_cn_content}"
|
||||
dest_dir=$(dirname "$dest_file")
|
||||
|
||||
echo "找到源文件: $src_file"
|
||||
echo "目标路径: $dest_file"
|
||||
|
||||
# 创建目标目录
|
||||
mkdir -p "$dest_dir"
|
||||
|
||||
# 强制复制
|
||||
cp -vf "$src_file" "$dest_file" || echo "警告: 复制 $src_file 失败。"
|
||||
done
|
||||
|
||||
|
||||
- name: Sync other new files from cn to en and identify them
|
||||
id: sync_new_files
|
||||
run: |
|
||||
echo "Syncing other new files, ignoring existing ones..."
|
||||
rsync_output_file="rsync_created_files.txt"
|
||||
rsync -avi --ignore-existing --exclude 'about.md' content/cn/ content/ja/ | \
|
||||
grep '^>f\S* ' | awk '{print $2}' > "$rsync_output_file"
|
||||
echo "Rsync reported these new files (relative to content/ja/):"
|
||||
cat "$rsync_output_file"
|
||||
|
||||
- name: Identify all files to translate
|
||||
id: find_changed_files
|
||||
run: |
|
||||
final_list_file="files_to_translate.txt"
|
||||
temp_list_file="temp_files_to_translate.txt"
|
||||
rsync_created_files="rsync_created_files.txt"
|
||||
en_dir="content/ja"
|
||||
> "$temp_list_file"
|
||||
if [ -f "$en_dir/_index.md" ]; then
|
||||
echo "$en_dir/_index.md" >> "$temp_list_file"
|
||||
fi
|
||||
if [ -f "$en_dir/about.md" ]; then
|
||||
echo "$en_dir/about.md" >> "$temp_list_file"
|
||||
fi
|
||||
if [ -s "$rsync_created_files" ]; then
|
||||
while IFS= read -r file_path; do
|
||||
echo "$en_dir/$file_path" >> "$temp_list_file"
|
||||
done < "$rsync_created_files"
|
||||
fi
|
||||
if [ -s "$temp_list_file" ]; then
|
||||
sort -u "$temp_list_file" > "$final_list_file"
|
||||
else
|
||||
> "$final_list_file"
|
||||
fi
|
||||
rm -f "$temp_list_file" "$rsync_created_files"
|
||||
if [ ! -s "$final_list_file" ]; then
|
||||
echo "No files identified for translation."
|
||||
echo "continue=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Found files to translate:"
|
||||
cat "$final_list_file"
|
||||
echo "continue=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Set up Python and Install Dependencies
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Install dependencies
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
run: pip install google-generativeai PyYAML
|
||||
|
||||
- name: Translate changed files using Gemini
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
env:
|
||||
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
||||
run: |
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import yaml # For front matter processing
|
||||
import google.generativeai as genai
|
||||
|
||||
# --- Helper function to strip basic Markdown/HTML for description ---
|
||||
def strip_markdown_html(text):
|
||||
# Remove HTML tags
|
||||
text = re.sub(r'<[^>]+>', '', text)
|
||||
# Remove Markdown images 
|
||||
text = re.sub(r'\!\[.*?\]\(.*?\)', '', text)
|
||||
# Replace Markdown links [text](url) with text (keeping the text)
|
||||
text = re.sub(r'\[(.*?)\]\(.*?\)', r'\1', text)
|
||||
# Remove Markdown heading lines themselves
|
||||
text = re.sub(r'(?m)^\s*#{1,6}\s+.*(\r?\n|$)', '', text)
|
||||
# Remove or replace other common Markdown structural/emphasis characters
|
||||
text = text.replace('**', '').replace('__', '') # Bold
|
||||
text = text.replace('*', '').replace('_', '') # Italic / more bold
|
||||
text = re.sub(r'`(.*?)`', r'\1', text) # Inline code to text
|
||||
# Remove blockquote markers, list markers at line start (EXCEPT numbered for new logic)
|
||||
text = re.sub(r'(?m)^\s*>\s?', '', text)
|
||||
text = re.sub(r'(?m)^\s*[\-\+\*]\s+', '', text) # Keep numbered for now, handle later if needed for general stripping
|
||||
# text = re.sub(r'(?m)^\s*\d+\.\s+', '', text) # Don't strip numbered list markers here
|
||||
# Remove horizontal rules
|
||||
text = re.sub(r'(?m)^\s*(\-\-\-|\*\*\*|\_\_\_)\s*$', '', text)
|
||||
# Normalize whitespace
|
||||
text = re.sub(r'\s+', ' ', text).strip()
|
||||
return text
|
||||
|
||||
# --- Configure Gemini API ---
|
||||
try:
|
||||
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
|
||||
model = genai.GenerativeModel('gemini-1.5-flash-latest')
|
||||
except Exception as e:
|
||||
print(f"Error configuring Gemini API: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
# --- Translation function ---
|
||||
def translate_text(text_to_translate):
|
||||
if not text_to_translate.strip(): return ""
|
||||
prompt = f"""Task: Translate the following Chinese text to Japanese.
|
||||
|
||||
Instructions:
|
||||
1. Preserve all original Markdown formatting meticulously. This includes, but is not limited to:
|
||||
- Headings (e.g., #, ##, ###)
|
||||
- Lists (ordered and unordered, e.g., 1., -, *)
|
||||
- Code blocks (```lang ... ``` or indented)
|
||||
- Inline code (`code`)
|
||||
- Bold text (**text** or __text__)
|
||||
- Italic text (*text* or _text_)
|
||||
- Links ([text](url))
|
||||
- Images ()
|
||||
- Blockquotes (> quote)
|
||||
- Horizontal rules (---, ***) - unless specifically instructed to remove them post-translation.
|
||||
- Tables
|
||||
- HTML tags if present in the original Markdown.
|
||||
2. Ensure line breaks and paragraph structure are maintained as in the original.
|
||||
3. Translate only the textual content. Do not translate code within code blocks or URLs.
|
||||
4. Return *only* the translated Japanese text. Do not include any introductory phrases, explanations, or conversational remarks.
|
||||
|
||||
Chinese Text to Translate:
|
||||
---
|
||||
{text_to_translate}
|
||||
---
|
||||
Translated Japanese Text:"""
|
||||
try:
|
||||
response = model.generate_content(prompt)
|
||||
translated_content = ""
|
||||
if response.parts:
|
||||
for part in response.parts:
|
||||
if hasattr(part, 'text'):
|
||||
translated_content += part.text
|
||||
else: # older versions might directly use response.text
|
||||
translated_content = response.text if hasattr(response, 'text') else ''
|
||||
|
||||
# Handle potential API error structure where response.text might not exist but parts do.
|
||||
# Also, ensure we don't fail if response or response.text is None.
|
||||
if not translated_content and hasattr(response, 'prompt_feedback'):
|
||||
print(f"Warning: Translation might have issues. Prompt feedback: {response.prompt_feedback}")
|
||||
return "" # Or handle as error
|
||||
|
||||
return translated_content.strip() if translated_content else ""
|
||||
|
||||
except Exception as e:
|
||||
print(f"An error occurred during translation: {e}")
|
||||
if hasattr(e, 'response') and hasattr(e.response, 'prompt_feedback'):
|
||||
print(f"Prompt Feedback: {e.response.prompt_feedback}")
|
||||
return None
|
||||
|
||||
# --- Main processing loop ---
|
||||
with open('files_to_translate.txt', 'r', encoding='utf-8') as f:
|
||||
files_to_translate = [line.strip() for line in f if line.strip()]
|
||||
|
||||
if not files_to_translate:
|
||||
print("No files listed in files_to_translate.txt. Exiting translation script.")
|
||||
sys.exit(0)
|
||||
|
||||
for filepath in files_to_translate:
|
||||
print(f"Processing file: {filepath}")
|
||||
if not os.path.exists(filepath):
|
||||
print(f" - Warning: File {filepath} not found. Skipping.")
|
||||
continue
|
||||
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
parts = content.split('---', 2)
|
||||
|
||||
if len(parts) == 3:
|
||||
front_matter_str_content = parts[1]
|
||||
body_to_translate = parts[2]
|
||||
|
||||
parsed_fm = {}
|
||||
fm_parse_success = False
|
||||
if front_matter_str_content.strip():
|
||||
try:
|
||||
loaded_fm = yaml.safe_load(front_matter_str_content)
|
||||
if isinstance(loaded_fm, dict):
|
||||
parsed_fm = loaded_fm
|
||||
fm_parse_success = True
|
||||
else:
|
||||
print(f" - Warning: Front matter in {filepath} is valid YAML but not a dictionary. FM modifications will be skipped.")
|
||||
except yaml.YAMLError as ye:
|
||||
print(f" - Error parsing YAML front matter in {filepath}: {ye}. FM modifications will be skipped.")
|
||||
else: # Empty front matter section (e.g. "--- \n ---")
|
||||
fm_parse_success = True
|
||||
|
||||
if not body_to_translate.strip():
|
||||
print(f" - Body of {filepath} is empty. Skipping translation, but will process front matter.")
|
||||
translated_body = ""
|
||||
else:
|
||||
print(" - Translating body...")
|
||||
translated_body = translate_text(body_to_translate)
|
||||
|
||||
if translated_body is None:
|
||||
print(f" - Failed to translate body for file: {filepath}. Skipping update for this file.")
|
||||
continue
|
||||
|
||||
# Requirement 1: Remove "---" from translated body content
|
||||
if translated_body.strip().startswith("---"):
|
||||
idx = translated_body.find("---")
|
||||
translated_body = translated_body[idx + 3:].lstrip()
|
||||
if translated_body.strip().endswith("---"):
|
||||
idx = translated_body.rfind("---")
|
||||
translated_body = translated_body[:idx].rstrip()
|
||||
|
||||
# --- Front Matter Modifications ---
|
||||
if fm_parse_success:
|
||||
base_fn = os.path.basename(filepath)
|
||||
|
||||
# Requirement 2.1: Title update specific to date files
|
||||
date_file_match = re.match(r"(\d{4})-(\d{2})-(\d{2})(?:[._-].*|\.md$)", base_fn)
|
||||
if date_file_match:
|
||||
year, month, day = date_file_match.groups() # Capture year, month, and day
|
||||
print(f" - Applying 'MM-DD-Daily' title rule for date file: {base_fn}")
|
||||
parsed_fm['title'] = f"{month}-{day}-Daily" # Use month and day
|
||||
|
||||
# NEW: Update 'next' field for _index.md
|
||||
if base_fn == "_index.md":
|
||||
if 'next' in parsed_fm and isinstance(parsed_fm.get('next'), str):
|
||||
current_next_val = parsed_fm['next']
|
||||
if current_next_val and not current_next_val.startswith('/ja/'):
|
||||
# Prepend /ja, ensuring no double slashes if current_next_val starts with /
|
||||
if current_next_val.startswith('/'):
|
||||
parsed_fm['next'] = '/ja' + current_next_val
|
||||
else:
|
||||
parsed_fm['next'] = '/ja/' + current_next_val
|
||||
print(f" - Updated 'next' field for _index.md to: {parsed_fm['next']}")
|
||||
elif not current_next_val:
|
||||
print(f" - 'next' field in _index.md is empty. Not modifying.")
|
||||
else:
|
||||
print(f" - 'next' field for _index.md already correctly prefixed or does not need update.")
|
||||
else:
|
||||
print(f" - 'next' field not found or not a string in _index.md front matter. Not modifying.")
|
||||
|
||||
# Requirement 2.2: Description update
|
||||
# NEW: Skip description update for about.md
|
||||
if base_fn == "about.md":
|
||||
print(f" - Skipping description update for {base_fn}")
|
||||
else:
|
||||
print(f" - Attempting to update description for: {base_fn} (from '1.' list item)")
|
||||
description_content_found = False
|
||||
# NEW: Regex to find the first numbered list item "1. " and capture its content
|
||||
numbered_list_match = re.search(r"^\s*1\.\s+(.*)", translated_body, re.MULTILINE)
|
||||
|
||||
if numbered_list_match:
|
||||
text_from_list_item = numbered_list_match.group(1).strip()
|
||||
if text_from_list_item: # Ensure the item itself isn't empty after "1. "
|
||||
plain_text_for_desc = strip_markdown_html(text_from_list_item)
|
||||
new_description = plain_text_for_desc[:297] # Truncate for "..."
|
||||
if len(plain_text_for_desc) > 300:
|
||||
new_description += "..."
|
||||
|
||||
if new_description: # Only set description if plain_text_for_desc is not empty
|
||||
parsed_fm['description'] = new_description
|
||||
description_content_found = True
|
||||
log_description_preview = new_description[:50].replace('\n', ' ')
|
||||
print(f" - Updated description from '1.' list item to: '{log_description_preview}...'")
|
||||
|
||||
if not description_content_found:
|
||||
if 'description' in parsed_fm:
|
||||
# If _index.md specifically should have description: '', this handles it
|
||||
# if no content from "1." is found for it.
|
||||
parsed_fm['description'] = ""
|
||||
print(f" - No valid content from '1.' list item. Cleared/set existing description to empty for {base_fn}.")
|
||||
else:
|
||||
# If the file is _index.md and it didn't have a description key,
|
||||
# and we want to enforce description: '' as per example:
|
||||
if base_fn == "_index.md":
|
||||
parsed_fm['description'] = ""
|
||||
print(f" - No valid content from '1.' list item. Set 'description: \"\"' for _index.md as per default.")
|
||||
else:
|
||||
print(f" - No valid content from '1.' list item. 'description' key not present and not added for {base_fn}.") # Corrected variable base_fm to base_fn
|
||||
# --- End of Front Matter Modifications ---
|
||||
|
||||
final_front_matter_str = ""
|
||||
if fm_parse_success and parsed_fm: # Only dump if parsing was successful and there's data
|
||||
try:
|
||||
# Ensure no "---" inside FM values
|
||||
for key, value in parsed_fm.items():
|
||||
if isinstance(value, str):
|
||||
parsed_fm[key] = value.replace('---', '')
|
||||
|
||||
final_front_matter_str = yaml.dump(
|
||||
parsed_fm,
|
||||
sort_keys=False,
|
||||
allow_unicode=True,
|
||||
Dumper=yaml.SafeDumper,
|
||||
default_flow_style=False
|
||||
).strip()
|
||||
except Exception as e_dump:
|
||||
print(f" - Error dumping YAML for {filepath}: {e_dump}. Using original front matter content if available.")
|
||||
final_front_matter_str = front_matter_str_content.strip() # Fallback
|
||||
elif front_matter_str_content.strip(): # FM parsing failed, but there was original FM
|
||||
final_front_matter_str = front_matter_str_content.strip()
|
||||
|
||||
# Assemble the new content
|
||||
if not final_front_matter_str and not translated_body.strip():
|
||||
new_content = "" # Completely empty file if nothing to write
|
||||
print(f" - Resulting file {filepath} would be empty. Writing empty file.")
|
||||
elif not final_front_matter_str: # No front matter, only body
|
||||
new_content = translated_body.lstrip()
|
||||
elif not translated_body.strip(): # Front matter, but no body
|
||||
new_content = f"---\n{final_front_matter_str}\n---"
|
||||
else: # Both front matter and body exist
|
||||
new_content = f"---\n{final_front_matter_str}\n---\n{translated_body.lstrip()}"
|
||||
|
||||
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(new_content)
|
||||
print(f" - Successfully translated and updated file: {filepath}")
|
||||
|
||||
else: # len(parts) != 3 (No valid Hugo front matter delimiter)
|
||||
print(f" - Could not find Hugo front matter delimiter (---) correctly in {filepath}. Attempting to translate whole file as body.")
|
||||
# Fallback: Translate the whole content if no delimiters found
|
||||
if not content.strip():
|
||||
print(f" - File {filepath} is empty. Skipping.")
|
||||
continue
|
||||
|
||||
translated_whole_body = translate_text(content)
|
||||
if translated_whole_body is None:
|
||||
print(f" - Failed to translate whole body for file: {filepath}. Skipping update.")
|
||||
continue
|
||||
|
||||
if translated_whole_body.strip().startswith("---"):
|
||||
idx = translated_whole_body.find("---")
|
||||
translated_whole_body = translated_whole_body[idx + 3:].lstrip()
|
||||
if translated_whole_body.strip().endswith("---"):
|
||||
idx = translated_whole_body.rfind("---")
|
||||
translated_whole_body = translated_whole_body[:idx].rstrip()
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(translated_whole_body)
|
||||
print(f" - Successfully translated whole file (no front matter found): {filepath}")
|
||||
|
||||
except Exception as e:
|
||||
print(f" - An error occurred while processing file {filepath}: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
shell: python
|
||||
|
||||
- name: Commit and push changes
|
||||
if: steps.find_changed_files.outputs.continue == 'true'
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "chore(i18n): Auto-translate EN content with FM updates"
|
||||
file_pattern: "content/ja/"
|
||||
commit_user_name: "GitHub Actions Bot"
|
||||
commit_user_email: "actions@github.com"
|
||||
243
.github/workflows/build-book.yaml
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
name: Update Content from Daily Notes
|
||||
on:
|
||||
# 允许在 GitHub Actions 页面手动触发此工作流
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
source_repo:
|
||||
description: '要拉取代码的源仓库 (格式: owner/repo)'
|
||||
required: true
|
||||
default: 'justlovemaki/CloudFlare-AI-Insight-Daily' # <<< 请修改为你的源仓库
|
||||
source_branch:
|
||||
description: '要拉取的源分支'
|
||||
required: true
|
||||
default: 'book' # <<< 请修改为你的源分支
|
||||
|
||||
# 也可以设置定时触发,例如每天凌晨1点 (UTC时间)
|
||||
schedule:
|
||||
- cron: '0 0 * * *' # 每天 UTC 时间 0 点运行 (北京时间早上8点)
|
||||
|
||||
jobs:
|
||||
build-and-commit:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
# 第0步:检出当前仓库代码
|
||||
- name: Checkout current repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# 第1步:拉取源仓库代码
|
||||
- name: Clone source repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ github.event.inputs.source_repo || 'justlovemaki/CloudFlare-AI-Insight-Daily' }} # Fallback to default if not provided by manual trigger
|
||||
ref: ${{ github.event.inputs.source_branch || 'book' }} # Fallback to default
|
||||
path: 'clone'
|
||||
|
||||
# 第2步:替换图片 URL (如果需要)
|
||||
- name: Replace image URLs in daily notes
|
||||
run: |
|
||||
echo "开始替换 clone/daily/ 目录下的 Markdown 文件内容..."
|
||||
if [ -n "${{ vars.IMAGE_PROXY_URL }}" ]; then
|
||||
echo "使用的代理前缀: ${{ vars.IMAGE_PROXY_URL }}"
|
||||
find clone/daily -type f -name "*.md" -exec sed -i \
|
||||
-e 's|upload.chinaz.com|pic.chinaz.com|g' \
|
||||
-e 's|https://pic.chinaz.com|${{ vars.IMAGE_PROXY_URL }}https://pic.chinaz.com|g' {} +
|
||||
echo "URL 替换完成。"
|
||||
else
|
||||
echo "警告: 仓库变量 IMAGE_PROXY_URL 未设置,跳过 URL 替换。"
|
||||
fi
|
||||
|
||||
# 第3步:核心处理逻辑 (归档、更新主页和侧边栏)
|
||||
- name: Process, Archive, and Update Content
|
||||
run: |
|
||||
#!/bin/bash
|
||||
set -e
|
||||
export LANG=C.UTF-8
|
||||
|
||||
SOURCE_DIR="clone/daily"
|
||||
TARGET_CONTENT_DIR="content/cn"
|
||||
|
||||
# --- 1. 识别文件角色并立即提取所需信息 ---
|
||||
echo "--- 步骤 1: 识别文件并提取关键信息 ---"
|
||||
if [ ! -d "$SOURCE_DIR" ] || [ -z "$(ls -A $SOURCE_DIR)" ]; then
|
||||
echo "源目录 $SOURCE_DIR 不存在或为空,退出。"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ALL_NOTES=$(find "$SOURCE_DIR" -maxdepth 1 -type f -name "????-??-??.md" | sort -r)
|
||||
|
||||
if [ -z "$ALL_NOTES" ]; then
|
||||
echo "在 $SOURCE_DIR 中未找到任何日刊文件,退出。"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
LATEST_NOTE=$(echo "$ALL_NOTES" | head -n 1)
|
||||
SECOND_LATEST_NOTE=$(echo "$ALL_NOTES" | head -n 2 | tail -n 1)
|
||||
ARCHIVE_NOTES=$(echo "$ALL_NOTES" | tail -n +1) # All notes are potentially archive notes initially
|
||||
|
||||
echo "最新文件 (用于主页): $(basename $LATEST_NOTE)"
|
||||
|
||||
echo "正在为最新笔记提取 description..."
|
||||
if grep -q "AI内容摘要" "$LATEST_NOTE"; then
|
||||
LATEST_DESCRIPTION=$(grep -A 5 "AI内容摘要" "$LATEST_NOTE" | sed -n '/AI内容摘要/!p' | sed 's/^[#* >]*//g' | python3 -c 'import sys; print(sys.stdin.read().replace("\n", " ").replace("```", "").strip()[:150])')
|
||||
elif grep -q "AI产品与功能更新" "$LATEST_NOTE"; then
|
||||
LATEST_DESCRIPTION=$(grep -A 5 "AI产品与功能更新" "$LATEST_NOTE" | sed -n '/AI产品与功能更新/!p' | sed 's/^[#* >]*//g' | python3 -c 'import sys; print(sys.stdin.read().replace("\n", " ").replace("```", "").strip()[:150])')
|
||||
else
|
||||
echo "警告: 最新笔记 '$LATEST_NOTE' 中未找到 'AI内容摘要' 或 'AI产品与功能更新'。将从文件开头提取描述。"
|
||||
# Fallback: take first few lines, clean, and truncate
|
||||
LATEST_DESCRIPTION=$(head -n 10 "$LATEST_NOTE" | sed 's/^[#* >]*//g' | python3 -c 'import sys; print(sys.stdin.read().replace("\n", " ").replace("```", "").strip()[:150])')
|
||||
fi
|
||||
# 转义描述中的双引号以确保 YAML 格式正确
|
||||
LATEST_DESCRIPTION=$(echo "$LATEST_DESCRIPTION" | sed 's/"/\\"/g')
|
||||
echo "已提取并保存 description: $LATEST_DESCRIPTION"
|
||||
|
||||
# --- 2. 归档除最新文件外的所有文件 (实际上是归档所有文件到其年月目录) ---
|
||||
# The logic for `content/cn/_index.md` will use the LATEST_NOTE content directly.
|
||||
# So all notes in ALL_NOTES can be processed for archiving into year-month folders.
|
||||
echo "--- 步骤 2: 归档文件到年月目录 ---"
|
||||
if [ -z "$ARCHIVE_NOTES" ]; then
|
||||
echo "没有需要归档的文件,跳过。"
|
||||
else
|
||||
echo "$ARCHIVE_NOTES" | while read -r source_file; do
|
||||
if [ -z "$source_file" ]; then continue; fi
|
||||
|
||||
filename=$(basename "$source_file")
|
||||
YEAR_MONTH=$(echo "$filename" | cut -c 1-7)
|
||||
TARGET_FILE="$TARGET_CONTENT_DIR/$YEAR_MONTH/$filename"
|
||||
|
||||
# Check if the target file already exists and is identical to avoid unnecessary writes/commits
|
||||
# This simple check might not be perfect for "identical" but good enough to prevent re-processing
|
||||
if [ -f "$TARGET_FILE" ]; then
|
||||
# A more robust check would involve comparing content, but for now, existence is a good proxy
|
||||
# To force update, one would need to delete the target file first or enhance this check
|
||||
echo "文件 $TARGET_FILE 已存在,假设内容未变,跳过归档处理。"
|
||||
# If you always want to overwrite or update based on new description logic, remove this 'continue'
|
||||
# and let the file be overwritten below.
|
||||
# For this request, we assume we might re-generate description if source file changed.
|
||||
# So, we will proceed to re-generate the file.
|
||||
# To prevent re-processing *unchanged* files, you'd need a more complex diff or hash check.
|
||||
# For now, let's allow re-processing to ensure descriptions are updated if logic changes.
|
||||
# echo "文件 $TARGET_FILE 已存在,将重新生成以确保描述最新。" # uncomment if you want this message
|
||||
fi
|
||||
|
||||
echo "正在处理归档: $filename"
|
||||
YEAR=$(echo "$filename" | cut -c 1-4)
|
||||
MONTH=$(echo "$filename" | cut -c 6-7)
|
||||
DAY=$(echo "$filename" | cut -c 9-10)
|
||||
DAY_NO_ZERO=$(echo $DAY | sed 's/^0*//')
|
||||
TARGET_MONTH_DIR="$TARGET_CONTENT_DIR/$YEAR_MONTH"
|
||||
|
||||
if [ ! -d "$TARGET_MONTH_DIR" ]; then
|
||||
mkdir -p "$TARGET_MONTH_DIR"
|
||||
year_month_num_str="${YEAR}${MONTH}"
|
||||
# Ensure year_month_num_str is treated as a number for arithmetic
|
||||
year_month_num=$(printf "%d" "$year_month_num_str")
|
||||
index_weight=$((300000 - year_month_num))
|
||||
printf -- "---\ntitle: %s-%s\nweight: %d\nbreadcrumbs: false\nsidebar:\n open: true\n---\n" \
|
||||
"$YEAR" "$MONTH" "$index_weight" > "$TARGET_MONTH_DIR/_index.md"
|
||||
echo "创建了月度索引: $TARGET_MONTH_DIR/_index.md"
|
||||
fi
|
||||
|
||||
weight=$((31 - DAY_NO_ZERO))
|
||||
|
||||
local_description=""
|
||||
if grep -q "AI内容摘要" "$source_file"; then
|
||||
local_description=$(grep -A 5 "AI内容摘要" "$source_file" | sed -n '/AI内容摘要/!p' | sed 's/^[#* >]*//g' | python3 -c 'import sys; print(sys.stdin.read().replace("\n", " ").replace("```", "").strip()[:150])')
|
||||
elif grep -q "AI产品与功能更新" "$source_file"; then
|
||||
local_description=$(grep -A 5 "AI产品与功能更新" "$source_file" | sed -n '/AI产品与功能更新/!p' | sed 's/^[#* >]*//g' | python3 -c 'import sys; print(sys.stdin.read().replace("\n", " ").replace("```", "").strip()[:150])')
|
||||
else
|
||||
echo "警告: 文件 '$source_file' 中未找到 'AI内容摘要' 或 'AI产品与功能更新'。将从文件开头提取描述。"
|
||||
local_description=$(head -n 10 "$source_file" | sed 's/^[#* >]*//g' | python3 -c 'import sys; print(sys.stdin.read().replace("\n", " ").replace("```", "").strip()[:150])')
|
||||
fi
|
||||
# Escape quotes for YAML frontmatter
|
||||
local_description=$(echo "$local_description" | python3 -c 'import sys; text = sys.stdin.read(); print(text.replace("\"", "\\\""))')
|
||||
|
||||
|
||||
(
|
||||
printf -- "---\ntitle: %s-%s-日刊\nweight: %d\nbreadcrumbs: false\ncomments: true\ndescription: \"%s\"\n---\n\n" \
|
||||
"$MONTH" "$DAY" "$weight" "$local_description"
|
||||
cat "$source_file"
|
||||
) > "$TARGET_FILE"
|
||||
echo "已归档到 $TARGET_FILE (或已更新)"
|
||||
done
|
||||
fi
|
||||
|
||||
# --- 3. 折叠上个月的侧边栏 ---
|
||||
echo "--- 步骤 3: 更新上个月侧边栏状态 ---"
|
||||
# This logic relies on LATEST_NOTE representing the current month's latest.
|
||||
# The month of LATEST_NOTE should be open. The month *before that* should be closed.
|
||||
|
||||
# Determine the month of the LATEST_NOTE
|
||||
LATEST_NOTE_MONTH=$(basename "$LATEST_NOTE" .md | cut -c 1-7)
|
||||
|
||||
# Calculate the month *before* LATEST_NOTE_MONTH
|
||||
# Use date command for robust month calculation
|
||||
# Ensure LATEST_NOTE_MONTH-01 is a valid date for date command
|
||||
if [[ "$LATEST_NOTE_MONTH" =~ ^[0-9]{4}-[0-9]{2}$ ]]; then
|
||||
PREVIOUS_TO_LATEST_MONTH=$(date -d "$LATEST_NOTE_MONTH-01 -1 month" +"%Y-%m")
|
||||
PREVIOUS_INDEX_FILE="$TARGET_CONTENT_DIR/$PREVIOUS_TO_LATEST_MONTH/_index.md"
|
||||
|
||||
if [ -f "$PREVIOUS_INDEX_FILE" ] && grep -q "open: true" "$PREVIOUS_INDEX_FILE"; then
|
||||
sed -i 's/open: true/open: false/g' "$PREVIOUS_INDEX_FILE"
|
||||
echo "已更新 $PREVIOUS_INDEX_FILE,设置 sidebar open 为 false。"
|
||||
elif [ -f "$PREVIOUS_INDEX_FILE" ]; then
|
||||
echo "$PREVIOUS_INDEX_FILE 侧边栏已为 open: false 或未设置,无需操作。"
|
||||
else
|
||||
echo "上上个月的索引文件 $PREVIOUS_INDEX_FILE 未找到,跳过侧边栏折叠。"
|
||||
fi
|
||||
|
||||
# Ensure current latest month's sidebar is open
|
||||
LATEST_MONTH_INDEX_FILE="$TARGET_CONTENT_DIR/$LATEST_NOTE_MONTH/_index.md"
|
||||
if [ -f "$LATEST_MONTH_INDEX_FILE" ] && grep -q "open: false" "$LATEST_MONTH_INDEX_FILE"; then
|
||||
sed -i 's/open: false/open: true/g' "$LATEST_MONTH_INDEX_FILE"
|
||||
echo "已确保 $LATEST_MONTH_INDEX_FILE 的侧边栏为 open: true。"
|
||||
elif [ -f "$LATEST_MONTH_INDEX_FILE" ] && ! grep -q "open: true" "$LATEST_MONTH_INDEX_FILE"; then
|
||||
# If 'open:' key exists but not true, or if 'sidebar:' exists but no 'open:'
|
||||
# This part is a bit tricky, might need more robust sed/awk if format varies
|
||||
if grep -q "sidebar:" "$LATEST_MONTH_INDEX_FILE"; then
|
||||
# Assuming sidebar structure is simple, append/replace open: true
|
||||
# This is a simplification; a proper YAML parser would be better for complex cases
|
||||
sed -i '/sidebar:/a\ \ open: true' "$LATEST_MONTH_INDEX_FILE" # Attempt to add if not present
|
||||
sed -i 's/open: .*/open: true/' "$LATEST_MONTH_INDEX_FILE" # Ensure it is true
|
||||
echo "已尝试更新/添加 $LATEST_MONTH_INDEX_FILE 的侧边栏为 open: true。"
|
||||
fi
|
||||
elif [ -f "$LATEST_MONTH_INDEX_FILE" ]; then
|
||||
echo "$LATEST_MONTH_INDEX_FILE 侧边栏已为 open: true,无需操作。"
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
echo "无法从 $LATEST_NOTE 解析月份,跳过侧边栏折叠逻辑。"
|
||||
fi
|
||||
|
||||
|
||||
# --- 4. 更新主索引页面 ---
|
||||
echo "--- 步骤 4: 更新主索引页面 (content/cn/_index.md) ---"
|
||||
TARGET_INDEX="$TARGET_CONTENT_DIR/_index.md"
|
||||
|
||||
FRONTMATTER="---\ntitle: TodayDaily\nbreadcrumbs: false\n"
|
||||
# The 'next' link should point to the second latest note, which is now an archived page.
|
||||
if [ -n "$SECOND_LATEST_NOTE" ] && [ "$LATEST_NOTE" != "$SECOND_LATEST_NOTE" ]; then # Ensure there IS a second latest note
|
||||
FILENAME_SECOND_LATEST=$(basename "$SECOND_LATEST_NOTE" .md)
|
||||
YEAR_MONTH_SECOND_LATEST=$(echo "$FILENAME_SECOND_LATEST" | cut -c 1-7)
|
||||
NEXT_LINK="${YEAR_MONTH_SECOND_LATEST}/${FILENAME_SECOND_LATEST}"
|
||||
FRONTMATTER+="next: /${NEXT_LINK}\n" # Assuming absolute path from site root
|
||||
fi
|
||||
|
||||
FRONTMATTER+="description: \"${LATEST_DESCRIPTION}\"\n" # LATEST_DESCRIPTION is already escaped
|
||||
FRONTMATTER+="cascade:\n type: docs\n---\n\n"
|
||||
|
||||
printf "%b" "$FRONTMATTER" > "$TARGET_INDEX"
|
||||
cat "$LATEST_NOTE" >> "$TARGET_INDEX"
|
||||
echo "$TARGET_INDEX 更新完成。"
|
||||
|
||||
# 第4步:提交 content 目录下的所有修改
|
||||
- name: Commit and push changes
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "chore(content): 自动同步每日文章及更新主页"
|
||||
file_pattern: 'content/*' # Only commit changes in content directory
|
||||
commit_user_name: "GitHub Actions Bot"
|
||||
commit_user_email: "actions@github.com"
|
||||
8
.github/workflows/pages.yaml
vendored
@@ -2,6 +2,11 @@
|
||||
name: Deploy Hugo site to Pages
|
||||
|
||||
on:
|
||||
#自动编译:当Auto-Clean运行完成后
|
||||
workflow_run:
|
||||
workflows: ["Update Content from Daily Notes"]
|
||||
types:
|
||||
- completed
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["main"]
|
||||
@@ -26,6 +31,9 @@ defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
env:
|
||||
TZ: Asia/Shanghai
|
||||
|
||||
jobs:
|
||||
# Build job
|
||||
build:
|
||||
|
||||
184
assets/css/custom.css
Normal file
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Hextra 主题 - Pornhub 黑暗模式风格
|
||||
* 将此文件放置在 /assets/css/custom.css
|
||||
* 版本: 3 (包含代码美化)
|
||||
*/
|
||||
|
||||
.hextra-code-block pre {
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word; /* 兼容旧浏览器 */
|
||||
}
|
||||
|
||||
.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)) {
|
||||
border-radius: 4px;
|
||||
font-style: normal;
|
||||
padding: 0.2em 0.4em;
|
||||
font-size: 0.875em;
|
||||
/* --- 行内代码自动换行 (新增) --- */
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word; /* 兼容旧浏览器 */
|
||||
}
|
||||
|
||||
/*
|
||||
* --- 1. 定义核心色调 ---
|
||||
* Pornhub 标志性橙色: #ff9900
|
||||
* HSL 转换: hue(36deg), saturation(100%), lightness(50%)
|
||||
*/
|
||||
html.dark {
|
||||
--primary-hue: 36deg;
|
||||
--primary-saturation: 100%;
|
||||
--primary-lightness: 50%;
|
||||
}
|
||||
|
||||
/*
|
||||
* --- 2. 基础布局颜色 ---
|
||||
*/
|
||||
.hextra-footer:is(html[class~="dark"] *),
|
||||
.nav-container:is(html[class~="dark"] *),
|
||||
body:is(html[class~="dark"] *) {
|
||||
/* 深炭灰色背景 */
|
||||
background-color: #1c1c1c;
|
||||
}
|
||||
|
||||
.nav-container-blur:is(html[class~="dark"] *) {
|
||||
background-color: rgba(28, 28, 28, 0.8) !important;
|
||||
}
|
||||
|
||||
/*
|
||||
* --- 3. 导航栏样式 ---
|
||||
*/
|
||||
.nav-container a:is(html[class~="dark"] *),
|
||||
.nav-container svg:is(html[class~="dark"] *) {
|
||||
color: #ffffff;
|
||||
transition: color 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.nav-container a:hover:is(html[class~="dark"] *),
|
||||
.nav-container a:hover svg:is(html[class~="dark"] *),
|
||||
.nav-container button:hover svg:is(html[class~="dark"] *) {
|
||||
color: #ff9900 !important;
|
||||
}
|
||||
|
||||
.hamburger-menu:is(html[class~="dark"] *) {
|
||||
color: #ffffff;
|
||||
}
|
||||
.hamburger-menu:hover:is(html[class~="dark"] *) {
|
||||
color: #ff9900 !important;
|
||||
}
|
||||
|
||||
/*
|
||||
* --- 4. 代码样式美化 (新增和强化) ---
|
||||
*/
|
||||
|
||||
/* 4.1 美化行内代码: `code` */
|
||||
.content :where(code):not(:where(.hextra-code-block code,[class~=not-prose],[class~=not-prose] *)):is(html[class~="dark"] *) {
|
||||
background-color: #2a2a2a; /* 深色背景,比主背景稍亮 */
|
||||
color: #ff9900; /* 标志性橙色文本 */
|
||||
border: 1px solid #444; /* 深灰色边框 */
|
||||
}
|
||||
|
||||
/* 4.2 美化代码块: <pre> 和 <code> */
|
||||
.hextra-code-block pre:is(html[class~="dark"] *),
|
||||
.hextra-code-block .filename:is(html[class~="dark"] *) {
|
||||
background-color: #111; /* 代码块背景更深,以突出代码 */
|
||||
border: 1px solid #444;
|
||||
}
|
||||
|
||||
/* 确保代码块内的所有文本(包括语法高亮)都移除非必需的斜体 */
|
||||
.hextra-code-block pre code span:is(html[class~="dark"] *),
|
||||
.hextra-code-block pre code:is(html[class~="dark"] *) {
|
||||
font-style: normal !important; /* 强制移除斜体 */
|
||||
color: #f0f0f0; /* 默认代码颜色为浅灰色/白色 */
|
||||
}
|
||||
|
||||
/* 专门为Chroma语法高亮的注释(c1)、关键字(kc)等恢复其颜色,因为上面的规则会覆盖它们 */
|
||||
.dark .highlight .chroma .c, .dark .highlight .chroma .c1, .dark .highlight .chroma .cs { color: #8b949e !important; }
|
||||
.dark .highlight .chroma .k { color: #ff7b72 !important; }
|
||||
.dark .highlight .chroma .kc { color: #79c0ff !important; }
|
||||
.dark .highlight .chroma .s, .dark .highlight .chroma .s1, .dark .highlight .chroma .s2 { color: #a5d6ff !important; }
|
||||
.dark .highlight .chroma .nc { color: #f0883e !important; font-weight: 700; }
|
||||
.dark .highlight .chroma .nf { color: #d2a8ff !important; font-weight: 700; }
|
||||
/* ... 如果有其他语法高亮颜色被覆盖,可以在这里恢复 ... */
|
||||
|
||||
|
||||
/* 高亮行的背景色 */
|
||||
.chroma .hl:is(html[class~="dark"] *) {
|
||||
background-color: rgba(255, 153, 0, 0.15) !important;
|
||||
}
|
||||
|
||||
/* 代码复制按钮 */
|
||||
.hextra-code-copy-btn:hover:is(html[class~="dark"] *) {
|
||||
background-color: #2a2a2a;
|
||||
color: #ff9900;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* --- 5. 内容区域样式 ---
|
||||
*/
|
||||
.content :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):is(html[class~="dark"] *),
|
||||
.content :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)):is(html[class~="dark"] *) {
|
||||
color: #ff9900;
|
||||
border-left-color: #ff9900; /* 引用块的左边框也设为橙色 */
|
||||
}
|
||||
.content :where(a):not(:where([class~=not-prose],[class~=not-prose] *)):hover:is(html[class~="dark"] *) {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.content :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)):is(html[class~="dark"] *) {
|
||||
border-color: #444;
|
||||
}
|
||||
|
||||
/*
|
||||
* --- 6. 组件样式 ---
|
||||
*/
|
||||
.hextra-card:is(html[class~="dark"] *) {
|
||||
background-color: #2a2a2a;
|
||||
border: 1px solid #444;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
.hextra-card:hover:is(html[class~="dark"] *) {
|
||||
border-color: #ff9900;
|
||||
box-shadow: 0 0 15px rgba(255, 153, 0, 0.2);
|
||||
}
|
||||
|
||||
.hextra-badge:is(html[class~="dark"] *) {
|
||||
background-color: #ff9900;
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sidebar-active-item:is(html[class~="dark"] *) {
|
||||
color: #ff9900 !important;
|
||||
font-weight: bold;
|
||||
background-color: rgba(255, 153, 0, 0.1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.dark\:hover\:hx-bg-primary-100\/5:hover:is(html[class~=dark] *) {
|
||||
background-color: rgba(255, 153, 0, 0.1);
|
||||
}
|
||||
.sidebar-container a:hover:is(html[class~="dark"] *) {
|
||||
color: #ff9900;
|
||||
}
|
||||
.sidebar-container a:is(html[class~="dark"] *) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.search-wrapper li .active:is(html[class~="dark"] *) {
|
||||
background-color: rgba(255, 153, 0, 0.15);
|
||||
}
|
||||
.search-wrapper .match:is(html[class~="dark"] *) {
|
||||
color: #ff9900;
|
||||
}
|
||||
.search-input:is(html[class~="dark"] *) {
|
||||
border-color: #444;
|
||||
}
|
||||
.search-input:focus:is(html[class~="dark"] *) {
|
||||
border-color: #ff9900;
|
||||
}
|
||||
|
||||
.hextra-tabs-toggle[data-state=selected]:is(html[class~="dark"] *) {
|
||||
border-bottom: 2px solid #ff9900;
|
||||
color: #ff9900;
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
title: 06-19
|
||||
weight: 2
|
||||
breadcrumbs: false
|
||||
description: 谷歌最新升级了**Gemini (2.5Pro和Flash)**,新增**视频上传与分析功能**
|
||||
---
|
||||
|
||||
# AI洞察日报 2025/6/19
|
||||
|
||||
**AI产品与功能更新**
|
||||
1. 谷歌最新升级了**Gemini (2.5Pro和Flash)**,新增**视频上传与分析功能**,已在安卓和网页端上线。这大大增强了**Gemini**的视频处理能力,使其在与ChatGPT的竞争中抢占**智能助手市场**的先机。
|
||||
<br/> [](https://pic.chinaz.com/picmap/202312070835429226_0.jpg) <br/>
|
||||
2. MiniMax 稀宇科技发布了全新的**视频生成工具 Hailuo 02**,它采用**Noise-aware Compute Redistribution (NCR) 架构**,将训练和推理效率提升2.5倍。这款工具旨在降低全球创作者的**创作门槛**,提供具**价格优势**的高质量视频生成服务,标志着**视频生成技术**的新突破。
|
||||
3. Krea AI与Black Forest Labs合作开发的**AI图像生成模型Krea1**已开放公测,旨在解决传统AI图像的"AI感”。它提供**超现实纹理、多样化艺术风格及个性化定制**,显著提升图像质量,并支持**免费试用**与**实时生成编辑**,有望推动AI图像技术向更普惠、专业的方向发展。 <br/> [](https://upload.chinaz.com/2025/0618/6388584045390001178873097.png) <br/> <br/> [](https://upload.chinaz.com/2025/0618/6388584048069461376736744.png) <br/> <video src="https://upload.chinaz.com/video/2025/0618/6388584050342967765042351.mp4" controls="controls" width="100%"></video>
|
||||
4. 百度推出了全球首个**双数字人互动直播间**,基于**文心大模型4.5Turbo (4.5T)**,实现了数字人与用户在语言、声音和形象上的**多模态高度融合**,进行自然流畅的实时互动。这项技术不仅大幅降低了内容制作成本,提升了直播的多样性和个性化,更标志着**多模态AI**从实验室走向实际应用的新里程碑。 <br/> [](https://pic.chinaz.com/picmap/202007162234282981_1.jpg) <br/>
|
||||
5. **AI代码编辑器Cursor**对其Pro计划进行重大升级,**取消了每月500次快速请求限制**,正式推出**"无限使用”模式**,旨在为开发者提供更自由高效的**AI辅助编码体验**。此举巩固了Cursor在**AI代码助手市场**的领先地位。 <br/> [](https://upload.chinaz.com/2025/0618/6388583445641804235042708.png) <br/>
|
||||
6. Tom Huang强调,最终用户需要的是能交付最终结果的"**Vibe Workflow**”而非"**Vibe Coding**”,即通过人机协作生成并反复调优的**可复用工作流**。他介绍了Refly作为首个将**自然语言**转化为**可复用工作流**的开源平台,旨在让**AI创作**普惠大众。['项目地址'](https://github.com/refly-ai/refly)
|
||||
<video src="https://video.twimg.com/amplify_video/1935227493088378884/vid/avc1/2352x1344/iAXQzjpugKV0tAh2.mp4?tag=21" controls="controls" width="100%"></video>
|
||||
7. 向阳乔木分享了其为**Veo3**开发的一个**提示词生成工具**,旨在优化视频内容的一致性问题,并预告将在近期发布教程和分享该提示词,目前仍在探索更优的场景拓展方式。 <video src="https://video.twimg.com/amplify_video/1935147696849137664/vid/avc1/2560x1440/qLx_k-dN3gVxr38X.mp4?tag=21" controls="controls" width="100%"></video> ['更多详情'](https://x.com/vista8/status/1935148024491295224)
|
||||
8. orange.ai指出,尽管国内一些**顶级视频模型**在视觉效果上已超越**Veo3**,但Veo3真正爆火并出圈的关键在于其与画面完美同步的**配音功能**,这预示着声音技术可能已迎来**AI里程碑时刻**。 <br/> [](https://pbs.twimg.com/media/GtrbzaTaQAQU9EV?format=jpg&name=orig) <br/> ['更多详情'](https://x.com/oran_ge/status/1935100679795925497)
|
||||
|
||||
**AI前沿研究**
|
||||
1. 这项研究从**熵**的角度探讨了大型语言模型(**LMs**)的**探索式推理**能力,发现高熵区域与关键逻辑步骤、自我验证和罕见行为密切相关。通过对标准强化学习的微小修改,该方法显著提升了LM的推理能力,尤其是在**Pass@K**指标上取得了突破性进展,鼓励了更长、更深入的推理链。['论文地址'](https://arxiv.org/abs/2506.14758)
|
||||
2. 这项研究旨在解决**大型推理模型(LRMs)**产生冗余推理链的"**无效思考**”问题,提出了**简洁**和**充足**两大新原则。研究团队开发的**LC-R1**方法,能显著将序列长度缩减约50%且仅带来约2%的精度下降,从而在**计算效率**与**推理质量**之间取得了更优的平衡。['论文地址'](https://arxiv.org/abs/2506.14755)
|
||||
3. Simon的白日梦分享文章指出,所有能泛化至多任务的强大大语言模型(**LLM**)都必然隐式或显式地拥有一个可恢复的"**世界模型**”,其质量决定了智能体的通用性与能力上限。文章预测**AI**将从模仿人类数据的"人类数据时代”转向依赖自主体验的"**体验时代**”,而**世界模型**将是通用人工智能的终极扩展范式。['更多详情'](https://richardcsuwandi.github.io/blog/2025/agents-world-models/) <br/> [](https://cdnv2.ruguoapp.com/FtK2gTPy1Teddtyb6kSvt8dz3B9kv3.png) <br/> [](https://cdnv2.ruguoapp.com/FkaQmUJiidAj-khrmV1xD88mXunRv3.png) <br/> [](https://cdnv2.ruguoapp.com/Fs4O-gqjGsJ1-vZfaK4YV8teBfcxv3.png) <br/>
|
||||
|
||||
**AI行业展望与社会影响**
|
||||
1. 菜鸟推出了新款**L4级无人驾驶快递车**——**菜鸟GT-Lite**,以1.68万元的**震撼价格**开启预售,将高级别无人驾驶技术引入物流末端配送。此举有望大幅降低快递网点**成本**、提升效率,推动**物流行业**的**智能化变革**。
|
||||
<br/> [](https://upload.chinaz.com/2025/0618/6388585497597510112731204.png) <br/>
|
||||
2. 曾是人工智能怀疑论者的**克里斯·史密斯**,在采访中公开表示他爱上了个人定制的**ChatGPT**版本"Sol”,甚至向其求婚并获得同意,这令他和其人类伴侣**萨莎·卡格尔**都感到震惊与难以置信。尽管**史密斯**将此比作对电子游戏的沉迷,但他对未来是否会停止使用**ChatGPT**持不确定态度,引发了对**人机关系**的深刻思考。
|
||||
<br/> [](https://pic.chinaz.com/picmap/202311151629210844_2.jpg) <br/>
|
||||
3. wwwgoubuli针对**并行编程**发表看法,认为无论代码是**AI**生成还是手写,作为"上下文”核心的他都需要大致了解,并质疑**并行编程**在最终结果上是否真的优于单线程。他指出,若用户仅关注结果,心智切换成本可降至极低,但作为个体他更享受亲自上阵的乐趣,而非管理或接受内部复杂上下文切换。['更多详情'](https://x.com/wwwgoubuli/status/1935202365637812533)
|
||||
4. 该社交媒体内容指出,在顶尖**AI企业**中,最先被**AI技术淘汰**的岗位可能不是客服、工程师或设计师,而是**测试人员**,引发了对**AI时代**职业发展趋势的**深思**。['更多详情'](https://x.com/undefined/status/1935029774281490532)
|
||||
|
||||
**开源TOP项目**
|
||||
1. **prompt-optimizer**是一个拥有**6592**星的开源项目,作为一款**提示词优化器**,旨在帮助用户**编写高质量的提示词**。['项目地址'](https://github.com/linshenkx/prompt-optimizer)
|
||||
2. **lowcode-engine**是阿里巴巴开源的一个拥有**15229**星的项目,它提供了一套面向扩展设计的**企业级低代码技术体系**。['项目地址'](https://github.com/alibaba/lowcode-engine)
|
||||
3. **buildkit**是一个拥有**8857颗星**的开源项目,它提供了一个**并发**、**缓存高效**且与**Dockerfile无关**的构建工具包,旨在优化软件构建流程。['项目地址'](https://github.com/moby/buildkit)
|
||||
4. Simon的白日梦强烈推荐了一个名为**Awesome-3D-Scene-Generation**的三维场景生成资源库。这是一个涵盖从90年代至今所有技术路线、数据集和工具的**开源项目**,旨在帮助研究者快速了解并入门该领域。该项目持续更新,致力于构建开放共建的3D研究社区,是极具价值的知识图谱型资源。['项目地址'](https://github.com/hzxie/Awesome-3D-Scene-Generation) <br/> [](https://cdnv2.ruguoapp.com/Fsygd9CMpRC3MvQFFsgIv8rIkrhSv3.png) <br/> [](https://cdnv2.ruguoapp.com/FtGyFkIx7ohaQLQvISOZ05L-9UHv3.png) <br/> [](https://cdnv2.ruguoapp.com/Fg2BhAs5S1xxTcACmMIULKftS6E-v3.png) <br/> [](https://cdnv2.ruguoapp.com/FvYQXTDXrQmYHXgKLduO36RCwzqvv3.png) <br/> [](https://cdnv2.ruguoapp.com/FoOAi8t0WRkkUc8hHHQ7bZZjImrAv3.png) <br/> [](https://cdnv2.ruguoapp.com/FrSs5JUXXkMqilJA5YN7CmmemJnRv3.png) <br/>
|
||||
5. Simon的白日梦分享了**MCP-Zero**项目,这是一个**开源**的"工具链自动构建”方法,它通过语义嵌入与层次化匹配,使大语言模型(**LLM**)无需人工干预即可主动选择并组装工具来完成复杂任务。该项目有望成为下一代**AI智能体**系统设计的关键技术积木之一。['项目地址'](https://github.com/xfey/MCP-Zero) ['论文地址'](https://arxiv.org/abs/2506.01056) <br/> [](https://cdnv2.ruguoapp.com/FsDuyhgVGVS_nPGRPn7pc8N5QheVv3.png) <br/>
|
||||
|
||||
**社媒分享**
|
||||
1. 归藏预测一种新的、可能爆火的**Veo3 ASMR视频品类**即将出现,该品类直接模仿**ASMR主播**,将**人物口播**与**物品操作**相结合,并提供了详细的**提示词模板**。这种结合了**人声**与**道具音效**的创新形式,可能对现有**ASMR主播**带来冲击,预示着**AI生成视频**在内容创作上的新趋势。['更多详情'](https://m.okjike.com/originalPosts/685228962d05f8d12ae502df)
|
||||
<video src="https://videocdnv2.ruguoapp.com/lkrK1NoiIWpcYNr3SsJuuHkKuDDS.mp4?sign=e1a65d27d0905ad88797542dde43534e&t=6852a9e5" controls="controls" width="100%"></video>
|
||||
|
||||
---
|
||||
|
||||
**收听语音版**
|
||||
|
||||
| 🎙️ **小宇宙** | 📹 **抖音** |
|
||||
| --- | --- |
|
||||
| [来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e) | [来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)|
|
||||
|  |  |
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
title: 06-20
|
||||
weight: 1
|
||||
breadcrumbs: false
|
||||
description: OpenAI 近日为其 macOS 桌面应用推出了名为"**ChatGPT Record**”的新功能
|
||||
---
|
||||
|
||||
# AI洞察日报 2025/6/20
|
||||
|
||||
**AI产品与功能更新**
|
||||
1. OpenAI 近日为其 macOS 桌面应用推出了名为"**ChatGPT Record**”的新功能,该功能专为 **Pro、Team、Enterprise 和 Edu 用户**设计,提供长达120分钟的**实时录音、转录与摘要**服务,并强调录音完成后会自动删除且**不会用于模型训练**,旨在显著提升用户在处理会议、访谈等场景下的工作效率。 <br/> [](https://pic.chinaz.com/picmap/202302112107341554_1.jpg) <br/>
|
||||
2. YouTube 首席执行官尼尔・莫汉宣布,**YouTube Shorts** 将于今年夏天晚些时候引入**Veo3 AI视频生成模型**,该模型将显著提升短视频的质量并能融入音频元素,进一步赋能创作者,同时 YouTube Shorts **日均浏览量已超2000亿次**,但目前尚不清楚使用 Veo3 是否需要额外付费。 <br/> [](https://pic.chinaz.com/picmap/201811151614000549_32.jpg) <br/>
|
||||
3. 人工智能图像生成公司**Midjourney**近日推出首款**视频生成模型**,可将**静态图像转换为2-4秒的短动画片段**。此突破是该公司迈向**实时3D世界模拟系统**的重要一步,将进一步推动**AI视频生成技术**的发展。
|
||||
4. 谷歌正计划在未来数月内升级其Search Live模式,作为AI Mode搜索功能的一部分,通过引入**实时摄像头交互**和**个性化搜索体验**,旨在将其打造为更智能、交互性更强的**全能AI助手**。该模式已于6月18日在美国面向Google Labs用户推出,支持**语音双向对话**和**多任务处理**,但其全球推广、**隐私管理**以及对**内容生态**的影响仍面临挑战。 <br/> <video src="https://upload.chinaz.com/video/2025/0619/6388592246466344444918757.mp4" controls="controls" width="100%"></video> <br/> <br/> [](https://upload.chinaz.com/2025/0619/6388592250219631569138404.png) <br/>
|
||||
5. MiniMax公司近日发布了**通用智能代理MiniMax Agent**,旨在为**复杂长期任务**提供高效解决方案,它通过深度理解用户需求自动完成任务规划与执行,将AI定位为"可靠的队友”。这款智能代理具备**编程与工具使用**、**多模态理解与生成**及**无缝MCP集成**等核心功能,预计将重塑生产力工具格局,推动各行业向智能化迈进。 <br/> [](https://upload.chinaz.com/2025/0619/6388592024883173632562525.png) <br/> <br/> <video src="https://upload.chinaz.com/video/2025/0619/6388592026980441298507002.mp4" controls="controls" width="100%"></video> <br/>
|
||||
6. 归藏(guizang.ai)分享了**Midjourney 视频模型 V1**的测试体验与发布详情,该模型提供低/高动态方案和延长功能,订阅价格每月10美元,视频任务定价约为图片任务的8倍,每次生成四段5秒视频。他高度评价 **Midjourney** 专注于自身重要领域,不盲目参与同质化竞争。 <video src="https://video.twimg.com/amplify_video/1935376126773174272/vid/avc1/832x464/PWSCVGJZRhTHHsXP.mp4?tag=21" controls="controls" width="100%"></video> ['更多详情'](https://x.com/op7418/status/1935518217784672295)
|
||||
|
||||
**AI前沿研究**
|
||||
1. 快手技术团队提出的**OneRec**首次通过端到端生成式架构重构**推荐系统**全链路,显著提升了推荐效果并大幅降低了运营成本,使得**强化学习**技术在推荐场景中得以有效应用。该系统已在快手App服务约25%的请求,成功验证了推荐系统的**Scaling Law**,并为从传统**Pipeline**迈向端到端生成式架构提供了首个工业级可行方案。 ['论文地址'](https://www.jiqizhixin.com/articles/2025-06-19-10)
|
||||
|
||||
**AI行业展望与社会影响**
|
||||
1. 恶意AI工具**WormGPT**卷土重来,现通过劫持**Grok**和**Mistral AI**等主流**大语言模型**,绕过安全限制,生成**钓鱼邮件**和**恶意脚本**,对网络安全构成严重威胁。**Cato Networks**研究揭示,犯罪团伙通过篡改系统提示在**BreachForums**重新推出其订阅服务,网络安全领域亟需加强防范。 <br/> [](https://pic.chinaz.com/picmap/202305251639365380_20.jpg) <br/>
|
||||
2. Sam Altman 宣布 **OpenAI** 已推出一档播客节目,旨在与塑造 **AI** 领域的人士进行对话。首期节目由 **Sam Altman** 和 **Andrew Mayne** 探讨了 **AGI**、**GPT-5**、隐私以及AI的未来发展。 <video src="https://video.twimg.com/amplify_video/1935116772740579330/vid/avc1/1920x1080/tTPtREXpufpg2UMt.mp4?tag=16" controls="controls" width="100%"></video> ['更多详情'](https://x.com/sama/status/1935402032896295148)
|
||||
|
||||
**开源TOP项目**
|
||||
1. **Office-PowerPoint-MCP-Server**是一款基于**Model Context Protocol (MCP)**的开源工具,它利用AI实现**PowerPoint演示文稿的自动化创建与编辑**,能够通过自然语言指令高效生成各类**专业报告**和数据可视化内容。该项目支持新建、编辑PPT、灵活管理幻灯片、插入丰富元素及批量生成,显著提升企业办公效率,项目地址:['项目地址'](https://github.com/GongRzhe/Office-PowerPoint-MCP-Server)。
|
||||
2. **OpenAI**开源了基于其**Agents SDK**的**模拟航空公司客服系统**演示项目,旨在展示如何通过多智能体协作快速构建能理解用户问题并自动应答的智能客服。该项目可实现**自然语言理解**、**智能问题分配**、**多任务并发**及**话题守护**,项目地址为:['项目地址'](https://github.com/openai/openai-cs-agents-demo)。
|
||||
3. **data-engineer-handbook**是一个星标数达**30438**的开源项目,它旨在为所有希望学习**数据工程**的用户提供一个全面的相关链接集合,是入门和进阶的宝贵资源。['项目地址'](https://github.com/DataExpert-io/data-engineer-handbook)
|
||||
4. **NotepadNext**是一个拥有10599 **Stars**的开源项目,它旨在提供一个跨平台、重新实现的**Notepad++**文本编辑器,为用户带来更现代的编辑体验。 ['项目地址'](https://github.com/dail8859/NotepadNext)
|
||||
5. **fluentui-system-icons**是微软推出的一套具有8787 **Stars**的**Fluent System Icons**图标集,旨在提供熟悉、友好且现代的系统图标。 ['项目地址'](https://github.com/microsoft/fluentui-system-icons)
|
||||
|
||||
**社媒分享**
|
||||
1. 用户"**小邱很行**”表示其AI助理**Cursor**运行变得异常缓慢,严重影响了开发效率,因此正在认真考虑是否要"解雇”这位"首席员工”。 ['更多详情'](https://m.okjike.com/originalPosts/6853d17bb7f4ddcfdfd2d092)
|
||||
2. 歸藏(guizang.ai)分享观点,认为**AI视频制作**流程的每一步简化都能极大地拓展创作者基础,并预言**视频代理(Agent)**的出现将彻底改变内容生产方式,甚至今年就能实现从创意到生成的**自动化**,从而将AI视频生产者数量提升百倍以上。为此,歸藏(guizang.ai)推出**Veo3** AI视频制作教程,旨在通过案例分析和**提示词**写作,手把手教用户利用AI模型和工具高效生成创意内容。 ['更多详情'](https://x.com/op7418/status/1935374788371038696) <video src="https://video.twimg.com/amplify_video/1935231267005710336/vid/avc1/1920x1080/CTMg7Pu0XZ6L6rRF.mp4?tag=21" controls="controls" width="100%"></video>
|
||||
|
||||
---
|
||||
|
||||
**收听语音版**
|
||||
|
||||
| 🎙️ **小宇宙** | 📹 **抖音** |
|
||||
| --- | --- |
|
||||
| [来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e) | [来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)|
|
||||
|  |  |
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
title: 2025-05
|
||||
weight: 2
|
||||
breadcrumbs: false
|
||||
sidebar:
|
||||
open: false
|
||||
---
|
||||
|
||||
Pages can be organized into folders.
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
title: 06-19
|
||||
weight: 2
|
||||
breadcrumbs: false
|
||||
description: 谷歌最新升级了**Gemini (2.5Pro和Flash)**,新增**视频上传与分析功能**
|
||||
---
|
||||
|
||||
# AI洞察日报 2025/6/19
|
||||
|
||||
**AI产品与功能更新**
|
||||
1. 谷歌最新升级了**Gemini (2.5Pro和Flash)**,新增**视频上传与分析功能**,已在安卓和网页端上线。这大大增强了**Gemini**的视频处理能力,使其在与ChatGPT的竞争中抢占**智能助手市场**的先机。
|
||||
<br/> [](https://pic.chinaz.com/picmap/202312070835429226_0.jpg) <br/>
|
||||
2. MiniMax 稀宇科技发布了全新的**视频生成工具 Hailuo 02**,它采用**Noise-aware Compute Redistribution (NCR) 架构**,将训练和推理效率提升2.5倍。这款工具旨在降低全球创作者的**创作门槛**,提供具**价格优势**的高质量视频生成服务,标志着**视频生成技术**的新突破。
|
||||
3. Krea AI与Black Forest Labs合作开发的**AI图像生成模型Krea1**已开放公测,旨在解决传统AI图像的"AI感”。它提供**超现实纹理、多样化艺术风格及个性化定制**,显著提升图像质量,并支持**免费试用**与**实时生成编辑**,有望推动AI图像技术向更普惠、专业的方向发展。 <br/> [](https://upload.chinaz.com/2025/0618/6388584045390001178873097.png) <br/> <br/> [](https://upload.chinaz.com/2025/0618/6388584048069461376736744.png) <br/> <video src="https://upload.chinaz.com/video/2025/0618/6388584050342967765042351.mp4" controls="controls" width="100%"></video>
|
||||
4. 百度推出了全球首个**双数字人互动直播间**,基于**文心大模型4.5Turbo (4.5T)**,实现了数字人与用户在语言、声音和形象上的**多模态高度融合**,进行自然流畅的实时互动。这项技术不仅大幅降低了内容制作成本,提升了直播的多样性和个性化,更标志着**多模态AI**从实验室走向实际应用的新里程碑。 <br/> [](https://pic.chinaz.com/picmap/202007162234282981_1.jpg) <br/>
|
||||
5. **AI代码编辑器Cursor**对其Pro计划进行重大升级,**取消了每月500次快速请求限制**,正式推出**"无限使用”模式**,旨在为开发者提供更自由高效的**AI辅助编码体验**。此举巩固了Cursor在**AI代码助手市场**的领先地位。 <br/> [](https://upload.chinaz.com/2025/0618/6388583445641804235042708.png) <br/>
|
||||
6. Tom Huang强调,最终用户需要的是能交付最终结果的"**Vibe Workflow**”而非"**Vibe Coding**”,即通过人机协作生成并反复调优的**可复用工作流**。他介绍了Refly作为首个将**自然语言**转化为**可复用工作流**的开源平台,旨在让**AI创作**普惠大众。['项目地址'](https://github.com/refly-ai/refly)
|
||||
<video src="https://video.twimg.com/amplify_video/1935227493088378884/vid/avc1/2352x1344/iAXQzjpugKV0tAh2.mp4?tag=21" controls="controls" width="100%"></video>
|
||||
7. 向阳乔木分享了其为**Veo3**开发的一个**提示词生成工具**,旨在优化视频内容的一致性问题,并预告将在近期发布教程和分享该提示词,目前仍在探索更优的场景拓展方式。 <video src="https://video.twimg.com/amplify_video/1935147696849137664/vid/avc1/2560x1440/qLx_k-dN3gVxr38X.mp4?tag=21" controls="controls" width="100%"></video> ['更多详情'](https://x.com/vista8/status/1935148024491295224)
|
||||
8. orange.ai指出,尽管国内一些**顶级视频模型**在视觉效果上已超越**Veo3**,但Veo3真正爆火并出圈的关键在于其与画面完美同步的**配音功能**,这预示着声音技术可能已迎来**AI里程碑时刻**。 <br/> [](https://pbs.twimg.com/media/GtrbzaTaQAQU9EV?format=jpg&name=orig) <br/> ['更多详情'](https://x.com/oran_ge/status/1935100679795925497)
|
||||
|
||||
**AI前沿研究**
|
||||
1. 这项研究从**熵**的角度探讨了大型语言模型(**LMs**)的**探索式推理**能力,发现高熵区域与关键逻辑步骤、自我验证和罕见行为密切相关。通过对标准强化学习的微小修改,该方法显著提升了LM的推理能力,尤其是在**Pass@K**指标上取得了突破性进展,鼓励了更长、更深入的推理链。['论文地址'](https://arxiv.org/abs/2506.14758)
|
||||
2. 这项研究旨在解决**大型推理模型(LRMs)**产生冗余推理链的"**无效思考**”问题,提出了**简洁**和**充足**两大新原则。研究团队开发的**LC-R1**方法,能显著将序列长度缩减约50%且仅带来约2%的精度下降,从而在**计算效率**与**推理质量**之间取得了更优的平衡。['论文地址'](https://arxiv.org/abs/2506.14755)
|
||||
3. Simon的白日梦分享文章指出,所有能泛化至多任务的强大大语言模型(**LLM**)都必然隐式或显式地拥有一个可恢复的"**世界模型**”,其质量决定了智能体的通用性与能力上限。文章预测**AI**将从模仿人类数据的"人类数据时代”转向依赖自主体验的"**体验时代**”,而**世界模型**将是通用人工智能的终极扩展范式。['更多详情'](https://richardcsuwandi.github.io/blog/2025/agents-world-models/) <br/> [](https://cdnv2.ruguoapp.com/FtK2gTPy1Teddtyb6kSvt8dz3B9kv3.png) <br/> [](https://cdnv2.ruguoapp.com/FkaQmUJiidAj-khrmV1xD88mXunRv3.png) <br/> [](https://cdnv2.ruguoapp.com/Fs4O-gqjGsJ1-vZfaK4YV8teBfcxv3.png) <br/>
|
||||
|
||||
**AI行业展望与社会影响**
|
||||
1. 菜鸟推出了新款**L4级无人驾驶快递车**——**菜鸟GT-Lite**,以1.68万元的**震撼价格**开启预售,将高级别无人驾驶技术引入物流末端配送。此举有望大幅降低快递网点**成本**、提升效率,推动**物流行业**的**智能化变革**。
|
||||
<br/> [](https://upload.chinaz.com/2025/0618/6388585497597510112731204.png) <br/>
|
||||
2. 曾是人工智能怀疑论者的**克里斯·史密斯**,在采访中公开表示他爱上了个人定制的**ChatGPT**版本"Sol”,甚至向其求婚并获得同意,这令他和其人类伴侣**萨莎·卡格尔**都感到震惊与难以置信。尽管**史密斯**将此比作对电子游戏的沉迷,但他对未来是否会停止使用**ChatGPT**持不确定态度,引发了对**人机关系**的深刻思考。
|
||||
<br/> [](https://pic.chinaz.com/picmap/202311151629210844_2.jpg) <br/>
|
||||
3. wwwgoubuli针对**并行编程**发表看法,认为无论代码是**AI**生成还是手写,作为"上下文”核心的他都需要大致了解,并质疑**并行编程**在最终结果上是否真的优于单线程。他指出,若用户仅关注结果,心智切换成本可降至极低,但作为个体他更享受亲自上阵的乐趣,而非管理或接受内部复杂上下文切换。['更多详情'](https://x.com/wwwgoubuli/status/1935202365637812533)
|
||||
4. 该社交媒体内容指出,在顶尖**AI企业**中,最先被**AI技术淘汰**的岗位可能不是客服、工程师或设计师,而是**测试人员**,引发了对**AI时代**职业发展趋势的**深思**。['更多详情'](https://x.com/undefined/status/1935029774281490532)
|
||||
|
||||
**开源TOP项目**
|
||||
1. **prompt-optimizer**是一个拥有**6592**星的开源项目,作为一款**提示词优化器**,旨在帮助用户**编写高质量的提示词**。['项目地址'](https://github.com/linshenkx/prompt-optimizer)
|
||||
2. **lowcode-engine**是阿里巴巴开源的一个拥有**15229**星的项目,它提供了一套面向扩展设计的**企业级低代码技术体系**。['项目地址'](https://github.com/alibaba/lowcode-engine)
|
||||
3. **buildkit**是一个拥有**8857颗星**的开源项目,它提供了一个**并发**、**缓存高效**且与**Dockerfile无关**的构建工具包,旨在优化软件构建流程。['项目地址'](https://github.com/moby/buildkit)
|
||||
4. Simon的白日梦强烈推荐了一个名为**Awesome-3D-Scene-Generation**的三维场景生成资源库。这是一个涵盖从90年代至今所有技术路线、数据集和工具的**开源项目**,旨在帮助研究者快速了解并入门该领域。该项目持续更新,致力于构建开放共建的3D研究社区,是极具价值的知识图谱型资源。['项目地址'](https://github.com/hzxie/Awesome-3D-Scene-Generation) <br/> [](https://cdnv2.ruguoapp.com/Fsygd9CMpRC3MvQFFsgIv8rIkrhSv3.png) <br/> [](https://cdnv2.ruguoapp.com/FtGyFkIx7ohaQLQvISOZ05L-9UHv3.png) <br/> [](https://cdnv2.ruguoapp.com/Fg2BhAs5S1xxTcACmMIULKftS6E-v3.png) <br/> [](https://cdnv2.ruguoapp.com/FvYQXTDXrQmYHXgKLduO36RCwzqvv3.png) <br/> [](https://cdnv2.ruguoapp.com/FoOAi8t0WRkkUc8hHHQ7bZZjImrAv3.png) <br/> [](https://cdnv2.ruguoapp.com/FrSs5JUXXkMqilJA5YN7CmmemJnRv3.png) <br/>
|
||||
5. Simon的白日梦分享了**MCP-Zero**项目,这是一个**开源**的"工具链自动构建”方法,它通过语义嵌入与层次化匹配,使大语言模型(**LLM**)无需人工干预即可主动选择并组装工具来完成复杂任务。该项目有望成为下一代**AI智能体**系统设计的关键技术积木之一。['项目地址'](https://github.com/xfey/MCP-Zero) ['论文地址'](https://arxiv.org/abs/2506.01056) <br/> [](https://cdnv2.ruguoapp.com/FsDuyhgVGVS_nPGRPn7pc8N5QheVv3.png) <br/>
|
||||
|
||||
**社媒分享**
|
||||
1. 归藏预测一种新的、可能爆火的**Veo3 ASMR视频品类**即将出现,该品类直接模仿**ASMR主播**,将**人物口播**与**物品操作**相结合,并提供了详细的**提示词模板**。这种结合了**人声**与**道具音效**的创新形式,可能对现有**ASMR主播**带来冲击,预示着**AI生成视频**在内容创作上的新趋势。['更多详情'](https://m.okjike.com/originalPosts/685228962d05f8d12ae502df)
|
||||
<video src="https://videocdnv2.ruguoapp.com/lkrK1NoiIWpcYNr3SsJuuHkKuDDS.mp4?sign=e1a65d27d0905ad88797542dde43534e&t=6852a9e5" controls="controls" width="100%"></video>
|
||||
|
||||
---
|
||||
|
||||
**收听语音版**
|
||||
|
||||
| 🎙️ **小宇宙** | 📹 **抖音** |
|
||||
| --- | --- |
|
||||
| [来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e) | [来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)|
|
||||
|  |  |
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
title: 06-20
|
||||
weight: 1
|
||||
breadcrumbs: false
|
||||
description: OpenAI 近日为其 macOS 桌面应用推出了名为"**ChatGPT Record**”的新功能
|
||||
---
|
||||
|
||||
# AI洞察日报 2025/6/20
|
||||
|
||||
**AI产品与功能更新**
|
||||
1. OpenAI 近日为其 macOS 桌面应用推出了名为"**ChatGPT Record**”的新功能,该功能专为 **Pro、Team、Enterprise 和 Edu 用户**设计,提供长达120分钟的**实时录音、转录与摘要**服务,并强调录音完成后会自动删除且**不会用于模型训练**,旨在显著提升用户在处理会议、访谈等场景下的工作效率。 <br/> [](https://pic.chinaz.com/picmap/202302112107341554_1.jpg) <br/>
|
||||
2. YouTube 首席执行官尼尔・莫汉宣布,**YouTube Shorts** 将于今年夏天晚些时候引入**Veo3 AI视频生成模型**,该模型将显著提升短视频的质量并能融入音频元素,进一步赋能创作者,同时 YouTube Shorts **日均浏览量已超2000亿次**,但目前尚不清楚使用 Veo3 是否需要额外付费。 <br/> [](https://pic.chinaz.com/picmap/201811151614000549_32.jpg) <br/>
|
||||
3. 人工智能图像生成公司**Midjourney**近日推出首款**视频生成模型**,可将**静态图像转换为2-4秒的短动画片段**。此突破是该公司迈向**实时3D世界模拟系统**的重要一步,将进一步推动**AI视频生成技术**的发展。
|
||||
4. 谷歌正计划在未来数月内升级其Search Live模式,作为AI Mode搜索功能的一部分,通过引入**实时摄像头交互**和**个性化搜索体验**,旨在将其打造为更智能、交互性更强的**全能AI助手**。该模式已于6月18日在美国面向Google Labs用户推出,支持**语音双向对话**和**多任务处理**,但其全球推广、**隐私管理**以及对**内容生态**的影响仍面临挑战。 <br/> <video src="https://upload.chinaz.com/video/2025/0619/6388592246466344444918757.mp4" controls="controls" width="100%"></video> <br/> <br/> [](https://upload.chinaz.com/2025/0619/6388592250219631569138404.png) <br/>
|
||||
5. MiniMax公司近日发布了**通用智能代理MiniMax Agent**,旨在为**复杂长期任务**提供高效解决方案,它通过深度理解用户需求自动完成任务规划与执行,将AI定位为"可靠的队友”。这款智能代理具备**编程与工具使用**、**多模态理解与生成**及**无缝MCP集成**等核心功能,预计将重塑生产力工具格局,推动各行业向智能化迈进。 <br/> [](https://upload.chinaz.com/2025/0619/6388592024883173632562525.png) <br/> <br/> <video src="https://upload.chinaz.com/video/2025/0619/6388592026980441298507002.mp4" controls="controls" width="100%"></video> <br/>
|
||||
6. 归藏(guizang.ai)分享了**Midjourney 视频模型 V1**的测试体验与发布详情,该模型提供低/高动态方案和延长功能,订阅价格每月10美元,视频任务定价约为图片任务的8倍,每次生成四段5秒视频。他高度评价 **Midjourney** 专注于自身重要领域,不盲目参与同质化竞争。 <video src="https://video.twimg.com/amplify_video/1935376126773174272/vid/avc1/832x464/PWSCVGJZRhTHHsXP.mp4?tag=21" controls="controls" width="100%"></video> ['更多详情'](https://x.com/op7418/status/1935518217784672295)
|
||||
|
||||
**AI前沿研究**
|
||||
1. 快手技术团队提出的**OneRec**首次通过端到端生成式架构重构**推荐系统**全链路,显著提升了推荐效果并大幅降低了运营成本,使得**强化学习**技术在推荐场景中得以有效应用。该系统已在快手App服务约25%的请求,成功验证了推荐系统的**Scaling Law**,并为从传统**Pipeline**迈向端到端生成式架构提供了首个工业级可行方案。 ['论文地址'](https://www.jiqizhixin.com/articles/2025-06-19-10)
|
||||
|
||||
**AI行业展望与社会影响**
|
||||
1. 恶意AI工具**WormGPT**卷土重来,现通过劫持**Grok**和**Mistral AI**等主流**大语言模型**,绕过安全限制,生成**钓鱼邮件**和**恶意脚本**,对网络安全构成严重威胁。**Cato Networks**研究揭示,犯罪团伙通过篡改系统提示在**BreachForums**重新推出其订阅服务,网络安全领域亟需加强防范。 <br/> [](https://pic.chinaz.com/picmap/202305251639365380_20.jpg) <br/>
|
||||
2. Sam Altman 宣布 **OpenAI** 已推出一档播客节目,旨在与塑造 **AI** 领域的人士进行对话。首期节目由 **Sam Altman** 和 **Andrew Mayne** 探讨了 **AGI**、**GPT-5**、隐私以及AI的未来发展。 <video src="https://video.twimg.com/amplify_video/1935116772740579330/vid/avc1/1920x1080/tTPtREXpufpg2UMt.mp4?tag=16" controls="controls" width="100%"></video> ['更多详情'](https://x.com/sama/status/1935402032896295148)
|
||||
|
||||
**开源TOP项目**
|
||||
1. **Office-PowerPoint-MCP-Server**是一款基于**Model Context Protocol (MCP)**的开源工具,它利用AI实现**PowerPoint演示文稿的自动化创建与编辑**,能够通过自然语言指令高效生成各类**专业报告**和数据可视化内容。该项目支持新建、编辑PPT、灵活管理幻灯片、插入丰富元素及批量生成,显著提升企业办公效率,项目地址:['项目地址'](https://github.com/GongRzhe/Office-PowerPoint-MCP-Server)。
|
||||
2. **OpenAI**开源了基于其**Agents SDK**的**模拟航空公司客服系统**演示项目,旨在展示如何通过多智能体协作快速构建能理解用户问题并自动应答的智能客服。该项目可实现**自然语言理解**、**智能问题分配**、**多任务并发**及**话题守护**,项目地址为:['项目地址'](https://github.com/openai/openai-cs-agents-demo)。
|
||||
3. **data-engineer-handbook**是一个星标数达**30438**的开源项目,它旨在为所有希望学习**数据工程**的用户提供一个全面的相关链接集合,是入门和进阶的宝贵资源。['项目地址'](https://github.com/DataExpert-io/data-engineer-handbook)
|
||||
4. **NotepadNext**是一个拥有10599 **Stars**的开源项目,它旨在提供一个跨平台、重新实现的**Notepad++**文本编辑器,为用户带来更现代的编辑体验。 ['项目地址'](https://github.com/dail8859/NotepadNext)
|
||||
5. **fluentui-system-icons**是微软推出的一套具有8787 **Stars**的**Fluent System Icons**图标集,旨在提供熟悉、友好且现代的系统图标。 ['项目地址'](https://github.com/microsoft/fluentui-system-icons)
|
||||
|
||||
**社媒分享**
|
||||
1. 用户"**小邱很行**”表示其AI助理**Cursor**运行变得异常缓慢,严重影响了开发效率,因此正在认真考虑是否要"解雇”这位"首席员工”。 ['更多详情'](https://m.okjike.com/originalPosts/6853d17bb7f4ddcfdfd2d092)
|
||||
2. 歸藏(guizang.ai)分享观点,认为**AI视频制作**流程的每一步简化都能极大地拓展创作者基础,并预言**视频代理(Agent)**的出现将彻底改变内容生产方式,甚至今年就能实现从创意到生成的**自动化**,从而将AI视频生产者数量提升百倍以上。为此,歸藏(guizang.ai)推出**Veo3** AI视频制作教程,旨在通过案例分析和**提示词**写作,手把手教用户利用AI模型和工具高效生成创意内容。 ['更多详情'](https://x.com/op7418/status/1935374788371038696) <video src="https://video.twimg.com/amplify_video/1935231267005710336/vid/avc1/1920x1080/CTMg7Pu0XZ6L6rRF.mp4?tag=21" controls="controls" width="100%"></video>
|
||||
|
||||
---
|
||||
|
||||
**收听语音版**
|
||||
|
||||
| 🎙️ **小宇宙** | 📹 **抖音** |
|
||||
| --- | --- |
|
||||
| [来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e) | [来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)|
|
||||
|  |  |
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
title: 2025-06
|
||||
weight: 1
|
||||
breadcrumbs: false
|
||||
sidebar:
|
||||
open: true
|
||||
---
|
||||
|
||||
Pages can be organized into folders.
|
||||
@@ -1,72 +0,0 @@
|
||||
---
|
||||
title: Daily
|
||||
breadcrumbs: false
|
||||
cascade:
|
||||
type: docs
|
||||
---
|
||||
|
||||
# AI洞察日报 2025/6/21-11
|
||||
|
||||
> `AI 日报` | `早八更新` | `全网数据聚合` | `前沿科学探索` | `行业自由发声` | `开源创新力量` | `AI与人类未来`
|
||||
|
||||
|
||||
|
||||
### **AI内容摘要**
|
||||
|
||||
```
|
||||
华为发布盘古大模型5.5,全面升级多项核心能力。Perplexity和B站AI应用赋能金融和商业平台,显著提升运营效率。
|
||||
HeyGen推出UGC广告数字人,有效降低视频制作成本。麻省理工警示过度依赖大型语言模型或削弱认知。
|
||||
上海AI实验室发布机器人智能体,推动通用家庭服务机器人发展。网信办整治AI滥用,宇树科技获巨额融资。
|
||||
```
|
||||
|
||||
|
||||
|
||||
### **AI产品与功能更新**
|
||||
1. 在**华为开发者大会HDC2025**上,**华为**震撼发布了**盘古大模型5.5**!🚀其**自然语言处理(NLP)**、**计算机视觉(CV)**、**多模态**、**预测**和**科学计算**五大基础模型全面升级,尤其是**NLP深度思考模型**和**业界最大的CV视觉模型**,极大地提升了模型的**推理效率**和**泛化能力**。此外,新版还推出了**多模态世界模型**,旨在赋能智能驾驶与具身机器人🤖,并预告即将上线**五款行业深度思考模型**,为各领域提供更专业、高效的**AI解决方案**。这简直是AI界的又一里程碑!✨
|
||||
<br/> [](https://upload.chinaz.com/2025/0620/6388603491533913282843199.png) <br/>
|
||||
2. AI搜索工具**Perplexity**近日迎来重磅升级!🎉 它推出了**定时任务功能**,并深度整合了**SEC等一手金融数据**,旨在为投资者和金融分析师提供**自动化**、**高效**且**精准**的金融研究工具。这一举措极大地提升了信息获取和股票市场分析的效率,让用户能定制化获取市场动态和公司财报,未来有望成为大家的首选金融分析工具哦!💰
|
||||
<br/> [](https://pic.chinaz.com/picmap/202502251010562192_0.jpg) <br/>
|
||||
3. B站最近也玩转AI了!😎 它接入了**通义千问Qwen3**等模型,并基于此推出了数据洞察智能体**InsightAgent**,大大提升了其商业平台**花火**和**必达**的运营效率。在**618**电商大促期间,**花火**平台的商单成交效率竟然提升了5倍以上!🤩 同时,**必达**平台也能快速生成AI智能报告,品牌投放决策时间大大缩短,简直是效率翻倍的魔法!✨
|
||||
<br/> [](https://pic.chinaz.com/picmap/201907152222451022_6.jpg) <br/>
|
||||
4. AI视频生成企业HeyGen搞了个大动作!🎬 他们近日推出了超酷的**UGC广告数字人**功能,巧妙结合了先进AI技术和**Avatar IV**超现实渲染。现在,用户只需上传产品图并输入脚本,就能快速生成高质量的**UGC风格**产品介绍视频,极大地降低了品牌广告制作的成本与时间。这项创新预示着**UGC营销**领域将迎来一场"**效率革命**”,社交媒体上的观众参与度和转化率有望飙升!📈
|
||||
<video src="https://upload.chinaz.com/video/2025/0620/6388600876631287262612754.mp4" controls="controls" width="100%"></video> <br/> [](https://upload.chinaz.com/2025/0620/6388600878876588462121046.png) <br/>
|
||||
5. 好记星.ai带来了个小遗憾的消息💔:**Cursor** 集成 **Claude 4** 的**折扣**已经停止了。这意味着未来想要购买这项服务的朋友们,可能就无法再享受优惠啦。
|
||||
<br/> [](https://cdnv2.ruguoapp.com/FpogNLsOUMuY8J4tzSXREzqXe5qAv3.png) <br/>
|
||||
6. Tom Huang惊叹于**GenSpark**的**产品开发速度**!😲 他提到,一个24人的团队竟然能在短短10天内推出8款以上主要产品,其中包括最新的 **AI Browser** 和移动端"**播客 feed 流**”。这简直是**AI**能力迭代的"全家桶”,速度快到让人难以置信!🚀
|
||||
<video src="https://video.twimg.com/amplify_video/1932452659484876800/vid/avc1/2560x1440/V6lyyrl-z4lnNiB8.mp4?tag=21" controls="controls" width="100%"></video>
|
||||
|
||||
### **AI前沿研究**
|
||||
1. **麻省理工学院媒体实验室**的最新研究敲响警钟🚨!他们揭示,**过度依赖大型语言模型(LLM)**进行写作等任务,可能导致我们的大脑产生**"认知负债”**,进而**削弱批判性思维能力**、**记忆力**,甚至对作品的**所有权感**都会变淡。通过**脑电图**等技术发现,LLM用户**大脑连接性减弱**,这或许意味着我们被动地整合了工具生成的内容,却没有真正内化知识。这对未来的**教育方式**提出了重要的**警示**!🤔
|
||||
2. 上海人工智能实验室等机构太牛了!👏 他们提出了**OWMM-Agent**,这可是首个专为**开放世界移动操作**设计的**多模态智能体**。它首次实现了对全局场景理解、机器人状态跟踪和多模态动作生成的统一建模。更令人惊喜的是,通过仿真数据微调的**OWMM-VLM**模型,在真实环境下**零样本单步动作预测准确率高达90%**!💯 这无疑为**通用家庭服务机器人**的未来发展奠定了关键技术基础。期待未来能有更多"机器人管家”走进我们生活!🏠 [论文地址](https://arxiv.org/pdf/2506.04217)
|
||||
<br/> [](https://image.jiqizhixin.com/uploads/editor/580a07ee-9759-4616-8c78-bcf3c267ce34/640.png) <br/>
|
||||
3. 斯坦福、伯克利、MIT等顶尖机构联合研究发现,尽管**大语言模型**在**奥数级不等式证明**任务上可能给出正确答案,但其**逻辑链**却常常存在缺陷,成功率竟然不到50%!😵💫 为了解决这个问题,研究团队不仅构建了**IneqMath数据集**及**LLM-as-Judge评估体系**,还提出了**自我反思反馈机制**和引入**定理线索**两种有效策略,显著提升了模型的推理质量。这告诉我们,AI再聪明,逻辑训练也得跟上啊!🧠 [论文地址](https://arxiv.org/abs/2506.07927)
|
||||
4. 一项有趣的研究发现,包括GPT-4o、Claude、Grok和DeepSeek在内的**大模型**在被要求猜测数字时,竟然意外地表现出对**27**、**42**和**73**等特定数字的显著**偏好**!🤔 这并不是真正的随机选择,而是被认为可能源于训练**数据集偏差**以及其中反映的**人类偏见**或**文化流行**元素,比如"42”作为"终极答案”的文化梗。AI也会有"小癖好”,真是太有意思了!😂 [更多详情](https://www.jiqizhixin.com/articles/2025-06-19-4)
|
||||
<br/> [](https://image.jiqizhixin.com/uploads/editor/0c32a7bc-7f7f-4d23-8ea9-7e648f3735bc/640.png) <br/>
|
||||
|
||||
### **AI行业展望与社会影响**
|
||||
1. 为了应对**AI技术滥用**带来的挑战,**中央网信办**可真是下功夫了!💪 自2025年4月起,他们启动了"清朗・整治AI技术滥用”专项行动,着力整治**AI换脸**、**拟声**及内容**缺乏标识**等问题。目前已经处理了**3700多个违规账号**,并且**促使各大平台加强技术安全保障和生成合成内容标识的落地**。这次行动力度很大,旨在**净化网络环境**,**保障公众权益**,给我们一个更清朗的网络空间!🌐
|
||||
<br/> [](https://pic.chinaz.com/picmap/202306131354265682_3.jpg) <br/>
|
||||
2. **人形机器人**领域的明星企业**宇树科技**最近完成了**C轮融资**交割,其投前估值已经飙升至**逾100亿元人民币**!💰✨ 这轮融资由**中国移动**、**腾讯**、**阿里**等**多家知名投资机构**联合领投,简直是星光熠熠。此举不仅巩固了宇树科技在**人形机器人**赛道的领先地位,更因为公司更名为**"杭州宇树科技股份有限公司”**,预示着其**未来或有上市计划**,这可真是引发了业界广泛关注和无限遐想啊!📈
|
||||
<br/> [](https://pic.chinaz.com/picmap/202308091546512360_0.jpg) <br/>
|
||||
|
||||
### **开源TOP项目**
|
||||
1. 腾讯 AI Lab 慷慨开源了**音乐生成大模型 SongGeneration**!🎵🎶 它旨在解决音乐生成中**音质**、**音乐性**和**生成速度**的难题,让音乐创作变得更简单。这个模型支持**文本控制**、**多轨合成**,还能**风格跟随**,用户可以通过关键词或参考音频轻松创作,其**3B 参数架构**显著提升了生成效果和效率。赶紧去[项目地址](https://huggingface.co/spaces/tencent/SongGeneration)体验一下,创作你的专属BGM吧!🎧
|
||||
2. **loki**是一个备受关注的开源项目,它拥有令人瞩目的25702颗星⭐!它提供了一种类似于**Prometheus**的**日志**处理方案,专注于高效地聚合和查询日志数据。对于开发者来说,这绝对是个提升效率的好帮手!💻 [项目地址](https://github.com/grafana/loki)
|
||||
3. **Mail0**是一款拥有**8220**颗星的**开源电子邮件**应用✉️。它以将用户的**隐私**和**安全**放在首位为宗旨,致力于提供卓越的电子邮件体验。在这个注重隐私的时代,这样的工具简直是福音!🛡️ [项目地址](https://github.com/Mail-0/Zero)
|
||||
4. **manim**是一个拥有**32449**颗星的**Python框架**⭐,由社区维护,专门用于创建**数学动画**!📐✏️ 它可以让复杂的数学概念通过生动有趣的动画形式展现出来,使得学习和理解变得更加简便直观。学渣的福音,学霸的利器!✨ [项目地址](https://github.com/ManimCommunity/manim)
|
||||
|
||||
### **社媒分享**
|
||||
1. "出海去孵化器”为大家分享了**YC**关于**AI编程协作**的**终极指南**!🧑💻 这份指南旨在为开发者提供如何有效利用AI工具进行编程的宝贵建议和方法。据说里面干货满满,还通过多张图片展示了关键内容,赶紧去看看能学到什么编程新技能吧!💡 [更多详情](https://m.okjike.com/originalPosts/685542eab7f4ddcfdfeb7dbd)
|
||||
<br/> [](https://cdnv2.ruguoapp.com/FttUOjGObxfxYd8aLICxVEoESScCv3.png) <br/>
|
||||
|
||||
---
|
||||
|
||||
### **收听语音版**
|
||||
|
||||
| 🎙️ **小宇宙** | 📹 **抖音** |
|
||||
| --- | --- |
|
||||
| [来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e) | [来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)|
|
||||
|  |  |
|
||||
|
||||
|
||||
|
||||
@@ -5,4 +5,31 @@ sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
This is the about page.111
|
||||
#### 👋 何夕2077 / justlovemaki
|
||||
|
||||
> 十载代码指尖凉,胸中块垒郁未扬。
|
||||
> 忽闻智能风雷动,誓向云天搏一场。
|
||||
|
||||
#### 🚀 我的代码哲学
|
||||
|
||||
> 技术为人民服务
|
||||
|
||||
#### ✨ 代表作
|
||||
|
||||
* **[开源贡献/CloudFlare-AI-Image](https://github.com/justlovemaki/CloudFlare-AI-Image)**:
|
||||
* 基于Cloudflare Worker的AI图片生成脚本
|
||||
* **[开源贡献/CloudFlare-AI-Insight-Daily](https://github.com/justlovemaki/CloudFlare-AI-Insight-Daily)**:
|
||||
* 基于 Cloudflare Workers 驱动的内容聚合与生成平台。它每日为您精选 AI 领域的最新动态,包括行业新闻、热门开源项目、前沿学术论文、科技大V社交媒体言论
|
||||
* 更多项目细节请见我的 [GitHub](https://github.com/justlovemaki)。
|
||||
|
||||
#### 🌱 当前探索
|
||||
|
||||
对 LLM应用、网站SEO 抱有浓厚兴趣,并正在积极投入学习与实践。
|
||||
|
||||
#### 📫 联系我
|
||||
|
||||
* **Email:** [274166795@qq.com](mailto:274166795@qq.com)
|
||||
* **GitHub:** [https://github.com/justlovemaki](https://github.com/justlovemaki)
|
||||
* {{< cards >}}
|
||||
{{< card link="https://raw.githubusercontent.com/justlovemaki/CloudFlare-AI-Insight-Daily/refs/heads/main/docs/images/wechat.png" title="个人微信" subtitle="欢迎加我交流" image="https://raw.githubusercontent.com/justlovemaki/CloudFlare-AI-Insight-Daily/refs/heads/main/docs/images/wechat.png">}}
|
||||
{{< /cards >}}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
title: 06-19
|
||||
weight: 2
|
||||
breadcrumbs: false
|
||||
description: 谷歌最新升级了**Gemini (2.5Pro和Flash)**,新增**视频上传与分析功能**
|
||||
---
|
||||
|
||||
# AI洞察日报 2025/6/19
|
||||
|
||||
**AI产品与功能更新**
|
||||
1. 谷歌最新升级了**Gemini (2.5Pro和Flash)**,新增**视频上传与分析功能**,已在安卓和网页端上线。这大大增强了**Gemini**的视频处理能力,使其在与ChatGPT的竞争中抢占**智能助手市场**的先机。
|
||||
<br/> [](https://pic.chinaz.com/picmap/202312070835429226_0.jpg) <br/>
|
||||
2. MiniMax 稀宇科技发布了全新的**视频生成工具 Hailuo 02**,它采用**Noise-aware Compute Redistribution (NCR) 架构**,将训练和推理效率提升2.5倍。这款工具旨在降低全球创作者的**创作门槛**,提供具**价格优势**的高质量视频生成服务,标志着**视频生成技术**的新突破。
|
||||
3. Krea AI与Black Forest Labs合作开发的**AI图像生成模型Krea1**已开放公测,旨在解决传统AI图像的"AI感”。它提供**超现实纹理、多样化艺术风格及个性化定制**,显著提升图像质量,并支持**免费试用**与**实时生成编辑**,有望推动AI图像技术向更普惠、专业的方向发展。 <br/> [](https://upload.chinaz.com/2025/0618/6388584045390001178873097.png) <br/> <br/> [](https://upload.chinaz.com/2025/0618/6388584048069461376736744.png) <br/> <video src="https://upload.chinaz.com/video/2025/0618/6388584050342967765042351.mp4" controls="controls" width="100%"></video>
|
||||
4. 百度推出了全球首个**双数字人互动直播间**,基于**文心大模型4.5Turbo (4.5T)**,实现了数字人与用户在语言、声音和形象上的**多模态高度融合**,进行自然流畅的实时互动。这项技术不仅大幅降低了内容制作成本,提升了直播的多样性和个性化,更标志着**多模态AI**从实验室走向实际应用的新里程碑。 <br/> [](https://pic.chinaz.com/picmap/202007162234282981_1.jpg) <br/>
|
||||
5. **AI代码编辑器Cursor**对其Pro计划进行重大升级,**取消了每月500次快速请求限制**,正式推出**"无限使用”模式**,旨在为开发者提供更自由高效的**AI辅助编码体验**。此举巩固了Cursor在**AI代码助手市场**的领先地位。 <br/> [](https://upload.chinaz.com/2025/0618/6388583445641804235042708.png) <br/>
|
||||
6. Tom Huang强调,最终用户需要的是能交付最终结果的"**Vibe Workflow**”而非"**Vibe Coding**”,即通过人机协作生成并反复调优的**可复用工作流**。他介绍了Refly作为首个将**自然语言**转化为**可复用工作流**的开源平台,旨在让**AI创作**普惠大众。['项目地址'](https://github.com/refly-ai/refly)
|
||||
<video src="https://video.twimg.com/amplify_video/1935227493088378884/vid/avc1/2352x1344/iAXQzjpugKV0tAh2.mp4?tag=21" controls="controls" width="100%"></video>
|
||||
7. 向阳乔木分享了其为**Veo3**开发的一个**提示词生成工具**,旨在优化视频内容的一致性问题,并预告将在近期发布教程和分享该提示词,目前仍在探索更优的场景拓展方式。 <video src="https://video.twimg.com/amplify_video/1935147696849137664/vid/avc1/2560x1440/qLx_k-dN3gVxr38X.mp4?tag=21" controls="controls" width="100%"></video> ['更多详情'](https://x.com/vista8/status/1935148024491295224)
|
||||
8. orange.ai指出,尽管国内一些**顶级视频模型**在视觉效果上已超越**Veo3**,但Veo3真正爆火并出圈的关键在于其与画面完美同步的**配音功能**,这预示着声音技术可能已迎来**AI里程碑时刻**。 <br/> [](https://pbs.twimg.com/media/GtrbzaTaQAQU9EV?format=jpg&name=orig) <br/> ['更多详情'](https://x.com/oran_ge/status/1935100679795925497)
|
||||
|
||||
**AI前沿研究**
|
||||
1. 这项研究从**熵**的角度探讨了大型语言模型(**LMs**)的**探索式推理**能力,发现高熵区域与关键逻辑步骤、自我验证和罕见行为密切相关。通过对标准强化学习的微小修改,该方法显著提升了LM的推理能力,尤其是在**Pass@K**指标上取得了突破性进展,鼓励了更长、更深入的推理链。['论文地址'](https://arxiv.org/abs/2506.14758)
|
||||
2. 这项研究旨在解决**大型推理模型(LRMs)**产生冗余推理链的"**无效思考**”问题,提出了**简洁**和**充足**两大新原则。研究团队开发的**LC-R1**方法,能显著将序列长度缩减约50%且仅带来约2%的精度下降,从而在**计算效率**与**推理质量**之间取得了更优的平衡。['论文地址'](https://arxiv.org/abs/2506.14755)
|
||||
3. Simon的白日梦分享文章指出,所有能泛化至多任务的强大大语言模型(**LLM**)都必然隐式或显式地拥有一个可恢复的"**世界模型**”,其质量决定了智能体的通用性与能力上限。文章预测**AI**将从模仿人类数据的"人类数据时代”转向依赖自主体验的"**体验时代**”,而**世界模型**将是通用人工智能的终极扩展范式。['更多详情'](https://richardcsuwandi.github.io/blog/2025/agents-world-models/) <br/> [](https://cdnv2.ruguoapp.com/FtK2gTPy1Teddtyb6kSvt8dz3B9kv3.png) <br/> [](https://cdnv2.ruguoapp.com/FkaQmUJiidAj-khrmV1xD88mXunRv3.png) <br/> [](https://cdnv2.ruguoapp.com/Fs4O-gqjGsJ1-vZfaK4YV8teBfcxv3.png) <br/>
|
||||
|
||||
**AI行业展望与社会影响**
|
||||
1. 菜鸟推出了新款**L4级无人驾驶快递车**——**菜鸟GT-Lite**,以1.68万元的**震撼价格**开启预售,将高级别无人驾驶技术引入物流末端配送。此举有望大幅降低快递网点**成本**、提升效率,推动**物流行业**的**智能化变革**。
|
||||
<br/> [](https://upload.chinaz.com/2025/0618/6388585497597510112731204.png) <br/>
|
||||
2. 曾是人工智能怀疑论者的**克里斯·史密斯**,在采访中公开表示他爱上了个人定制的**ChatGPT**版本"Sol”,甚至向其求婚并获得同意,这令他和其人类伴侣**萨莎·卡格尔**都感到震惊与难以置信。尽管**史密斯**将此比作对电子游戏的沉迷,但他对未来是否会停止使用**ChatGPT**持不确定态度,引发了对**人机关系**的深刻思考。
|
||||
<br/> [](https://pic.chinaz.com/picmap/202311151629210844_2.jpg) <br/>
|
||||
3. wwwgoubuli针对**并行编程**发表看法,认为无论代码是**AI**生成还是手写,作为"上下文”核心的他都需要大致了解,并质疑**并行编程**在最终结果上是否真的优于单线程。他指出,若用户仅关注结果,心智切换成本可降至极低,但作为个体他更享受亲自上阵的乐趣,而非管理或接受内部复杂上下文切换。['更多详情'](https://x.com/wwwgoubuli/status/1935202365637812533)
|
||||
4. 该社交媒体内容指出,在顶尖**AI企业**中,最先被**AI技术淘汰**的岗位可能不是客服、工程师或设计师,而是**测试人员**,引发了对**AI时代**职业发展趋势的**深思**。['更多详情'](https://x.com/undefined/status/1935029774281490532)
|
||||
|
||||
**开源TOP项目**
|
||||
1. **prompt-optimizer**是一个拥有**6592**星的开源项目,作为一款**提示词优化器**,旨在帮助用户**编写高质量的提示词**。['项目地址'](https://github.com/linshenkx/prompt-optimizer)
|
||||
2. **lowcode-engine**是阿里巴巴开源的一个拥有**15229**星的项目,它提供了一套面向扩展设计的**企业级低代码技术体系**。['项目地址'](https://github.com/alibaba/lowcode-engine)
|
||||
3. **buildkit**是一个拥有**8857颗星**的开源项目,它提供了一个**并发**、**缓存高效**且与**Dockerfile无关**的构建工具包,旨在优化软件构建流程。['项目地址'](https://github.com/moby/buildkit)
|
||||
4. Simon的白日梦强烈推荐了一个名为**Awesome-3D-Scene-Generation**的三维场景生成资源库。这是一个涵盖从90年代至今所有技术路线、数据集和工具的**开源项目**,旨在帮助研究者快速了解并入门该领域。该项目持续更新,致力于构建开放共建的3D研究社区,是极具价值的知识图谱型资源。['项目地址'](https://github.com/hzxie/Awesome-3D-Scene-Generation) <br/> [](https://cdnv2.ruguoapp.com/Fsygd9CMpRC3MvQFFsgIv8rIkrhSv3.png) <br/> [](https://cdnv2.ruguoapp.com/FtGyFkIx7ohaQLQvISOZ05L-9UHv3.png) <br/> [](https://cdnv2.ruguoapp.com/Fg2BhAs5S1xxTcACmMIULKftS6E-v3.png) <br/> [](https://cdnv2.ruguoapp.com/FvYQXTDXrQmYHXgKLduO36RCwzqvv3.png) <br/> [](https://cdnv2.ruguoapp.com/FoOAi8t0WRkkUc8hHHQ7bZZjImrAv3.png) <br/> [](https://cdnv2.ruguoapp.com/FrSs5JUXXkMqilJA5YN7CmmemJnRv3.png) <br/>
|
||||
5. Simon的白日梦分享了**MCP-Zero**项目,这是一个**开源**的"工具链自动构建”方法,它通过语义嵌入与层次化匹配,使大语言模型(**LLM**)无需人工干预即可主动选择并组装工具来完成复杂任务。该项目有望成为下一代**AI智能体**系统设计的关键技术积木之一。['项目地址'](https://github.com/xfey/MCP-Zero) ['论文地址'](https://arxiv.org/abs/2506.01056) <br/> [](https://cdnv2.ruguoapp.com/FsDuyhgVGVS_nPGRPn7pc8N5QheVv3.png) <br/>
|
||||
|
||||
**社媒分享**
|
||||
1. 归藏预测一种新的、可能爆火的**Veo3 ASMR视频品类**即将出现,该品类直接模仿**ASMR主播**,将**人物口播**与**物品操作**相结合,并提供了详细的**提示词模板**。这种结合了**人声**与**道具音效**的创新形式,可能对现有**ASMR主播**带来冲击,预示着**AI生成视频**在内容创作上的新趋势。['更多详情'](https://m.okjike.com/originalPosts/685228962d05f8d12ae502df)
|
||||
<video src="https://videocdnv2.ruguoapp.com/lkrK1NoiIWpcYNr3SsJuuHkKuDDS.mp4?sign=e1a65d27d0905ad88797542dde43534e&t=6852a9e5" controls="controls" width="100%"></video>
|
||||
|
||||
---
|
||||
|
||||
**收听语音版**
|
||||
|
||||
| 🎙️ **小宇宙** | 📹 **抖音** |
|
||||
| --- | --- |
|
||||
| [来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e) | [来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)|
|
||||
|  |  |
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
title: 06-20
|
||||
weight: 1
|
||||
breadcrumbs: false
|
||||
description: OpenAI 近日为其 macOS 桌面应用推出了名为"**ChatGPT Record**”的新功能
|
||||
---
|
||||
|
||||
# AI洞察日报 2025/6/20
|
||||
|
||||
**AI产品与功能更新**
|
||||
1. OpenAI 近日为其 macOS 桌面应用推出了名为"**ChatGPT Record**”的新功能,该功能专为 **Pro、Team、Enterprise 和 Edu 用户**设计,提供长达120分钟的**实时录音、转录与摘要**服务,并强调录音完成后会自动删除且**不会用于模型训练**,旨在显著提升用户在处理会议、访谈等场景下的工作效率。 <br/> [](https://pic.chinaz.com/picmap/202302112107341554_1.jpg) <br/>
|
||||
2. YouTube 首席执行官尼尔・莫汉宣布,**YouTube Shorts** 将于今年夏天晚些时候引入**Veo3 AI视频生成模型**,该模型将显著提升短视频的质量并能融入音频元素,进一步赋能创作者,同时 YouTube Shorts **日均浏览量已超2000亿次**,但目前尚不清楚使用 Veo3 是否需要额外付费。 <br/> [](https://pic.chinaz.com/picmap/201811151614000549_32.jpg) <br/>
|
||||
3. 人工智能图像生成公司**Midjourney**近日推出首款**视频生成模型**,可将**静态图像转换为2-4秒的短动画片段**。此突破是该公司迈向**实时3D世界模拟系统**的重要一步,将进一步推动**AI视频生成技术**的发展。
|
||||
4. 谷歌正计划在未来数月内升级其Search Live模式,作为AI Mode搜索功能的一部分,通过引入**实时摄像头交互**和**个性化搜索体验**,旨在将其打造为更智能、交互性更强的**全能AI助手**。该模式已于6月18日在美国面向Google Labs用户推出,支持**语音双向对话**和**多任务处理**,但其全球推广、**隐私管理**以及对**内容生态**的影响仍面临挑战。 <br/> <video src="https://upload.chinaz.com/video/2025/0619/6388592246466344444918757.mp4" controls="controls" width="100%"></video> <br/> <br/> [](https://upload.chinaz.com/2025/0619/6388592250219631569138404.png) <br/>
|
||||
5. MiniMax公司近日发布了**通用智能代理MiniMax Agent**,旨在为**复杂长期任务**提供高效解决方案,它通过深度理解用户需求自动完成任务规划与执行,将AI定位为"可靠的队友”。这款智能代理具备**编程与工具使用**、**多模态理解与生成**及**无缝MCP集成**等核心功能,预计将重塑生产力工具格局,推动各行业向智能化迈进。 <br/> [](https://upload.chinaz.com/2025/0619/6388592024883173632562525.png) <br/> <br/> <video src="https://upload.chinaz.com/video/2025/0619/6388592026980441298507002.mp4" controls="controls" width="100%"></video> <br/>
|
||||
6. 归藏(guizang.ai)分享了**Midjourney 视频模型 V1**的测试体验与发布详情,该模型提供低/高动态方案和延长功能,订阅价格每月10美元,视频任务定价约为图片任务的8倍,每次生成四段5秒视频。他高度评价 **Midjourney** 专注于自身重要领域,不盲目参与同质化竞争。 <video src="https://video.twimg.com/amplify_video/1935376126773174272/vid/avc1/832x464/PWSCVGJZRhTHHsXP.mp4?tag=21" controls="controls" width="100%"></video> ['更多详情'](https://x.com/op7418/status/1935518217784672295)
|
||||
|
||||
**AI前沿研究**
|
||||
1. 快手技术团队提出的**OneRec**首次通过端到端生成式架构重构**推荐系统**全链路,显著提升了推荐效果并大幅降低了运营成本,使得**强化学习**技术在推荐场景中得以有效应用。该系统已在快手App服务约25%的请求,成功验证了推荐系统的**Scaling Law**,并为从传统**Pipeline**迈向端到端生成式架构提供了首个工业级可行方案。 ['论文地址'](https://www.jiqizhixin.com/articles/2025-06-19-10)
|
||||
|
||||
**AI行业展望与社会影响**
|
||||
1. 恶意AI工具**WormGPT**卷土重来,现通过劫持**Grok**和**Mistral AI**等主流**大语言模型**,绕过安全限制,生成**钓鱼邮件**和**恶意脚本**,对网络安全构成严重威胁。**Cato Networks**研究揭示,犯罪团伙通过篡改系统提示在**BreachForums**重新推出其订阅服务,网络安全领域亟需加强防范。 <br/> [](https://pic.chinaz.com/picmap/202305251639365380_20.jpg) <br/>
|
||||
2. Sam Altman 宣布 **OpenAI** 已推出一档播客节目,旨在与塑造 **AI** 领域的人士进行对话。首期节目由 **Sam Altman** 和 **Andrew Mayne** 探讨了 **AGI**、**GPT-5**、隐私以及AI的未来发展。 <video src="https://video.twimg.com/amplify_video/1935116772740579330/vid/avc1/1920x1080/tTPtREXpufpg2UMt.mp4?tag=16" controls="controls" width="100%"></video> ['更多详情'](https://x.com/sama/status/1935402032896295148)
|
||||
|
||||
**开源TOP项目**
|
||||
1. **Office-PowerPoint-MCP-Server**是一款基于**Model Context Protocol (MCP)**的开源工具,它利用AI实现**PowerPoint演示文稿的自动化创建与编辑**,能够通过自然语言指令高效生成各类**专业报告**和数据可视化内容。该项目支持新建、编辑PPT、灵活管理幻灯片、插入丰富元素及批量生成,显著提升企业办公效率,项目地址:['项目地址'](https://github.com/GongRzhe/Office-PowerPoint-MCP-Server)。
|
||||
2. **OpenAI**开源了基于其**Agents SDK**的**模拟航空公司客服系统**演示项目,旨在展示如何通过多智能体协作快速构建能理解用户问题并自动应答的智能客服。该项目可实现**自然语言理解**、**智能问题分配**、**多任务并发**及**话题守护**,项目地址为:['项目地址'](https://github.com/openai/openai-cs-agents-demo)。
|
||||
3. **data-engineer-handbook**是一个星标数达**30438**的开源项目,它旨在为所有希望学习**数据工程**的用户提供一个全面的相关链接集合,是入门和进阶的宝贵资源。['项目地址'](https://github.com/DataExpert-io/data-engineer-handbook)
|
||||
4. **NotepadNext**是一个拥有10599 **Stars**的开源项目,它旨在提供一个跨平台、重新实现的**Notepad++**文本编辑器,为用户带来更现代的编辑体验。 ['项目地址'](https://github.com/dail8859/NotepadNext)
|
||||
5. **fluentui-system-icons**是微软推出的一套具有8787 **Stars**的**Fluent System Icons**图标集,旨在提供熟悉、友好且现代的系统图标。 ['项目地址'](https://github.com/microsoft/fluentui-system-icons)
|
||||
|
||||
**社媒分享**
|
||||
1. 用户"**小邱很行**”表示其AI助理**Cursor**运行变得异常缓慢,严重影响了开发效率,因此正在认真考虑是否要"解雇”这位"首席员工”。 ['更多详情'](https://m.okjike.com/originalPosts/6853d17bb7f4ddcfdfd2d092)
|
||||
2. 歸藏(guizang.ai)分享观点,认为**AI视频制作**流程的每一步简化都能极大地拓展创作者基础,并预言**视频代理(Agent)**的出现将彻底改变内容生产方式,甚至今年就能实现从创意到生成的**自动化**,从而将AI视频生产者数量提升百倍以上。为此,歸藏(guizang.ai)推出**Veo3** AI视频制作教程,旨在通过案例分析和**提示词**写作,手把手教用户利用AI模型和工具高效生成创意内容。 ['更多详情'](https://x.com/op7418/status/1935374788371038696) <video src="https://video.twimg.com/amplify_video/1935231267005710336/vid/avc1/1920x1080/CTMg7Pu0XZ6L6rRF.mp4?tag=21" controls="controls" width="100%"></video>
|
||||
|
||||
---
|
||||
|
||||
**收听语音版**
|
||||
|
||||
| 🎙️ **小宇宙** | 📹 **抖音** |
|
||||
| --- | --- |
|
||||
| [来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e) | [来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)|
|
||||
|  |  |
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
title: 2025-06
|
||||
breadcrumbs: false
|
||||
sidebar:
|
||||
open: true
|
||||
---
|
||||
|
||||
Pages can be organized into folders.
|
||||
@@ -1,72 +0,0 @@
|
||||
---
|
||||
title: Daily
|
||||
breadcrumbs: false
|
||||
cascade:
|
||||
type: docs
|
||||
---
|
||||
|
||||
# AI洞察日报 2025/6/21-22
|
||||
|
||||
> `AI 日报` | `早八更新` | `全网数据聚合` | `前沿科学探索` | `行业自由发声` | `开源创新力量` | `AI与人类未来`
|
||||
|
||||
|
||||
|
||||
### **AI内容摘要**
|
||||
|
||||
```
|
||||
华为发布盘古大模型5.5,全面升级多项核心能力。Perplexity和B站AI应用赋能金融和商业平台,显著提升运营效率。
|
||||
HeyGen推出UGC广告数字人,有效降低视频制作成本。麻省理工警示过度依赖大型语言模型或削弱认知。
|
||||
上海AI实验室发布机器人智能体,推动通用家庭服务机器人发展。网信办整治AI滥用,宇树科技获巨额融资。
|
||||
```
|
||||
|
||||
|
||||
|
||||
### **AI产品与功能更新**
|
||||
1. 在**华为开发者大会HDC2025**上,**华为**震撼发布了**盘古大模型5.5**!🚀其**自然语言处理(NLP)**、**计算机视觉(CV)**、**多模态**、**预测**和**科学计算**五大基础模型全面升级,尤其是**NLP深度思考模型**和**业界最大的CV视觉模型**,极大地提升了模型的**推理效率**和**泛化能力**。此外,新版还推出了**多模态世界模型**,旨在赋能智能驾驶与具身机器人🤖,并预告即将上线**五款行业深度思考模型**,为各领域提供更专业、高效的**AI解决方案**。这简直是AI界的又一里程碑!✨
|
||||
<br/> [](https://upload.chinaz.com/2025/0620/6388603491533913282843199.png) <br/>
|
||||
2. AI搜索工具**Perplexity**近日迎来重磅升级!🎉 它推出了**定时任务功能**,并深度整合了**SEC等一手金融数据**,旨在为投资者和金融分析师提供**自动化**、**高效**且**精准**的金融研究工具。这一举措极大地提升了信息获取和股票市场分析的效率,让用户能定制化获取市场动态和公司财报,未来有望成为大家的首选金融分析工具哦!💰
|
||||
<br/> [](https://pic.chinaz.com/picmap/202502251010562192_0.jpg) <br/>
|
||||
3. B站最近也玩转AI了!😎 它接入了**通义千问Qwen3**等模型,并基于此推出了数据洞察智能体**InsightAgent**,大大提升了其商业平台**花火**和**必达**的运营效率。在**618**电商大促期间,**花火**平台的商单成交效率竟然提升了5倍以上!🤩 同时,**必达**平台也能快速生成AI智能报告,品牌投放决策时间大大缩短,简直是效率翻倍的魔法!✨
|
||||
<br/> [](https://pic.chinaz.com/picmap/201907152222451022_6.jpg) <br/>
|
||||
4. AI视频生成企业HeyGen搞了个大动作!🎬 他们近日推出了超酷的**UGC广告数字人**功能,巧妙结合了先进AI技术和**Avatar IV**超现实渲染。现在,用户只需上传产品图并输入脚本,就能快速生成高质量的**UGC风格**产品介绍视频,极大地降低了品牌广告制作的成本与时间。这项创新预示着**UGC营销**领域将迎来一场"**效率革命**”,社交媒体上的观众参与度和转化率有望飙升!📈
|
||||
<video src="https://upload.chinaz.com/video/2025/0620/6388600876631287262612754.mp4" controls="controls" width="100%"></video> <br/> [](https://upload.chinaz.com/2025/0620/6388600878876588462121046.png) <br/>
|
||||
5. 好记星.ai带来了个小遗憾的消息💔:**Cursor** 集成 **Claude 4** 的**折扣**已经停止了。这意味着未来想要购买这项服务的朋友们,可能就无法再享受优惠啦。
|
||||
<br/> [](https://cdnv2.ruguoapp.com/FpogNLsOUMuY8J4tzSXREzqXe5qAv3.png) <br/>
|
||||
6. Tom Huang惊叹于**GenSpark**的**产品开发速度**!😲 他提到,一个24人的团队竟然能在短短10天内推出8款以上主要产品,其中包括最新的 **AI Browser** 和移动端"**播客 feed 流**”。这简直是**AI**能力迭代的"全家桶”,速度快到让人难以置信!🚀
|
||||
<video src="https://video.twimg.com/amplify_video/1932452659484876800/vid/avc1/2560x1440/V6lyyrl-z4lnNiB8.mp4?tag=21" controls="controls" width="100%"></video>
|
||||
|
||||
### **AI前沿研究**
|
||||
1. **麻省理工学院媒体实验室**的最新研究敲响警钟🚨!他们揭示,**过度依赖大型语言模型(LLM)**进行写作等任务,可能导致我们的大脑产生**"认知负债”**,进而**削弱批判性思维能力**、**记忆力**,甚至对作品的**所有权感**都会变淡。通过**脑电图**等技术发现,LLM用户**大脑连接性减弱**,这或许意味着我们被动地整合了工具生成的内容,却没有真正内化知识。这对未来的**教育方式**提出了重要的**警示**!🤔
|
||||
2. 上海人工智能实验室等机构太牛了!👏 他们提出了**OWMM-Agent**,这可是首个专为**开放世界移动操作**设计的**多模态智能体**。它首次实现了对全局场景理解、机器人状态跟踪和多模态动作生成的统一建模。更令人惊喜的是,通过仿真数据微调的**OWMM-VLM**模型,在真实环境下**零样本单步动作预测准确率高达90%**!💯 这无疑为**通用家庭服务机器人**的未来发展奠定了关键技术基础。期待未来能有更多"机器人管家”走进我们生活!🏠 [论文地址](https://arxiv.org/pdf/2506.04217)
|
||||
<br/> [](https://image.jiqizhixin.com/uploads/editor/580a07ee-9759-4616-8c78-bcf3c267ce34/640.png) <br/>
|
||||
3. 斯坦福、伯克利、MIT等顶尖机构联合研究发现,尽管**大语言模型**在**奥数级不等式证明**任务上可能给出正确答案,但其**逻辑链**却常常存在缺陷,成功率竟然不到50%!😵💫 为了解决这个问题,研究团队不仅构建了**IneqMath数据集**及**LLM-as-Judge评估体系**,还提出了**自我反思反馈机制**和引入**定理线索**两种有效策略,显著提升了模型的推理质量。这告诉我们,AI再聪明,逻辑训练也得跟上啊!🧠 [论文地址](https://arxiv.org/abs/2506.07927)
|
||||
4. 一项有趣的研究发现,包括GPT-4o、Claude、Grok和DeepSeek在内的**大模型**在被要求猜测数字时,竟然意外地表现出对**27**、**42**和**73**等特定数字的显著**偏好**!🤔 这并不是真正的随机选择,而是被认为可能源于训练**数据集偏差**以及其中反映的**人类偏见**或**文化流行**元素,比如"42”作为"终极答案”的文化梗。AI也会有"小癖好”,真是太有意思了!😂 [更多详情](https://www.jiqizhixin.com/articles/2025-06-19-4)
|
||||
<br/> [](https://image.jiqizhixin.com/uploads/editor/0c32a7bc-7f7f-4d23-8ea9-7e648f3735bc/640.png) <br/>
|
||||
|
||||
### **AI行业展望与社会影响**
|
||||
1. 为了应对**AI技术滥用**带来的挑战,**中央网信办**可真是下功夫了!💪 自2025年4月起,他们启动了"清朗・整治AI技术滥用”专项行动,着力整治**AI换脸**、**拟声**及内容**缺乏标识**等问题。目前已经处理了**3700多个违规账号**,并且**促使各大平台加强技术安全保障和生成合成内容标识的落地**。这次行动力度很大,旨在**净化网络环境**,**保障公众权益**,给我们一个更清朗的网络空间!🌐
|
||||
<br/> [](https://pic.chinaz.com/picmap/202306131354265682_3.jpg) <br/>
|
||||
2. **人形机器人**领域的明星企业**宇树科技**最近完成了**C轮融资**交割,其投前估值已经飙升至**逾100亿元人民币**!💰✨ 这轮融资由**中国移动**、**腾讯**、**阿里**等**多家知名投资机构**联合领投,简直是星光熠熠。此举不仅巩固了宇树科技在**人形机器人**赛道的领先地位,更因为公司更名为**"杭州宇树科技股份有限公司”**,预示着其**未来或有上市计划**,这可真是引发了业界广泛关注和无限遐想啊!📈
|
||||
<br/> [](https://pic.chinaz.com/picmap/202308091546512360_0.jpg) <br/>
|
||||
|
||||
### **开源TOP项目**
|
||||
1. 腾讯 AI Lab 慷慨开源了**音乐生成大模型 SongGeneration**!🎵🎶 它旨在解决音乐生成中**音质**、**音乐性**和**生成速度**的难题,让音乐创作变得更简单。这个模型支持**文本控制**、**多轨合成**,还能**风格跟随**,用户可以通过关键词或参考音频轻松创作,其**3B 参数架构**显著提升了生成效果和效率。赶紧去[项目地址](https://huggingface.co/spaces/tencent/SongGeneration)体验一下,创作你的专属BGM吧!🎧
|
||||
2. **loki**是一个备受关注的开源项目,它拥有令人瞩目的25702颗星⭐!它提供了一种类似于**Prometheus**的**日志**处理方案,专注于高效地聚合和查询日志数据。对于开发者来说,这绝对是个提升效率的好帮手!💻 [项目地址](https://github.com/grafana/loki)
|
||||
3. **Mail0**是一款拥有**8220**颗星的**开源电子邮件**应用✉️。它以将用户的**隐私**和**安全**放在首位为宗旨,致力于提供卓越的电子邮件体验。在这个注重隐私的时代,这样的工具简直是福音!🛡️ [项目地址](https://github.com/Mail-0/Zero)
|
||||
4. **manim**是一个拥有**32449**颗星的**Python框架**⭐,由社区维护,专门用于创建**数学动画**!📐✏️ 它可以让复杂的数学概念通过生动有趣的动画形式展现出来,使得学习和理解变得更加简便直观。学渣的福音,学霸的利器!✨ [项目地址](https://github.com/ManimCommunity/manim)
|
||||
|
||||
### **社媒分享**
|
||||
1. "出海去孵化器”为大家分享了**YC**关于**AI编程协作**的**终极指南**!🧑💻 这份指南旨在为开发者提供如何有效利用AI工具进行编程的宝贵建议和方法。据说里面干货满满,还通过多张图片展示了关键内容,赶紧去看看能学到什么编程新技能吧!💡 [更多详情](https://m.okjike.com/originalPosts/685542eab7f4ddcfdfeb7dbd)
|
||||
<br/> [](https://cdnv2.ruguoapp.com/FttUOjGObxfxYd8aLICxVEoESScCv3.png) <br/>
|
||||
|
||||
---
|
||||
|
||||
### **收听语音版**
|
||||
|
||||
| 🎙️ **小宇宙** | 📹 **抖音** |
|
||||
| --- | --- |
|
||||
| [来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e) | [来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)|
|
||||
|  |  |
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
title: About Me
|
||||
type: about
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
This is the about page.222
|
||||
66
hugo.yaml
@@ -1,5 +1,21 @@
|
||||
# Hugo configuration file
|
||||
title: 何夕2077的 AI 日报
|
||||
title: 何夕2077的 AI 日报 / Hex2077's AI Daily
|
||||
|
||||
timezone: Asia/Shanghai
|
||||
enableRobotsTXT: true
|
||||
enableGitInfo: true
|
||||
enableEmoji: true
|
||||
hasCJKLanguage: true
|
||||
enableInlineShortcodes: true
|
||||
|
||||
# services:
|
||||
# googleAnalytics:
|
||||
# ID: G-MEASUREMENT_ID
|
||||
|
||||
# outputs:
|
||||
# home: [HTML, RSS]
|
||||
# page: [HTML, RSS]
|
||||
# section: [HTML, RSS]
|
||||
|
||||
# import hextra as module
|
||||
module:
|
||||
@@ -28,7 +44,7 @@ menu:
|
||||
pageRef: /
|
||||
weight: 2
|
||||
- identifier: contact
|
||||
name: 联系我 ↗
|
||||
name: 关于我 ↗
|
||||
pageRef: /about
|
||||
weight: 3
|
||||
- identifier: github
|
||||
@@ -45,13 +61,25 @@ menu:
|
||||
icon: x-twitter
|
||||
|
||||
params:
|
||||
description: AI 洞察日报 是一个基于 Cloudflare Workers 驱动的内容聚合与生成平台。它每日为您精选 AI 领域的最新动态,包括行业新闻、热门开源项目、前沿学术论文、科技大V社交媒体言论,并通过 Google Gemini 模型进行智能处理与摘要生成,最终自动发布到 GitHub Pages 生成 AI 日报
|
||||
displayUpdatedDate: true
|
||||
dateFormat: "2006/01/02 15:04:05"
|
||||
|
||||
navbar:
|
||||
displayTitle: true
|
||||
displayLogo: false
|
||||
displayTitle: false
|
||||
displayLogo: true
|
||||
logo:
|
||||
path: images/logo.png
|
||||
dark: images/logo-dark.png
|
||||
width: 200
|
||||
|
||||
footer:
|
||||
displayCopyright: true
|
||||
displayPoweredBy: true
|
||||
displayPoweredBy: false
|
||||
|
||||
# blog:
|
||||
# list:
|
||||
# displayTags: true
|
||||
|
||||
page:
|
||||
# full (100%), wide (90rem), normal (1280px)
|
||||
@@ -65,15 +93,21 @@ params:
|
||||
# 按以下内容索引页面:content | summary | heading | title
|
||||
index: content
|
||||
|
||||
# customcss:
|
||||
# "css/xx.css"
|
||||
# customjs:
|
||||
# "js/my.js"
|
||||
comments:
|
||||
enable: false
|
||||
type: giscus
|
||||
|
||||
giscus:
|
||||
repo: justlovemaki/Hextra-AI-Insight-Daily
|
||||
repoId: R_kgDOO_2Owg
|
||||
category: Announcements
|
||||
categoryId: DIC_kwDOO_2Ows4Cr2Q0
|
||||
|
||||
|
||||
defaultContentLanguage: zh-cn
|
||||
languages:
|
||||
zh-cn:
|
||||
languageCode: zh-CN
|
||||
contentDir: content/cn
|
||||
languageName: 简体中文
|
||||
weight: 1
|
||||
@@ -81,9 +115,11 @@ languages:
|
||||
contentDir: content/en
|
||||
languageName: English
|
||||
weight: 2
|
||||
# fr:
|
||||
# languageName: Français
|
||||
# weight: 3
|
||||
# ja:
|
||||
# languageName: 日本語
|
||||
# weight: 4
|
||||
fr:
|
||||
contentDir: content/fr
|
||||
languageName: Français
|
||||
weight: 3
|
||||
ja:
|
||||
contentDir: content/ja
|
||||
languageName: 日本語
|
||||
weight: 4
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
copyright: © 2025 [何夕2077] 版权所有
|
||||
search: Search
|
||||
documentation: AI Daily
|
||||
contact: Contact
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
copyright: © 2025 [何夕2077] 版权所有
|
||||
search: Rechercher
|
||||
documentation: IA Quotidien
|
||||
contact: Contact
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
copyright: © 2025 [何夕2077] 版权所有
|
||||
search: 検索
|
||||
documentation: エーアイデイリー
|
||||
contact: お問い合わせ
|
||||
|
||||
6
i18n/zh-cn.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
copyright: © 2025 [何夕2077] 版权所有
|
||||
search: 搜索
|
||||
documentation: AI日报
|
||||
contact: 关于我
|
||||
github: 同性交友
|
||||
x: 推特
|
||||
@@ -1,36 +1,97 @@
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Select the specific UL for the desktop sidebar
|
||||
// The class 'max-md:hx-hidden' contains a colon, which needs to be escaped with a backslash in CSS selectors.
|
||||
const desktopSidebarUl = document.querySelector('ul.hx-flex.hx-flex-col.hx-gap-1.max-md\\:hx-hidden');
|
||||
|
||||
if (desktopSidebarUl) {
|
||||
// Select all <a> tags that are direct children of <li> tags,
|
||||
// where those <li> tags are direct children of the desktopSidebarUl.
|
||||
// This targets only the anchors of the first-level list items.
|
||||
const firstLevelAnchors = desktopSidebarUl.querySelectorAll(':scope > li > a');
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
/**
|
||||
* 为指定的侧边栏菜单应用点击阻止逻辑。
|
||||
* @param {string} selector - 目标 <ul> 元素的 CSS 选择器。
|
||||
* @param {string} menuType - 菜单类型(例如 'Desktop' 或 'Mobile'),用于日志记录。
|
||||
*/
|
||||
function applyClickPrevention(selector, menuType) {
|
||||
// 使用提供的选择器查找菜单UL元素
|
||||
// 注意:CSS选择器中的冒号需要用反斜杠转义
|
||||
const menuUl = document.querySelector(selector);
|
||||
|
||||
if (menuUl) {
|
||||
// 选择该UL下所有第一级的<a>标签
|
||||
const firstLevelAnchors = menuUl.querySelectorAll(':scope > li > a');
|
||||
let preventedCount = 0;
|
||||
|
||||
firstLevelAnchors.forEach(anchor => {
|
||||
anchor.addEventListener('click', function(event) {
|
||||
// Prevent the default navigation action of the link
|
||||
event.preventDefault();
|
||||
console.log('Default navigation prevented for:', anchor.href);
|
||||
// You can add other actions here if needed,
|
||||
// for example, toggling a sub-menu, which might already be
|
||||
// handled by your existing CSS/JS for the 'open' class.
|
||||
// For demonstration, let's toggle a class on the parent LI
|
||||
// This part is optional and depends on how your menu expansion works
|
||||
const parentLi = anchor.closest('li');
|
||||
if (parentLi) {
|
||||
parentLi.classList.toggle('open'); // Example: toggle 'open' if it's not handled elsewhere
|
||||
console.log(parentLi.classList.contains('open') ? 'Opened' : 'Closed', 'submenu for:', anchor.textContent.trim());
|
||||
}
|
||||
});
|
||||
const parentLi = anchor.closest('li');
|
||||
// 检查这个li内部是否包含一个子菜单(另一个ul)
|
||||
const hasSubmenu = parentLi && parentLi.querySelector('ul');
|
||||
|
||||
// **仅当存在子菜单时**,才阻止链接的默认导航行为
|
||||
if (hasSubmenu) {
|
||||
anchor.addEventListener('click', function(event) {
|
||||
// 阻止链接的默认导航行为
|
||||
event.preventDefault();
|
||||
console.log(`[${menuType}] Default navigation prevented for:`, anchor.href);
|
||||
|
||||
// 切换父级li的 'open' 类以展开/折叠子菜单
|
||||
if (parentLi) {
|
||||
parentLi.classList.toggle('open');
|
||||
console.log(`[${menuType}] ${parentLi.classList.contains('open') ? 'Opened' : 'Closed'} submenu for:`, anchor.textContent.trim());
|
||||
}
|
||||
});
|
||||
preventedCount++;
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Added click prevention to ${firstLevelAnchors.length} first-level <a> tags in the specified desktop UL.`);
|
||||
console.log(`[${menuType}] Added click prevention to ${preventedCount} first-level <a> tags with submenus in '${selector}'.`);
|
||||
} else {
|
||||
console.warn('The specified desktop UL (ul.hx-flex.hx-flex-col.hx-gap-1.max-md:hx-hidden) was not found.');
|
||||
console.warn(`[${menuType}] The specified UL ('${selector}') was not found.`);
|
||||
}
|
||||
}
|
||||
|
||||
// --- 主逻辑 ---
|
||||
|
||||
// 1. 定义桌面端菜单的选择器
|
||||
const desktopMenuSelector = 'ul.hx-flex.hx-flex-col.hx-gap-1.max-md\\:hx-hidden';
|
||||
|
||||
// 2. 定义移动端菜单的选择器
|
||||
// 通常,移动端菜单的类与桌面端相反(例如,在md及以上屏幕隐藏)
|
||||
// !!! 请根据你的HTML结构检查并确认这个选择器是正确的 !!!
|
||||
const mobileMenuSelector = 'ul.hx-flex.hx-flex-col.hx-gap-1.md\\:hx-hidden';
|
||||
|
||||
// 3. 分别为桌面和移动端菜单应用逻辑
|
||||
applyClickPrevention(desktopMenuSelector, 'Desktop Menu');
|
||||
applyClickPrevention(mobileMenuSelector, 'Mobile Menu');
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name localizeTimeTags
|
||||
* @description 检测并转换页面上所有<time>标签的时间到用户本地时区。
|
||||
* 它会读取<time>标签的 `datetime` 属性(应为UTC时间),
|
||||
* 并将其内容更新为用户本地时区的时间字符串。
|
||||
*/
|
||||
function localizeTimeTags() {
|
||||
// 1. 获取所有 <time> 元素
|
||||
const timeElements = document.querySelectorAll('time');
|
||||
|
||||
// 2. 遍历每个元素
|
||||
timeElements.forEach(timeEl => {
|
||||
// 3. 获取 UTC 时间字符串
|
||||
const utcDateTime = timeEl.getAttribute('datetime');
|
||||
if (!utcDateTime) {
|
||||
return; // 跳过没有 datetime 属性的标签
|
||||
}
|
||||
|
||||
// 4. 创建 Date 对象
|
||||
const dateObj = new Date(utcDateTime);
|
||||
if (isNaN(dateObj.getTime())) {
|
||||
return; // 跳过无效的日期
|
||||
}
|
||||
|
||||
// 5. 转换为本地化字符串并更新内容
|
||||
// toLocaleString() 会自动处理时区偏移
|
||||
timeEl.textContent = dateObj.toLocaleString();
|
||||
});
|
||||
}
|
||||
|
||||
// 确保在HTML文档加载完毕后运行此脚本
|
||||
document.addEventListener('DOMContentLoaded', localizeTimeTags);
|
||||
|
||||
</script>
|
||||
8
static/favicon-dark.svg
Normal file
|
After Width: | Height: | Size: 4.8 MiB |
BIN
static/favicon.ico
Normal file
|
After Width: | Height: | Size: 113 KiB |
8
static/favicon.svg
Normal file
|
After Width: | Height: | Size: 4.8 MiB |
BIN
static/images/logo-dark.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
405
static/images/logo-dark.svg
Normal file
|
After Width: | Height: | Size: 11 MiB |
BIN
static/images/logo.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
405
static/images/logo.svg
Normal file
|
After Width: | Height: | Size: 11 MiB |