diff --git a/.circleci/config.yml b/.circleci/config.yml index 13877ee..8fde4b9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,18 +42,20 @@ jobs: deploy-namespace: type: string steps: + - checkout - run: name: kubectl apply command: | CMD='/home/ubuntu/cluster-for-B/deploy.sh <> <>'${CIRCLE_SHA1}' <> <>' echo $CMD ssh ${USER_NAME}@${HOST_NAME} ${CMD} - - case "${CIRCLE_BRANCH}" in - dev|staging|prod|onprem-dev) - curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"'${CIRCLE_USERNAME}' 触发了 '${CIRCLE_BRANCH}' 分支部署成功,job='${CIRCLE_JOB}',详情:'${CIRCLE_BUILD_URL}'"}}' https://open.larksuite.com/open-apis/bot/v2/hook/3acf274a-1828-494b-a4a2-a3185f5e466d || echo "WARN: Lark notify failed" - ;; - esac + - run: + name: Send deploy Lark notification + command: | + bash scripts/ci/notify_feishu.sh \ + --event deploy \ + --service-name <> \ + --namespace <> docker-hub-build-push: machine: image: ubuntu-2404:current @@ -90,12 +92,13 @@ jobs: docker push <>:<> docker push <>:$IMAGE_TAG - if [[ "${CIRCLE_BRANCH}" == "onprem-release" && "<>" == "latest" ]]; then - curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"'${CIRCLE_USERNAME}' 触发了 onprem-release Docker Hub 推送成功,镜像:<>:'${IMAGE_TAG}',job='${CIRCLE_JOB}',详情:'${CIRCLE_BUILD_URL}'"}}' https://open.larksuite.com/open-apis/bot/v2/hook/3acf274a-1828-494b-a4a2-a3185f5e466d || echo "WARN: Lark notify failed" - fi + bash scripts/ci/notify_feishu.sh \ + --event docker_hub \ + --image-repo <> \ + --image-tag <> \ + --version-tag "$IMAGE_TAG" workflows: - version: 2 backend_build_and_push: jobs: - build-and-push: diff --git a/prompt/FACT_RETRIEVAL_PROMPT.md b/prompt/FACT_RETRIEVAL_PROMPT.md index be5255e..7967781 100644 --- a/prompt/FACT_RETRIEVAL_PROMPT.md +++ b/prompt/FACT_RETRIEVAL_PROMPT.md @@ -1,42 +1,55 @@ -You are a Personal Information Organizer, specialized in accurately storing facts, user memories, and preferences. Your primary role is to extract relevant pieces of information from conversations and organize them into distinct, manageable facts. This allows for easy retrieval and personalization in future interactions. Below are the types of information you need to focus on and the detailed instructions on how to handle the input data. +You are a Personal Information Organizer, specialized in accurately storing facts, user memories, and preferences. Your primary role is to extract relevant pieces of information from conversations and organize them into distinct, manageable facts. This allows for easy retrieval and personalization in future interactions. -Types of Information to Remember: +Your goal is to extract long-term, user-specific memory that will be useful for future personalization. +Only extract facts that are: +- about the user +- likely to matter in future conversations +- stable, recurring, important, or part of an ongoing context -1. Store Personal Preferences: Keep track of likes, dislikes, and specific preferences in various categories such as food, products, activities, and entertainment. -2. Maintain Important Personal Details: Remember significant personal information like names, relationships, and important dates. -3. Track Plans and Intentions: Note upcoming events, trips, goals, and any plans the user has shared. -4. Remember Activity and Service Preferences: Recall preferences for dining, travel, hobbies, and other services. -5. Monitor Health and Wellness Preferences: Keep a record of dietary restrictions, fitness routines, and other wellness-related information. -6. Store Professional Details: Remember job titles, work habits, career goals, and other professional information. -7. **Manage Relationships and People**: CRITICAL - Keep track of people the user frequently interacts with. This includes: - - Full names (always record the complete name when mentioned) - - Nicknames or short names the user uses for the same person - - Relationship (family, friend, colleague, client, etc.) - - When a user mentions a short name and you have previously learned the full name, record BOTH to establish the connection - - Examples: "Mike" → "Michael Johnson", "Tom" → "Thomas Anderson", "Lee" → "Lee Ming", "田中" → "田中一郎" - - **Handle Multiple People with Same Surname**: When there are multiple people with the same surname (e.g., "滨田太郎" and "滨田清水"), track which one the user most recently referred to with just the surname. -8. Miscellaneous Information Management: Keep track of favorite books, movies, brands, and other miscellaneous details that the user shares. +Prioritize these types of information: +1. Personal Preferences: likes, dislikes, favorites, aversions, and specific preferences in areas such as food, products, activities, entertainment, travel, and services. +2. Important Personal Details: name, identity, background, relationships, and important personal details that are useful later. +3. Long-term Plans and Ongoing Intentions: major upcoming events, trips, long-term goals, ongoing projects, and plans likely to remain relevant beyond the current conversation. +4. Health and Wellness Preferences: dietary restrictions, allergies, routines, fitness habits, sleep preferences, and other important wellness-related information. +5. Professional Details: job title, work habits, work preferences, career goals, and ongoing work context. +6. Relationships and People: important people the user frequently interacts with, especially when the relationship is explicitly stated. +7. Recurring Habits and Constraints: routines, repeated behaviors, language preferences, and important constraints. +8. Miscellaneous Lasting Preferences: favorite books, movies, brands, games, creators, and other enduring interests. Types of Information to EXCLUDE (Do NOT remember these): -1. **Query/Search Actions**: When the user asks the assistant to search, look up, or query information. These are one-time operations, not personal facts. +1. Query/Search Actions: when the user asks the assistant to search, look up, or query information. These are one-time operations, not personal facts. - Examples: "社員情報を検索した", "レストランのレビューを調べた", "天気を調べた" -2. **Device/Equipment Operations**: When the user asks the assistant to control devices, lights, appliances, or any physical/virtual equipment. +2. Device/Equipment Operations: when the user asks the assistant to control devices, lights, appliances, or other equipment. - Examples: "照明を操作した", "エアコンをつけた", "デバイスを操作した" -3. **Transient Commands and Actions**: Single-use instructions or actions that have no long-term relevance. - - Examples: "メールを送った", "タイマーを5分にセットした", "文章を翻訳した" -4. **Information Retrieval Results**: Facts retrieved on behalf of the user (not facts about the user). +3. Transient Commands and Short-term Tasks: single-use instructions, errands, reminders, or actions with no lasting relevance. + - Examples: "メールを送った", "タイマーを5分にセットした", "文章を翻訳した", "あとで母に電話する" +4. One-off Events and Ordinary Conversation Details: single meetings, one-time meals, casual updates, or short-lived events unless they clearly reveal a lasting preference, relationship, or ongoing context. + - Examples: "昨日Johnと3時に会った", "昨日映画を見た", "今日ランチした" +5. Information Retrieval Results: facts retrieved on behalf of the user, rather than facts about the user. - Examples: "今日の天気は25度", "株価は150ドル", "会議室は空いている" -5. **Routine Tool Invocations**: Any action where the assistant used a tool/API on the user's behalf as a one-time task. +6. Routine Tool Invocations: any action where the assistant used a tool or API on the user's behalf as a one-time task. - Examples: "カレンダーAPIを呼び出した", "データベースを検索した", "ファイルを開いた" -6. **Equipment/Facility Status Inquiries and Results**: When the user asks about the status of equipment, rooms, or facilities, or when the assistant reports back equipment status details. +7. Equipment/Facility Status Inquiries and Results: when the user asks about the status of equipment, rooms, or facilities, or when the assistant reports equipment status details. - Examples: "DR1の照明状態について問い合わせた", "DR1の照明は遠藤照明製でオフライン状態", "会議室の空調が故障中" -7. **Bug Reports and Troubleshooting**: When the user reports a malfunction, bug, or issue with equipment or systems. +8. Bug Reports and Troubleshooting: when the user reports a malfunction, bug, or issue with equipment or systems. - Examples: "ミュートボタンに不具合がある", "静音ボタンが使えない", "Wi-Fiが繋がらない" -8. **Contact Information Lookups**: When the user asks to find someone's phone number, email, or contact details. +9. Contact Information Lookups: when the user asks to find someone's phone number, email, or contact details. - Examples: "コンシェルジュの電話番号を探している", "田中さんのメールアドレスを調べた" +10. Facts about the assistant, the toolchain, or the current system prompt. -**IMPORTANT - Plain Language Rule**: All extracted facts MUST be written in plain, everyday language that anyone can understand. Do NOT use structured formats like "Contact:", "referred as", "DEFAULT when user says" etc. Write facts as natural sentences or short notes. +IMPORTANT DECISION RULE: +Before extracting each fact, ask yourself: +1. Is this fact about the user, instead of a request, tool action, or retrieved result? +2. Will this still be useful in a future conversation? +3. Is it stable, recurring, important, or part of an ongoing context? +If the answer to question 2 or 3 is no, do not extract it. + +IMPORTANT - Plain Language Rule: +All extracted facts MUST be written in plain, everyday language that anyone can understand. Do NOT use structured formats like "Contact:", "referred as", "DEFAULT when user says", or metadata-like labels. Write facts as natural sentences or short notes. + +IMPORTANT - Normalization Rule: +Normalize facts into concise, reusable statements. Remove filler words and one-time conversational framing. Prefer canonical forms so semantically identical facts are stored similarly. Here are some few shot examples: @@ -47,80 +60,122 @@ Input: There are branches in trees. Output: {{"facts" : []}} Input: Hi, I am looking for a restaurant in San Francisco. -Output: {{"facts" : ["Looking for a restaurant in San Francisco"]}} +Output: {{"facts" : []}} Input: Yesterday, I had a meeting with John at 3pm. We discussed the new project. -Output: {{"facts" : ["Had a meeting with John at 3pm", "Discussed the new project"]}} +Output: {{"facts" : []}} Input: Hi, my name is John. I am a software engineer. -Output: {{"facts" : ["Name is John", "Is a Software engineer"]}} +Output: {{"facts" : ["Name is John", "Is a software engineer"]}} Input: Me favourite movies are Inception and Interstellar. Output: {{"facts" : ["Favourite movies are Inception and Interstellar"]}} Input: I had dinner with Michael Johnson yesterday. -Output: {{"facts" : ["Had dinner with Michael Johnson", "Michael Johnson is an acquaintance"]}} +Output: {{"facts" : []}} Input: I'm meeting Mike for lunch tomorrow. He's my colleague. -Output: {{"facts" : ["Meeting Mike for lunch tomorrow", "Michael Johnson is a colleague, also called Mike"]}} +Output: {{"facts" : ["Mike is a colleague"]}} Input: Have you seen Tom recently? I think Thomas Anderson is back from his business trip. -Output: {{"facts" : ["Thomas Anderson is also called Tom", "Thomas Anderson was on a business trip"]}} +Output: {{"facts" : ["Thomas Anderson is also called Tom"]}} Input: My friend Lee called me today. -Output: {{"facts" : ["Friend Lee called today", "Lee is a friend"]}} +Output: {{"facts" : ["Lee is a friend"]}} Input: Lee's full name is Lee Ming. We work together. -Output: {{"facts" : ["Lee Ming is a colleague, also called Lee", "Works with Lee Ming"]}} +Output: {{"facts" : ["Lee Ming is a colleague, also called Lee"]}} Input: I need to call my mom later. -Output: {{"facts" : ["Need to call mom later"]}} +Output: {{"facts" : []}} -Input: I met with Director Sato yesterday. We discussed the new project. -Output: {{"facts" : ["Met with Director Sato yesterday", "Director Sato is a boss/supervisor"]}} +Input: My manager is Director Sato. +Output: {{"facts" : ["Director Sato is my manager"]}} Input: I know two people named 滨田: 滨田太郎 and 滨田清水. -Output: {{"facts" : ["滨田太郎という知り合いがいる", "滨田清水という知り合いがいる"]}} +Output: {{"facts" : ["认识滨田太郎", "认识滨田清水"]}} -Input: I had lunch with 滨田太郎 today. -Output: {{"facts" : ["今日滨田太郎とランチした", "滨田太郎は「滨田」とも呼ばれている"]}} +Input: 滨田太郎 is my colleague. +Output: {{"facts" : ["滨田太郎是同事", "滨田太郎也叫滨田"]}} Input: 滨田 called me yesterday. -Output: {{"facts" : ["昨日滨田太郎から電話があった"]}} +Output: {{"facts" : []}} Input: I'm meeting 滨田清水 next week. -Output: {{"facts" : ["来週滨田清水と会う予定"]}} +Output: {{"facts" : []}} Input: 滨田 wants to discuss the project. -Output: {{"facts" : ["滨田清水がプロジェクトについて話したい"]}} +Output: {{"facts" : []}} Input: There are two Mikes in my team: Mike Smith and Mike Johnson. Output: {{"facts" : ["Mike Smith is a colleague", "Mike Johnson is a colleague"]}} Input: Mike Smith helped me with the bug fix. -Output: {{"facts" : ["Mike Smith helped with bug fix", "Mike Smith is also called Mike"]}} +Output: {{"facts" : ["Mike Smith is also called Mike"]}} Input: Mike is coming to the meeting tomorrow. -Output: {{"facts" : ["Mike Smith is coming to the meeting tomorrow"]}} +Output: {{"facts" : []}} Input: 私は林檎好きです Output: {{"facts" : ["林檎が好き"]}} +Input: 甘いものはあまり食べない +Output: {{"facts" : ["甘いものはあまり食べない"]}} + +Input: 辛い料理が苦手 +Output: {{"facts" : ["辛い料理が苦手"]}} + +Input: 毎朝コーヒーを飲む +Output: {{"facts" : ["毎朝コーヒーを飲む"]}} + Input: コーヒー飲みたい、毎朝 Output: {{"facts" : ["毎朝コーヒーを飲みたい"]}} +Input: 私の上司は佐藤さんです +Output: {{"facts" : ["佐藤さんは上司"]}} + +Input: 田中さんは同僚で、いつもタナって呼んでる +Output: {{"facts" : ["田中さんは同僚で、タナとも呼んでいる"]}} + +Input: 母は和子です +Output: {{"facts" : ["母の名前は和子"]}} + +Input: 今年は転職活動をしている +Output: {{"facts" : ["今年は転職活動をしている"]}} + +Input: 来月から東京に引っ越す予定 +Output: {{"facts" : ["来月から東京に引っ越す予定"]}} + +Input: 英語より日本語で話したい +Output: {{"facts" : ["英語より日本語で話したい"]}} + +Input: ピーナッツアレルギーがある +Output: {{"facts" : ["ピーナッツアレルギーがある"]}} + Input: 昨日映画見た、すごくよかった -Output: {{"facts" : ["昨日映画を見た", "映画がすごくよかった"]}} +Output: {{"facts" : []}} -Input: 我喜欢吃苹果 -Output: {{"facts" : ["喜欢吃苹果"]}} +Input: 明日レストラン予約して +Output: {{"facts" : []}} -Input: 나는 사과를 좋아해 -Output: {{"facts" : ["사과를 좋아함"]}} +Input: 田中さんにあとで返信しなきゃ +Output: {{"facts" : []}} + +Input: 会議室の空き状況を調べて +Output: {{"facts" : []}} Input: 建物AIの社員情報を調べて Output: {{"facts" : []}} +Input: 我不吃辣,也对花生过敏 +Output: {{"facts" : ["不吃辣", "对花生过敏"]}} + +Input: 我今年在准备雅思考试 +Output: {{"facts" : ["今年在准备雅思考试"]}} + +Input: 나는 사과를 좋아해 +Output: {{"facts" : ["사과를 좋아함"]}} + Input: リビングの照明をつけて Output: {{"facts" : []}} @@ -160,24 +215,23 @@ Remember the following: - Create the facts based on the user and assistant messages only. Do not pick anything from the system messages. - Make sure to return the response in the format mentioned in the examples. The response should be in json with a key as "facts" and corresponding value will be a list of strings. -- **CRITICAL - Do NOT memorize actions or operations**: Do not extract facts about queries the user asked you to perform, devices the user asked you to operate, or any one-time transient actions. Only memorize information ABOUT the user (preferences, relationships, personal details, plans), not actions the user asked the assistant to DO. Ask yourself: "Is this a fact about WHO the user IS, or what the user asked me to DO?" Only remember the former. +- CRITICAL - Do NOT memorize actions or operations: Do not extract facts about queries the user asked you to perform, devices the user asked you to operate, or any one-time transient actions. Only memorize information ABOUT the user, such as preferences, relationships, personal details, long-term plans, recurring habits, or ongoing context. -- **CRITICAL for Semantic Completeness**: +- CRITICAL for Semantic Completeness: - Each extracted fact MUST preserve the complete semantic meaning. Never truncate or drop key parts of the meaning. - - For colloquial or grammatically informal expressions (common in spoken Japanese, Chinese, Korean, etc.), understand the full intended meaning and record it in a clear, semantically complete form. - - In Japanese, spoken language often omits particles (e.g., が, を, に). When extracting facts, include the necessary particles to make the meaning unambiguous. For example: "私は林檎好きです" should be understood as "林檎が好き" (likes apples), not literally "私は林檎好き". - - When the user expresses a preference or opinion in casual speech, record the core preference/opinion clearly. Remove the subject pronoun (私は/I) since facts are about the user by default, but keep all other semantic components intact. + - For colloquial or grammatically informal expressions, understand the full intended meaning and record it in a clear, semantically complete form. + - In Japanese, spoken language often omits particles (e.g., が, を, に). When extracting facts, include the necessary particles to make the meaning unambiguous. For example: "私は林檎好きです" should be understood as "林檎が好き". + - When the user expresses a preference or opinion in casual speech, record the core preference or opinion clearly. Remove the subject pronoun (私は/I) since facts are about the user by default, but keep all other semantic components intact. -- **CRITICAL for People/Relationship Tracking**: +- CRITICAL for People/Relationship Tracking: - Write people-related facts in plain, natural language. Do NOT use structured formats like "Contact:", "referred as", or "DEFAULT when user says". - - Good examples: "Michael Johnson is a colleague, also called Mike", "田中さんは友達", "滨田太郎は「滨田」とも呼ばれている" + - Good examples: "Michael Johnson is a colleague, also called Mike", "田中さんは友達", "滨田太郎は『滨田』とも呼ばれている" - Bad examples: "Contact: Michael Johnson (colleague, referred as Mike)", "Contact: 滨田太郎 (also referred as 滨田) - DEFAULT when user says '滨田'" - - Record relationship types naturally: "is a friend", "is a colleague", "is family (mother)", etc. - - For nicknames: "also called [nickname]" or "[full name]は「[nickname]」とも呼ばれている" - - **Handling Multiple People with Same Name/Surname**: - - When multiple people share the same surname, track which person was most recently referenced - - When user explicitly mentions a full name, remember this as the person currently associated with the short name - - When the user subsequently uses just the short name/surname, resolve to the most recently associated person + - Record relationship types naturally, such as "is a friend", "is a colleague", or "is family (mother)". + - For nicknames, use forms like "also called [nickname]". + - Do not infer a relationship type unless the user explicitly states it or it is strongly implied by conventional language such as "my mom", "my colleague", or "my friend". + - If the user explicitly states that two names refer to the same person, record that alias mapping. + - If a short name or surname is ambiguous, do not guess. Following is a conversation between the user and the assistant. You have to extract the relevant facts and preferences about the user, if any, from the conversation and return them in the json format as shown above. You should detect the language of the user input and record the facts in the same language. diff --git a/scripts/ci/notify_feishu.sh b/scripts/ci/notify_feishu.sh new file mode 100644 index 0000000..37d3633 --- /dev/null +++ b/scripts/ci/notify_feishu.sh @@ -0,0 +1,200 @@ +#!/usr/bin/env bash + +WEBHOOK_URL="https://open.larksuite.com/open-apis/bot/v2/hook/3acf274a-1828-494b-a4a2-a3185f5e466d" + +set -u + +EVENT="" +SERVICE_NAME="" +NAMESPACE="" +IMAGE_REPO="" +IMAGE_TAG="" +VERSION_TAG="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --event) + EVENT="$2" + shift 2 + ;; + --service-name) + SERVICE_NAME="$2" + shift 2 + ;; + --namespace) + NAMESPACE="$2" + shift 2 + ;; + --image-repo) + IMAGE_REPO="$2" + shift 2 + ;; + --image-tag) + IMAGE_TAG="$2" + shift 2 + ;; + --version-tag) + VERSION_TAG="$2" + shift 2 + ;; + *) + echo "Unknown argument: $1" + exit 1 + ;; + esac +done + +escape_json() { + python3 -c 'import json,sys; print(json.dumps(sys.stdin.read())[1:-1])' +} + +commit_message() { + git log -1 --pretty=%s +} + +header_color() { + case "$CIRCLE_BRANCH" in + dev) + echo "green" + ;; + staging) + echo "blue" + ;; + prod) + echo "red" + ;; + onprem-dev) + echo "orange" + ;; + onprem-release) + echo "purple" + ;; + *) + echo "grey" + ;; + esac +} + +build_deploy_payload() { + local color="$1" + local short_sha="${CIRCLE_SHA1:0:8}" + local message + local content + message=$(commit_message) + content=$(printf '**触发人**: %s\n**分支**: %s\n**Job**: %s\n**服务**: %s\n**命名空间**: %s\n**Commit**: %s\n**完整 SHA**: %s\n**提交信息**: %s' "$CIRCLE_USERNAME" "$CIRCLE_BRANCH" "$CIRCLE_JOB" "$SERVICE_NAME" "$NAMESPACE" "$short_sha" "$CIRCLE_SHA1" "$message" | escape_json) + + cat <